關鍵詞:initial, always

過程結構語句有 2 種,initial 與 always 語句。它們是行為級建模的 2 種基本語句。

一個模塊中可以包含多個 initial 和 always 語句,但 2 種語句不能嵌套使用。

這些語句在模塊間並行執行,與其在模塊的前後順序沒有關係。

但是 initial 語句或 always 語句內部可以理解為是順序執行的(非阻塞賦值除外)。

每個 initial 語句或 always 語句都會產生一個獨立的控製流,執行時間都是從 0 時刻開始。

initial語句

initial 語句從 0 時刻開始執行,隻執行一次,多個 initial 塊之間是相互獨立的。

如果 initial 塊內包含多個語句,需要使用關鍵字 begin 和 end 組成一個塊語句。

如果 initial 塊內隻要一條語句,關鍵字 begin 和 end 可使用也可不使用。

initial 理論上來講是不可綜合的,多用於初始化、信號檢測等。

對上一節代碼稍作修改,進行仿真,代碼如下。

實例

`timescale 1ns/1ns
 
module test ;
    reg  ai, bi ;
 
    initial begin
        ai         = 0 ;
        #25 ;      ai        = 1 ;
        #35 ;      ai        = 0 ;        //absolute 60ns
        #40 ;      ai        = 1 ;        //absolute 100ns
        #10 ;      ai        = 0 ;        //absolute 110ns
    end
 
    initial begin
        bi         = 1 ;
        #70 ;      bi        = 0 ;        //absolute 70ns
        #20 ;      bi        = 1 ;        //absolute 90ns
    end
 
    //at proper time stop the simulation
    initial begin
        forever begin
            #100;
            //$display("---gyc---%d", $time);
            if ($time >= 1000) begin
                $finish ;
            end
        end
   end
 
endmodule

仿真結果如下:

可以看出,2 個 initial 進程語句分別給信號 ai,bi 賦值時,相互間並沒有影響。

信號 ai,bi 的值按照賦值順序依次改變,所以 initial 內部語句也可以看做是順序執行。

always 語句

與 initial 語句相反,always 語句是重複執行的。always 語句塊從 0 時刻開始執行其中的行為語句;當執行完最後一條語句後,便再次執行語句塊中的第一條語句,如此循環反複。

由於循環執行的特點,always 語句多用於仿真時鍾的產生,信號行為的檢測等。

下麵用 always 產生一個 100MHz 時鍾源,並在 1010ns 時停止仿真代碼如下。

代碼如下:

實例

`timescale 1ns/1ns
 
module test ;
 
    parameter CLK_FREQ   = 100 ; //100MHz
    parameter CLK_CYCLE  = 1e9 / (CLK_FREQ * 1e6) ;   //switch to ns
 
    reg  clk ;
    initial      clk = 1'b0 ;      //clk is initialized to "0"
    always     # (CLK_CYCLE/2) clk = ~clk ;       //generating a real clock by reversing
 
    always begin
        #10;
        if ($time >= 1000) begin
            $finish ;
        end
    end
 
endmodule

仿真結果如下:

可見,時鍾周期是我們想要得到的 100MHz。而且仿真在 1010ns 時停止。

源碼下載

Download