TCJJ

导航

SV_8_Processes

摘要:在一个组合逻辑建模的always块中,忘记一个其他块会导致意外的锁存。为了避免这种错误,SV添加了专门的always_comb和always_latch块来表明设计意图,还增加了一个always_iff块来指示顺序逻辑。

      • 静态进程:always,initial, fork...join;
      • 动态进程:fork...join_any  fork...join_any

1. always_comb

  • 用于对组合逻辑建模;
  • always_combo块里面赋值左侧的部分不能被其他任何程序写入;
  • 在initial块和always块执行之后的0时刻自动执行;
 1 module always_comb_process();
 2 
 3 reg [7:0] sum,a,b;
 4 reg       parity;
 5 
 6 initial begin
 7   $monitor ("@%g a = %h b = %h sum = %h parity = %b",
 8    $time, a, b, sum, parity);
 9   #1 a = 1;
10   #1 b = 1;
11   #5 a = 10;
12   #1 $finish;
13 end
14 
15 always_comb
16 begin : ADDER
17   sum = b + a;
18   parity = ^sum;
19 end
20 
21 endmodule
22 
23 //compile result
24  @0 a = xx b = xx sum = xx parity = x
25  @1 a = 01 b = xx sum = xx parity = x
26  @2 a = 01 b = 01 sum = 02 parity = 1
27  @7 a = 0a b = 01 sum = 0b parity = 1
View Code

2. always_latch

SV提供always_latch对锁存逻辑行为建模,

 1 module always_latch_process();
 2 
 3 reg [7:0] sum,a,b;
 4 reg       parity;
 5 reg       enable = 0;
 6 
 7 initial begin
 8   $monitor ("@%g a = %h b = %h sum = %h parity = %b",
 9     $time, a, b, sum, parity);
10   #2 a = 1;
11   #2 b = 1;
12   #2 a = 10;
13   #2 $finish;
14 end
15 
16 always #1 enable = ~enable;
17 
18 always_latch
19 begin : ADDER
20   if (enable) begin
21     sum    <= b + a;
22     parity <= ^(b + a);
23   end
24 end
25 
26 endmodule
27 
28 //compile result
29  @0 a = xx b = xx sum = xx parity = x
30  @2 a = 01 b = xx sum = xx parity = x
31  @4 a = 01 b = 01 sum = xx parity = x
32  @5 a = 01 b = 01 sum = 02 parity = 1
33  @6 a = 0a b = 01 sum = 02 parity = 1
34  @7 a = 0a b = 01 sum = 0b parity = 1
View Code

3. always_ff

  • 为可综合的顺序逻辑建模
  • 赋值左边的变量,包括来自被调用函数内容的变量,不能被任何其他进程写入;
 1 module always_ff_process();
 2 
 3 reg [7:0] sum,a,b;
 4 reg       parity;
 5 logic     clk = 0;
 6 reg       rst = 0;
 7 
 8 initial begin
 9   $monitor ("@%g clk = %b rst = %b a = %h b = %h sum = %h parity = %b",
10   $time, clk, rst, a, b, sum, parity);
11   #1 rst = 1;
12   #5 rst = 0;
13   #2 a = 1;
14   #2 b = 1;
15   #2 a = 10;
16   #2 $finish;
17 end
18 
19 always #1 clk ++;
20 
21 // use of iff makes sure that block does not get
22 // triggered due to posedge of clk when rst == 1
23 always_ff @(posedge clk iff rst == 0 or posedge rst)
24 begin : ADDER
25 //由于rst=1块always_ff不触发,sum和parity 的初始化不起作用
26   if (rst) begin
27     sum    <= 0;
28     parity <= 0;
29     $display ("Reset is asserted BLOCK 1");
30   end else begin
31     sum    <= b + a;
32     parity <= ^(b + a);
33   end
34 end
35 
36 // To show how iff affected in earlier code
37 always_ff @(posedge clk  or posedge rst)
38 begin
39   if (rst) begin
40     $display ("Reset is asserted BLOCK 2");
41   end
42 end
43 
44 endmodule
45 
46 //compile result
47  @0 clk = 0 rst = 0 a = xx b = xx sum = xx parity = x
48  Reset is asserted BLOCK 1
49  Reset is asserted BLOCK 2
50  @1 clk = 1 rst = 1 a = xx b = xx sum = 00 parity = 0
51  @2 clk = 0 rst = 1 a = xx b = xx sum = 00 parity = 0
52  Reset is asserted BLOCK 2
53  @3 clk = 1 rst = 1 a = xx b = xx sum = 00 parity = 0
54  @4 clk = 0 rst = 1 a = xx b = xx sum = 00 parity = 0
55  Reset is asserted BLOCK 2
56  @5 clk = 1 rst = 1 a = xx b = xx sum = 00 parity = 0
57  @6 clk = 0 rst = 0 a = xx b = xx sum = 00 parity = 0
58  @7 clk = 1 rst = 0 a = xx b = xx sum = xx parity = x
59  @8 clk = 0 rst = 0 a = 01 b = xx sum = xx parity = x
60  @9 clk = 1 rst = 0 a = 01 b = xx sum = xx parity = x
61  @10 clk = 0 rst = 0 a = 01 b = 01 sum = xx parity = x
62  @11 clk = 1 rst = 0 a = 01 b = 01 sum = 02 parity = 1
63  @12 clk = 0 rst = 0 a = 0a b = 01 sum = 02 parity = 1
64  @13 clk = 1 rst = 0 a = 0a b = 01 sum = 0b parity = 1
View Code

