Title

SystemVerilog -- 11.3 SystemVerilog $rose、$fell、$stable

SystemVerilog \(rose、\)fell、$stable

A 是 SystemVerilog assertion 中的简单构成基块,可以表示某些表达式以帮助创建更复杂的属性。sequence

Simple Sequence

module tb;
  bit a;
  bit clk;
  
  // This sequence states that 'a' should fall on every posedge clk
  sequence s_a;
    @(posedge clk) $rose(a);
  endsequence

 // When the above sequence is asserted, the assertion fails if negedge 'a' is not found on every posedge clk
  assert property(s_a);

  always #10 clk = ~clk;

  initial begin
    for (int i = 0; i < 10; i++) begin
      a = $random;
      @(posedge clk);
      
      // Assertion is evaluated in the preponed region and use $display to see the value of 'a' in that region
      $display ("[%0t] a=%0d", $time, a);
    end
    #20 $finish;
  end
endmodule
Time (ns) a Transition Result
10 0 FAIL
30 1 0->1 PASS
50 1 PASS
70 1 PASS
90 1 PASS
110 1 PASS
130 1 PASS
150 0 1->0 FAIL
170 1 0->1 PASS
190 1 PASS

模拟日志

Compiler version P-2019.06-1; Runtime version P-2019.06-1; Dec 11 15:26 2019
[10]  a=0
"testbench.sv", 12: tb.unnamed$$_0: started at 10ns failed at 10ns
  Offending '$rose(a)'
[30]  a=1
[50]  a=1
[70]  a=1
[90]  a=1
[110] a=1
[130] a=1
[150] a=0
"testbench.sv", 12: tb.unnamed$$_0: started at 150ns failed at 150ns
  Offending '$rose(a)'
[170] a=1
[190] a=1
$finish called from file "testbench.sv", line 27.
$finish at simulation time        210

$rose

系统任务用于检测给定信号的正边沿。在这种情况下,a表示a的正边沿应该在clk的每个正边沿上看到。由于SystemVerilog assertion在预处理区域中计算,因此它只能检测预处理区域中给定信号的值。信号值在第一个边上为0,然后在下一个边上为1时,假定发生了正边沿。因此,这需要识别2个时钟。$rose $rose

module tb;
  bit a;
  bit clk;
  
  // This sequence states that 'a' should fall on every posedge clk
  sequence s_a;
    @(posedge clk) $rose(a);
  endsequence

 // When the above sequence is asserted, the assertion fails if negedge 'a' is not found on every posedge clk
  assert property(s_a);

 // Rset of the testbench stimulus
endmodule

在下图中,检测到一个正边沿,并且assertion在30ns时通过。这是因为a的值在10ns时为0,在30ns时为1,在此值上assertion完成并被证明是成功的。

Time (ns) a Transition Result
10 0 FAIL
30 1 0->1 PASS
50 1 FAIL
70 1 FAIL
90 1 FAIL
110 1 FAIL
130 1 FAIL
150 0 1->0 FAIL
170 1 0->1 PASS
190 1 FAIL

该行为在模拟日志中可见,其中assertion在30ns和170ns以外的所有时间都失败。

模拟日志

Compiler version P-2019.06-1; Runtime version P-2019.06-1; Dec 11 15:26 2019
[10]  a=0
"testbench.sv", 12: tb.unnamed$$_0: started at 10ns failed at 10ns
  Offending '$rose(a)'
[30]  a=1
[50]  a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 50ns failed at 50ns
  Offending '$rose(a)'
[70]  a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 70ns failed at 70ns
  Offending '$rose(a)'
[90]  a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 90ns failed at 90ns
  Offending '$rose(a)'
[110] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 110ns failed at 110ns
  Offending '$rose(a)'
[130] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 130ns failed at 130ns
  Offending '$rose(a)'
[150] a=0
"testbench.sv", 12: tb.unnamed$$_0: started at 150ns failed at 150ns
  Offending '$rose(a)'
[170] a=1
[190] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 190ns failed at 190ns
  Offending '$rose(a)'
$finish called from file "testbench.sv", line 27.
$finish at simulation time        210

$fell

系统任务用于检测给顶信号的负边沿。在这种情况下,a表示a的负边应该在clk的每个位置上看到。由于SystemVerilog assertion在预处理区域中计算,因此它只能检测预处理区域中给定信号的值。当信号值在第一个边上为1,然后在下一个边上为0时,假定发生了负边沿。因此,这需要识别2个时钟。$fell $fell

module tb;
  bit a;
  bit clk;
  
  // This sequence states that 'a' should fall on every posedge clk
  sequence s_a;
    @(posedge clk) $fell(a);
  endsequence

 // When the above sequence is asserted, the assertion fails if negedge 'a' is not found on every posedge clk
  assert property(s_a);
endmodule

在下图中,检测到负边沿,assertion在1500ns处通过。这是因为a的值在130ns时为1,在150ns时为0,在此值上assertion完成并被证明是成功的。

Time (ns) a Transition Result
10 0 FAIL
30 1 0->1 FAIL
50 1 FAIL
70 1 FAIL
90 1 FAIL
110 1 FAIL
130 1 FAIL
150 0 1->0 PASS
170 1 0->1 FAIL
190 1 FAIL

模拟日志

Compiler version P-2019.06-1; Runtime version P-2019.06-1; Dec 11 15:26 2019
[10]  a=0
"testbench.sv", 12: tb.unnamed$$_0: started at 10ns failed at 10ns
  Offending '$fell(a)'
[30]  a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 30ns failed at 30ns
  Offending '$fell(a)'
[50]  a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 50ns failed at 50ns
  Offending '$fell(a)'
[70]  a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 70ns failed at 70ns
  Offending '$fell(a)'
[90]  a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 90ns failed at 90ns
  Offending '$fell(a)'
[110] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 110ns failed at 110ns
  Offending '$fell(a)'
[130] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 130ns failed at 130ns
  Offending '$fell(a)'
[150] a=0
[170] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 170ns failed at 170ns
  Offending '$fell(a)'
[190] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 190ns failed at 190ns
  Offending '$fell(a)'
$finish called from file "testbench.sv", line 27.
$finish at simulation time        210

$stable

module tb;
  bit a;
  bit clk;

  // This sequence states that 'a' should be stable on every clock and should not have posedge/negedge at any posedge clk
  sequence s_a;
    @(posedge clk) $stable(a);
  endsequence

  // When the above sequence is asserted, the assertion fails if 'a' toggles at any posedge clk
  assert property (s_a);

endmodule
Time (ns) a Transition Result
10 0 FAIL
30 1 0->1 FAIL
50 1 PASS
70 1 PASS
90 1 PASS
110 1 PASS
130 1 PASS
150 0 1->0 FAIL
170 1 0->1 FAIL
190 1 PASS

模拟日志

Compiler version P-2019.06-1; Runtime version P-2019.06-1; Dec 11 15:26 2019
[10] a=0
[30] a=0
"testbench.sv", 12: tb.unnamed$$_0: started at 30ns failed at 30ns
  Offending '$stable(a)'
[50]  a=1
[70]  a=1
[90]  a=1
[110] a=1
[130] a=1
[150] a=0
"testbench.sv", 12: tb.unnamed$$_0: started at 150ns failed at 150ns
  Offending '$stable(a)'
[170] a=1
"testbench.sv", 12: tb.unnamed$$_0: started at 170ns failed at 170ns
  Offending '$stable(a)'
[190] a=1
$finish called from file "testbench.sv", line 27.
$finish at simulation time        210

posted on 2024-05-10 21:18  松—松  阅读(61)  评论(0编辑  收藏  举报

导航