UVM中的p_sequencer和m_sequencer

p - parent sequencer - 要处理的实际sequencer类型的句柄,这个是自己定义的。

m - m_表示隐藏或局部变量(member),m_sequencer是uvm_sequencer_base类型,定义在uvm_sequence_item类中。

可以使用`uvm_declare_p_sequencer宏声明p_sequencer。

但是你也可以在sequence中做以下相同的事情:

my_sequencer p_sequencer;

task body;
assert($cast(p_sequencer,m_sequencer));

....

如果实际的sequencer有一些您需要访问的方法或变量,则p_sequencer可能很有用。在大多数情况下,m_sequencer具有您需要的一切。

sequence负责生成激励或sequence_items,因此当通过.start()方法启动sequence时,sequence会连接到特定的sequencer。m_sequencer是一个通用的sequencer,或者可以认为是一个指针,其句柄包含对sequence运行的sequencer的引用。 同时m_sequencer可用于从sequence中访问组件层次结构中的配置信息和其他资源。因为sequence是从uvm_object拓展而来,它不能访问uvm_component组成的uvm层次结构的,如果非要访问uvm_component就要通过一个媒介,这个媒介就是sequencer。

例如,如果您在名为bar_sequencer的sequencer,foo_sequence.start(bar_sequencer)上启动名为foo_sequence的序列,则start()任务将分配foo_sequence.m_sequencer作为bar_sequencer。现在,foo_sequence可以使用m_sequencer访问组件层次结构。例如,您可以通过调用m_sequencer.get_full_name()来获取sequencer的完整层次名称。请注意,m_sequencer的类型是uvm_sequencer_base。这意味着如果你有自己的sequencer,并且你已经在sequencer中定义了新的属性,那么你不能通过m_sequencer访问它们,因为它不知道它们。现在p_sequencer开始显示威力了。

如果在sequence中使用`uvm_declare_p_sequencer宏,则p_sequencer会被实例化。

例如,你可以像这样在foo_sequence中使用此宏:

class foo_sequence extends uvm_sequence #( my_transaction );
  `uvm_object_utils( foo_sequence )
  `uvm_declare_p_sequencer( bar_sequencer_class )
   
  task body;
    p_sequencer.ana_port.write(item);
    p_sequencer.prop_a;

 // ...

UVM中的p_sequencer和m_sequencer_第1张图片

那么`uvm_declare_p_sequencer宏到底做了哪些工作呢?无非就是用$cast实现的一个动态向下类型转换操作。从OOP继承和多态的角度来说,m_sequencer是uvm_sequencer_base类型的变量。它可以存储从uvm_sequencer_base派生的任何对象的句柄。但是,您只能引用从uvm_sequencer或uvm_sequencer扩展的任何类方法或变量。

假设你有两个从uvm_sequencer扩展的类:sqrA和sqrB sqrA有一个成员A,sqrB有一个成员B.如果你试图引用m_sequencer.A,但是m_sequencer目前有一个sqrB类型的对象的句柄,会发生什么?另外,如果sqrA和sqB都有称为C的变量但它们是完全不同的类型呢? SystemVerilog不会让你犯这个错误,它不允许动态类型切换。

因此,如果您想引用仅在sqrA中的成员或方法,则必须使用该类类型的变量引用它们。它知道sqrA_h.A总是有效的,如果sqrA_h不为空,并且sqrA_h.M是一个固定类型。

以下图为例,该宏使用您提供的sequencer类型(在本例中为bar_sequencer_class)声明p_sequencer。然后宏定义了一个名为m_set_p_sequencer的函数,它将m_sequencer转换为p_sequencer。现在,您可以通过p_sequencer访问bar_sequencer_class中定义的属性,如foo_sequence的body任务内部的p_sequencer.my_property。

UVM中的p_sequencer和m_sequencer_第2张图片

你可能感兴趣的:(system,verilog,UVM)