fork join中的語句爲並執行執行的,爲並行語句塊。語句之間同時開始,並行執行,雖然無法綜合,但是用於testbench的編寫時非常有用;此處以自己利用fork join編寫測試文件的例子入手,對fork join語句、begin end語句進行介紹,並展示了begin end於fork join相互嵌套用於測試文件的過程;
目錄
一、基礎
begin end
概念:
begin end 用來標識順序執行的語句,用它標識的塊稱作順序塊;
使用:
begin
語句1;
語句2;
....
語句n;
end
特點:
- 塊內語句順序執行的,即只有上面一條語句執行完後下面的語句才能執行;
- 最後一條語句執行完,程序才跳出該語句塊。
fork join
概念:
fork join 用來標識並行執行的語句,用它標識的塊稱作並行塊;
使用:
fork
語句1;
語句2;
....
語句n;
join
特點:
- 塊內語句同時執行的,程序流程控制進入該模塊時刻,塊內語句即開始同時並行執行;
- 當耗時最長的語句執行完成後,程序才跳出該並行模塊;
實例
測試文件:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: CLL
//
// Create Date: 2020/03/05 10:02:40
// Design Name:
// Module Name: clk_tsb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module clk_tsb(
);
// port declaration
reg clk1,clk2,clk3,clk4,clk5,clk6;
// test
initial
begin
clk1 = 0;
clk2 = 0;
clk3 = 0;
#10 clk1 = 1;
#20 clk2 = 1;
#30 clk3 = 1;
end
initial
begin
clk4 = 0;
clk5 = 0;
clk6 = 0;
fork
#10 clk4 = 1;
#20 clk5 = 1;
#30 clk6 = 1;
join
end
endmodule
代碼分析:
先看順序塊:語句順序執行,說明clk1相比於模塊起始延時10ns後輸出1;
clk2在clk1語句執行結束後延時20ns輸出1,說明clk2置1的時刻相比於模塊起始延時30ns
clk3在clk2語句執行結束後延時30ns輸出1,說明clk3置1的時刻相比於模塊起始延時60ns
再看並行塊:語句並行執行,說明clk4相比於模塊起始延時10ns後輸出1;
clk5相比於模塊起始延時20ns後輸出1;
clk6相比於模塊起始延時30ns後輸出1;
仿真結果:
與分析一致;
二、進階
核心:
- begin end與fork join之間可以相互嵌套
- 嵌套依舊遵循各自的執行邏輯
測試文件:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: CLL
//
// Create Date: 2020/03/05 10:02:40
// Design Name:
// Module Name: clk_tsb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module clk_tsb(
);
// port declaration
reg clk1,clk2,clk3,clk4,clk5,clk6;
// test
initial
begin
clk1 = 0;
clk2 = 0;
clk3 = 0;
#10 clk1 = 1;
fork
#20 clk2 = 1;
#30 clk3 = 1;
join
end
initial
begin
clk4 = 0;
clk5 = 0;
clk6 = 0;
fork
#10 clk4 = 1;
begin
#10 clk5 = 1;
#20 clk5 = 0;
end
#30 clk6 = 1;
join
end
endmodule
代碼分析:
先看begin end嵌套fork join塊:
語句順序執行,說明clk1相比於模塊起始延時10ns後輸出1;
fork join塊在clk1語句執行結束開始執行(它在順序塊中),而fork join塊中的clk2與clk3並行執行(在並行塊中),clk2在clk1語句執行結束後延時20ns輸出1,clk3在clk1語句執行結束後延時30ns輸出1,說明clk2置1的時刻相比於模塊起始延時30ns,clk3置1的時刻相比於模塊起始延時40ns;
再看並行塊:
語句並行執行,說明clk4相比於模塊起始延時10ns後輸出1;
begin end塊與clk4語句同時開始執行(它在並行塊中),而begin end塊中的clk5與clk6順序執行(在順序塊中),clk5相比於模塊起始延時20ns後輸出1,clk6在clk5語句執行結束後延時30ns輸出1,說明clk6置1的時刻相比於模塊起始延時50ns;
仿真結果:
與分析一致;
靈活使用fork join以及嵌套,對編寫測試文件非常有用!
如:Verilog實現RAM(7-異步雙口SRAM:原理、實現、仿真、分析)中的測試文件只有利用嵌套才能更好的描述異步時鐘同時讀寫的工作過程;