Verilog 語句塊

2023-02-28 10:08 更新

關(guān)鍵詞:順序塊,并行塊,嵌套塊,命名塊,disable

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í),信號(hào) ?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í)行,所以信號(hào) ?ai_paral2 ?和信號(hào) ?bi_paral2 ?分別在 10ns, 15ns 時(shí)被賦值。而并行塊中最長(zhǎng)的執(zhí)行時(shí)間為 15ns,所以順序塊中的信號(hào) ?bi_sequen2 ?在 35ns 時(shí)被賦值。


命名塊

我們可以給塊語句結(jié)構(gòu)命名。

命名的塊中可以聲明局部變量,通過層次名引用的方法對(duì)變量進(jìn)行訪問。

仿真代碼如下:

`timescale 1ns/1ns
 
module test;
 
    initial begin: w3cschool   //命名模塊名字為w3cschool,分號(hào)不能少
        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)中退出、處理錯(cuò)誤等。

與 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é)果如下:

由圖可知,信號(hào) ?i_d ?累加到 50 以后,便不再累加,以后 ?clk ?時(shí)鐘也不再產(chǎn)生。

可見,?disable ?退出了當(dāng)前的 ?while ?塊。


需要說明的是,?disable ?在 ?always ?或 ?forever ?塊中使用時(shí)只能退出當(dāng)前回合,下一次語句還是會(huì)在 ?always ?或 ?forever ?中執(zhí)行。因?yàn)?nbsp;?always ?塊和 ?forever ?塊是一直執(zhí)行的,此時(shí)的 ?disable ?有點(diǎn)類似 C 語言中的 ?continue? 功能。

點(diǎn)擊這里下載源碼


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)