virtual_sequencer的使用总结

现在我们来一步一步解析,如何构造virtual sequencer和virtual sequence以及他们背后的原理,先看一段uvm 源码:

uvm_do_on的源码如下:

// MACRO: `uvm_do_on
//
//| `uvm_do_on(SEQ_OR_ITEM, SEQR)
//
// This is the same as <`uvm_do> except that it also sets the parent sequence to
// the sequence in which the macro is invoked, and it sets the sequencer to the
// specified ~SEQR~ argument.

`define uvm_do_on(SEQ_OR_ITEM, SEQR) \
  `uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, -1, {})

uvm_do_on_with的源码如下:

// MACRO: `uvm_do_on_pri_with
//
//| `uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, PRIORITY, CONSTRAINTS)
//
// This is the same as `uvm_do_pri_with except that it also sets the parent
// sequence to the sequence in which the macro is invoked, and it sets the
// sequencer to the specified ~SEQR~ argument.

`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_on其实是套着uvm_do_on_pri_with源码的壳子,实际上我们仍然调用的是uvm_do_on_pri_with本质上没有任何区别,只是uvm_do_on 默认了优先级和constraints,

uvm_declare_p_sequencer(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  

简单地分析一下源码,uvm_delcare_p_sequencer实际上就是传递一个SEQUENCER类型的sequencer,将 m_sequencer强制类型转换成p_sequencer也就是说SEQUENCER类型的sequencer。

前置需要说明展示的源码已经展示完,现在看virtual sequencer 和 virtual sequence的实现。

1,virtual  sequencer 和virtual sequence的实现意义

virtual sequence:挂在到virtual sequencer上的虚假的sequence,是实现在真实sequencer上实现sequence的一种手段,用于控制sequence的执行顺序。

virtual sequencer:连接不同的sequencer,本身与在同一个sequencer上启动多个sequence是一样的,本身是一个连接器,将不同的sequencer句柄放在一起。

2,具体实现

1,virtual sequencer

class sample_virtual_sequencer extends uvm_sequencer;
    `uvm_component_utils(sample_virtual_sequencer)
    wr_sequencer wr_seqr;
    rd_sequencer rd_seqr;

    function new(string name="sample_virtual_sequencer",uvm_component parent=null);
        super.new(name,parent);
    endfunction

endclass : sample_virtual_sequencer

2,virtual sequence

class sample_virtual_sequence extends uvm_sequence;
    `uvm_declare_p_sequencer(sample_virtual_seqencer)
    `uvm_object_utils(sample_virtual_sequence);
    
    wr_sequence wr_seq;
    rd_sequence rd_seq;

    virtual task body();

        `uvm_do_on(wr_seq,p_sequencer.wr_seqr)
        `uvm_do_on(rd_seq,p_sequencer.rd_seqr)
    endtask

 endclass sample_virtual_sequence

1,uvm_do_on 的使用:

          关注上面的uvm_do_on的源码,uvm_do_on宏实际上时调用的uvm_do_on_pri_with这个宏:`define uvm_do_on_pri_with(SEQ_OR_ITEM,SEQR,PRIORITY,CONSTRAINTS)

第一个参数是sequence,第二个参数是sequencer,这里使用uvm_do_on的目的就是为了将seq 和 p_sequencer.seqr关联起来,将来是想要在 p_sequencer.seqr 上启动wr_seq,也就是env.agent0.seqr

2,uvm_do_on_with的使用:

         uvm_do_on和uvm_do_on_with在源码上看都是同一套东西,无非是uvm_do_on_with可以是添加constraints,由于使用了uvm_declare_p_sequencer宏,可以通过p_sequencer来使用virtual_sequencer中的变量和参数:

`uvm_do_on_with(wr_seq,p_sequencer.wr_seqr,p_sequencer.xxx)

3,连接

class sample_testcase extends uvm_test;
    
    sample_virtual_sequencer v_sequencer;
......
......
......

function void connect_phase(uvm_phase phase);
    v_sequencer.wr_seqr = env.agent0.sequencer;
    v_sequencer.rd_seqr = env.agent1.sequencer;
endfunction

endclss

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值