Monday, July 17, 2017

cast p_sequencer m_sequencer details

We can use p_sequencer as a handle to the sequencer and through that we can access other sequencers or environment hierarchy in the sequence where uvm_declare_p_sequencer macro has been used.
Below is my understanding and relevant information. You may please correct if required.
`define uvm_declare_p_sequencer(SEQUENCER) \
SEQUENCER p_sequencer;\
virtual function void m_set_p_sequencer();\
super.m_set_p_sequencer(); \
if( !$cast(p_sequencer, m_sequencer)) \
`uvm_fatal("DCLPSQ", \
$sformatf("%m %s Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer", get_full_name())) \
endfunction

p_sequencer type is specified in the argument(SEQUENCER) of `uvm_declare_p_sequencer macro.
When we call `uvm_declare_p_sequencer from sequence, it calls super.m_set_p_sequencer function, which internally will call m_set_sequencer of uvm_base_sequencer. 
When we call start task of sequence, it internally calls for set_item_context, set_item_context calls set_sequencer, set_sequencer assigns handle of sequencer (which we have passed in start task of sequence) to m_sequencer using static cast (***This is first casting or down casting)
virtual function void set_sequencer(uvm_sequencer_base sequencer);
m_sequencer = sequencer;
m_set_p_sequencer();
endfunction

set_sequencer also calls m_set_p_sequencer(declaring `uvm_declare_p_sequencer macro should override the m_set_p_sequencer hence m_set_p_sequencer defined in macro should be executed) which will cast m_sequencer back into p_sequencer using dynamic $cast. (***This is reverse casting or up casting)

MY QUESTIONs:
1. Why do we need this reverse/up casting? what is intended and achieved with this step?
2. Can we pass virtual sequencer as an argument to uvm_declare_p_sequencer inside both virtual sequence and non-virtual sequence? 
3. In case when we are using virtual sequence, and passed virtual sequencer as an argument to uvm_declare_p_sequencer inside it , when we call this virtual sequence from test , we pass null in the start task of the virtual sequence. In this case what will happen? m_sequencer = null and then , m_sequencer = p_sequencer and p_sequencer = m_sequencer , is that correct understanding? OR m_sequencer = p_sequencer and then m_sequencer = null and p_sequencer = m_sequencer , is that correct understanding?

No comments:

Post a Comment