SV_7_Procedural Statements And Control Flow
摘要:本章主要介绍过程控制语句与控制流的一下方法
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
浙公网安备 33010602011771号