4. fork-join

创建并发进程:

  • fork - join (join all)
  • fork - join_none
  • fork - join_any

4.1 fork-join

只有所有子进程执行完毕,才会执行负进程;

 1 module fork_join_all_process();
 2 
 3 task automatic print_value;
 4   input [7:0] value;
 5   input [7:0] delay;
 6   begin
 7     #(delay) $display("@%g Passed Value %d Delay %d",
 8       $time, value, delay);
 9   end
10 endtask
11 
12 initial begin
13   fork
14     #1 print_value (10,7);
15     #1 print_value (8,5);
16     #1 print_value (4,2);
17   join
18   $display("@%g Came out of fork-join", $time);
19   #20 $finish;
20 end
21 
22 endmodule
23 
24 //compile result
25  @3 Passed Value   4 Delay   2
26  @6 Passed Value   8 Delay   5
27  @8 Passed Value  10 Delay   7
28  @8 Came out of fork-join
View Code

4.2 fork-join_any

任一子进程执行完毕,父进程开始执行;

 1 module fork_join_any_process();
 2 
 3 task automatic print_value;
 4   input [7:0] value;
 5   input [7:0] delay;
 6   begin
 7     #(delay) $display("@%g Passed Value %d Delay %d",
 8       $time, value, delay);
 9   end
10 endtask
11 
12 initial begin
13   fork
14     #1 print_value (10,7);
15     #1 print_value (8,5);
16     #1 print_value (4,2);
17   join_any
18   $display("@%g Came out of fork-join", $time);
19   #20 $finish;
20 end
21 
22 endmodule
23 
24 //compile result
25  @3 Passed Value   4 Delay   2
26  @3 Came out of fork-join
27  @6 Passed Value   8 Delay   5
28  @8 Passed Value  10 Delay   7
View Code

4.3 fork-join_none

子进程和父进程同时执行;

 1 module fork_join_none_process();
 2 
 3 task automatic print_value;
 4   input [7:0] value;
 5   input [7:0] delay;
 6   begin
 7     #(delay) $display("@%g Passed Value %d Delay %d",
 8       $time, value, delay);
 9   end
10 endtask
11 
12 initial begin
13   fork
14     #1 print_value (10,7);
15     #1 print_value (8,5);
16     #1 print_value (4,2);
17   join_none
18   $display("@%g Came out of fork-join", $time);
19   #20 $finish;
20 end
21 
22 endmodule
23 
24 //compile result
25  @0 Came out of fork-join
26  @3 Passed Value   4 Delay   2
27  @6 Passed Value   8 Delay   5
28  @8 Passed Value  10 Delay   7
View Code

 

 

5. 进程控制

  • wait fork:等待所有fork进程的完成;
  • disable fork:停止fork进程以及其所有子进程的执行;

5.1 wait-fork

 1 module fork_join_wait_process();
 2 
 3 task automatic print_value;
 4   input [7:0] value;
 5   input [7:0] delay;
 6   begin
 7     #(delay) $display("@%g Passed Value %d Delay %d",
 8         $time, value, delay);
 9   end
10 endtask
11 
12 initial begin
13   fork
14     #1 print_value (10,7);
15     #1 print_value (8,5);
16     #1 print_value (4,2);
17   join_none
18   #5;
19   fork
20     #1 print_value (1,1);
21     #1 print_value (2,2);
22     #1 print_value (3,3);
23   join_any
24   $display("@%g Came out of fork-join", $time);
25   // Wait till all the forks (threads are completed their execution)
26   wait fork;
27   $display("@%g All threads completed execution", $time);
28   #20 $finish;
29 end
30 
31 endmodule
32 
33 //compile result
34  @3 Passed Value   4 Delay   2
35  @6 Passed Value   8 Delay   5
36  @7 Passed Value   1 Delay   1
37  @7 Came out of fork-join
38  @8 Passed Value  10 Delay   7
39  @8 Passed Value   2 Delay   2
40  @9 Passed Value   3 Delay   3
41  @9 All threads completed execution
View Code

5.2 disable fork

 1 module fork_join_disable_process();
 2 
 3 task automatic print_value;
 4   input [7:0] value;
 5   input [7:0] delay;
 6   begin
 7     #(delay) $display("@%g Passed Value %d Delay %d",
 8       $time, value, delay);
 9   end
10 endtask
11 
12 initial begin
13   fork
14     #1 print_value (10,7);
15     #1 print_value (8,5);
16     #1 print_value (4,2);
17   join_none
18   $display("@%g Came out of fork-join", $time);
19   // terminate all the theads
20   #5 disable fork;
21   $display("@%g All threads are disabled", $time);
22   #20 $finish;
23 end
24 
25 endmodule
26 
27 //compile result
28  @0 Came out of fork-join
29  @3 Passed Value   4 Delay   2
30  @5 All threads are disabled
View Code

posted on 2021-02-27 18:55  TCJJ  阅读(71)  评论(0)    收藏  举报

1