Copying Sequence ID via req.clone()

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 .

In reply to TC_2017:

I think the preference should be in copy() because that is the functionality you are preforming. I never see anyone use copy() directly—it’s always clone() which calls create followed by copy. So I don’t think it matters much.

The transaction_id matters when you have pipelined requests and responses, or out-of-order responses. The sequence_id will matter when you have more than one sequencer.

I agree the cookbook should say finish_item. I don’t know that it makes any difference because no one will be looking at it until it gets to the driver.