跨时钟域稳定信号SVA验证遇工具兼容问题,求替代实现方案
针对你提到的《Asynchronous Behaviors Meet Their Match with SystemVerilog Assertions》论文中图8的跨时钟域strobe信号验证场景——要求strobe在src_clk域拉高后,在dst_clk域稳定至少3个周期,原断言因旧版工具(Cadence Incisive 15.20、Synopsys VCS 2014.10)不支持多时钟序列的intersect操作而报错,这里提供几种兼容性更好的替代实现方式:
方案1:基于同步器的单时钟断言拆分(最推荐)
实际设计中跨时钟信号通常会通过同步寄存器(比如两级FF)同步到目标时钟域,我们可以利用同步后的信号拆分断言,分别在两个时钟域验证:
1.1 目标时钟域(dst_clk)验证稳定性
假设sync_strobe是strobe经过两级同步到dst_clk域的信号,直接在dst_clk域断言信号稳定至少3个周期:
assert property (@(posedge dst_clk) $rose(sync_strobe) |-> sync_strobe[*3] );
1.2 源时钟域(src_clk)验证保持时间
根据src_clk和dst_clk的频率关系,计算src_clk中需要保持strobe有效的最小周期数(比如src_clk是dst_clk的2倍,则至少需要6个src_clk周期),确保strobe的持续时间覆盖dst_clk的3个周期:
// N为src_clk中对应dst_clk 3个周期的最小周期数,需根据实际时钟频率比计算 assert property (@(posedge src_clk) $rose(strobe) |-> strobe[*N] );
这种方案完全基于单时钟断言,兼容性最好,也符合实际设计的跨时钟处理逻辑。
方案2:利用序列triggered方法关联跨时钟条件
如果无法依赖同步器,可以将两个时钟域的条件封装为独立序列,通过triggered方法关联触发关系:
// 定义源时钟域序列:strobe拉高后持续有效 sequence src_strobe_hold; @(posedge src_clk) $rose(strobe) ##1 strobe[*1:$]; endsequence // 定义目标时钟域序列:strobe稳定3个周期 sequence dst_strobe_stable; @(posedge dst_clk) strobe[*3]; endsequence // 断言:源序列触发后,目标序列必须触发 assert property ( src_strobe_hold.triggered |-> dst_strobe_stable.triggered );
注意:这种方式需要确保两个时钟域的时序对齐,跨时钟采样strobe时要考虑亚稳态风险,建议仅在验证环境中使用,不适合直接断言异步信号的原始值。
方案3:跨时钟触发的单时钟断言(工具兼容性需验证)
部分旧版工具可能支持跨时钟的$rose触发语法,可以尝试在dst_clk域直接用src_clk的$rose(strobe)作为触发条件:
assert property (@(posedge dst_clk) $rose(strobe, @(posedge src_clk)) |-> strobe[*3] );
这种方式语法更简洁,但工具支持性因版本而异,需要在你的目标工具上测试验证。
总结
旧版EDA工具对多时钟序列的intersect操作支持有限,拆分断言到单个时钟域(尤其是基于同步后的信号)是兼容性和可靠性最高的选择,既符合设计规范,也能避免工具语法支持的限制。
内容的提问来源于stack exchange,提问作者qkzxc

