System verilog 周期信号的意外SVA断言行为

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的计算结果不是

引用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)会失败

但当我使用风投在操场上跑步时,我得到了一种不同的行为

# 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
是@time
10
,因此
a
的采样值是
0
(因为采样是在
posedge
之前完成的,
a
的初始值是
0
根据
initial
块)。
a
的这个值不会触发断言(不符合断言的前身,即断言的左侧)。

我认为有两个问题

  • 我认为蕴涵算子中存在误解。在您的案例中,断言不应该失败。这意味着右手边的表达式最终是真的。因此,如果
    a
    上升,它最终会下降。因此,在#50时,它在#30时采样高后下降,这导致断言通过,并进入下一个评估周期:#70->90
  • 对于前件序列的每个成功匹配,将分别评估后件属性。先行序列_expr匹配的终点是结果属性_expr求值的起点

  • 您使用的编译器中有一个bug。在时间#10时不应有断言消息。我在vcs 2017.03上试用过,效果良好
  • 您还可以将此行添加到代码中,以获得一些调试打印:

    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
    

    哈哈,你问的问题和我问的完全一样<代码>我不明白的是,根据您的日志,断言通过@time 10。此外,我并不期望断言总是失败,因为我提到它应该在@time 10、50和90失败。我没有说清楚。我不明白为什么会被“触发”。断言触发器是
    a
    。您编写了
    ,但我预计断言在模拟时会失败#10、#50、#90
    。由于在初始块中重新触发
    a
    ,您的断言在这个测试台中永远不会失败。这就回答了你的问题。关于这种奇怪的行为@time
    10
    :提供更多详细信息-选通信号、波形或尝试另一个模拟器并比较结果。可能VCS假设sim卡的启动为
    1
    (选通和检查)?断言是在什么时候触发的,它的前导匹配还是后继匹配?我应该合并哪些初始块?我希望断言在10ns时失败,因为在10ns时,a的采样值仍然是0,而不是“1”。因此它不会触发antecedantTime
    10
    (first
    posedge
    )断言检查
    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