我想编写并发断言,该断言在从 UVM 测试台对 DUT 执行一些寄存器写入后开始。
class test extends uvm_test;
bit flag;
task run_phase(uvm_phase phase);
//call register write task , data is chosen in a random fashion
write(addr,data);
flag = 1; // flag gives the time when the register is written.
// after this task the assertions must start depending on data.
endtask
endclass
module top();
//instantiate dut, interface and other stuff
property p1(logic a,logic [4:0] b,logic flag,logic c);
disable iff(!reset || b[i] == 1 || !flag)
/*
default register value is 0, enable assertion only if 0 is written into it.
(0 is for enabling certain feature in DUT and by-default it is enabled.
1 is for disabling that feature. Assertion must never be enabled if b[i] contains 1)
*/
@(posedge clk)
a == 0 |-> $stable(c);
endproperty
assert property p1(dut_top.path_to_dut_signal,uvm_test_top.data,uvm_test_top.flag,dut_top.path_to_dut_other_signal); // gives compile error
// basically I need here dut's signal and the data written to register
// call run_test and set config_db for interface here
initial
begin
// ... run_test
end
这会产生跨模块引用编译错误,因为uvm_test_top是在运行时创建的,我猜断言输入是在编译时设置的。
因此,我为此找到了一些解决方法。
在全局空间中声明一些临时变量和标志变量,如下所示:
bit flag; // in global space
logic [4:0] temp;
class test extends uvm_test;
task run_phase(uvm_phase phase);
//call register write task
write(addr,data);
temp=data, flag=1;
// after this task the assertions must start depending on temp.
endtask
endclass
/** In top, **/
property p1(logic a,logic [4:0] b,logic flag,logic c);
disable iff(!reset || b[i] == 0 || flag ==0)
@(posedge clk)
a == 0 |-> $stable(c);
endproperty
assert property p1(dut_top.path_to_dut_signal,temp,flag,dut_top.path_to_dut_other_signal);
// solves the error
这里使用了两个全局空间变量;最好避免。
无论哪种方式,我都可以将这些变量放在顶部并在测试中通过 $root 访问它们。但是,我不喜欢使用 $root 来解决可重用性和包问题(如果我的顶级名称更改,或者编写了单独的断言模块,测试将出错)。
我想知道有没有其他更好的方法来实现这一点?这样我就可以延迟断言的执行。即使我将它延迟 1timestamp,我也会对 uvm_test_top 进行评估(听起来很疯狂..!!)。
另外,我不想使用接口信号,因为 DUT 与协议无关,它可以支持基于 `ifdefs.xml 的不同接口。(其实这也是另一种解决方法!!)
任何帮助是极大的赞赏。