Verilog 描述的是硬體。僅此而已。
如果你已經掌握了微控制器編程,那麼改掉這個習慣是最難的。雖然 Verilog 看起來像是時序程式碼,但它與 74 系列邏輯閘的相似之處遠多於 C 語言程式設計。
使用閘電路原語理解 Verilog 並行性
讓我們從數位邏輯課上的一個積之和範例開始(清單 1 和圖 1)。在這個例子中,我們使用 Verilog 閘電路原語來執行 𝑌 =∑𝑚(2,4,5)。
這些 Verilog 閘電路原語在風格上類似於 C 函數,由閘類型、布林輸出參數和輸入參數組成。例如,and (Out, in_1, in_2, in_3).。
它們看起來像函數,但實際上並非函數。它們永遠不會運作。硬體只是存在而已。
module sop3_prims (
input wire C, // LSB
input wire B,
input wire A,
output wire Y
);
wire nA, nB, nC; // inverter wires
wire m2, m4, m5; // minterm wires
not (nA, A);
not (nB, B);
not (nC, C);
and (m2, nA, B, nC); // minterm 2 (010)
and (m4, A, nB, nC); // minterm 4 (100)
and (m5, A, nB, C); // minterm 5 (101)
or (Y, m2, m4, m5); // Sum-of-products
endmodule
列表 1:使用閘電路原語建構的 Verilog 積之和硬體。
技術提示:清單 1 和圖 1 僅用於說明。沒有人會這樣寫程式碼。它太耗時,而且容易出錯。請參閱清單 2 以獲得更好的解決方案。
這是一個純組合邏輯電路,用 Verilog 來描述。所有元件同時存在;沒有時脈,也沒有暫存器。這與使用 74HC04 六反相器、一個三輸入 74HC11 與閘和一個三輸入 74HC4075 或閘建構電路幾乎完全相同。
積之和硬體的標準 Verilog 描述
清單 2 展示了我們積和硬體的首選 Verilog 程式碼。它比清單 1 更簡潔,也更不容易出錯。然而,我們預期 FPGA 綜合工具會為給定的 FPGA 產生幾乎相同的網表。在所有情況下,綜合工具都會將邏輯提煉為結構高效且時序高效的 FPGA 配置位,以實現最小的佔用空間和最短的傳播延遲。
技術提示:如果您仍然以微控制器的角度來看待 FPGA,那麼 FPGA 的位元檔案實際上是一個用於配置周邊裝置的大型表格。
module sop3_standard (
input wire C, B, A, // LSB to MSB
output wire Y
);
assign Y = (~A & B & ~C) | // minterm 2 (010)
( A & ~B & ~C) | // minterm 4 (100)
( A & ~B & C); // minterm 5 (101)
endmodule
列表 2:積之和電路的建議程式碼。
FPGA LUT 的誤解及其對時序的影響
FPGA 並非邏輯閘的集合。相反,其核心建置區塊是查找表(LUT)。本文中描述的積之和電路對應到單一 LUT。實際上,由於現代 LUT 的位數超過 3 位,因此還有剩餘空間。例如,Terasic DE23-Lite 上的 Altera Agilex 3 A3CZ135BB18AE7S 就具有一個 8 輸入 LUT,如圖 2 所示。
回顧圖 1,我們可以看到,由於反相器具有較長的傳播延遲,因此會出現典型的毛邊風險。LUT 可以將所有乘積總和合併到一個 LUT 中,從而最大限度地減少這種風險。但這並不意味著時序毛邊完全消除,而是顯著減少。對於包含多個 LUT 的大型設計,使用暫存器可以更好地實現。
圖 2:Agilex 3 FPGA 自適應邏輯方塊圖
暫存器和時脈訊號控制 FPGA 硬體
到目前為止,我們一直假設 FPGA 中的所有操作都是同時進行的。現在,隨著時脈和觸發器(也稱為暫存器或同步記憶體)的引入,我們將從組合邏輯過渡到時序邏輯。
圖 2 清晰地展示了這種差異。舉個簡單的例子,我們可以看到最上面的輸出訊號直接取自查找表 (LUT),而下一個輸出訊號則取自最上面的觸發器 (Reg)。它們分別代表組合邏輯輸出和同步邏輯輸出。
-
組合邏輯輸出持續更新。
-
暫存器在時脈訊號的上升沿更新。
例如,Terasic 開發板使用可編程的 TI 的 LMK3C0105A05RERR 為 FPGA 提供三個時脈訊號。
清單 3 展示了同步 Verilog 程式碼。最顯著的變化是引入了非阻塞賦值運算子「<=」以及對時脈上升沿的敏感度。與圖 2 相比,查找表 (LUT) 仍然用於執行 SOP 操作,但現在我們新增了一個暫存器。此暫存器的值與時脈訊號同步。
module sop3_registered (
input wire clk, C, B, A,
output reg Y
);
always @(posedge clk) begin
Y <= (~A & B & ~C) |
( A & ~B & ~C) |
( A & ~B & C);
end
endmodule
清單 3:註冊積之和硬體描述。
模擬舒適圈謬誤:Verilog 何時不再是硬體
我們一直專注於綜合邏輯,它會被轉換為配置 FPGA 的位元檔。但這並非 Verilog 的唯一用途。很快,您將會接觸到基於 Verilog 的測試平台。測試平台並非駐留在 FPGA 上,而是駐留在您的 PC 上。因此,編譯後的 Verilog 測試平台可以執行 FPGA 無法實現的功能。主要區別在於時間控制和循環能力。例如,可以開發一個 Verilog 測試平台來產生 N 個時脈週期。
如果 Verilog 程式碼開始帶有程式設計的痕跡,它將無法被綜合。
區分硬體和測試平台
我們可以從清單 4 看到一些明顯的特徵。這包括模擬時間刻度、tb(測試平台)前置碼以及表示 5 個時間單位延遲的 #5。
THIS WILL NOT SYNTHESIZE INTO AN FPGA BITFILE.
`timescale 1ns/1ps
initial begin
clk = 0;
{A, B, C} = 3'b010; // Apply minterm 2
for (i = 0; i < 10; i = i + 1) begin
#5 clk = ~clk; // Rising edge - Y updates here!
#5 clk = ~clk; // Falling edge
end
// Add code to test all minterms.
$stop;
end
清單 4:Verilog 測試平台程式碼片段。此代碼無法綜合。
技術提示:我們改天再討論 Verilog 生成器。它們看起來像是程序,但實際上是迭代硬體產生器。它們提供了一種便捷的方式來實例化 N 個模組。
作者的相關文章
如果您喜歡這篇文章,您可能也會覺得以下相關文章很有幫助:
- Implementing a Clock Boundary Synchronizer in Verilog
- How to Implement a PNT derived Pulse Per Second (PPS) External Trigger for an ADC and FPGA
- Implementing a Robust Microcontroller to FPGA SPI Interface: Part 1 - FPGA Challenges

