SystemVerilog throughout运算符序列终点检查的正确编码方法
SystemVerilog断言属性实现方案
现有写法的语义判定
你编写的代码(X throughout Y) |-> term_to_check本身就完全符合需求,不会在Y序列匹配过程中持续触发term_to_check的检查,仅会在Y匹配完成的终点时刻触发检查,核心语义依据如下:
X throughout Y作为序列前件,本身只有一个匹配成功时点:即Y序列走完自身匹配流程、且从Y匹配起点到终点的全周期内X始终为真的那个终点时刻;匹配过程中任意时刻X为假都会直接判定本次前件匹配失败,不会向后传导触发事件。- 重叠蕴含操作符
|->的触发规则是:仅在前件序列成功匹配到达终点的同一时刻,才启动对右侧后件的检查,前件匹配过程中不会触发任何后件检查逻辑。
语义验证示例
举个具象场景说明执行逻辑:
假设Y定义为
##2 1,即从匹配起点开始等待2个时钟周期,在第2个周期到达匹配终点。
属性执行流程为:
- 每个时钟上升沿尝试启动Y的匹配流程
- 匹配推进的3个周期(起点、第1个等待周期、第2个终点周期)内持续检查X是否为1,任意时刻X拉低则本次匹配直接终止,不触发后件检查
- 仅当Y顺利走完2个周期匹配到终点、且全程X保持为1时,才会在该终点时刻采样检查
term_to_check的取值,匹配过程中不会对term_to_check做任何采样检查
无歧义编码建议
如果需要让代码语义更直白,避免其他维护者误解触发时机,可以补充##0明确标注是当前时刻(即前件匹配终点)检查,写法如下,和原有写法语义完全等价:
(X throughout Y) |-> ##0 term_to_check
注意不要误用非重叠蕴含|=>,该操作符会在前件匹配终点的下一个时钟周期才检查后件,不符合终点时刻检查的需求;也不要把后件逻辑写到throughout的括号内部,否则会触发匹配过程中的持续检查。
内容的提问来源于stack exchange,提问作者maor shariki
相关产品推荐
相关产品推荐

