谈一谈UVM中的p_sequencer

先从SystemVerilog的语法说起

我们先来看一个简单的例子:

bird是一个基类

class bird;
bit [3:0] src =0;
bit [3:0] drc = 1;

virtual task exec_task();
     $display("in bird");
endtask
endclass

parr是一个bird的扩展类

class parr extends bird;
bit [3:0] test =2;
virtual task exec_task();
  $display("in parr");
endtask
endclass

top层调用

program ex6_14_tb;
bird A;
parr B;
parr C;
 initial 
      begin
              A = new();
              B = new();
              C = new();
              A = B;
              //$cast(C,A);
              A.exec_task(); 
              $display("A.src = %d,A.drc = %d",A.src,A.drc);
              $display("A.test = %d",A.test);
     end
endprogram
仿真结果

原因分析:

  • A是bird的基类句柄,A=B,A基类的句柄指向B扩展类。
  • A.exec_task因为有virtual修饰,所以是调用A句柄指向的B的对象,也就是B的exec_task的定义。
  • A虽然是指向的B的对象,但是A句柄的类型是bird,并没有test的变量。

综上:所以会报错!

解决方案:A句柄指向的是B扩展类,C是扩展类的句柄,如果指向B扩展类对象是可以的。**用cast做类型转换,cast的用法:https://www.cnblogs.com/xuqing125/p/14759124.html

修改top层代码:

program ex6_14_tb;
bird A;
parr B;
parr C;
 initial 
      begin
              A = new();
              B = new();
              C = new();
              A = B;
              $cast(C,A);
              A.exec_task(); 
              $display("A.src = %d,A.drc = %d",A.src,A.drc);
              $display("C.test = %d",C.test);
     end
endprogram
仿真结果

m_sequencer与p_sequencer

uvm_sequencer_base m_sequencer;是uvm_sequence中的protected变量。

  • my_sequencer是从uvm_sequencer中扩展来的,并拥有独特的dmac/smac的变量。
  • m_sequencer是uvm_sequencer_base类型的句柄,实际指向的对象是my_sequencer。
  • 所以如果想通过基类的句柄m_sequencer来访问扩展类在中独有的damc/smac的变量是不合法的,解决方案就是按照上面的来。
  • p_sequencer和m_sequencer实际上都是指向my_sequencer的对象!

宏定义:`uvm_declare_p_sequencer(my_sequencer)

  • 宏定义其实就是将上面的操作打了一个报,封装了一下。
  • m_set_p_seqeuncer():是set_item_context(parent_seq, sqr);的callback函数,(如果没有定义的话,默认为空)也就是说这个uvm_declare_p_sequencer宏只能在uvm_sequence的扩展类中定义。

如果你没有访问my_sequencer中相对于uvm_sequencer_base中独有的变量话,你是没有必要声明uvm_declare_p_sequencer这个宏定义的。

你可能感兴趣的:(谈一谈UVM中的p_sequencer)