One of the most iconic DV interview questions is “What are m_sequencer and p_sequencer?”. So, A good way to impress the interviewer is to answer the question by explaining how they work :)
What are p_sequencer and m_sequencer? Link to heading
p_sequencer
is declared using uvm_declare_p_sequencer
in the sequence to have access to the correct specialization of uvm_sequencer
.
class my_sequence extends uvm_sequence;
...
...
`uvm_declare_p_sequencer(ubus_slave_sequencer)
Which expands to the following where $cast
will only work if m_sequencer
can be cast to p_sequencer
(ie cast from base class to parameterized derived class)
`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
For m_sequencer
, It is defined in uvm_sequence_item
(The base class of uvm_sequence).
class uvm_sequence_item extends uvm_transaction;
...
...
protected uvm_sequencer_base m_sequencer;
who sets m_sequencer and p_sequencer? Link to heading
I will start with p_sequencer
and work my way backward and m_sequencer
will magically show up.
m_set_p_sequencer
is called from set_sequencer
in uvm_sequence_item.svh
virtual function void set_sequencer(uvm_sequencer_base sequencer);
m_sequencer = sequencer;
m_set_p_sequencer();
endfunction
see?! m_sequencer
showed up :)
set_sequencer
is called from set_item_context
function void set_item_context(uvm_sequence_base parent_seq,
uvm_sequencer_base sequencer = null);
set_sequencer(sequencer);
endfunction
set_item_context
is called from start()
virtual task start (uvm_sequencer_base sequencer,
uvm_sequence_base parent_sequence = null,
int this_priority = -1,
bit call_pre_post = 1);
set_item_context(parent_sequence, sequencer);
and here we are,At the good old sequence start.
m_myseq.start(m_myenv.m_seqr);