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

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: m_sequencer是指MIDI序列器,是一种电子乐器,用于控制MIDI设备的音乐序列。它可以通过编程或手动输入来创建和编辑音乐序列,并将其发送到MIDI设备以播放音乐。 p_sequencer是指程序序列器,是一种计算机程序,用于控制计算机系统的进程或任务的执行顺序。它可以通过编程来创建和编辑程序序列,并将其发送到计算机系统以控制进程或任务的执行顺序。 ### 回答2: m_sequencer和p_sequencer是指在数字逻辑电路常见的两种类型的时序电路。 m_sequencer是一种可编程时序电路,它通过内部存储器的指令来控制电路的操作顺序。它可以根据需求编程,实现不同的操作序列。m_sequencer通常用于控制处理器、存储器和其他外设之间的数据流和时序,并协调它们之间的操作。 p_sequencer是一种预定时序电路,它使用预定义的时序逻辑,按照固定的顺序执行操作。p_sequencer通常用于一些简单的逻辑电路和控制电路,其操作的顺序不需要频繁更改,因此不需要动态的编程能力。 m_sequencer和p_sequencer在功能和特性上有一些区别。m_sequencer具有较高的灵活性和可编程性,可以根据需求随时修改操作序列,适用于复杂的系统。而p_sequencer则更简单,由于其固定的时序逻辑,在设计和测试方面更容易控制和实现。 综上所述,m_sequencer和p_sequencer是两种不同类型的时序电路,m_sequencer可以根据需求编程,提供更大的灵活性和可变性;而p_sequencer使用预定义的时序逻辑,适用于一些简单的电路。根据具体需求选择适合的时序电路是设计和实现数字逻辑电路的关键。 ### 回答3: m_sequencer和p_sequencer分别是两种不同类型的序列器。m_sequencer代表的是"主序列器",而p_sequencer则代表的是"并行序列器"。 主序列器(m_sequencer)是一种按照顺序执行任务的序列器。它根据事先定义好的特定顺序,按照一定的逻辑连续执行多个任务。主序列器通常用于需要按照特定顺序执行的任务序列,比如编程的一系列函数调用,或者某个流程按照固定步骤执行的操作。使用主序列器可以确保任务的有序执行,避免出现混乱或错误。 并行序列器(p_sequencer)则是一种能够同时执行多个任务的序列器。它允许多个任务在同一时间片段内并行执行,可以充分利用处理器的多核心或者多线程能力。并行序列器常用于需要同时处理大量数据或者执行多个独立操作的场景。使用并行序列器可以提高任务的处理效率,加快任务的执行速度。 总结来说,m_sequencer和p_sequencer可以根据任务的执行需求选择不同的序列器。如果任务需要按照特定顺序执行,可以选择主序列器(m_sequencer);如果任务可以同时进行,并发性能较好,可以选择并行序列器(p_sequencer)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值