如何在 systemverilog 断言中使用 throughout 运算符
How to use throughout operator in systemverilog assertions
这是一个规格:
如果信号 a
被断言,那么它必须被断言直到信号 b
被断言,然后它应该在下一个时钟边沿取消断言。
我正在阅读 LRM 的 16.9.9(以及 http://www.testbench.in/AS_06_SEQUENCES.html)以及我理解它的方式,上面提到的规范可以写成
property a2b_notA;
@(posedge clk) ($rose (a) ##0 (a throughout b)) |=> (~a);
endproperty
a_a2b_notA: assert property (a2b_notA);
然而,这在启动后的第二个时钟边沿立即失败,我不明白为什么。
您想要使用 throughout
运算符进行断言是正确的,但是您编写的代码存在一些问题。一块块来看吧。
每当我写一个断言时,我都会注意我想要检查的内容的自然语言描述。在您的情况下,我们知道我们想要在 a
从 0
变为 1
时触发。之后发生的一切都是我们要检查的行为,因此它应该在蕴涵运算符的右侧:
$rose(a) |-> ... something ...
按照您编写断言的方式,它只会触发检查 throughout
序列是否也发生在 rose(a)
之后。这会让您忽略不良行为。
下一个难题是“a
必须保持高电平直到 b
被断言”。这里我们将使用 throughout 运算符。序列"until b
is asserted"表示为b [->1]
。这相当于 !b [*] ##1 b
。因此,我们的顺序应该是 a throughout b [->1]
.
throughout
序列将在 b
变高时结束。此时我们需要检查 a
在下一个周期变低:##1 !a
。我在这里使用了逻辑否定,因为我发现它比按位否定更清楚,但结果应该是一样的。
把它们放在一起,整个属性应该是:
$rose(a) |-> (a throughout b [->1]) ##1 !a;
我在这里使用了重叠蕴涵,因为当 a
变高时 b
可能已经变高了,在这种情况下,我假设 a
应该立即变低下一个周期。如果没有,您可以fiddle自己提供详细信息。
您可以在 EDAPlayground 上找到工作示例。
这是一个规格:
如果信号 a
被断言,那么它必须被断言直到信号 b
被断言,然后它应该在下一个时钟边沿取消断言。
我正在阅读 LRM 的 16.9.9(以及 http://www.testbench.in/AS_06_SEQUENCES.html)以及我理解它的方式,上面提到的规范可以写成
property a2b_notA;
@(posedge clk) ($rose (a) ##0 (a throughout b)) |=> (~a);
endproperty
a_a2b_notA: assert property (a2b_notA);
然而,这在启动后的第二个时钟边沿立即失败,我不明白为什么。
您想要使用 throughout
运算符进行断言是正确的,但是您编写的代码存在一些问题。一块块来看吧。
每当我写一个断言时,我都会注意我想要检查的内容的自然语言描述。在您的情况下,我们知道我们想要在 a
从 0
变为 1
时触发。之后发生的一切都是我们要检查的行为,因此它应该在蕴涵运算符的右侧:
$rose(a) |-> ... something ...
按照您编写断言的方式,它只会触发检查 throughout
序列是否也发生在 rose(a)
之后。这会让您忽略不良行为。
下一个难题是“a
必须保持高电平直到 b
被断言”。这里我们将使用 throughout 运算符。序列"until b
is asserted"表示为b [->1]
。这相当于 !b [*] ##1 b
。因此,我们的顺序应该是 a throughout b [->1]
.
throughout
序列将在 b
变高时结束。此时我们需要检查 a
在下一个周期变低:##1 !a
。我在这里使用了逻辑否定,因为我发现它比按位否定更清楚,但结果应该是一样的。
把它们放在一起,整个属性应该是:
$rose(a) |-> (a throughout b [->1]) ##1 !a;
我在这里使用了重叠蕴涵,因为当 a
变高时 b
可能已经变高了,在这种情况下,我假设 a
应该立即变低下一个周期。如果没有,您可以fiddle自己提供详细信息。
您可以在 EDAPlayground 上找到工作示例。