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
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
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
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
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
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
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
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
浙公网安备 33010602011771号