關鍵詞: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 理論上來講是不可綜合的,多用於初始化、信號檢測等。
對上一節代碼稍作修改,進行仿真,代碼如下。
實例
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 時停止仿真代碼如下。
代碼如下:
實例
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 時停止。