在断言

时间:2016-10-05 14:15:05

标签: system-verilog system-verilog-assertions

我有一些断言使用序列的triggered属性。这对于检查表单的属性非常有用“当X发生时,Y必须在过去的某个时间发生过。”

我们举一个简单的例子:

鉴于abc三个信号,c只有a在3个周期前高且{{}}才允许变高1}}在2个周期前很高。这是满足此属性的跟踪:

enter image description here

为了能够检查这一点,我们需要一个辅助(时钟)序列,该序列应该在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之间的时钟周期内变为活动状态:

enter image description here

在这种情况下,天真的方法是在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...

1 个答案:

答案 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");

概念证明:https://www.edaplayground.com/x/6Luf