System verilog 周期信号的意外SVA断言行为
引用Ashok Mehta在第42页的《Systemverilog断言和功能覆盖率》一书 @(posedge clk)a |=>!A. 在上面的序列中,让我们假设变量“a”同时更改为“1” 采样边缘时钟变为posedge clk(并假设“a”之前为“0”) 转到“1”)。是否会有一个匹配的先行词“a”?不由于a从“0”变为“1”的时间与时钟变为posedge clk的时间相同,因此时钟采样的“a”的值将为“0”(前置区域),而不是“1”。这不会导致触发属性,因为antecedent的计算结果不是true。这会让你困惑 在调试期间。您希望对“1”进行采样并触发属性 其中。然而,你会得到相反的结果。 这一点非常重要,因为在模拟波形中 (或者对于Verilog$monitor或$strobe),您将在带有 posedge clk,不理解该房产为何未起火或起火 失败(或就此通过)。请始终记住,在采样边缘 “先前”值(即前置区域中采样边缘之前的增量) 使用采样变量 我试图通过这个测试台来测试这个场景。然而,我预计断言在模拟时间(10,50,90)会失败 但当我使用风投在操场上跑步时,我得到了一种不同的行为System verilog 周期信号的意外SVA断言行为,system-verilog,system-verilog-assertions,System Verilog,System Verilog Assertions,引用Ashok Mehta在第42页的《Systemverilog断言和功能覆盖率》一书 @(posedge clk)a |=>!A. 在上面的序列中,让我们假设变量“a”同时更改为“1” 采样边缘时钟变为posedge clk(并假设“a”之前为“0”) 转到“1”)。是否会有一个匹配的先行词“a”?不由于a从“0”变为“1”的时间与时钟变为posedge clk的时间相同,因此时钟采样的“a”的值将为“0”(前置区域),而不是“1”。这不会导致触发属性,因为antecedent的计算结果不是
# 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
你为什么期望你的断言失败?您指示测试台在
initial
块中更改a
每个posedge
,这样您的断言将在触发时通过(您将有一系列a、!a、a、!a
),因此我预期通过两次断言
我不明白的是,根据您的日志,断言通过@time
10
。您的第一个posedge
是@time10
,因此a
的采样值是0
(因为采样是在posedge
之前完成的,a
的初始值是0
根据initial
块)。a
的这个值不会触发断言(不符合断言的前身,即断言的左侧)。我认为有两个问题
a
上升,它最终会下降。因此,在#50时,它在#30时采样高后下降,这导致断言通过,并进入下一个评估周期:#70->90always @(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
哈哈,你问的问题和我问的完全一样<代码>我不明白的是,根据您的日志,断言通过@time 10。此外,我并不期望断言总是失败,因为我提到它应该在@time 10、50和90失败。我没有说清楚。我不明白为什么会被“触发”。断言触发器是
a
。您编写了,但我预计断言在模拟时会失败#10、#50、#90
。由于在初始块中重新触发a
,您的断言在这个测试台中永远不会失败。这就回答了你的问题。关于这种奇怪的行为@time10
:提供更多详细信息-选通信号、波形或尝试另一个模拟器并比较结果。可能VCS假设sim卡的启动为1
(选通和检查)?断言是在什么时候触发的,它的前导匹配还是后继匹配?我应该合并哪些初始块?我希望断言在10ns时失败,因为在10ns时,a的采样值仍然是0,而不是“1”。因此它不会触发antecedantTime10
(firstposedge
)断言检查a
信号值是否与先行项匹配。事实并非如此(a==0
,断言在a
上触发,这是a==1
的缩写,我认为这是误解的根源。它不会使断言失败,它只会使断言保持在非活动的状态。如果a==1
,断言将触发。只有在那时,当断言触发,并且是我N<代码>活动< <代码>状态,它可以<代码> >代码>失败>代码>或<代码>禁用< /代码>。忽略我的注释,对初始块进行合并,编辑它,因为它不是一个好的建议。不幸的是,不考虑。另一个断言消息:<代码>在50 中输入断言。断言被触发@时间<代码> 30 < /代码>。(a
在时间30
为1
之前,它将被采样并触发断言)。@下一个posedge clk
(时间50
)断言成功完成(pass
),然后执行$display
。因此构造assert属性()else
将在断言过程结束时显示消息。如果您有立即断言,例如断言(A==B)
它将在相同的时钟点执行,因为立即断言将在相同的时钟点完成。您预期的行为是什么?@KaranShah预期的行为是在10时输入assert
并且在10时通过
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