Verilog 語句塊提供了將兩條或更多條語句組成語法結(jié)構(gòu)上相當(dāng)于一條一句的機(jī)制。主要包括兩種類型:順序塊和并行塊。
順序塊用關(guān)鍵字 ?begin
?和 ?end
?來表示。
順序塊中的語句是一條條執(zhí)行的。當(dāng)然,非阻塞賦值除外。
順序塊中每條語句的時(shí)延總是與其前面語句執(zhí)行的時(shí)間相關(guān)。
在本節(jié)之前的仿真中,?initial
?塊中的阻塞賦值,都是順序塊的實(shí)例。
并行塊有關(guān)鍵字 ?fork
?和 ?join
?來表示。
并行塊中的語句是并行執(zhí)行的,即便是阻塞形式的賦值。
并行塊中每條語句的時(shí)延都是與塊語句開始執(zhí)行的時(shí)間相關(guān)。
順序塊與并行塊的區(qū)別顯而易見,下面用仿真說明。
仿真代碼如下:
`timescale 1ns/1ns
module test ;
reg [3:0] ai_sequen, bi_sequen ;
reg [3:0] ai_paral, bi_paral ;
reg [3:0] ai_nonblk, bi_nonblk ;
//============================================================//
//(1)Sequence block
initial begin
#5 ai_sequen = 4'd5 ; //at 5ns
#5 bi_sequen = 4'd8 ; //at 10ns
end
//(2)fork block
initial fork
#5 ai_paral = 4'd5 ; //at 5ns
#5 bi_paral = 4'd8 ; //at 5ns
join
//(3)non-block block
initial fork
#5 ai_nonblk <= 4'd5 ; //at 5ns
#5 bi_nonblk <= 4'd8 ; //at 5ns
join
endmodule
仿真結(jié)果如下:
如圖所示,順序塊順序執(zhí)行,第 10ns 時(shí),信號 ?bi_sequen
?才賦值為 8。
而并行塊,?ai_paral
?與 ?bi_paral
?的賦值是同時(shí)執(zhí)行的,所以均在 5ns 時(shí)被賦值。
而非阻塞賦值,也能達(dá)到和并行塊同等的賦值效果。
順序塊和并行塊還可以嵌套使用。
仿真代碼如下:
`timescale 1ns/1ns
module test ;
reg [3:0] ai_sequen2, bi_sequen2 ;
reg [3:0] ai_paral2, bi_paral2 ;
initial begin
ai_sequen2 = 4'd5 ; //at 0ns
fork
#10 ai_paral2 = 4'd5 ; //at 10ns
#15 bi_paral2 = 4'd8 ; //at 15ns
join
#20 bi_sequen2 = 4'd8 ; //at 35ns
end
endmodule
仿真結(jié)果如下:
并行塊語句塊內(nèi)是并行執(zhí)行,所以信號 ?ai_paral2
?和信號 ?bi_paral2
?分別在 10ns, 15ns 時(shí)被賦值。而并行塊中最長的執(zhí)行時(shí)間為 15ns,所以順序塊中的信號 ?bi_sequen2
?在 35ns 時(shí)被賦值。
我們可以給塊語句結(jié)構(gòu)命名。
命名的塊中可以聲明局部變量,通過層次名引用的方法對變量進(jìn)行訪問。
仿真代碼如下:
`timescale 1ns/1ns
module test;
initial begin: w3cschool //命名模塊名字為w3cschool,分號不能少
integer i ; //此變量可以通過test.w3cschool.i 被其他模塊使用
i = 0 ;
forever begin
#10 i = i + 10 ;
end
end
reg stop_flag ;
initial stop_flag = 1'b0 ;
always begin : detect_stop
if ( test.w3cschool.i == 100) begin //i累加10次,即100ns時(shí)停止仿真
$display("Now you can stop the simulation!!!");
stop_flag = 1'b1 ;
end
#10 ;
end
endmodule
仿真結(jié)果如下:
命名的塊也可以被禁用,用關(guān)鍵字 ?disable
?來表示。
?disable
?可以終止命名塊的執(zhí)行,可以用來從循環(huán)中退出、處理錯誤等。
與 C 語言中 ?break
?類似,但是 ?break
?只能退出當(dāng)前所在循環(huán),而 ?disable
?可以禁用設(shè)計(jì)中任何一個(gè)命名的塊。
仿真代碼如下:
`timescale 1ns/1ns
module test;
initial begin: w3cschool_d //命名模塊名字為w3cschool_d
integer i_d ;
i_d = 0 ;
while(i_d<=100) begin: w3cschool_d2
# 10 ;
if (i_d >= 50) begin //累加5次停止累加
disable w3cschool_d3.clk_gen ;//stop 外部block: clk_gen
disable w3cschool_d2 ; //stop 當(dāng)前block: w3cschool_d2
end
i_d = i_d + 10 ;
end
end
reg clk ;
initial begin: w3cschool_d3
while (1) begin: clk_gen //時(shí)鐘產(chǎn)生模塊
clk=1 ; #10 ;
clk=0 ; #10 ;
end
end
endmodule
仿真結(jié)果如下:
由圖可知,信號 ?i_d
?累加到 50 以后,便不再累加,以后 ?clk
?時(shí)鐘也不再產(chǎn)生。
可見,?disable
?退出了當(dāng)前的 ?while
?塊。
需要說明的是,?disable
?在 ?always
?或 ?forever
?塊中使用時(shí)只能退出當(dāng)前回合,下一次語句還是會在 ?always
?或 ?forever
?中執(zhí)行。因?yàn)?nbsp;?always
?塊和 ?forever
?塊是一直執(zhí)行的,此時(shí)的 ?disable
?有點(diǎn)類似 C 語言中的 ?continue
? 功能。
點(diǎn)擊這里下載源碼
更多建議: