2007年3月12日 星期一

範例

一個計數器的電路如下︰

module Div20x (rst, clk, cet, cep, count,tc);
//TITLE 'Divide-by-20 Counter with enables'
//enable CEP is a clock enable only
//enable CET is a clock enable and enables the TC output
// 使用 Verilog 語言描述的一個計數器
parameter size = 5;
parameter length = 20;
input rst; // 這些輸出/輸入表示這個模組的對外連線
input clk;
input cet;
input cep;
output [size-1:0] count;
output tc;
reg [size-1:0] count; // 宣告硬體內的暫存器
wire tc; // 連接線

// 下方的 always 塊是屬於平行執行的塊,當任何時間 rst 或 clk 訊號有從 low 到 high 的轉變時候就會被執行
always @ (posedge rst or posedge clk)
begin
if (rst) // 這個模擬計數器的重設
count <= 5'b0;
else if (cet && cep) // 這個模擬兩個 enable 訊號都為 true
begin
if (count == length-1)
begin
count <= 5'b0;
end
else
count <= count + 5'b1; // 5'b1 是 5 bits 寬度且等於 1 的數值
end
end
// tc的值將按照後面的運算式實時改變
assign tc = (cet && (count == length-1));
endmodule


Verilog 中的"<="運算子的是它成為硬體描述語言而跟普通程序語言不同之處。這種敘述稱為"非阻塞賦值"(non-blocking)。當電路模擬執行時候,所有使用 "<=" 運算子的訊號(signals)都是平行被執行。這點跟實際硬體中觸發器(台譯:正反器)(Flip-Flop)的行為很相似。

另外一種指定運算的描述是 "=" 運算子,也就是 "阻塞賦值"(blocking) 的賦值方式。當使用 "=" 運算子時後,所有的東西都會循序的執行,類似普通的程式語言一樣。

範例:
...
reg a, b, c, d;
wire e;
...
always @(b or e)
begin
a = b & e;
b = a b;
#5 c = b;
d = #6 c ^ e;
end

上面的 always 句子描述了另外一種使用的方法,例如,任何在表列中的實體,像是 b 或 e 的內容在任何時候有所改變,always 後的就會被執行。當這些值有所改變,a 和 b 就會馬上給上新的值。經過 5 個時間單位的延遲,b 的值才會指定給 c,且 c ^ e 運算的值會藏入看不到儲存的空間中。然後經過 6 單位的時間後,d 才會得到剛才計算的值。

來自 維基百科

沒有留言: