SV_14_Assertions

目录

1. 断言的两种形式 

1.1 Immediate Assertions

1.1.1 一些打印的信息:

2. Concurrent assertions

2.1 并发断言有以下几层

一个例子:

2.2 Boolean layer

布尔层的使用限制

2.3 Sequences

2.3.1 ## operator

2.3.2 Repetition operators

2.3.4 Binary operators

2.3.5 Match operators

2.3.6 System tasks

2.3.7 Sequence arguments

2.3.8 Local Variables

2.3.9 Calling subroutine 

2.4 Properties

2.4.1 Another named property  

2.4.2 Negation

2.4.3 Disjunction

2.4.4 conjunction

2.4.5 if...else

2.4.6 Implication

2.4.7 disable iff

2.4.8 Recursive property 

3. Multi clock support

3.1 Multi clock sequence

3.2 Multi clock property

4. Assert,Assume,Cover

5. Binding

6. Expect

7. Clock resolution


摘要:断言验证是指使用断言语言来指定设计中的预期行为,以及相对于验证中的设计来评估断言的工具。

  • ABV:基于断言的验证运行设计工程师在设计过程中获取验证信息,还支持内部状态、数据路径和错误先决条件覆盖分析;
  • 一个 简单例子就是FIFO的判断空满;
  • HDL可以编写断言,但其形式是很复杂的;

1. 断言的两种形式 

  • Immediate Assertions:基于事件语义,与always块相似;
  • Concurrent Assertions:基于时钟语义,与带时钟的always块相似。

1.1 Immediate Assertions

  • 立即断言是对过程语句宏表达式的测试;
  • 如果表达式的结果为x、z、0,则断言解释为false,断言失败;否则断言成功。
1 assertion_label : assert (expression)
2  pass block code;
3 else
4 fail block code;

1.1.1 一些打印的信息:

  • $fatal:运行致命错误;
  • $error:运行错误;
  • $warning:运行警告,可以被一些特殊工具覆盖掉;
  • $info:打印一些失败信息,无特定的严重程度;

也可以使用$display()函数

 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 // DUT With Immediate assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module assert_immediate();
 5
 6 reg clk, grant, request;
 7 time current_time;
 8
 9 initial begin
10 clk = 0;
11 grant = 0;
12 request = 0;
13 #4 request = 1;
14 #4 grant = 1;
15 #4 request = 0;
16 #4 $finish;
17 end
18
19 always #1 clk = ~clk;
20 //=================================================
21 // Assertion used in always block
22 //=================================================
23 always @ (posedge clk)
24 begin
25 if (grant == 1) begin
26 CHECK_REQ_WHEN_GNT : assert (grant && request) begin
27 $display ("Seems to be working as expected");
28 end else begin
29 current_time = $time;
30 #1 $error("assert failed at time %0t", current_time);
31 end
32 end
33 end
34
35 endmodule
36
37 //compile result
38
39 Info: "assert_immediate.sv", 21:
40 assert_immediate.CHECK_REQ_WHEN_GNT: at time 9
41  Seems to be working as expected
42 Info: "assert_immediate.sv", 21:
43 assert_immediate.CHECK_REQ_WHEN_GNT: at time 11
44  Seems to be working as expected
45 "assert_immediate.sv", 21:
46  assert_immediate.CHECK_REQ_WHEN_GNT:
47  started at 13s failed at 13s
48 Offending '(grant && request)'
49 Error: "assert_immediate.sv", 21:
50 assert_immediate.CHECK_REQ_WHEN_GNT: at time 14
51 assert failed at time 13
52 "assert_immediate.sv", 21:
53  assert_immediate.CHECK_REQ_WHEN_GNT:
54  started at 15s failed at 15s
55 Offending '(grant && request)'
View Code

2. Concurrent assertions

  • 并发断言描述跨时间的行为;
  • 并发断言仅在时钟tick时才计算;
  • 评估中使用的值为采样值,避免了模拟器对事件的影响;
  • 关键字propert将并发断言与立即断言分开;

 

2.1 并发断言有以下几层

  • Boolean:布尔代数层
  • Sequences:序列层
  • Property:属性层
  • Property directive:属性指令层

一个例子:

测试波形:

 

 测试代码:

 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 // DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module concurrent_assertion(
 5 input wire clk,req,reset,
 6 output reg gnt);
 7 //=================================================
 8 // Sequence Layer
 9 //=================================================
10 sequence req_gnt_seq;
11 // (~req & gnt) and (~req & ~gnt) is Boolean Layer
12 (~req & gnt) ##1 (~req & ~gnt);
13 endsequence
14 //=================================================
15 // Property Specification Layer
16 //=================================================
17 property req_gnt_prop;
18 @ (posedge clk)
19 disable iff (reset)
20 req |-> req_gnt_seq;
21 endproperty
22 //=================================================
23 // Assertion Directive Layer
24 //=================================================
25 req_gnt_assert : assert property (req_gnt_prop)
26 else
27 $display("@%0dns Assertion Failed", $time);
28 //=================================================
29 // Actual DUT RTL
30 //=================================================
31 always @ (posedge clk)
32 gnt <= req;
33
34 endmodule
35
36 //+++++++++++++++++++++++++++++++++++++++++++++++
37 // Testbench Code
38 //+++++++++++++++++++++++++++++++++++++++++++++++
39 module concurrent_assertion_tb();
40
41 reg clk = 0;
42 reg reset, req = 0;
43 wire gnt;
44
45 always #3 clk ++;
46
47 initial begin
48 reset <= 1;
49 #20 reset <= 0;
50 // Make the assertion pass
51 #100 @ (posedge clk) req <= 1;
52 @ (posedge clk) req <= 0;
53 // Make the assertion fail
54 #100 @ (posedge clk) req <= 1;
55 repeat (5) @ (posedge clk);
56 req <= 0;
57 #10 $finish;
58 end
59
60 concurrent_assertion dut (clk,req,reset,gnt);
61
62 endmodule
63 //compile result
64
65  @129ns Assertion Failed
66  @237ns Assertion Failed
67  @243ns Assertion Failed
68  @249ns Assertion Failed
69  @255ns Assertion Failed
70 @261ns Assertion Failed
View Code

  在并发断言的所有层中:

  • 基本的构建块是布尔层,它的值为0或1;
  • 序列层基本是建立在布尔层上,序列定义任何并发断言的最基本构造;
  • 属性层建立在序列层之上(并不总是如此)。
  • 要使属性成为模拟的一部分,需要在属性执行层中的assert语句中使用该属性。

2.2 Boolean layer

  • 布尔层是并发断言的最底层,对变量进行布尔表达式检查;
  • 布尔表达式允许包含函数调用;
  1. 出现在表达式中的函数不能包含 output 或 ref 参数 (允许使用 const ref 参数 );
  2. 函数应该是automatic的(或者不保留状态信息),并且没有副作用;

布尔层的使用限制

不能使用的数据类型:

  • shortreal, real,realtime
  • string
  • event
  • handle
  • class
  • associative arrays
  • dynamic arrays

不能使用的操作符:

  • assignment(赋值),increment(自增),decrement(自减)
1 module assertion_boolean();
2
3 wire ce, en;
4 wire [7:0] addr;
5
6 // This code will not compile
7 (en && ce && addr < 100);
8
9 endmodule

2.3 Sequences

  • 序列层使用布尔层来构造有效地时间序列;
  • 最简单的序列行为是线性序列;
  1. 线性序列是一个有限的SV布尔表达式列表,它按线性顺序递增;
  2. 在第一个时钟周期的第一个布尔表达式为真,第二个时钟周期的第二个布尔表达式为真,直到最后一个 时钟周期的布尔表达式为真,才会匹配成功。
  • 序列可以声明的位置:
  1. module
  2. interface
  3. program
  4. clocking block
  5. package
  • 序列之间可以互相调用;
  • 一些构造序列的操作符:
  1. ##
  2. [* ]
  3. [= ]
  4. [-> ]
  5. throughout
  6. within left
  7. intersect
  8. and
  9. or

