首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >引用UVM序列

引用UVM序列
EN

Stack Overflow用户
提问于 2016-09-21 15:58:33
回答 1查看 598关注 0票数 1

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

代码语言:javascript
复制
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

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-21 22:38:49

首先是个小问题。序列没有生成或运行阶段。与其他uvm_components不同的是,它们不是使用分相系统自动启动的。序列具有一个主体任务,该任务被重写以实现功能(在本例中是读取寄存器)。因此,需要将run_phase中的代码移到body函数中。

代码语言:javascript
复制
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寄存器读取值,并更新类my_seq中的regs中的"a“字段。

代码语言:javascript
复制
 regs = seq.regs; // 

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

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

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

代码语言:javascript
复制
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信号。)

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39621359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档