uvm基础--p_sequencer

349 阅读1分钟

`uvm_delare_p_sequencer常见用法:

`//| class mysequence extends uvm_sequence#(mydata);
//|   `uvm_object_utils(mysequence)
//|   `uvm_declare_p_sequencer(some_seqr_type)
//|   task body`;`
//|     //Access some variable in the user's custom sequencer
//|     if(p_sequencer.some_variable) begin
//|       ...
//|     end
//|   endtask
//| endclass
//`

即在sequence中想要使用sequencer中函数或变量时才会使用psequencer.

1. :`uvm_delare_p_sequencer 分析

源码如下:

`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句柄,类型为该宏传入的sequencer类型,一般为要挂载的sequencer类型。

2 start()如何处理p_sequencer?

                      uvm_sequence_base parent_sequence = null,
                      int this_priority = -1,
                      bit call_pre_post = 1);
    bit                  old_automatic_phase_objection;
     
    set_item_context(parent_sequence, sequencer);

    if (!(m_sequence_state inside {UVM_CREATED,UVM_STOPPED,UVM_FINISHED})) begin
      uvm_report_fatal("SEQ_NOT_DONE", 
         {"Sequence ", get_full_name(), " already started"},UVM_NONE);
    end



  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

可见,start()函数会传入实际使用的sequencer句柄,这个句柄会赋给m_sequencer,再由m_sequencer赋给p_sequencer,m_squencer是base_sequencer类型,但p_sequcner是具体使用的sequencer类型,因此必须保证p_sequncer declare类型与start()传入句柄类型一致。