2.3.1 ## operator

  • ##后跟一个数字或者一个范围;
  • req ##1 gnt :表示gnt在 req一个时钟后发生;
  • req ##0 gnt:表示gnt 与 req 在同一边缘上,通常用于合并两个序列;
  • req  ##[0:3] gnt:表示  gnt 在 req的0-3个时钟后有效;
  • 可以用变量代替常量表示延迟。
  1 //+++++++++++++++++++++++++++++++++++++++++++++++++
  2 //   DUT With assertions
  3 //+++++++++++++++++++++++++++++++++++++++++++++++++
  4 module hash_sequence();
  5 
  6 logic clk = 0;
  7 always #1 clk ++;
  8 
  9 logic [2:0] req,gnt;
 10 logic reset;
 11 //=================================================
 12 // Shows basic usage of ## delay operator
 13 //=================================================
 14 sequence req_gnt_1clock_seq;
 15   req[0] ##1 gnt[0];
 16 endsequence
 17 //=================================================
 18 // Shows range usage of ## delay operator
 19 //=================================================
 20 sequence req_gnt_3to5clock_seq;
 21   req[1] ##[3:5] gnt[1];
 22 endsequence
 23 //=================================================
 24 // Shows zero delay usage of ## delay operator
 25 //=================================================
 26 sequence req_gnt_0clock_seq;
 27   req[2] ##0 gnt[2];
 28 endsequence
 29 //=================================================
 30 // Shows sequence called within sequence 
 31 //=================================================
 32 sequence master_seq;
 33   req_gnt_1clock_seq ##1 req_gnt_3to5clock_seq ##1 req_gnt_0clock_seq;
 34 endsequence
 35 //=================================================
 36 //  Declare property for each of sequence
 37 //  We may use more then one seuqnce in a property
 38 //=================================================
 39 property req_gnt_1clock_prop;
 40   @ (posedge clk)
 41   disable iff (reset)
 42      req[0] |-> req_gnt_1clock_seq;
 43 endproperty
 44 
 45 property req_gnt_3to5clock_prop;
 46   @ (posedge clk)
 47   disable iff (reset)
 48      req[1] |-> req_gnt_3to5clock_seq;
 49 endproperty
 50 
 51 property req_gnt_0clock_prop;
 52   @ (posedge clk)
 53   disable iff (reset)
 54      req[2] |-> req_gnt_0clock_seq;
 55 endproperty
 56 
 57 property master_prop;
 58   @ (posedge clk)
 59   disable iff (reset)
 60      req[0] |-> master_seq;
 61 endproperty
 62   
 63 //=================================================
 64 // Assertion Directive Layer
 65 //=================================================
 66 req_gnt_1clock_assert    : assert property (req_gnt_1clock_prop);
 67 req_gnt_3to5clock_assert : assert property (req_gnt_3to5clock_prop);
 68 req_gnt_0clock_assert    : assert property (req_gnt_0clock_prop);
 69 master_assert            : assert property (master_prop);
 70 
 71 //=================================================
 72 // Drive the input vectors to test assetion
 73 //=================================================
 74 initial begin
 75   // Init all the values
 76   reset  <= 0;
 77   for (int i = 0; i < 3; i++) begin
 78     req[i] <= 0;
 79     gnt[i] <= 0;
 80   end
 81   @ (posedge clk);
 82   req[0] <= 1;
 83   @ (posedge clk);
 84   gnt[0] <= 1;
 85   req[0] <= 0;
 86   @ (posedge clk);
 87   gnt[0] <= 0;
 88   req[1] <= 1;
 89   @ (posedge clk);
 90   req[1] <= 0;
 91   repeat(3) @ (posedge clk);
 92   gnt[1] <= 1;
 93   @ (posedge clk);
 94   gnt[1] <= 0;
 95   req[2] <= 1;
 96   gnt[2] <= 1;
 97   @ (posedge clk);
 98   req[2] <= 0;
 99   gnt[2] <= 0;
100   // Cause assertion to fail
101   @ (posedge clk);
102   req[0] <= 1;
103   repeat(2) @ (posedge clk);
104   gnt[0] <= 1;
105   req[0] <= 0;
106   #30 $finish;
107 end
108 
109 endmodule
110 
111 //compile  result
112  Error: Assertion error.
113  Time: 23 ns Started: 21 ns  Scope: 
114  hash_sequence.req_gnt_1clock_assert File: hash_sequence.sv Line: 63
115  Error: Assertion error.
116  Time: 23 ns Started: 21 ns  Scope: 
117  hash_sequence.master_assert File: hash_sequence.sv Line: 66
118  Error: Assertion error.
119  Time: 27 ns Started: 23 ns  Scope: 
120  hash_sequence.master_assert File: hash_sequence.sv Line: 66
View Code

2.3.2 Repetition operators

