我需要监控一个登记簿的状态。我已经创建了一个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正如你所看到的,我不断地启动序列,这样我就不会错过任何更新。我相信启动任务顺序不会创建新对象,因此在开始调用之间,对象内的值应该保持不变。
假设我不每次从seq读取regs值,测试类的regs将不会从seq获得更新。这意味着regs = seq.regs;没有创建对seq.regs的实际引用。我想知道为什么是这样,我怎样才能创建对那个对象的绝对引用?(这样我就不会在读取和更新测试类中的regs值时浪费模拟周期)。还有,如果有更好的方法,请告诉我。
发布于 2016-09-21 22:38:49
首先是个小问题。序列没有生成或运行阶段。与其他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寄存器读取值,并更新类my_seq中的regs中的"a“字段。
regs = seq.regs; // regs (在测试中)将提供到序列中的regs字段的永久链接。因此,每当序列读取寄存器并更新regs字段时,test_reg中的变量regs将看到更改,但这意味着必须从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
endtaskhttps://stackoverflow.com/questions/39621359
复制相似问题