SVA技术问询:如何仅用SVA实现每8周期仅允许data变更的检查
纯SVA实现“data仅能每8个时钟周期变更一次”的检查
你提到的需求完全可以用纯SVA实现,不需要额外的计数器逻辑。先来分析你之前代码的问题:你尝试的递归写法里,($stable(data)[*8])[0:$]这种嵌套的序列重复操作不仅语法容易出问题,逻辑上也没有准确表达“变更间隔至少8个周期”的约束,这才导致编译失败。
下面提供两种优雅的纯SVA实现方案,分别对应两种常见的需求场景:
场景1:允许data长时间稳定(变更间隔≥8个周期)
如果你的需求是data可以保持稳定任意时长,但只要发生变更,两次变更之间必须至少间隔8个时钟周期(也就是不能在变更后的1-7个周期内再次变更),可以用最简洁的断言写法:
assert property (@(posedge clk) not ($changed(data) ##[1:7] $changed(data)) );
逻辑解释:
这个断言直接禁止了“data变更后,1到7个周期内再次变更”的非法情况。##[1:7]表示从当前周期开始的1到7个周期后,只要出现这种情况,断言就会触发失败,完美保证了两次变更的间隔至少为8个时钟周期。
场景2:严格要求变更仅能发生在每8个周期的固定点(和你原计数器方案逻辑一致)
如果你需要和原来的计数器方案完全对齐——data变更只能发生在每8个周期的特定时钟沿(比如计数器归0的时刻),中间周期绝对不能变更,同时允许data保持稳定不变,可以用递归属性来实现:
property data_change_only_every_8_cycles; @(posedge clk) // 初始状态:要么data保持稳定,要么发生变更后,接下来7个周期必须稳定,然后递归检查后续 ($stable(data) or ($changed(data) |=> $stable(data)[*7] ##1 data_change_only_every_8_cycles)); endproperty // 实例化断言 assert property (data_change_only_every_8_cycles);
逻辑解释:
- 递归属性
data_change_only_every_8_cycles会持续检查整个时钟序列; - 一旦检测到
$changed(data),就强制要求接下来的7个周期$stable(data)必须成立; - 第8个周期开始后,又回到初始的检查逻辑:要么继续稳定,要么再次触发变更(此时又会启动下一轮7个周期的稳定约束)。
这个实现完全复刻了你原计数器方案的逻辑,但不需要额外的硬件计数器,纯SVA即可完成。
内容的提问来源于stack exchange,提问作者Jonathan Drolet
相关产品推荐
相关产品推荐

