Cookbook mentions that $cast( rsp , req.clone() ) doesn’t copy the sequence_id by default
By default , req.clone() would call clone() method in uvm_object which then calls do_copy defined in uvm_transaction class.
As a result m_sequence_id isn’t copied via $cast( rsp , req.clone() ) .
However I am trying to write a code that copies it automatically .
`include "uvm_pkg.sv"
`include "uvm_macros.svh"
import uvm_pkg::*;
`define COMP_NEW function new ( string name , uvm_component parent ) ; \
super.new(name,parent);\
endfunction
`define OBJ_NEW function new ( string name = "" ) ; \
super.new(name);\
endfunction
class user_seq_item extends uvm_sequence_item ;
`uvm_object_utils(user_seq_item)
`OBJ_NEW
`ifdef COPY
function void do_copy (uvm_object rhs); // IMP_NOTE :: Called internally from clone() !!
user_seq_item req_item ;
`uvm_info(get_name,$sformatf(" In do_copy() "),UVM_NONE)
super.do_copy(rhs);
$cast( req_item , rhs ) ; // To Pass req_item to Copy Sequence_ID N Transaction_ID
this.set_id_info( req_item ) ; // Copies Sequence_ID N Transaction_ID from RHS
// argument !!
endfunction
`endif
`ifdef CLONE
function user_seq_item clone (); // IMP_NOTE :: return type isn't uvm_object , rather it's extended type 'user_seq_item' !!
user_seq_item req_item ;
$cast( req_item , super.clone() ) ;
req_item.set_id_info( this ) ;
return req_item ;
endfunction
`endif
endclass
typedef uvm_sequencer #(user_seq_item) user_sequencer ;
class my_driver extends uvm_driver #(user_seq_item) ;
`uvm_component_utils(my_driver)
`COMP_NEW
task main_phase( uvm_phase phase ) ;
forever
begin
seq_item_port.get_next_item(req) ;
`uvm_info(get_name(),$sformatf(" Received request"),UVM_NONE)
#10 ;
`ifdef COPY
rsp = user_seq_item::type_id::create("rsp",this) ;
rsp.copy( req ) ;
`elsif CLONE
rsp = req.clone() ;
`endif
`uvm_info(get_name,$sformatf(" req is %0p ",req),UVM_NONE)
`uvm_info(get_name,$sformatf(" rsp is %0p ",rsp),UVM_NONE)
seq_item_port.item_done() ;
end
endtask
endclass
class user_seq extends uvm_sequence#(user_seq_item) ;
`uvm_object_utils(user_seq)
`OBJ_NEW
task body() ;
req = user_seq_item::type_id::create("req") ;
repeat(2) begin
start_item(req);
finish_item(req);
end
endtask
endclass
I have a few questions ::
[Q1] Is there a preference between the 2 possible solution
( via +define+COPY OR +define+CLONE ) ?
[Q2] Via sequence_id the Sequencer routes the response to the appropraite
Sequence . What’s the application of transaction_id ??
[Q3] I observe that in both iterations of the body() task ,
after the driver fetches the Request both times m_sequence_id is set as 1
by the sequencer .
When can I expect to see a different value for m_sequence_id ??
{Q4] Apart from m_sequence_id and m_transaction_id , is there any other property I
should also copy ?
[Q5] I believe there is a correction needed in the Cookbook .
Cookbook says ::
“The uvm_sequence_item contains an id field which is set by a sequencer during the sequence start_item() call”
**Whereas in the Source Code its actually implementation of function ::
send_request() where the sequencer sets the transaction_id and sequence_id for
the sequence**
So in reality its actually call to finish_item() that sets the sequence_id
Thanks .