SV_7_Procedural Statements And Control Flow

本文详细介绍了Verilog及System Verilog中的选择语句、循环语句、跳转语句等过程控制语句,包括if...else...if、case、for循环、while循环等的使用方法,并通过具体实例讲解了unique、priority、foreach等特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. Selection statement

1.1 if...else...if

1.2 case

1.3 例子:

2. Loop statement

do...while loop例子:

for loop例子

foreach loop 例子:

2. 跳转语句

break :

continue:

return :

return expression例子:

3. final block

4. Named Blocks

5. Disable Block

6. Event control

7. sequence 


摘要:本章主要介绍过程控制语句与控制流的一下方法

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.
View Code

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
View Code

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
View Code

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
View Code

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
View Code

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
View Code

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
View Code

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
View Code

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 ----
View Code

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
View Code

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
View Code

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
View Code

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
View Code
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值