目录
摘要:本章主要介绍过程控制语句与控制流的一下方法
Procedural statement:
- initial:在仿真的一开始使用,只执行一次;
- final:在仿真结束前执行,SV新增的内容;
- always:always_comb, always_latch, always_ff, SV新增的内容;
- task:当task被召唤时执行;
- function:当function被召唤时执行,并返回一个值
Control flow:
- do...while, break, continue;
- 顺序块和并行块;
- 时间控制。
1. Selection statement
在selection的语句之前增加了如下两个关键词,对语句进行强化;
- unique:在selection的条件中没有重复匹配的情况,如有,则会报错;(强调条件的完备性和唯一性)
- priority:在selection的条件中有多个重复匹配则执行第一个匹配结果;
1.1 if...else...if
1 unique if()
2 else if
3 else
4 priority if()
5 else if
6 else
1.2 case
1 unique case ()
2 case 1:
3 ...
4 endcase
5
6 priority case ()
7 case 1:
8 ...
9 endcase
- case;
- casez:不在乎x;
- casex:不在乎x;
1.3 例子:
1 module unique_priority ();
2
3 byte a = 0;
4
5 // unique
6 always @ (*)
7 begin
8 unique if ((a==0) || (a==1)) begin
9 $display("Unique if : 0 or 1");
10 end else if (a == 2) begin
11 $display("Unique if : 2");
12 end else if (a == 4) begin
13 $display("Unique if : 4");
14 end
15 end
16 // priority
17 always @ (*)
18 begin
19 priority if (a[2:1]==0) begin
20 $display("Priority if : 0 or 1");
21 end else if (a[2] == 0) begin
22 $display("Priority if : 2 or 3");
23 end else begin
24 $display("Priority if : 4 to 7");
25 end
26 end
27 // unique case
28 always @ (*)
29 begin
30 unique case(a)
31 0,1: $display("Unique Case 0 or 1");
32 2 : $display("Unique Case 2");
33 4 : $display("Unique Case 4");
34 endcase
35 end
36 // priority case
37 always @ (*)
38 begin
39 priority casez(a)
40 3'b00?: $display("Priority Casez 0 or 1");
41 3'b0??: $display("Priority Casez 2 or 3");
42 endcase
43 end
44 // unique case inside
45 always @ (*)
46 begin
47 unique case(a) inside
48 [0 : 3]: $display("Unique Case inside 0 to 3");
49 2 : $display("Unique Case inside 2");
50 4 : $display("Unique Case inside 4");
51 endcase
52 end
53
54 initial begin
55 repeat (7) begin
56 #1 a ++;
57 end
58 #1 $finish;
59 end
60
61 endmodule
62
63 //compile result
64
65 Unique if : 0 or 1
66 Unique Case 0 or 1
67 Priority Casez 0 or 1
68 Unique Case inside 0 to 3
69 Unique if : 2
70 Unique Case 2
71 Priority Casez 2 or 3
72 Warning: More than one conditions match in 'unique case' statement.
73 "unique_priority.sv", line 47,.
74 Line 48 & 49 are overlapping at time 2.
75 Unique Case inside 0 to 3
76 Priority if : 2 or 3
77 Warning: No condition matches in 'unique if' statement.
78 "unique_priority.sv", line 8, at time 3.
79 Warning: No condition matches in 'unique case' statement.
80 "unique_priority.sv", line 30, at time 3.
81 Priority Casez 2 or 3
82 Unique Case inside 0 to 3
83 Unique if : 4
84 Unique Case 4
85 Warning: No condition matches in 'priority case' statement.
86 "unique_priority.sv", line 39, at time 4.
87 Unique Case inside 4
88 Priority if : 4 to 7
89 Warning: No condition matches in 'unique if' statement.
90 "unique_priority.sv", line 8, at time 5.
91 Warning: No condition matches in 'unique case' statement.
92 "unique_priority.sv", line 30, at time 5.
93 Warning: No condition matches in 'priority case' statement.
94 "unique_priority.sv", line 39, at time 5.
95 Warning: No condition matches in 'unique case' statement.
96 "unique_priority.sv", line 47, at time 5.
97 Warning: No condition matches in 'unique if' statement.
98 "unique_priority.sv", line 8, at time 6.
99 Warning: No condition matches in 'unique case' statement.
100 "unique_priority.sv", line 30, at time 6.
101 Warning: No condition matches in 'priority case' statement.
102 "unique_priority.sv", line 39, at time 6.
103 Warning: No condition matches in 'unique case' statement.
104 "unique_priority.sv", line 47, at time 6.
105 Priority if : 4 to 7
106 Warning: No condition matches in 'unique if' statement.
107 "unique_priority.sv", line 8, at time 7.
108 Warning: No condition matches in 'unique case' statement.
109 "unique_priority.sv", line 30, at time 7.
110 Warning: No condition matches in 'priority case' statement.
111 "unique_priority.sv", line 39, at time 7.
112 Warning: No condition matches in 'unique case' statement.
113 "unique_priority.sv", line 47, at time 7.
2. Loop statement
- verilog 提供了for,while,repeat,forever循环;
- SV对其进行了加强,在for循环中增加了循环内部定义变量的能力;
- foreach结构对数组中元素进行迭代;
- do...while...;
do...while loop例子:
1 module while_loop ();
2
3 byte a = 0;
4
5 initial begin
6 do begin
7 $display ("Current value of a = %g", a);
8 a ++;
9 end while (a < 10);
10 #1 $finish;
11 end
12
13 endmodule
14
15 //compile result
16 Current value of a = 0
17 Current value of a = 1
18 Current value of a = 2
19 Current value of a = 3
20 Current value of a = 4
21 Current value of a = 5
22 Current value of a = 6
23 Current value of a = 7
24 Current value of a = 8
25 Current value of a = 9
for loop例子
1 module for_loop ();
2
3 initial begin
4 fork
5 for (int i = 0 ; i < 4; i ++) begin
6 #1 $display ("First -> Current value of i = %g", i);
7 end
8 for (int i = 4 ; i > 0; i --) begin
9 #1 $display ("Second -> Current value of i = %g", i);
10 end
11 join
12 #1 $finish;
13 end
14
15 endmodule
16
17 //compile result
18 First -> Current value of i = 0
19 Second -> Current value of i = 4
20 First -> Current value of i = 1
21 Second -> Current value of i = 3
22 First -> Current value of i = 2
23 Second -> Current value of i = 2
24 First -> Current value of i = 3
25 Second -> Current value of i = 1
foreach loop 例子:
1 module foreach_loop ();
2
3 byte a [10] = '{0,6,7,4,5,66,77,99,22,11};
4
5 initial begin
6 foreach (a[i]) begin
7 $display ("Value of a is %g",i);
8 end
9 #1 $finish;
10 end
11
12 endmodule
13
14 //compile result
15 Value of a is 0
16 Value of a is 1
17 Value of a is 2
18 Value of a is 3
19 Value of a is 4
20 Value of a is 5
21 Value of a is 6
22 Value of a is 7
23 Value of a is 8
24 Value of a is 9
2. 跳转语句
- break:跳转出整个循环;
- continue:跳转到当前循环末尾;
- return expression:跳出函数;
- return:跳出任务或空函数;
break :
1 module break_loop ();
2
3 initial begin
4 for (int i = 0 ; i < 10; i ++) begin
5 #1 $display ("Current value of i = %g", i);
6 if ( i == 5) begin
7 $display ("Coming out of for loop");
8 break;
9 end
10 end
11 #1 $finish;
12 end
13
14 endmodule
15
16 //compile result
17 Current value of i = 0
18 Current value of i = 1
19 Current value of i = 2
20 Current value of i = 3
21 Current value of i = 4
22 Current value of i = 5
23 Coming out of for loop
continue:
1 module continue_loop ();
2
3 initial begin
4 for (int i = 0 ; i < 10; i ++) begin
5 if ( (i >= 5) && (i < 8)) begin
6 $display ("Continue with next interation");
7 continue;
8 end
9 #1 $display ("Current value of i = %g", i);
10 end
11 #1 $finish;
12 end
13
14 endmodule
15
16 //compile result
17 Current value of i = 0
18 Current value of i = 1
19 Current value of i = 2
20 Current value of i = 3
21 Current value of i = 4
22 Continue with next interation
23 Continue with next interation
24 Continue with next interation
25 Current value of i = 8
26 Current value of i = 9
return :
1 module return_function ();
2
3 initial begin
4 printI();
5 #1 $finish;
6 end
7
8 function void printI;
9 begin
10 for (int i = 0 ; i < 10; i ++) begin
11 if (i >= 5) begin
12 return; // no value returned
13 end
14 $display ("Current value of i = %g", i);
15 end
16 end
17 endfunction
18
19 endmodule
20
21 //compile result
22 Current value of i = 0
23 Current value of i = 1
24 Current value of i = 2
25 Current value of i = 3
26 Current value of i = 4
return expression例子:
1 module return_value_function ();
2
3
4 initial begin
5 $display ("Value returned from function = %g", printI());
6 #1 $finish;
7 end
8
9 function int printI;
10 begin
11 for (int i = 0 ; i < 10; i ++) begin
12 if (i >= 5) begin
13 return i ; // value returned
14 end
15 $display ("Current value of i = %g", i);
16 end
17 end
18 endfunction
19
20 endmodule
21
22 //compile result
23 Current value of i = 0
24 Current value of i = 1
25 Current value of i = 2
26 Current value of i = 3
27 Current value of i = 4
28 Value returned from function = 5
3. final block
- 发生在模拟结束时,没有延迟,通常用于显示模拟的统计信息
- 在final块允许的语句是只有在函数声明中允许的语句;这保证了他只在单个周期执行;
- final 不作为一个单独进程执行;
1 module final_block ();
2
3 initial begin
4 for (int i = 0 ; i < 10; i ++) begin
5 if ( (i >= 5) && (i < 8)) begin
6 $display ("@%g Continue with next interation", $time);
7 continue;
8 end
9 #1 $display ("@%g Current value of i = %g", $time, i);
10 end
11 #1 $finish;
12 end
13
14 final begin
15 $display ("Final block called at time %g", $time);
16 $display ("---- We can not have delays in it ----");
17 end
18
19 endmodule
20
21 //compile result
22
23 @1 Current value of i = 0
24 @2 Current value of i = 1
25 @3 Current value of i = 2
26 @4 Current value of i = 3
27 @5 Current value of i = 4
28 @5 Continue with next interation
29 @5 Continue with next interation
30 @5 Continue with next interation
31 @6 Current value of i = 8
32 @7 Current value of i = 9
33 Final block called at time 8
34 ---- We can not have delays in it ----
4. Named Blocks
verilog允许在begin和fork后添加命名块;
- begin : "MY_NAMED_BLOCK1"
- fork : "MY_NAMED_BLOCK2"
SV对其进行了扩充:
- "MY_NAMED_BLOCK" : begin 或者 begin: "MY_NAMED_BLOCK"
- "MY_NAMED_BLOCK" : fork 或者 fork: "MY_NAMED_BLOCK"
- end: "MY_NAMED_BLOCK"
- join: "MY_NAMED_BLOCK"
- join_any: "MY_NAMED_BLOCK"
- join_none: "MY_NAMED_BLOCK"
1 module named_block ();
2
3 reg clk = 0;
4
5 initial
6 FIRST_BLOCK : begin
7 $display ("This is first block");
8 end
9
10 initial begin : SECOND_BLOCK
11 $display ("This is second block");
12 fork : FORK_BLOCK
13 #1 $display ("Inside fork with delay 1");
14 #2 $display ("Inside fork with delay 2");
15 join_none
16 FORK_NONE : fork
17 #4 $display ("Inside fork with delay 4");
18 #5 $display ("Inside fork with delay 5");
19 join_none
20 #10 $finish;
21 end
22
23 always begin : THIRD_BLOCK
24 #1 clk = ~clk;
25 end : THIRD_BLOCK
26
27 endmodule
28
29 //compile result
30 This is first block
31 This is second block
32 Inside fork with delay 1
33 Inside fork with delay 2
34 Inside fork with delay 4
35 Inside fork with delay 5
5. Disable Block
- disable 可以禁用一个块;
- 如果块正在执行,disable将导致程序跳转到该块之后的语句,
- 如果块是循环体,disable作用类似于continue;
1 module disable_block ();
2
3 initial begin
4 fork : FORK
5 for (int i = 0 ; i < 9; i ++) begin
6 if (1 == 5) begin
7 $display ("break first for loop");
8 break;
9 end
10 #1 $display ("First -> Current value of i = %g", i);
11 end
12 for (int i = 9 ; i > 0; i --) begin : FOR_LOOP
13 if (i == 6) begin
14 $display ("Disable FOR_LOOP");
15 disable FOR_LOOP;
16 end
17 #1 $display ("Second -> Current value of i = %g", i);
18 end
19 for (int i = 0 ; i < 30; i += 2) begin : FOR_LOOP
20 if (i == 16) begin
21 $display ("Disable FORK");
22 disable FORK;
23 end
24 #1 $display ("third -> Current value of i = %g", i);
25 end
26 join
27 #10 $finish;
28 end
29
30 endmodule
31
32 //compile result
33 First -> Current value of i = 0
34 Second -> Current value of i = 9
35 third -> Current value of i = 0
36 First -> Current value of i = 1
37 Second -> Current value of i = 8
38 third -> Current value of i = 2
39 First -> Current value of i = 2
40 Second -> Current value of i = 7
41 Disable FOR_LOOP
42 third -> Current value of i = 4
43 First -> Current value of i = 3
44 Second -> Current value of i = 5
45 third -> Current value of i = 6
46 First -> Current value of i = 4
47 Second -> Current value of i = 4
48 third -> Current value of i = 8
49 First -> Current value of i = 5
50 Second -> Current value of i = 3
51 third -> Current value of i = 10
52 First -> Current value of i = 6
53 Second -> Current value of i = 2
54 third -> Current value of i = 12
55 First -> Current value of i = 7
56 Second -> Current value of i = 1
57 third -> Current value of i = 14
58 Disable FORK
6. Event control
- @ *
- @ (*):在verilog中()中需有所有敏感信号,而SV中可以写成(*)形式;
- event expression , iff(iff后的条件为真才触发事件);
-
1 always @ (posedge clk iff reset == 0 or posedge reset)
reset为高时,块不会触发。
-
1 module event_control ();
2
3 reg clk = 0;
4 reg rst, d, enable, q, latch;
5
6
7 always @ (*)
8 if (enable) begin
9 latch <= d;
10 end
11
12 always @ (posedge clk iff rst == 0 or posedge rst)
13 if (rst) begin
14 q <= 0;
15 $display ("Reset is asserted with iff");
16 end else begin
17 q <= d;
18 end
19
20 always @ (posedge clk or posedge rst)
21 if (rst) begin
22 $display ("Reset is asserted, no iff");
23 end
24
25 always #1 clk = ~clk;
26
27
28 initial begin
29 $monitor ("@%g clk %b rst %b enable %b d %b q %b latch %b",
30 $time, clk, rst, enable, d, q, latch);
31 rst = 0;
32 #1 d = 0;
33 #1 rst = 1;
34 #4 rst = 0;
35 #1 enable = 1;
36 #1 d = 1;
37 #10 d = 0;
38 #5 $finish;
39 end
40
41 endmodule
42
43 //compile result
44 @0 clk 0 rst 0 enable x d x q x latch x
45 @1 clk 1 rst 0 enable x d 0 q 0 latch x
46 Reset is asserted with iff
47 Reset is asserted, no iff
48 @2 clk 0 rst 1 enable x d 0 q 0 latch x
49 Reset is asserted, no iff
50 @3 clk 1 rst 1 enable x d 0 q 0 latch x
51 @4 clk 0 rst 1 enable x d 0 q 0 latch x
52 Reset is asserted, no iff
53 @5 clk 1 rst 1 enable x d 0 q 0 latch x
54 @6 clk 0 rst 0 enable x d 0 q 0 latch x
55 @7 clk 1 rst 0 enable 1 d 0 q 0 latch 0
56 @8 clk 0 rst 0 enable 1 d 1 q 0 latch 1
57 @9 clk 1 rst 0 enable 1 d 1 q 1 latch 1
58 @10 clk 0 rst 0 enable 1 d 1 q 1 latch 1
59 @11 clk 1 rst 0 enable 1 d 1 q 1 latch 1
60 @12 clk 0 rst 0 enable 1 d 1 q 1 latch 1
61 @13 clk 1 rst 0 enable 1 d 1 q 1 latch 1
62 @14 clk 0 rst 0 enable 1 d 1 q 1 latch 1
63 @15 clk 1 rst 0 enable 1 d 1 q 1 latch 1
64 @16 clk 0 rst 0 enable 1 d 1 q 1 latch 1
65 @17 clk 1 rst 0 enable 1 d 1 q 1 latch 1
66 @18 clk 0 rst 0 enable 1 d 0 q 1 latch 0
67 @19 clk 1 rst 0 enable 1 d 0 q 0 latch 0
68 @20 clk 0 rst 0 enable 1 d 0 q 0 latch 0
69 @21 clk 1 rst 0 enable 1 d 0 q 0 latch 0
70 @22 clk 0 rst 0 enable 1 d 0 q 0 latch 0
7. sequence
在事件表达式中使用,用序列的成功匹配触发块的执行;
1 module sequence_event ();
2
3 reg a, b, c;
4 reg clk = 0;
5
6 sequence abc;
7 @(posedge clk) a ##1 b ##1 c;
8 endsequence
9
10 always @ (posedge clk)
11 begin
12 @ (abc) $display ("@%g ABC all are asserted", $time);
13 end
14
15 // Testbench code
16 initial begin
17 $monitor("@%g clk %b a %b b %b c %b", $time, clk, a, b, c);
18 repeat (2) begin
19 #2 a = 1;
20 #2 b = 1;
21 #2 c = 1;
22 #2 a = 0;
23 b = 0;
24 c = 0;
25 end
26 #2 $finish;
27 end
28
29 always #1 clk = ~clk;
30
31 endmodule
32
33 //compile result
34 @0 clk 0 a x b x c x
35 @1 clk 1 a x b x c x
36 @2 clk 0 a 1 b x c x
37 @3 clk 1 a 1 b x c x
38 @4 clk 0 a 1 b 1 c x
39 @5 clk 1 a 1 b 1 c x
40 @6 clk 0 a 1 b 1 c 1
41 @7 ABC all are asserted
42 @7 clk 1 a 1 b 1 c 1
43 @8 clk 0 a 0 b 0 c 0
44 @9 clk 1 a 0 b 0 c 0
45 @10 clk 0 a 1 b 0 c 0
46 @11 clk 1 a 1 b 0 c 0
47 @12 clk 0 a 1 b 1 c 0
48 @13 clk 1 a 1 b 1 c 0
49 @14 clk 0 a 1 b 1 c 1
50 @15 ABC all are asserted
51 @15 clk 1 a 1 b 1 c 1
52 @16 clk 0 a 0 b 0 c 0
53 @17 clk 1 a 0 b 0 c 0