测试的序列需要重复时,有以下三种方式可供选择:(最小值可以小于0,最大值为$)

  • a[*n ]b:连续跟随重复操作符,重复之间以及两个匹配之间只有一个时钟的延迟;

 

  • [-> ]:不连续跟随重复操作符,重复之间可以有多个时钟的延迟,两个匹配之间只有一个时钟的延迟;

 

  • [= ]:不连续不跟随重复操作符,重复之间以及两个匹配之间可以有多个时钟的延迟;

 

  •  empty sequence:空序列是一个不匹配任何正整数时钟ticks的序列;
    • (empty ##0 seq ) 没有匹配结果;
    • (seq ##0 empty ) 没有匹配结果;
    • (empty ##n seq ) 其中n>0,相当于 (##(n-1)seq);
    • (seq ##n empty ) 其中n>0,相当于(seq  ##(n-1));

consective repetition例子波形图:

 

 consective repetition例子代码:

View Code

 Goto repetition例子波形图:

 

  Goto repetition例子代码:

 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module goto_assertion();
 5 
 6 logic clk = 0;
 7 always #1 clk ++;
 8 
 9 logic req,busy,gnt;
10 //=================================================
11 // Sequence Layer
12 //=================================================
13 sequence boring_way_seq;
14   req ##1 ((!busy[*0:$] ##1 busy) [*3]) ##1 gnt;
15 endsequence
16 
17 sequence cool_way_seq;
18   req ##1 (busy [->3]) ##1 gnt;
19 endsequence
20 
21 //=================================================
22 // Property Specification Layer
23 //=================================================
24 property boring_way_prop;
25   @ (posedge clk) 
26       req |=> boring_way_seq;
27 endproperty
28 
29 property cool_way_prop;
30   @ (posedge clk) 
31       req |=> cool_way_seq;
32 endproperty
33 //=================================================
34 // Assertion Directive Layer
35 //=================================================
36 boring_way_assert : assert property (boring_way_prop);
37 cool_way_assert   : assert property (cool_way_prop);
38 
39 //=================================================
40 // Generate input vectors
41 //=================================================
42 initial begin
43   // Pass sequence
44   gen_seq(3,0); 
45   repeat (20) @ (posedge clk);
46   // Fail sequence (gnt is not asserted properly)
47   gen_seq(3,1); 
48   // Terminate the sim
49   #30 $finish;
50 end
51 //=================================================
52 /// Task to generate input sequence
53 //=================================================
54 task  gen_seq (int busy_delay,int gnt_delay);
55   req <= 0; busy <= 0;gnt <= 0;
56   @ (posedge clk);
57   req <= 1;
58   @ (posedge clk);
59   req  <= 0;
60   repeat (busy_delay) begin
61    @ (posedge clk);
62     busy <= 1;
63    @ (posedge clk);
64     busy <= 0;
65   end
66   repeat (gnt_delay) @ (posedge clk);
67   gnt <= 1;
68   @ (posedge clk);
69   gnt <= 0;
70 endtask
71 
72 endmodule
73 
74 //compile result
75     
76  "goto_assertion.sv", 33: boring_way_assert: 
77    started at 61s failed at 75s
78          Offending 'gnt'
79  "goto_assertion.sv", 34: cool_way_assert: 
80    started at 61s failed at 75s
81          Offending 'gnt
View Code

  NonConsective repetition例子波形图:

 

NonConsective repetition例子代码:

 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module noncon_assertion();
 5 
 6 logic clk = 0;
 7 always #1 clk ++;
 8 
 9 logic req,busy,gnt;
10 //=================================================
11 // Sequence Layer
12 //=================================================
13 sequence boring_way_seq;
14   req ##1 ((!busy[*0:$] ##1 busy) [*3]) ##1 !busy[*0:$] ##1 gnt;
15 endsequence
16 
17 sequence cool_way_seq;
18   req ##1 (busy [=3]) ##1 gnt;
19 endsequence
20 
21 //=================================================
22 // Property Specification Layer
23 //=================================================
24 property boring_way_prop;
25   @ (posedge clk) 
26       req |-> boring_way_seq;
27 endproperty
28 
29 property cool_way_prop;
30   @ (posedge clk) 
31       req |-> cool_way_seq;
32 endproperty
33 //=================================================
34 // Assertion Directive Layer
35 //=================================================
36 boring_way_assert : assert property (boring_way_prop);
37 cool_way_assert   : assert property (cool_way_prop);
38 
39 //=================================================
40 // Generate input vectors
41 //=================================================
42 initial begin
43   // Pass sequence
44   gen_seq(3,0); 
45   repeat (20) @ (posedge clk);
46   // This was fail in goto, but not here
47   gen_seq(3,1); 
48   repeat (20) @ (posedge clk);
49   gen_seq(3,5); 
50   // Lets fail one 
51   repeat (20) @ (posedge clk);
52   gen_seq(5,5); 
53   // Terminate the sim
54   #30 $finish;
55 end
56 //=================================================
57 /// Task to generate input sequence
58 //=================================================
59 task  gen_seq (int busy_delay,int gnt_delay);
60   req <= 0; busy <= 0;gnt <= 0;
61   @ (posedge clk);
62   req <= 1;
63   @ (posedge clk);
64   req  <= 0;
65   repeat (busy_delay) begin
66    @ (posedge clk);
67     busy <= 1;
68    @ (posedge clk);
69     busy <= 0;
70   end
71   repeat (gnt_delay) @ (posedge clk);
72   gnt <= 1;
73   @ (posedge clk);
74   gnt <= 0;
75 endtask
76 
77 endmodule
78 
79 //compile result
80     
81  "noncon_assertion.sv", 33: boring_way_assert: 
82    started at 189s failed at 205s
83          Offending 'gnt'
84  "noncon_assertion.sv", 34: cool_way_assert: 
85    started at 189s failed at 205s
86          Offending 'gnt'
View Code

2.3.4 Binary operators

  • 二元操作符接受两个操作数或两个序列,并生成一个新序列;
  • 几个常用的二元操作符:
  1. and:两个序列同时 开始,不一定同时结束,匹配长度取最大的;
  2. intersect:两个序列同时开始,同时结束;
  3. or :两个序列有一个匹配即可,匹配 长度取最小的;
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module binary_assertion();
 5 
 6 logic clk = 0;
 7 always #1 clk ++;
 8 
 9 logic req,gnt,busy;
10 //=================================================
11 // Sequence Specification Layer
12 //=================================================
13 sequence s1;
14  $past(!req,1) ##1 ($rose(gnt) and $past(!gnt,1));
15 endsequence
16 
17 sequence s2;
18  $past(!req,1) ##1 $rose(gnt) ##1 $fell(gnt);
19 endsequence 
20 
21 sequence s3;
22   req ##1 gnt ##1 busy ##1 (!req and !gnt and !busy);
23 endsequence
24 
25 sequence s4;
26   req ##[1:3] gnt;
27 endsequence
28 //=================================================
29 // Property Specification Layer
30 //=================================================
31 property and_prop;
32   @ (posedge clk) 
33     req |-> s1 and s2;
34 endproperty
35 
36 property intersect_prop;
37   @ (posedge clk) 
38     req |-> s1 intersect s3;
39 endproperty
40 
41 property or_prop;
42   @ (posedge clk) 
43     req |-> s1 or s4;
44 endproperty
45 //=================================================
46 // Assertion Directive Layer
47 //=================================================
48 and_assert       : assert property (and_prop);
49 intersect_assert : assert property (intersect_prop);
50 or_assert        : assert property (or_prop);
51 //=================================================
52 // Generate input vectors
53 //=================================================
54 initial begin
55   req <= 0;gnt <= 0;busy<=0;
56   repeat(10) @ (posedge clk);
57   req <= 1;
58   @( posedge clk);
59   gnt <= 1;
60   req <= 0;
61   @( posedge clk);
62   busy <= 1;
63   // Make the assertion fail now
64   // OR will not fail
65   req <= 0;gnt <= 0; busy <= 0;
66   repeat(10) @ (posedge clk);
67   req <= 1;
68   repeat (2) @( posedge clk);
69   req <= 0;
70   gnt <= 1;
71   @( posedge clk);
72   @( posedge clk);
73   req <= 0;gnt <= 0; busy <= 0;
74   // Terminate the sim
75   #30 $finish;
76 end
77 
78 endmodule
79 
80 //compil result
81     
82  Error: Assertion error.
83  Time: 23 ns Started: 21 ns  
84   intersect_assert File: binary_assertion.sv Line: 46
85  Error: Assertion error.
86  Time: 47 ns Started: 47 ns  
87  and_assert File: binary_assertion.sv Line: 45
88  Error: Assertion error.
89  Time: 47 ns Started: 45 ns  
90  and_assert File: binary_assertion.sv Line: 45
91  Error: Assertion error.
92  Time: 47 ns Started: 47 ns  
93  intersect_assert File: binary_assertion.sv Line: 46
94  Error: Assertion error.
95  Time: 47 ns Started: 45 ns  
96  intersect_assert File: binary_assertion.sv Line: 46
View Code

2.3.5 Match operators

  • 匹配操作符接受两个操作数或两个序列,并生成一个新序列;

first_match

只取第一次匹配成功的序列;

throughout

在匹配throughout后面的一个序列时,throughout前的序列一直有效;

within

在匹配长度上within前的序列包含于within后的序列;

 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module match_assertion();
 5 
 6 logic clk = 0;
 7 always #1 clk ++;
 8 
 9 logic burst_enable, master_busy, slave_busy;
10 //=================================================
11 // Property Specification Layer
12 //=================================================
13 property first_match_prop;
14   @ (posedge clk) 
15     $rose(burst_enable) |=> 
16       first_match(burst_enable ##[0:4] !master_busy);
17 endproperty
18        
19 property throughout_prop;
20   @ (posedge clk) 
21     $rose(burst_enable) |-> 
22       (burst_enable) throughout 
23           ( ##2 (!slave_busy && !master_busy) [*6]);
24 endproperty
25 
26 property within_prop;
27   @ (posedge clk) 
28     $rose(burst_enable) |=> 
29        (!slave_busy[*6]) within 
30            (($fell(master_busy)) ##1 !master_busy[*7]);
31 endproperty
32 //=================================================
33 // Assertion Directive Layer
34 //=================================================
35 within_assert     : assert property (within_prop);
36 throughout_assert : assert property (throughout_prop);
37 first_match_assert: assert property (first_match_prop);
38 //=================================================
39 // Generate input vectors
40 //=================================================
41 initial begin
42   burst_enable <= 0; master_busy <= 1; slave_busy <= 1;
43   @ (posedge clk); 
44   burst_enable <= 1;
45   @ (posedge clk); 
46   master_busy <= 0;
47   @ (posedge clk); 
48   slave_busy <= 0;
49   repeat(6) @ (posedge clk);
50   slave_busy <= 1;
51   @ (posedge clk); 
52   burst_enable <= 0;
53   master_busy <= 1;
54   // Fail both the assertion
55   repeat(20) @ (posedge clk);
56   burst_enable <= 0; master_busy <= 1; slave_busy <= 1;
57   @ (posedge clk); 
58   burst_enable <= 1;
59   @ (posedge clk); 
60   master_busy <= 0;
61   @ (posedge clk); 
62   slave_busy <= 0;
63   repeat(5) @ (posedge clk);
64   slave_busy <= 1;
65   @ (posedge clk); 
66   burst_enable <= 0;
67   master_busy <= 1;
68   // Terminate the sim
69   repeat(20) @ (posedge clk);
70   $finish;
71 end
72 
73 endmodule
74 
75 //compile result
76  "match_assertion.sv", 26: within_assert: started at 63s failed at 77s
77          Offending '(!slave_busy)'
78  "match_assertion.sv", 27: throughout_assert: started at 63s failed at 77s
79          Offending '((!slave_busy) && (!master_busy))'
View Code

2.3.6 System tasks

  • $sampled:返回与上次时钟事件相关的表达式的采样值(有些多余);
  • $rose:信号跳变为1,返回true;
  • $fell:信号跳变为0,返回true;
  • $stable:两次时钟事件的信号值不变,返回true;
  • $past:返回前一个时钟周期的表达式的采样值。
  • $onehot:信号只拉高一次则为真;
  • $onehot0:信号只拉低一次为真;
  • $isunknown:匹配到x或者z为真;
 1 module system_assertion();
 2 
 3 logic clk = 0;
 4 always #1 clk ++;
 5 
 6 logic req,gnt;
 7 //-------------------------------------------------
 8 // Property Specification Layer
 9 //-------------------------------------------------
10 property system_prop;
11   @ (posedge clk) 
12       ($rose(req) && $past(!req,1)) |=> 
13          ($rose(gnt) && $past(!gnt,1));
14 endproperty
15 //-------------------------------------------------
16 // Assertion Directive Layer
17 //-------------------------------------------------
18 system_assert : assert property (system_prop);
19 //-------------------------------------------------
20 // Generate input vectors
21 //-------------------------------------------------
22 initial begin
23   req <= 0;gnt <= 0;
24   repeat(10) @ (posedge clk);
25   req <= 1;
26   @( posedge clk);
27   gnt <= 1;
28   req <= 0;
29   @( posedge clk);
30   // Make the assertion fail now
31   req <= 0;gnt <= 0;
32   repeat(10) @ (posedge clk);
33   req <= 1;
34   @( posedge clk);
35   req <= 0;
36   gnt <= 0;
37   // Terminate the sim
38   #30 $finish;
39 end
40 
41 endmodule
42 
43 //compile result
44     
45  "system_assertion.sv", 18: 
46  system_assertion.system_assert: started at 45s failed at 47s
47          Offending '($rose(gnt) && $past((!gnt), 1))'
View Code

2.3.7 Sequence arguments

  • 序列可以用参数声明,当一个序列被实例化时,实际的参数可以传递给该序列;
  • 通过将形式参数替换为实际参数,序列用实际参数展开; 
  • 使用带参数的序列有一大优点是,它可以重用。
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module propargs_assertion();
 5 logic clk = 0;
 6 logic req,gnt;
 7 logic a,b;
 8 //=================================================
 9 // Sequence Layer with args (NO TYPE)
10 //=================================================
11 sequence notype_seq (X, Y);
12   (~X & Y) ##1 (~X & ~Y);
13 endsequence
14 //=================================================
15 // Sequence Layer with args (NO TYPE)
16 //=================================================
17 sequence withtype_seq (logic X, logic Y);
18   (~X & Y) ##1 (~X & ~Y);
19 endsequence
20 //=================================================
21 // Property Specification Layer
22 //=================================================
23 property req_gnt_notype_prop(M,N);
24   @ (posedge clk) 
25       req |=> notype_seq(M,N);
26 endproperty
27 
28 property a_b_type_prop(logic M, logic N;
29   @ (posedge clk) 
30       a |=> withtype_seq(M,N);
31 endproperty
32 //=================================================
33 // Assertion Directive Layer
34 //=================================================
35 req_gnt_notype_assert : assert property (req_gnt_notype_prop(req,gnt));
36 a_b_type_assert       : assert property (a_b_type_prop(a,b));
37 //=================================================
38 // Actual DUT RTL
39 //=================================================
40 always @ (posedge clk)
41   gnt <= req;
42 
43 always @ (posedge clk)
44   b <= a;
45 
46 //+++++++++++++++++++++++++++++++++++++++++++++++++
47 //  Assertion testing code
48 //+++++++++++++++++++++++++++++++++++++++++++++++++
49 always #3 clk ++;
50 
51 initial begin
52   // Make the assertion pass
53   #100 @ (posedge clk) req  <= 1;
54   @ (posedge clk) req <= 0;
55   // Make the assertion fail
56   #100 @ (posedge clk) req  <= 1;
57   repeat (2) @ (posedge clk);
58   req <= 0;
59 
60   // Make the assertion pass
61   #100 @ (posedge clk) a  <= 1;
62   @ (posedge clk) a <= 0;
63   // Make the assertion fail
64   #100 @ (posedge clk) a  <= 1;
65   repeat (2) @ (posedge clk);
66   a <= 0;
67   #10 $finish;
68 end
69 
70 endmodule
71 
72 //compile result
73    (~X & Y) ##1 (~X & ~Y);
74        |
75  ERROR (args_assertion.sv,46): (time 225 NS) 
76  Assertion args_assertion.req_gnt_type_assert 
77  has failed (2 cycles, starting 219 NS)
78    (~X & Y) ##1 (~X & ~Y);
79        |
80  ERROR (args_assertion.sv,45): (time 225 NS)
81   Assertion args_assertion.req_gnt_notype_assert 
82  has failed (2 cycles, starting 219 NS)
83    (~X & Y) ##1 (~X & ~Y);
84        |
85  ERROR (args_assertion.sv,48): (time 447 NS) 
86  Assertion args_assertion.a_b_type_assert 
87  has failed (2 cycles, starting 441 NS)
88    (~X & Y) ##1 (~X & ~Y);
89        |
90  ERROR (args_assertion.sv,47): (time 447 NS) 
91  Assertion args_assertion.a_b_notype_assert 
92  has failed (2 cycles, starting 441 NS)
View Code

2.3.8 Local Variables

可以在序列或者属性中包含局部变量。可以为这些局部变量赋值,并在之后采样;

 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module localvar_assertion();
 5 
 6 logic clk = 0;
 7 always #1 clk ++;
 8 
 9 logic [7:0] portin, portout;
10 logic       in_en, out_en;
11 //=================================================
12 // Sequence Layer
13 //=================================================
14 sequence local_var_seq;
15    logic [7:0] lport;
16    (in_en, lport = portin) ##[1:5] 
17       (out_en and lport == portout);
18 endsequence
19 //=================================================
20 // Property Specification Layer
21 //=================================================
22 property local_var_prop;
23   @ (posedge clk) 
24       in_en |-> local_var_seq;
25 endproperty
26 //=================================================
27 // Assertion Directive Layer
28 //=================================================
29 local_var_assert : assert property (local_var_prop);
30 //=================================================
31 // Simple DUT logic 
32 //=================================================
33 always @ (posedge clk)
34 begin
35   portout <= (portin < 4) ? portin : portin + 1;
36   out_en  <= in_en;
37 end
38 //=================================================
39 // Generate input vectors
40 //=================================================
41 initial begin
42   in_en <= 0; out_en <= 0;
43   portin <= 0; portout <= 0;
44   repeat (20) @ (posedge clk);
45   for (int i =0 ; i < 8; i ++) begin
46     @ (posedge clk);
47     in_en <= 1;
48     portin <= i;
49     @ (posedge clk);
50     in_en <= 0;
51     portin <= 0;
52   end
53   #30 $finish;
54 end
55 
56 endmodule
57 
58 //compile result
59  Assertion error.
60  Time: 69 ns Started: 59 ns  
61  localvar_assertion.local_var_assert Line: 26
62  Assertion error.
63  Time: 73 ns Started: 63 ns  
64  localvar_assertion.local_var_assert Line: 26
65  Assertion error.
66  Time: 77 ns Started: 67 ns  
67  localvar_assertion.local_var_assert Line: 26
68  Assertion error.
69  Time: 81 ns Started: 71 ns  
70  localvar_assertion.local_var_assert Line: 26
View Code

2.3.9 Calling subroutine 

  • 任务、方法,空函数、系统任务等子例程都可以在成功匹配序列的最后被调用;
  • 序列和后面的子例程用()括起来;
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module subroutine_assertion();
 5 
 6 logic clk = 0;
 7 always #1 clk ++;
 8 
 9 logic [7:0] portin, portout;
10 logic       in_en, out_en;
11 //=================================================
12 // Sequence Layer
13 //=================================================
14 sequence local_var_seq;
15    logic [7:0] lport;
16    (in_en, lport = portin) ##[1:5] 
17       (out_en and lport == portout, 
18         $display ("@%0dns Input port %0d and Output port %0d match", 
19          $time, lport,portout));
20 endsequence
21 //=================================================
22 // Property Specification Layer
23 //=================================================
24 property local_var_prop;
25   @ (posedge clk) 
26       in_en |-> local_var_seq;
27 endproperty
28 //=================================================
29 // Assertion Directive Layer
30 //=================================================
31 local_var_assert : assert property (local_var_prop);
32 //=================================================
33 // Simple DUT logic 
34 //=================================================
35 always @ (posedge clk)
36 begin
37   portout <= (portin < 4) ? portin : portin + 1;
38   out_en  <= in_en;
39 end
40 //=================================================
41 // Generate input vectors
42 //=================================================
43 initial begin
44   in_en <= 0; out_en <= 0;
45   portin <= 0; portout <= 0;
46   repeat (20) @ (posedge clk);
47   for (int i =0 ; i < 8; i ++) begin
48     @ (posedge clk);
49     in_en <= 1;
50     portin <= i;
51     @ (posedge clk);
52     in_en <= 0;
53     portin <= 0;
54   end
55   #30 $finish;
56 end
57 
58 endmodule
59 
60 //compile result
61     
62  @45ns Input port 0 and Output port 0 match
63  @49ns Input port 1 and Output port 1 match
64  @53ns Input port 2 and Output port 2 match
65  @57ns Input port 3 and Output port 3 match
66  Assertion error.
67  Time: 69 ns Started: 59 ns  localvar_assertion.local_var_assert Line: 28
68  Assertion error.
69  Time: 73 ns Started: 63 ns  localvar_assertion.local_var_assert Line: 28
70  Assertion error.
71  Time: 77 ns Started: 67 ns  localvar_assertion.local_var_assert Line: 28
72  Assertion error.
73  Time: 81 ns Started: 71 ns  localvar_assertion.local_var_assert Line: 28
View Code

2.4 Properties

  • 属性层构建在序列层之上,它使用零个或多个序列来检查设计假设;
  • 为了 使用行为验证 ,必须 shiyassert、assume、cover语句;
  • 属性本身不会产生任何结果,在序列的情况下,才有断言的真假。

属性可以在下列模块中声明:

  1. module
  2. interface
  3. program
  4. clocking block
  5. package
  6. a compilation unit

属性可以有以下几种形式:

  1. sequence  
     1 //+++++++++++++++++++++++++++++++++++++++++++++++++
     2 //   DUT With assertions
     3 //+++++++++++++++++++++++++++++++++++++++++++++++++
     4 module propseq_assertion();
     5 
     6 logic req,gnt,clk;
     7 //=================================================
     8 //  Clock generator
     9 //=================================================
    10 initial begin
    11  clk = 0; 
    12  forever #1 clk ++;
    13 end
    14 //=================================================
    15 // Simple DUT behaviour
    16 //=================================================
    17 always @ (posedge clk)
    18   gnt <= req;
    19 //=================================================
    20 // Test Vector generation
    21 //=================================================
    22 initial begin
    23   req <= 0;
    24   #3 req <= 1;
    25   #5 req <= 0;
    26   #1 $finish;
    27 end
    28 //=================================================
    29 // A sequence property
    30 //=================================================
    31 property propseq_prop;
    32   @ (posedge clk)
    33     req ##1 gnt;
    34 endproperty
    35 //=================================================
    36 // Assertion Directive Layer
    37 //=================================================
    38 propseq_assert : assert property (propseq_prop);
    39 
    40 endmodule
    41 
    42 //compile result
    43     
    44  "propseq_assertion.sv", 38:
    45   propseq_assertion.propseq_assert: started at 1s failed at 1s
    46          Offending 'req'
    47  "propseq_assertion.sv", 38: 
    48  propseq_assertion.propseq_assert: started at 3s failed at 3s
    49          Offending 'req'
    
    View Code
  2. negation
  3. disjunction
  4. if...else
  5. implication
  6. another named property

2.4.1 Another named property  

  • 一个属性可以调用另一个属性;
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module nameproperty_assertion();
 5 
 6 logic req,gnt,clk;
 7 //=================================================
 8 //  Clock generator
 9 //=================================================
10 initial begin
11  clk = 0; 
12  forever #1 clk ++;
13 end
14 //=================================================
15 // Simple DUT behaviour
16 //=================================================
17 always @ (posedge clk)
18   gnt <= req;
19 //=================================================
20 // Test Vector generation
21 //=================================================
22 initial begin
23   req <= 0;
24   #3 req <= 1;
25   #5 req <= 0;
26   #1 $finish;
27 end
28 //=================================================
29 // One property called inside another property
30 //=================================================
31 property vanila_prop;
32    req ##1 gnt;
33 endproperty
34 
35 property nameproperty_prop;
36   @ (posedge clk)
37     vanila_prop;
38 endproperty
39 //=================================================
40 // Assertion Directive Layer
41 //=================================================
42 nameproperty_assert : assert property (nameproperty_prop);
43 
44 endmodule
45 
46 //compile result
47     
48  "nameproperty_assertion.sv", 42: 
49  nameproperty_assertion.nameproperty_assert: started at 1s failed at 1s
50          Offending 'req'
51  "nameproperty_assertion.sv", 42: 
52  nameproperty_assertion.nameproperty_assert: started at 3s failed at 3s
53          Offending 'req'
54  $finish called from file "nameproperty_assertion.sv", line 26.
View Code

2.4.2 Negation

  • 用(not)操作符实现对属性的否定操作
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module negation_assertion();
 5 
 6 logic req,gnt,clk;
 7 //=================================================
 8 //  Clock generator
 9 //=================================================
10 initial begin
11  clk = 0; 
12  forever #1 clk ++;
13 end
14 //=================================================
15 // Simple DUT behaviour
16 //=================================================
17 always @ (posedge clk)
18   gnt <= req;
19 //=================================================
20 // Test Vector generation
21 //=================================================
22 initial begin
23   req <= 0;
24   #3 req <= 1;
25   #5 req <= 0;
26   #1 $finish;
27 end
28 //=================================================
29 // A negation property
30 //=================================================
31 property negation_prop;
32   @ (posedge clk)
33     not (req ##1 gnt);
34 endproperty
35 //=================================================
36 // Assertion Directive Layer
37 //=================================================
38 negation_assert : assert property (negation_prop);
39 
40 endmodule
41  "negation_assertion.sv", 38: 
42  negation_assertion.negation_assert: started at 5s failed at 7s
View Code

2.4.3 Disjunction

  • 用或(or)来实现对属性的disjunction,至少有一个属性为真,则结果为真。
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module disjunction_assertion();
 5 
 6 logic req,gnt,clk;
 7 //=================================================
 8 //  Clock generator
 9 //=================================================
10 initial begin
11  clk = 0; 
12  forever #1 clk ++;
13 end
14 //=================================================
15 // Simple DUT behaviour
16 //=================================================
17 logic gnt2;
18 initial begin
19   gnt2 <= 0; gnt <= 0;
20 end
21 always @ (posedge clk)
22 begin
23   gnt2 <= req;
24   gnt  <= gnt2;
25 end
26 //=================================================
27 // Test Vector generation
28 //=================================================
29 initial begin
30   req <= 0;
31   #3 req <= 1;
32   #5 req <= 0;
33   #1 $finish;
34 end
35 //=================================================
36 // A disjunction property
37 //=================================================
38 property delay1;
39     req ##1 gnt;
40 endproperty
41 property delay2;
42     req ##2 gnt;
43 endproperty
44 // See the OR operator
45 property disjunction_prop;
46   @ (posedge clk)
47     delay1 or delay2;
48 endproperty
49 //=================================================
50 // Assertion Directive Layer
51 //=================================================
52 disjunction_assert : assert property (disjunction_prop);
53 
54 endmodule
55 
56 //compile result
57  "disjunction_assertion.sv", 52: 
58  disjunction_assertion.disjunction_assert: started at 1s failed at 1s
59          Offending 'req'
60  "disjunction_assertion.sv", 52: 
61  disjunction_assertion.disjunction_assert: started at 3s failed at 3s
62          Offending 'req'
63  $finish called from file "disjunction_assertion.sv", line 33.
View Code

2.4.4 conjunction

  • 用(and)实现对属性的conjunction,所有属性为真,结果才为真。
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module conjunction_assertion();
 5 
 6 logic req,gnt,clk;
 7 //=================================================
 8 //  Clock generator
 9 //=================================================
10 initial begin
11  clk = 0; 
12  forever #1 clk ++;
13 end
14 //=================================================
15 // Simple DUT behaviour
16 //=================================================
17 logic gnt2;
18 initial begin
19   gnt2 <= 0; gnt <= 0;
20 end
21 always @ (posedge clk)
22 begin
23   gnt2 <= req;
24   gnt  <= gnt2;
25 end
26 //=================================================
27 // Test Vector generation
28 //=================================================
29 initial begin
30   req <= 0;
31   #3 req <= 1;
32   #5 req <= 0;
33   #1 $finish;
34 end
35 //=================================================
36 // A conjunction property
37 //=================================================
38 property delay1;
39     req ##1 gnt;
40 endproperty
41 property delay2;
42     req ##2 gnt;
43 endproperty
44 // See the AND operator
45 property conjunction_prop;
46   @ (posedge clk)
47     delay1 and delay2;
48 endproperty
49 //=================================================
50 // Assertion Directive Layer
51 //=================================================
52 conjunction_assert : assert property (conjunction_prop);
53 
54 endmodule
55 
56 //compile result
57     
58  "conjunction_assertion.sv", 52: 
59  conjunction_assertion.conjunction_assert: started at 1s failed at 1s
60          Offending 'req'
61  "conjunction_assertion.sv", 52: 
62  conjunction_assertion.conjunction_assert: started at 3s failed at 3s
63          Offending 'req'
64  "conjunction_assertion.sv", 52: 
65  conjunction_assertion.conjunction_assert: started at 5s failed at 7s
66          Offending 'gnt'
67  $finish called from file "conjunction_assertion.sv", line 33.
View Code

2.4.5 if...else

1 //形式1
2 if (expression_or_dist) property_expr1
3 //形式2
4 if (expression_or_dist) property_expr1
5  else property_expr2
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module ifelse_assertion();
 5 
 6 logic req,gnt,clk,check;
 7 //=================================================
 8 //  Clock generator
 9 //=================================================
10 initial begin
11  clk = 0; 
12  forever #1 clk ++;
13 end
14 //=================================================
15 // Simple DUT behaviour
16 //=================================================
17 logic gnt2;
18 initial begin
19   gnt2 <= 0; gnt <= 0;
20 end
21 always @ (posedge clk)
22 begin
23   gnt2 <= req;
24   gnt  <= gnt2;
25 end
26 //=================================================
27 // Test Vector generation
28 //=================================================
29 initial begin
30   req <= 0;check <= 0;
31   #3 req <= 1;
32   #10 req <= 0;check <= 1;
33   #3 req <= 1;
34   #5 req <= 0;
35   #1 $finish;
36 end
37 //=================================================
38 // A ifelse property
39 //=================================================
40 property delay1;
41     req ##1 gnt;
42 endproperty
43 property delay2;
44     req ##2 gnt;
45 endproperty
46 // See the OR operator
47 property ifelse_prop;
48   @ (posedge clk)
49     if (check)
50        delay1
51     else
52        delay2;
53 endproperty
54 //=================================================
55 // Assertion Directive Layer
56 //=================================================
57 ifelse_assert : assert property (ifelse_prop);
58 
59 endmodule
60 //compile result
61     
62  "ifelse_assertion.sv", 57: ifelse_assertion.ifelse_assert: 
63  started at 1s failed at 1s
64          Offending 'req'
65  "ifelse_assertion.sv", 57: ifelse_assertion.ifelse_assert: 
66  started at 3s failed at 3s
67          Offending 'req'
68  "ifelse_assertion.sv", 57: ifelse_assertion.ifelse_assert: 
69  started at 15s failed at 15s
70          Offending 'req'
71  "ifelse_assertion.sv", 57: ifelse_assertion.ifelse_assert:
72   started at 17s failed at 19s
73          Offending 'gnt'
74  $finish called from file "ifelse_assertion.sv", line 35.
75  
View Code

2.4.6 Implication

  • 类似于if...else属性操作,用于检查前面的序列是否发生,从而检查接下来的行为。
  • 如果sequence_expr匹配成功,而property_expr匹配失败,则结果为真,是一种伪真;
  • sequence_expr的结束点是property_expr的起点;
1 sequence_expr |-> property_expr
  • |->:重叠隐含操作符;
  • 前面匹配和后面匹配在同一个时钟内;
1 sequence_expr |=> property_expr
  • |->:非重叠隐含操作符;
  • 前面匹配和后面匹配相差一个时钟;
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module implication_assertion();
 5 
 6 logic clk = 0;
 7 always #1 clk ++;
 8 
 9 logic req,busy,gnt;
10 //=================================================
11 // Sequence Layer
12 //=================================================
13 sequence implication_seq;
14   req ##1 (busy [->3]) ##1 gnt;
15 endsequence
16 
17 //=================================================
18 // Property Specification Layer
19 //=================================================
20 property overlap_prop;
21   @ (posedge clk) 
22       req |-> implication_seq;
23 endproperty
24 
25 property nonoverlap_prop;
26   @ (posedge clk) 
27       req |=> implication_seq;
28 endproperty
29 //=================================================
30 // Assertion Directive Layer
31 //=================================================
32 overlap_assert    : assert property (overlap_prop);
33 nonoverlap_assert : assert property (nonoverlap_prop);
34 
35 //=================================================
36 // Generate input vectors
37 //=================================================
38 initial begin
39   // Pass sequence
40   gen_seq(3,0); 
41   repeat (20) @ (posedge clk);
42   // Fail sequence (gnt is not asserted properly)
43   gen_seq(3,1); 
44   // Terminate the sim
45   #30 $finish;
46 end
47 //=================================================
48 /// Task to generate input sequence
49 //=================================================
50 task  gen_seq (int busy_delay,int gnt_delay);
51   req <= 0; busy <= 0;gnt <= 0;
52   @ (posedge clk);
53   req <= 1;
54   @ (posedge clk);
55   req  <= 0;
56   repeat (busy_delay) begin
57    @ (posedge clk);
58     busy <= 1;
59    @ (posedge clk);
60     busy <= 0;
61   end
62   repeat (gnt_delay) @ (posedge clk);
63   gnt <= 1;
64   @ (posedge clk);
65   gnt <= 0;
66 endtask
67 
68 endmodule
69 
70 //compile result
71  "implication_assertion.sv", 33: 
72  implication_assertion.nonoverlap_assert: started at 3s failed at 5s
73          Offending 'req'
74  "implication_assertion.sv", 33: 
75  implication_assertion.nonoverlap_assert: started at 61s failed at 63s
76          Offending 'req'
77  "implication_assertion.sv", 32: 
78  implication_assertion.overlap_assert: started at 61s failed at 75s
79          Offending 'gnt'
80  $finish called from file "implication_assertion.sv", line 45.
View Code

2.4.7 disable iff

  • 如果后面的表达式是激活的,则禁用该属性,用于重置检查;
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module disableiff_assertion(
 5   input wire clk,req,reset, 
 6   output reg gnt);
 7 //=================================================
 8 // Sequence Layer
 9 //=================================================
10 sequence req_gnt_seq;
11   // (~req & gnt) and (~req & ~gnt) is Boolean Layer
12   (~req & gnt) ##1 (~req & ~gnt);
13 endsequence
14 //=================================================
15 // Property Specification Layer
16 //=================================================
17 property req_gnt_prop;
18   @ (posedge clk) // At every posedge clk
19     disable iff (reset) // disable if reset is asserted
20       req |=> req_gnt_seq;
21 endproperty
22 //=================================================
23 // Assertion Directive Layer
24 //=================================================
25 req_gnt_assert : assert property (req_gnt_prop);
26 //=================================================
27 // Actual DUT RTL
28 //=================================================
29 always @ (posedge clk)
30   gnt <= req;
31 
32 endmodule
33 
34 //+++++++++++++++++++++++++++++++++++++++++++++++
35 //   Testbench Code
36 //+++++++++++++++++++++++++++++++++++++++++++++++
37 module disableiff_assertion_tb();
38 
39 reg clk = 0;
40 reg reset, req = 0;
41 wire gnt;
42 
43 always #3 clk ++;
44 
45 initial begin
46   reset <= 1;
47   #20 reset <= 0;
48   // Make the assertion pass
49   #100 @ (posedge clk) req  <= 1;
50   @ (posedge clk) req <= 0;
51   // Make the assertion fail
52   #100 @ (posedge clk) req  <= 1;
53   repeat (5) @ (posedge clk);
54   req <= 0;
55   #10 $finish;
56 end
57 
58 disableiff_assertion dut (clk,req,reset,gnt);
59 
60 endmodule
61 
62 //compile result
63     
64  "disableiff_assertion.sv", 25: disableiff_assertion_tb.dut.req_gnt_assert:
65   started at 237s failed at 243s
66          Offending '((~req) & gnt)'
67  "disableiff_assertion.sv", 25: disableiff_assertion_tb.dut.req_gnt_assert:
68   started at 243s failed at 249s
69          Offending '((~req) & gnt)'
70  "disableiff_assertion.sv", 25: disableiff_assertion_tb.dut.req_gnt_assert:
71   started at 249s failed at 255s
72          Offending '((~req) & gnt)'
73  "disableiff_assertion.sv", 25: disableiff_assertion_tb.dut.req_gnt_assert:
74   started at 255s failed at 261s
75          Offending '((~req) & gnt)'
76  $finish called from file "disableiff_assertion.sv", line 55.
View Code

2.4.8 Recursive property 

  • 当属性调用自身时,被称为递归属性;
  • 否定运算符not不可用于递归属性;
  • disable iff不能用于递归属性;
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module recursive_assertion();
 5 logic clk = 0;
 6 logic req;
 7 //=================================================
 8 // Property Specification Layer
 9 //=================================================
10 property recursive_prop(M);
11       M and (1'b1 |=> recursive_prop(M));
12 endproperty
13 //=================================================
14 // Assertion Directive Layer
15 //=================================================
16 recursive_assert : assert property (recursive_prop(req));
17 //+++++++++++++++++++++++++++++++++++++++++++++++++
18 //  Assertion testing code
19 //+++++++++++++++++++++++++++++++++++++++++++++++++
20 always #1 clk ++;
21 
22 initial begin
23   // Make the assertion pass
24   #100 @ (posedge clk) req  <= 1;
25   repeat (20) @ (posedge clk);
26   req <= 0;
27   #10 $finish;
28 end
29 
30 endmodule
View Code

3. Multi clock support

  • 检查来自多个时钟域的信号或变量;
  • 在序列和属性中都支持多时钟声明;

3.1 Multi clock sequence

  • 多时钟序列是使用单延迟连接操作符##1连接单时钟子序列来建立的;
  • 该操作不重叠,并在 两个序列的时钟之间进行同步;
  • ##1解释为第一个序列的结束点到最近的第二个序列点开始的时间;
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module multi_clock_seq_assertion();
 5 logic clk1 = 0;
 6 logic clk2 = 0;
 7 logic req;
 8 logic gnt;
 9 //=================================================
10 // Sequence Specification Layer
11 //=================================================
12 sequence multi_clock_seq;
13    @(posedge clk1) req ##1 @(posedge clk2) gnt;
14 endsequence
15 //=================================================
16 // Property Specification Layer
17 //=================================================
18 property multi_clock_prop;
19   @ (posedge clk1)
20       req |-> multi_clock_seq;
21 endproperty
22 //=================================================
23 // Assertion Directive Layer
24 //=================================================
25 multi_clock_assert : assert property (multi_clock_prop);
26 //=================================================
27 // Here gnt is driven with respect to CLK2
28 //=================================================
29 initial begin
30   #20 gnt <= 1;
31   #120 gnt <= 0;
32 end
33 //+++++++++++++++++++++++++++++++++++++++++++++++++
34 //  Assertion testing code
35 //+++++++++++++++++++++++++++++++++++++++++++++++++
36 initial begin
37   // Make the assertion pass
38   req  <= 0; gnt <= 0;
39   #100 @ (posedge clk1) req  <= 1;
40   repeat (20) @ (posedge clk1);
41   req <= 0;
42   #10 $finish;
43 end
44 
45 always #1   clk1 ++;
46 always #6.1 clk2 ++;
47 
48 endmodule
49 
50 //compile result
51     
52  "multi_clock_seq_assertion.sv", 25: 
53  multi_clock_seq_assertion.multi_clock_assert: started at 139s failed at 150s
54          Offending 'gnt'
55  "multi_clock_seq_assertion.sv", 25: 
56  multi_clock_seq_assertion.multi_clock_assert: started at 141s failed at 150s
57          Offending 'gnt'
58  $finish called from file "multi_clock_seq_assertion.sv", line 42.
View Code

3.2 Multi clock property

  • 多时钟序列本身就是一种多时钟属性。
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module multi_clock_prop_assertion();
 5 logic clk1 = 0;
 6 logic clk2 = 0;
 7 logic req;
 8 logic gnt;
 9 //=================================================
10 // Property Specification Layer
11 //=================================================
12 property multi_clock_prop;
13   @(posedge clk1) req |-> ##1 @(posedge clk2) gnt;
14 endproperty
15 //=================================================
16 // Assertion Directive Layer
17 //=================================================
18 multi_clock_assert : assert property (multi_clock_prop);
19 //=================================================
20 // Here gnt is driven with respect to CLK2
21 //=================================================
22 initial begin
23   #20 gnt <= 1;
24   #120 gnt <= 0;
25 end
26 //+++++++++++++++++++++++++++++++++++++++++++++++++
27 //  Assertion testing code
28 //+++++++++++++++++++++++++++++++++++++++++++++++++
29 initial begin
30   // Make the assertion pass
31   req  <= 0; gnt <= 0;
32   #100 @ (posedge clk1) req  <= 1;
33   repeat (20) @ (posedge clk1);
34   req <= 0;
35   #10 $finish;
36 end
37 
38 always #1   clk1 ++;
39 always #6.1 clk2 ++;
40 
41 endmodule
42 
43 //compile result
44     
45  "multi_clock_prop_assertion.sv", 18: 
46  multi_clock_prop_assertion.multi_clock_assert: started at 139s failed at 150s
47          Offending 'gnt'
48  "multi_clock_prop_assertion.sv", 18: 
49  multi_clock_prop_assertion.multi_clock_assert: started at 141s failed at 150s
50          Offending 'gnt'
51  $finish called from file "multi_clock_prop_assertion.sv", line 35.
View Code

4. Assert,Assume,Cover

  • property本身不能用于检查,需要与assert、assume、cover一起使用。
  1. assert:指定该 属性是否正确;
  2. assume:指定属性作为验证环境的假定,对于正式的验证工具显得更有用;
  3. cover:为了覆盖率而监视属性,可以咋模拟结束后查看覆盖率报告。
  • 可以使用的地方:
  1. initial or always block
  2. module
  3. interface
  4. program
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module assert_assume_cover_assertion();
 5 logic clk = 0;
 6 logic req,gnt;
 7 logic ce,wr;
 8 logic [7:0] addr, data;
 9 //=================================================
10 // Property Specification Layer
11 //=================================================
12 property req_gnt_prop;
13   @ (posedge clk)
14       req |=> gnt;
15 endproperty
16 //=================================================
17 // Check if address falls in range for a write 
18 // operation
19 //=================================================
20 property addr_hit_prop(int min, int max);
21   @ (posedge clk)
22    (ce & wr) |-> (addr >= min && addr <= max);
23 endproperty
24 //=================================================
25 // Simple DUT with assert
26 //=================================================
27 always @ (posedge clk)
28 begin
29    gnt <= req;
30    //==============================================
31    // Assert inside a always block
32    //==============================================
33    req_gnt_assert : assert property (req_gnt_prop);
34 end
35 //=================================================
36 // This is how you use "assume"
37 //=================================================
38 req_gnt_assume  : assume property (req_gnt_prop);
39 //=================================================
40 // This is how you use "assert"
41 //=================================================
42 req_gnt_assert2 : assert property (req_gnt_prop);
43 //=================================================
44 // This is how you use "cover"
45 //=================================================
46 req_gnt_cover   : cover property (req_gnt_prop);
47 addr_hit_cover  : cover property (addr_hit_prop(1,5));
48 //+++++++++++++++++++++++++++++++++++++++++++++++++
49 //  Assertion testing code
50 //+++++++++++++++++++++++++++++++++++++++++++++++++
51 always #1 clk ++;
52 
53 initial begin
54   ce <= 0; wr <= 0; addr <= 0; req <= 0; gnt <= 0;
55   data <= 0;
56   // Make the assertion pass
57   @ (posedge clk) req  <= 1;
58   @ (posedge gnt);
59   for (int i = 0; i < 10; i ++) begin
60     @ (posedge clk);
61     ce <= 1;
62     wr <= 1;
63     addr <= i;
64     data <= $random;
65     @ (posedge clk);
66     ce <= 0;
67     wr <= 0;
68     addr <= 0;
69   end
70   @ (posedge clk);
71   req <= 0;
72   // Check 
73   #10 $finish;
74 end
75 
76 endmodule
77 
78 //compile result
79 $finish called from file "assert_assume_cover_assertion.sv", line 73.
80  $finish at simulation time                   55
81  "assert_assume_cover_assertion.sv", 46: 
82  assert_assume_cover_assertion.req_gnt_cover, 27 attempts, 22 match
83  "assert_assume_cover_assertion.sv", 47: 
84  assert_assume_cover_assertion.addr_hit_cover, 27 attempts, 5 match
View Code

5. Binding

  • 在验证工程师 添加断言的时候往往不希望对RTL设计进行改动,可以用Binding的方法进行验证;
  • 可以将断言内容写在单独的一个文件内,并使用bind将断言端口与testbench代码的RTL端口进行连接;
  • bind可以使用的地方:
  1. module
  2. interface
  3. compilation unit scope
  • 两种形式的bind
  1. multi instance:对一个模块的多个实例进行绑定;
  2. single instance:对一个模块的单个实例进行绑定;

一个 完整的实例:

 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module bind_assertion(
 5   input wire clk,req,reset, 
 6   output reg gnt);
 7 //=================================================
 8 // Actual DUT RTL
 9 //=================================================
10 always @ (posedge clk)
11   gnt <= req;
12 
13 endmodule
DUT File
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   Assertion Verification IP
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module assertion_ip(input wire clk_ip, req_ip,reset_ip,gnt_ip);
 5 //=================================================
 6 // Sequence Layer
 7 //=================================================
 8 sequence req_gnt_seq;
 9   (~req_ip & gnt_ip) ##1 (~req_ip & ~gnt_ip);
10 endsequence
11 //=================================================
12 // Property Specification Layer
13 //=================================================
14 property req_gnt_prop;
15   @ (posedge clk_ip) 
16     disable iff (reset_ip)
17       req_ip |=> req_gnt_seq;
18 endproperty
19 //=================================================
20 // Assertion Directive Layer
21 //=================================================
22 req_gnt_assert : assert property (req_gnt_prop)
23                  else
24                  $display("@%0dns Assertion Failed", $time);
25 
26 endmodule
Assertion File
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //  Binding File 
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module binding_module();
 5 //=================================================
 6 // Bind by Module name : This will bind all instance
 7 // of DUT
 8 //=================================================
 9 // Here RTL : stands for design under test
10 //      VIP : Assertion file
11 //   RTL Module Name  VIP module Name   Instance Name
12 bind bind_assertion   assertion_ip      U_assert_ip (
13 // .vip port (RTL port)
14  .clk_ip   (clk),
15  .req_ip   (req),
16  .reset_ip (reset),
17  .gnt_ip   (gnt)
18 );
19 //=================================================
20 // Bind by instance name : This will bind only instance
21 //  names in list
22 //=================================================
23 // Here RTL : stands for design under test
24 //      VIP : Assertion file
25 //     RTL Module Name Instance Path               VIP module Name Instance Name
26 //bind bind_assertion :$root.bind_assertion_tb.dut assertion_ip    U_assert_ip (
27 // .vip port (RTL port)
28 // .clk_ip   (clk),
29 // .req_ip   (req),
30 // .reset_ip (reset),
31 // .gnt_ip   (gnt)
32 //);
33 //=================================================
34 
35 endmodule
Binding File
 1 //+++++++++++++++++++++++++++++++++++++++++++++++
 2 //   Testbench Code
 3 //+++++++++++++++++++++++++++++++++++++++++++++++
 4 `include "assertion_ip.sv"
 5 `include "bind_assertion.sv"
 6 `include "binding_module.sv"
 7 
 8 module bind_assertion_tb();
 9 
10 reg clk = 0;
11 reg reset, req = 0;
12 wire gnt;
13 
14 always #3 clk ++;
15 
16 initial begin
17   reset <= 1;
18   #20 reset <= 0;
19   // Make the assertion pass
20   #100 @ (posedge clk) req  <= 1;
21   @ (posedge clk) req <= 0;
22   // Make the assertion fail
23   #100 @ (posedge clk) req  <= 1;
24   repeat (5) @ (posedge clk);
25   req <= 0;
26   #10 $finish;
27 end
28 
29 bind_assertion dut (clk,req,reset,gnt);
30 
31 endmodule
Testbench File
 1     
 2  "assertion_ip.sv", 22: bind_assertion_tb.dut.U_assert_ip.req_gnt_assert:
 3   started at 237s failed at 243s
 4          Offending '((~req_ip) & gnt_ip)'
 5  @243ns Assertion Failed
 6  "assertion_ip.sv", 22: bind_assertion_tb.dut.U_assert_ip.req_gnt_assert: 
 7   started at 243s failed at 249s
 8          Offending '((~req_ip) & gnt_ip)'
 9  @249ns Assertion Failed
10  "assertion_ip.sv", 22: bind_assertion_tb.dut.U_assert_ip.req_gnt_assert: 
11   started at 249s failed at 255s
12          Offending '((~req_ip) & gnt_ip)'
13  @255ns Assertion Failed
14  "assertion_ip.sv", 22: bind_assertion_tb.dut.U_assert_ip.req_gnt_assert: 
15   started at 255s failed at 261s
16          Offending '((~req_ip) & gnt_ip)'
17  @261ns Assertion Failed
18  $finish called from file "bind_assertion_tb.sv", line 26.
Simulation : Binding

6. Expect

  • 语法上 与assert相同,但expect是在过程块中使用的,他会等待一个属性的值为true或者false;
 1 module expect_assertion;
 2 
 3 logic clk = 0;
 4 always #1 clk ++;
 5 
 6 logic a, b,c;
 7 
 8 default clocking myclk @ (posedge clk);
 9 
10 endclocking
11 
12 initial begin 
13   a <= 0;
14   b <= 0;
15   c <= 0;
16   ##1;
17   a <= 1;
18   ##1;
19   a <= 0;
20   b <= 1;
21   ##1;
22   b <= 0;
23   c <= 0;
24   ##1;
25   c <= 0;
26   ##20000 $finish;
27 end
28 
29 initial begin
30   ##1;
31   // Wait for the sequence if pass, terminate sim
32   expect ( @ (posedge clk) a ##1 b ##1 c ##1 !c)
33      $finish;
34    else
35      $error ("Something is wrong");
36 end
37   
38 endmodule
39 
40 //compile result
41     
42  Something is wrong
43  Simulation complete via $finish(1) at time 40007 NS + 0
View Code

7. Clock resolution

  • 并发断言需要时钟的参与,有多种方式可以解决时钟的产生问题;
  1. 带有时钟的序列实例:在序列声明本身指定时钟;
  2. 带有时钟的属性实例:在属性声明本身指定时钟;
  3. 从程序块中引用时钟:触发器解析时钟;
  4. 时钟块:专门定义一个时钟;
  5. 默认时钟:与上面类似。
  • 3:Contextually inferred clock from a procedural block. : In this procedural block trigger resolve to clock.
  • 4:Clocking block : A clocking block can be used for resolving the clock.
 1 //+++++++++++++++++++++++++++++++++++++++++++++++++
 2 //   DUT With assertions
 3 //+++++++++++++++++++++++++++++++++++++++++++++++++
 4 module clock_resolve_assertion();
 5 logic clk = 0;
 6 logic req,gnt;
 7 //=================================================
 8 // Clock inside a sequence 
 9 //=================================================
10 sequence req_gnt_seq;
11   @ (posedge clk)
12       req ##1 gnt;
13 endsequence
14 //=================================================
15 // Clock inside a property
16 //=================================================
17 property req_gnt_prop;
18   @ (posedge clk)
19       req |=> gnt;
20 endproperty
21 //=================================================
22 // Clock infered from a always block
23 //=================================================
24 always @ (posedge clk)
25 begin
26    gnt <= req;
27    //==============================================
28    // Here clock is infered to be posedge clk
29    //==============================================
30    req_gnt_assert : assert property (req  |=> gnt);
31 end
32 //=================================================
33 // Default clocking
34 //=================================================
35 default clocking aclk @ (posedge clk);
36   input req;
37   input gnt;
38 endclocking
39 
40 property req_gnt_default_prop;
41    req |-> ##1 gnt;
42 endproperty
43 //=================================================
44 // clocking clocking
45 //=================================================
46 clocking reqclk @ (posedge clk);
47   input req;
48   input gnt;
49 endclocking
50 
51 property req_gnt_clocking_prop;
52    reqclk.req |-> ##1 reqclk.gnt;
53 endproperty
54 //+++++++++++++++++++++++++++++++++++++++++++++++++
55 // Now call all the assertion in one go
56 //+++++++++++++++++++++++++++++++++++++++++++++++++
57 a1  : assert property (req_gnt_prop);
58 a2  : assert property (req_gnt_default_prop);
59 a3  : assert property (req_gnt_clocking_prop);
60 //+++++++++++++++++++++++++++++++++++++++++++++++++
61 //  Assertion testing code
62 //+++++++++++++++++++++++++++++++++++++++++++++++++
63 always #1 clk ++;
64 
65 initial begin
66   $monitor("Req %b Gnt %b",req,gnt);
67   req <= 0; gnt <= 0;
68   // Make the assertion pass
69   ##1 req  <= 1;
70   ##20;
71   req <= 0;
72   #10 $finish;
73 end
74 
75 endmodule
76 
77 //compile result
78  Req 0 Gnt 0
79  Req 1 Gnt 0
80  Req 1 Gnt 1
81  Req 0 Gnt 1
82  Req 0 Gnt 0
View Code
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值