如何在 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 运算符进行断言是正确的,但是您编写的代码存在一些问题。一块块来看吧。

每当我写一个断言时,我都会注意我想要检查的内容的自然语言描述。在您的情况下,我们知道我们想要在 a0 变为 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 上找到工作示例。