我有一些断言使用序列的triggered
属性。这对于检查表单的属性非常有用“当X发生时,Y必须在过去的某个时间发生过。”
我们举一个简单的例子:
鉴于a
,b
和c
三个信号,c
只有a
在3个周期前高且{{}}才允许变高1}}在2个周期前很高。这是满足此属性的跟踪:
为了能够检查这一点,我们需要一个辅助(时钟)序列,该序列应该在b
合法的位置匹配:
c
然后我们可以在断言中使用这个序列:
sequence two_cycles_after_a_and_b;
@(posedge clk)
a ##1 b ##2 1;
endsequence
这种说法在大多数情况下都能正常工作,但在处理重置时它会变得混乱。
假设我们还有一个复位信号,它在 c_two_cycles_after_a_then_b : assert property (
c |-> two_cycles_after_a_and_b.triggered )
$info("Passed");
和b
之间的时钟周期内变为活动状态:
在这种情况下,天真的方法是在c
子句中实现断言之外的重置感知:
default disable iff
期望是,由于重置在 default disable iff !rst_n;
之前处于活动状态,之前发生的c
不计算,并且断言失败。然而,这不是发生的事情,因为序列的评估与重置无关。
要实现此行为,必须使序列重置:
a ##1 b
并且断言需要使用重置感知版本:
sequence two_cycles_after_a_and_b__reset_aware;
@(posedge clk)
rst_n throughout two_cycles_after_a_and_b;
endsequence
第二个断言确实会失败,因为 c_two_cycles_after_a_then_b__reset_aware : assert property (
c |-> two_cycles_after_a_and_b__reset_aware.triggered )
$info("Passed");
序列由于重置的发生而不匹配。
这显然有效,但它需要更多的努力,并且需要重置才能成为序列/属性的组成部分,而不是在每个范围的基础上进行控制。在这种情况下是否还有其他方法可以实现重置感知,更接近使用two_cycles...
?
答案 0 :(得分:0)
我能想出的最佳解决方案是为样本rst_n
添加一些辅助代码,并将其保持足够长的时间以便按时钟进行采样。
always @(posedge clk, negedge rst_n) begin
if(!rst_n) smpl_rst_n <= 1'b0;
else smpl_rst_n <= 1'b1;
end
然后使用通用序列进行重置感知,使用smpl_rst_n
和对目标序列的引用。
sequence reset_aware(sequence seq);
@(posedge clk)
smpl_rst_n throughout seq;
endsequence
最终断言将如下工作:
a_two_cycles_after_a_then_b__reset_aware : assert property (
c |-> reset_aware(two_cycles_after_a_and_b).triggered )
$info("Passed");