让我们举一个带异步复位的d触发器的简单例子。
q应该在时钟的下一个边沿用d更新,这可以用简单的蕴涵算子断言来编写。
但是如何在断言中捕获重置行为。 我试过了几个
assert @(posedge rst) (1'b1 |-> !Q);
assert @(posedge rst) (1'b1 ##0 !Q);
这两个断言都失败了,我想因为rst没有下一个假设?
assert @(posedge clk) ($rose(rst) |-> !Q);
通过,但需要自由运行时钟,并在时钟的2个边沿之间断言(不是第一个有意义的行为)
assert #0 (not (rst & Q));
根据我的理解,这是一个正确的立即断言,但是我无法在波形查看器中看到这个通过/失败。还有更多我认为我无法在最后一种断言上写封面。
答案 0 :(得分:2)
断言失败,因为Q
在更新之前被采样。在模拟器调度程序的早期,采样发生在触发事件的LHS上。 Q
在反应区域中更新,该区域稍后在调度顺序中。
解决此问题的一种简单方法是添加一个微小的延迟,例如SystemVerilog的1step
。我建议将rst
置于检查条件中,该条件可作为最小脉冲宽度检查的一部分。
wire #(1step) rst_delay = rst;
assert @(posedge rst_delay) (1'b1 |-> rst && !Q);
如果您使用重置为q的延迟进行模拟,例如使用SDF注释或人工延迟,则将偏移量添加到rst_delay
。
wire #(r2q+1step) rst_delay = rst;
assert @(posedge rst_delay) (1'b1 |-> rst && !Q);