首先要注意的是 disable iff (rst) 子句是异步的。因此,它不遵守常规的断言采样规则。
来自 LRM:
禁用 iff 的表达式称为禁用条件。这
disable iff 子句允许指定抢先式重置。为
property_spec 的评估,有一个评估
基础属性_expr。如果禁用条件在任何时候为真
在观察区域的尝试开始之间,包括在内,
以及评估尝试的结束,包括在内,然后是整体
财产评估结果禁用。一个属性有
如果由于禁用 iff 而被抢占,则禁用评估
健康)状况。
禁用条件中使用的变量值是
当前模拟周期,即未采样。
在您的情况下,对于重置之前的每个周期,都会为您的断言生成一个新线程。一旦重置出现,所有这些实例都被禁用并且它们的属性评估被暂停。任何新的评估只会在重置被取消断言后开始。因此,我看不出这怎么会是您的问题的原因。
但是,我可以提出两个可能导致您的问题的问题:
1. 在您的 sim Signal_ia 的开头是 'X.在 20 个周期后,如果尚未断言复位,则前面的序列 $stable(Signal_ia) 将评估为真,并且断言将立即转移到评估后续序列 Signal_oq==Signal_ia (在同一个周期中,因为非重叠暗示是用过的)。如果这两个信号都是'X,则 1'X == 1'X 评估为 1'X,因此断言将失败。
2. 您提到您希望在第 21 个周期进行检查。然而,这个断言实际上会在第 20 个周期检查。如果有 20 次 flop,此时输出仍将是 'X,即使输入已 0 持续 20 个周期。
我怀疑选项 1. 更有可能,因为 2. 可能很明显。
为了解决这两个问题,我建议您更改断言以在输入更改时触发以解决此问题。
CHECK_OUTPUT: assert property(@(posedge ClkRs_ix.clk)
disable iff (ClkRs_ix.reset) $changed(Signal_ia) |=>
$stable(Signal_ia)[*20] ##0 (Signal_oq==Signal_ia));
正如所指出的,您还可以选择性地启用断言。 $asserton 和 $assetkill (assertoff) 可以帮助你做到这一点:
$asserton[(levels[, list])] 等价于 $assertcontrol(3, 15,
7、levels[,list])——$assertoff[(levels[,list])]等价于
$assertcontrol(4, 15, 7, 级别 [,list]) — $assertkill[(级别[,
list])] 等价于 $assertcontrol(5, 15, 7, levels [,list])
assertkill 将杀死任何已经在运行的线程(与 asseroff 不同,它只会阻止未来的线程)。在我看来,你会在 assertkill 之后。然后,您可以通过 asserton 重新启用您的断言。
正如所指出的,在正式场景中,这自然需要通过断言中的控制信号和 FSM 来生成它。