System verilog 如何在systemverilog断言中使用贯穿运算符

System verilog 如何在systemverilog断言中使用贯穿运算符,system-verilog,assertions,system-verilog-assertions,System Verilog,Assertions,System Verilog Assertions,以下是一个规范: 如果断言信号a,则必须断言该信号,直到断言信号b,然后应在下一个时钟边缘取消断言。 我正在阅读LRM的16.9.9(以及),按照我的理解,上述规范可以写成 property a2b_notA; @(posedge clk) ($rose (a) ##0 (a throughout b)) |=> (~a); endproperty a_a2b_notA: assert property (a2b_notA); 但是,在启动后的第二个时钟

以下是一个规范: 如果断言信号
a
,则必须断言该信号,直到断言信号
b
,然后应在下一个时钟边缘取消断言。 我正在阅读LRM的16.9.9(以及),按照我的理解,上述规范可以写成

   property a2b_notA;
        @(posedge clk) ($rose (a) ##0 (a throughout b)) |=> (~a);
   endproperty
   a_a2b_notA: assert property (a2b_notA);

但是,在启动后的第二个时钟边缘,这会立即失败,我不知道为什么。

您希望在断言中使用
通篇
运算符是正确的,但是您编写的代码有一些问题。让我们一件一件地看一下

每当我写断言时,我都会注意我想要检查的内容的自然语言描述。在您的情况下,我们知道我们希望在
a
0
变为
1
时触发。之后发生的一切都是我们要检查的行为,因此它应该位于蕴涵运算符的右侧:

$rose(a) |-> ... something ...
按照编写断言的方式,如果整个
序列也发生在
rose(a)
之后,它只会触发检查。这会导致你忽视不良行为

下一个难题是“
a
必须保持高位,直到断言
b
”。这里我们将使用贯穿操作符。序列“直到
b
被断言”表示为
b[->1]
。这相当于
!b[*]##1 b
。因此,我们的顺序应该是
a贯穿b[->1]

b
变高时,整个
序列将结束。此时,我们需要检查
a
是否在下一个周期处于低位:
##1!a
。我在这里使用了逻辑求反,因为我发现它比按位求反更清晰,但结果应该是一样的

综上所述,整个物业应为:

$rose(a) |-> (a throughout b [->1]) ##1 !a;
我在这里使用了重叠含义,因为当
a
变高时,
b
可能已经变高了,在这种情况下,我假设
a
应该在下一个周期立即变低。如果没有,你可以自己处理细节


您可以在上找到一个工作示例。

谢谢,我完全理解错了。我以为只要在整个b
中编写
就可以了,直到
b
失败。谢谢你提供的关于决定先行词和先行词的建议谢谢,@Tudor。这个例子很好,但我不明白为什么使用“b[->1]”?由于goto Repeation操作符表示非连续重复,因此我理解,当a为高时,b必须在整整1个时钟周期内为高。我们可以这样做吗:
a[*0:$]|->b[*0:$]#1!a
@rottengg
[1:$]~b
中的a
或b
不是合法语法。你是说
~b[*1:$]
?如果是这样(将属性重写为
(a贯穿(~b[*1:$]##1b))
),则跳过了一个时钟周期,在该时钟周期中,您不会检查
a
在结果中是否处于高位。这没什么大不了的,因为结果(
$rose(a)
)已经要求
a
在该特定周期内处于高位。您仍然需要使用
###1结束属性!a
,否则您没有检查“它应该在下一个时钟边缘[在b变高后]取消断言”的要求。@rottengg
s_最终(b)
没有说明关于a的任何内容,即它在这段时间内保持高位<代码>[*1:$]b
也可以代替
[->b]
,但这两种情况并非在所有情况下都是等效的。第一个将在跟踪上匹配多次,如
!Bb b b
,而第二个for将仅在第一次出现的
b
时匹配并停止。由于序列被用作隐含属性中的结果,因此当
[*1:$]b
第一次匹配时,整个属性也将完成,并且不会开始进一步的计算。@IlanBiala在自然语言中,第一个说“在我看到
a
上升后,我想看到
a
保持高位直到
b
上升,然后看到
a
立即下降。第二种说法是,在我看到a上升后,如果我看到a一直保持高位直到b上升,那么我想看到a立即下降。第二种形式允许
a
b
之前不保持高位。如果是这种情况,则第二个蕴涵将以真空方式传递,从而导致整个属性的传递。它们并不等同。