SystemVerilog断言问题:A触发后B未出现时未触发UVM_ERROR
解决SystemVerilog断言中A触发后B未出现不报错的问题
我来帮你搞定这个断言问题!你遇到的核心问题是SystemVerilog断言对无限等待序列的默认行为——默认情况下,像##[0:$]这种无限等待的序列,如果仿真结束时还没满足条件,工具不会判定断言失败,因为它认为“未来还有可能触发B”。下面给你具体的解决方案:
1. 用strong()操作符强制有限时间内满足条件
你之前尝试过strong()但没效果?大概率是用法不对。正确的做法是把整个需要等待的序列包裹在strong()里,而不是只包B[->1]。修正后的断言代码如下:
example : assert property( @(posedge clk) disable iff(reset) A |-> strong(##[0:$] B[->1])) else `uvm_error("ASSERT_FAILURE", "Assertion failed: A was asserted but B never went high afterwards");
为什么这样有效?
- 默认的断言序列是weak语义:只要序列在仿真结束前没被证伪,就不会触发失败(哪怕一直没满足条件)。
strong()语义则要求:被包裹的序列必须在有限的时钟周期内成功匹配,如果仿真结束时序列还未完成,就会触发断言失败,输出你预期的类似example: started at xxxxxxps not finished的报错。
2. 配合仿真器选项确保最终检查
有些仿真器默认不会主动检查未完成的断言,即使你用了strong(),可能还需要开启额外选项来触发最终报告:
- Synopsys VCS:添加
-assert final_report选项 - Cadence Xcelium:添加
-assert enable_final_check选项 - Siemens Questa:添加
-assert finishonfail或-assert reportall选项
这些选项会强制仿真器在$finish时检查所有未完成的断言,确保不会漏掉这类场景。
3. 额外验证小技巧
如果想更直观地验证断言逻辑,可以在测试用例的$finish前手动触发一个检查,或者添加一个覆盖点来监控“A为真后B从未触发”的场景,辅助定位问题。
内容的提问来源于stack exchange,提问作者Shuaiyu Jiang
相关产品推荐
相关产品推荐

