經常使用這兩種方式啟動sequence,那它們有什麼區別呢?
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);
....
endtask
//from class uvm_sequence_item
function void set_item_context (uvm_sequence_base parent_seq,
uvm_sequencer_base sequencer = null);
set_use_sequence_info(1);
if (parent_seq != null) set_parent_sequence(parent_seq);
if (sequencer == null && m_parent_sequence != null) sequencer = m_parent_sequence.get_sequencer();
set_sequencer(sequencer);
if (m_parent_sequence != null) set_depth(m_parent_sequence.get_depth() + 1);
reseed();
endfunction
virtual function void set_sequencer(uvm_sequencer_base sequencer);
m_sequencer = sequencer;
m_set_p_sequencer();
endfunction
`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(...)\
function uvm_sequencer_base get_sequencer( );
return m_sequencer;
endfunction
function void set_parent_sequence(uvm_sequence_base parent);
m_parent_sequence = parent;
endfunction
function uvm_sequence_base get_parent_sequence();
return (m_parent_sequence);
endfunction
Class Hierarchy
uvm_void
uvm_object
uvm_transaction
uvm_sequence_item
uvm_sequence_base
uvm_sequence#(REQ,RSP)
从上面function看出:
1. 每次调用start task均会更新m_sequencer(m_sequencer指向调用start时指定的sequencer) ;
如果有调用uvm_declare_p_sequencer 进而会更新p_sequencer
2. 调用start时如果没有指定sequencer,则会调用parent_sequence的m_sequencer;
3. 若使用seq.start(null)则表明seq的sequencer和parent_sequence均为null;
uvm_do
`define uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, PRIORITY, CONSTRAINTS) \
begin \
uvm_sequence_base __seq; \
`uvm_create_on(SEQ_OR_ITEM, SEQR) \
if (!$cast(__seq,SEQ_OR_ITEM)) start_item(SEQ_OR_ITEM, PRIORITY);\
if ((__seq == null || !__seq.do_not_randomize) && !SEQ_OR_ITEM.randomize() with CONSTRAINTS ) begin \
`uvm_warning("RNDFLD", "Randomization failed in uvm_do_with action") \
end\
if (!$cast(__seq,SEQ_OR_ITEM)) finish_item(SEQ_OR_ITEM, PRIORITY); \
else __seq.start(SEQR, this, PRIORITY, 0); \
end
若使用`uvm_do(seq)启动sequence,有以下特點:
- 默認指定当前sequence为parent_sequence;
- `uvm_do(seq)只執行top sequence 的pre/post_body函數,sub sequence的pre/post_body不執行;
- seq中的staring_phase是為null的;