参考UVM序列

时间:2016-09-21 15:58:33

标签: system-verilog uvm

我需要监控寄存器的状态。我创建了一个UVM序列来读取寄存器并将它们存储在本地。现在在我的测试代码中,我需要访问它们 寄存器。这是一个sudo代码:

typedef struct {
    int a;
} my_regs;

class my_seq extends uvm_sequence;
     // register to uvm db 
    reg_map       map;
    my_regs       regs;
    uvm_status_e  status;

    task build_phase(uvm_phase phase);
    endtask 

    task run_phase(uvm_phase phase);
        map.CORE.reg_a.read(status, regs.a, UVM_BACKDOOR)
    endtask
endclass

class test_reg extends uvm_test;
     // register to uvm db 
     my_seq  seq;
     my_regs regs;

     task build_phase(uvm_phase phase);
         seq  = my_seq::type_id::create("reg_seq", this);
         regs = seq.regs;
     endtask 

     task run_phase(uvm_phase phase);
         reg_seq.start(null);
         // read reg values from seq??????
         if(rqgs.a>1)
            //do some thing

     endtask
endclass

正如你所看到的,我不断开始顺序,所以我不会错过任何更新。我相信序列中的 start 任务不会创建新对象 所以对象内部的值应该在启动调用之间保持不变。

假设我每次都没有从seq读取regs值,测试类的regs将不会从seq获取更新。意味着 regs = seq.regs; 不会创建对 seq.regs 的实际引用。我想知道为什么会这样,我怎样才能创建对该对象的绝对引用? (这样我就不会浪费模拟周期来读取和更新测试类中的regs值)。如果有更好的方法,请告诉我。

1 个答案:

答案 0 :(得分:2)

首先是一个小修复。序列没有构建或运行阶段。与其他uvm_components不同,它们不会自动启动[使用定相系统]。 序列有一个正文任务被覆盖以实现功能(在这种情况下是读取寄存器)。因此,需要将run_phase中的代码移动到body函数。

class my_seq extends uvm_sequence;
     // register to uvm db 
    reg_map       map;
    my_regs       regs;
    uvm_status_e  status;
function  new(string name="my_seq");
    super.new(name);
  endfunction

  task body ();
        map.CORE.reg_a.read(status, regs.a, UVM_BACKDOOR);
    endtask
endclass

一旦调用序列,它将从RTL寄存器读取值并更新" a" my_seq类中的regs字段。

 regs = seq.regs; // 

regs(在测试中)将提供序列中regs字段的永久链接。因此,只要序列读取寄存器并更新regs字段,test_reg中的变量reg将会看到更改,但这意味着必须从RTL读取寄存器。 test_reg需要实现一个循环来定期读取寄存器(通过调用序列my_seq)。这是因为变量regs或寄存器字段map.CORE.reg_a不是RTL中寄存器的直接链接。

您需要花费模拟周期来读取RTL寄存器,因为uvm_register只是一个镜像/副本,只有在发出读取时才会更新。

问题是固件如何访问寄存器?如果通过极化机制访问寄存器,则最好在测试用例中模仿相同的寄存器。

task run_phase(uvm_phase phase);
     task_done = 0;
     while ( !task_done ) 
      begin
         // wait for some delay as backdoor access takes 0 simulation time
         reg_seq.start(null);   // regs is updates 
         // read reg values from seq - done
         if(regs.a>1)    // check for bit to be set 
         begin
            task_done = 1;
            //do some thing
         end
         // else continue to poll register 
       end
end task

或者我们可以等待RTL信号改变然后发出读取(这种方法不可取,因为我们从测试台访问RTL信号。)

task run_phase(uvm_phase phase);
             wait ( RTL.module.reg.CORE.reg_a == 1 ) ;
             reg_seq.start(null);   // regs file is updates 
             // read reg values from seq - done
             if(regs.a>1)    // check for bit to be set 
                //do some thing
    endtask