引自“Systemverilog Assertions and Functional Coverage”一书,Ashok Mehta,第42页,
@(posedge clk)a | => !一个; 在上面的序列中,让我们说变量'a'同时变为'1' 采样边缘时钟变为posedge clk(并假设'a'在它之前为'0' 去了'1')。先前的'a'会匹配吗?没有!由于a'从'0'变为'1',同时时钟变为posedge clk,由时钟采样的'a'的值将为'0'(推迟的区域)而不是'1'。这不会导致属性触发,因为前提条件未被评估为真。这会让你感到困惑 在调试期间。你会期望'1'被采样并触发属性 它们。但是,你会得到相反的结果。 这是一个非常重要的要点,因为在模拟波形中 (或者对于Verilog $ monitor或$ strobe),你会在'a'上看到'1' posedge clk并不明白为什么财产没有开火或为什么 失败(或通过此事)。永远记住,在采样边缘, “先前的”值(即在预定区域中的采样边缘之前的增量) 使用了采样变量。
我尝试通过此Testbench测试此场景。但是我期望在仿真时间#10,#50,#90
断言失败module assert_immediate();
reg a,b,clk;
initial
begin
clk = 0;
forever #10 clk = !clk;
end
initial
begin
a = 0;
b = 0;
repeat (10) @(posedge clk) a = ~a;
end
// always@(posedge clk) $display("a = %d at time %t \n", a, $time);
property p1;
@(posedge clk) a |=> !a;
endproperty
initial #100 $finish;
assert property (p1) $display("Entered assert at %t \n", $time); else $display("FAIL at %t \n", $time);
cover property (p1) $display("PASS at %t \n", $time);
endmodule
但是当我使用VCS运行EDAPlayground时,我得到了不同的行为
# KERNEL: Entered assert at 10
# KERNEL:
# KERNEL: PASS at 10
# KERNEL:
# KERNEL: Entered assert at 50
# KERNEL:
# KERNEL: Entered assert at 50
# KERNEL:
# KERNEL: PASS at 50
# KERNEL:
# KERNEL: PASS at 50
# KERNEL:
# KERNEL: Entered assert at 90
# KERNEL:
# KERNEL: Entered assert at 90
# KERNEL:
# KERNEL: PASS at 90
# KERNEL:
# KERNEL: PASS at 90
答案 0 :(得分:1)
为什么你期望你的断言失败?您指示您的测试平台在a
块中更改posedge
每initial
个,这样您的断言将在触发时通过(您将有一个a, !a, a, !a
序列)所以我希望2断言通行证。
我不明白的是断言根据您的日志传递@ time 10
。您的第一个posedge
是{时间10
,因此a
的采样值为0
(因为抽样是在posedge
之前完成的,您的初始值为{ {1}} a
正在0
阻止。 initial
的这个值不会触发断言(不符合断言的前任,即断言的左侧)。
答案 1 :(得分:0)
我认为那里有两个问题。
a
上升,它最终会下降。因此,在#50处,它在#30处取样为高电平后下降,这导致断言通过,并进入下一个评估周期:#70 - > #90。对于先行词sequence_expr的每次成功匹配,后续的property_expr被分别评估。先行sequence_expr匹配的结束点是后续property_expr的评估起点。
您也可以将此行添加到您的代码中以获得一些调试打印:
always @(posedge clk) $display("%0t a = %b", $time, $sampled(a));
我在模拟过程中得到了这些结果:
10 a = 0
30 a = 1
50 a = 0
Entered assert at 50
PASS at 50
70 a = 1
90 a = 0
Entered assert at 90
PASS at 90