Verilog 硬體描述語言:從基礎到實戰,掌握數位電路設計

目次

1. Verilog 是什麼?其概述與用途

Verilog 的基本定義

Verilog(或稱 Verilog HDL)是一種用於設計數位電路的硬體描述語言(HDL)。如果說軟體程式語言是用來描述電腦程式,那麼 Verilog 則是專門用於描述數位電路或系統的行為。透過使用 Verilog,可以簡化複雜的電路設計過程,並協助設計人員有效率地進行電路模擬與合成(將電路轉換為可製造的形式)。

Verilog 於 1984 年開發,並於 1995 年由 IEEE(電機電子工程師學會)標準化。其後持續發展,現今已廣泛應用於 FPGA(Field-Programmable Gate Array,現場可程式化邏輯閘陣列)和 ASIC(Application-Specific Integrated Circuit,特殊應用積體電路)的設計中。

Verilog 在數位電路設計中的角色

數位電路設計是建構利用電氣訊號處理資訊的系統的過程。例如,智慧型手機或電腦內部運作的處理器和記憶體就是其中一例。Verilog 作為一種工具,被用於提高這類數位系統設計的效率。

具體來說,Verilog 用於以下場景:

  • FPGA 設計: FPGA 是一種電路設計靈活性高的元件。使用 Verilog 可以自由定義 FPGA 的功能,並將其作為可重複程式設計的設備使用。
  • ASIC 設計: ASIC 是專門用於特定目的的積體電路。透過 Verilog 可以設計客製化的 IC。
  • 模擬 (Simulation): 使用 Verilog 描述的電路可以在軟體上進行模擬,以預先驗證其功能是否正確。這有助於早期發現和修正設計錯誤。

本文學習內容與目標讀者

本文旨在為初次學習 Verilog 或想複習基礎知識的讀者,分階段講解以下內容:

  1. Verilog 的基本語法與設計基礎
  2. 實用的設計範例與除錯方法
  3. 有助於學習的資源與工具介紹

目標讀者包含以下人士:

  • 剛開始學習 Verilog 或 HDL 的初學者
  • 準備開始 FPGA 或 ASIC 設計的工程師
  • 想複習基礎知識的設計人員或學生

2. Verilog 的基本語法與概念

Verilog 的基本語法與機制

模組(module)的定義與使用方法

在開始 Verilog 設計時,最基本的單位是「模組(module)」。模組代表電路的組成要素,用於描述輸入/輸出和內部結構。以下是一個簡單的模組範例:

module AND_gate (
    input wire a, // 入力a (輸入 a)
    input wire b, // 入力b (輸入 b)
    output wire y // 出力y (輸出 y)
);
    assign y = a & b; // AND演算 (AND 運算)
endmodule

這段程式碼描述了一個將兩個輸入訊號(ab)進行 AND 運算,並將結果連接到輸出(y)的電路。使用關鍵字 module 定義模組,並使用 endmodule 結束。

資料型別種類與選擇(wire, reg 的區別使用)

Verilog 的資料型別主要有以下兩種:

  • wire: 代表導線,用於連接訊號。
  • reg: 代表暫存器 (register),用於同步於時脈訊號保持數值。

例如,以下程式碼展示了 wirereg 的區別使用:

module Example (
    input wire clk,    // クロック入力 (時脈輸入)
    input wire rst,    // リセット入力 (重置輸入)
    input wire a,      // 入力a (輸入 a)
    output reg y       // 出力y (輸出 y)
);
    always @(posedge clk or posedge rst) begin
        if (rst)
            y <= 0;    // リセット時、出力を0に (重置時,將輸出設為 0)
        else
            y <= a;    // クロック時、入力aを出力yに代入 (時脈上升沿時,將輸入 a 賦值給輸出 y)
    end
endmodule

在此例中,輸出 y 根據時脈訊號 clk 變化。reg 型別用於保持數值,並在 always 區塊中使用。

控制結構(if, case)與模擬時的注意事項

if 語句的使用方法

在 Verilog 中,描述條件分支時使用 if 語句。以下是一個基本的 if 語句範例:

always @(posedge clk) begin
    if (a == 1'b1)
        y <= 1'b0;  // aが1の場合、yを0に設定 (如果 a 是 1,則將 y 設為 0)
    else
        y <= 1'b1;  // それ以外の場合、yを1に設定 (否則,將 y 設為 1)
end

if 語句在根據電路條件改變行為時非常方便。

case 語句的使用方法

當需要處理多個條件分支時,使用 case 語句會更有效率。以下是一個表示狀態轉換的範例:

always @(state) begin
    case (state)
        2'b00: y = 1'b0;
        2'b01: y = 1'b1;
        2'b10: y = 1'b0;
        2'b11: y = 1'b1;
        default: y = 1'bx; // 不明な状態 (未知狀態)
    endcase
end

在此例中,輸出 y 根據狀態 state 變化。使用 case 語句可以使程式碼更易讀。

初學者應知的基礎概念

阻塞式賦值與非阻塞式賦值的區別

Verilog 中有兩種賦值方式:

  • 阻塞式賦值(=: 一系列處理依序執行。
  • 非阻塞式賦值(<=: 數值平行更新。

例如,請看以下程式碼:

always @(posedge clk) begin
    a = b;     // ブロッキング代入 (阻塞式賦值)
    c <= d;    // ノンブロッキング代入 (非阻塞式賦值)
end

阻塞式賦值的行為類似軟體程式的依序執行。另一方面,非阻塞式賦值用於準確描述平行運作的硬體。特別是在 always 區塊中,通常建議使用非阻塞式賦值。

平行處理的思維與描述方法

Verilog 支援描述可以平行運作的硬體。以下範例中,兩個 always 區塊獨立運作:

always @(posedge clk) begin
    a <= b + 1;
end

always @(posedge clk) begin
    c <= d - 1;
end

像這樣,每個 always 區塊都執行獨立的程序,可以描述接近實際硬體電路的行為。

模擬與合成的區別

  • 模擬 (Simulation): 在軟體上驗證設計好的電路是否如預期運作的過程。
  • 合成 (Synthesis): 將設計轉換為實際硬體的過程。

在 Verilog 中,用於模擬的程式碼(例如 initial 區塊)不會用於合成。因此,將可合成的程式碼與用於模擬的程式碼明確分開是非常重要的。

3. Verilog 的主要功能與特色

Verilog 的特色與其他 HDL 的區別

Verilog 的優勢

與其他硬體描述語言(HDL)相比,Verilog 具有以下優勢:

  1. 簡單的語法
  • Verilog 語法類似 C 語言,對於有程式設計經驗的工程師來說較易學習。
  • 模組、資料型別、運算子等基本語法直觀,對初學者友善。
  1. 廣泛的支援
  • Verilog 是 FPGA 和 ASIC 設計工具(如 Vivado、ModelSim 等)的標準支援語言。
  • 豐富的學習資源和社群存在,對初學者學習有很大幫助。
  1. 高靈活性的設計方法
  • 以 RTL(Register Transfer Level,暫存器傳輸層級)設計為核心,支援從低層級到高層級的廣泛設計方法。

與 VHDL 和 SystemVerilog 的比較

讓我們看看 Verilog 與其他 HDL,特別是 VHDL 和 SystemVerilog 有哪些區別。

語言 (Language)特色 (Features)應用範例 (Application Examples)
Verilog簡潔的語法,學習成本較低。廣泛用於 FPGA/ASIC 設計。高速原型開發,FPGA 設計
VHDL語法嚴謹,可進行穩固的設計。易於描述複雜的規格。關鍵任務系統設計
SystemVerilogVerilog 的擴充版。支援進階的測試平台和基於類的設計。進階測試平台建立,系統設計
  • 與 VHDL 的區別: VHDL 語法嚴謹,較能避免錯誤發生,但 Verilog 簡單且程式碼量較少,效率較高。
  • 與 SystemVerilog 的區別: SystemVerilog 是 Verilog 的上位相容,增加了進階的驗證工具和物件導向程式設計功能。

初學者開始數位設計時,通常會選擇語法較為簡潔的 Verilog。

Verilog 的具體應用範例

Verilog 在 FPGA 設計中的作用

FPGA 是一種使用者可程式設計的積體電路。透過使用 Verilog,可以輕鬆設計複雜的邏輯電路。以下是 Verilog 在 FPGA 設計中的作用:

  1. 原型開發 (Prototyping)
  • 用於產品開發初期驗證電路功能。
  • 使用 Verilog 可以快速試作設計,並靈活應對規格變更。
  1. 功能驗證 (Functional Verification)
  • 在 FPGA 設計中,使用 Verilog 進行模擬,以早期發現設計錯誤。
  • 在模擬工具(例如:ModelSim)中建立測試平台 (testbench),驗證電路的功能。

電路模擬的流程

使用 Verilog 進行模擬的基本流程如下:

  1. 電路描述
  • 使用 Verilog 描述目標設計的電路。
  1. 建立測試平台 (Testbench)
  • 測試平台用於定義驗證設計電路功能的環境。以下是一個簡單測試平台的範例:
module Testbench;
    reg a, b;
    wire y;

    // テスト対象のモジュールをインスタンス化 (例化測試目標模組)
    AND_gate uut (
        .a(a),
        .b(b),
        .y(y)
    );

    initial begin
        // テストパターンの適用 (套用測試 pattern)
        a = 0; b = 0;
        #10; a = 0; b = 1;
        #10; a = 1; b = 0;
        #10; a = 1; b = 1;
        #10;
    end
endmodule
  1. 執行模擬
  • 在模擬器中執行測試平台,確認電路功能是否如預期。
  1. 結果分析
  • 分析模擬結果,找出設計中的問題。

4. 使用 Verilog 的實際設計範例

透過 Verilog 範例程式碼學習

計數器設計範例(附程式碼解說)

計數器是數位電路設計中基本且重要的元件。以下是根據時脈訊號增加數值的計數器範例:

module Counter (
    input wire clk,    // クロック入力 (時脈輸入)
    input wire rst,    // リセット入力 (重置輸入)
    output reg [3:0] count // 4ビットのカウンタ出力 (4位元計數器輸出)
);
    always @(posedge clk or posedge rst) begin
        if (rst)
            count <= 4'b0000; // リセット時にカウンタを0にする (重置時,將計數器歸零)
        else
            count <= count + 1; // クロックが立ち上がるたびにカウンタをインクリメント (時脈上升沿時,計數器遞增)
    end
endmodule

解說:

  1. clk 是時脈訊號,用於控制電路的時序。
  2. rst 是重置訊號,用於計數器的初始化。
  3. 計數器的數值為 4 位元(0~15),並在時脈訊號的上升沿同步增加。

狀態轉換電路(FSM)的描述與應用範例

FSM(Finite State Machine,有限狀態機)用於設計具有多個狀態的電路。以下是具有三種狀態的 FSM 設計範例:

module FSM (
    input wire clk,    // クロック入力 (時脈輸入)
    input wire rst,    // リセット入力 (重置輸入)
    input wire in,     // 状態遷移のトリガー (狀態轉換的觸發)
    output reg [1:0] state // 現在の状態 (目前狀態)
);
    // 状態定義 (狀態定義)
    localparam STATE0 = 2'b00,
               STATE1 = 2'b01,
               STATE2 = 2'b10;

    always @(posedge clk or posedge rst) begin
        if (rst)
            state <= STATE0; // 初期状態 (初始狀態)
        else begin
            case (state)
                STATE0: state <= (in) ? STATE1 : STATE0;
                STATE1: state <= (in) ? STATE2 : STATE0;
                STATE2: state <= (in) ? STATE0 : STATE1;
                default: state <= STATE0;
            endcase
        end
    end
endmodule

解說:

  1. 使用 localparam 定義狀態。
  2. 使用 case 語句根據輸入 in 進行狀態轉換。
  3. 這個設計範例可以應用於例如簡單的控制系統或訊號產生電路。

簡單加法器設計(初學者步驟)

接下來,設計一個簡單的 2 位元加法器:

module Adder (
    input wire [1:0] a, // 2ビットの入力a (2位元輸入 a)
    input wire [1:0] b, // 2ビットの入力b (2位元輸入 b)
    output wire [2:0] sum // 3ビットの出力(最大値が3ビットになるため)(3位元輸出(因為最大值為 3 位元))
);
    assign sum = a + b; // 加算処理 (加法運算)
endmodule

解說:

  1. 使用 assign 語句進行加法。
  2. 輸出設定為 3 位元,考慮到進位。
  3. 這類加法器是運算處理電路的基礎,非常重要。

常見問題及其解決方法

常見錯誤範例(模擬時・合成時)

  1. 模擬時的錯誤
  • 錯誤範例: 訊號為未定義值(x)。
  • 原因: 初始化不足,或模組連接錯誤。
  • 解決方案: 明確定義輸入訊號或初始狀態,或在測試平台中進行初始化。
  1. 合成時的錯誤
  • 錯誤範例: 不可合成的語法(例如:initial 區塊)。
  • 原因: 使用了合成工具不支援的描述。
  • 解決方案: 使用可合成的語法(例如:always 區塊)。

除錯工具的活用法

在 Verilog 設計中,除錯非常重要。以下是常用的除錯工具及其使用方法:

  1. 模擬器(例如:ModelSim)
  • Verilog 模擬的經典工具。用於確認訊號的行為和波形。
  • 特色
    • 介面友善,初學者易於上手。
    • 波形檢視器直觀,非常適合除錯。
  1. 波形檢視器 (Waveform Viewer)
  • 視覺化確認輸入和輸出訊號的變化,找出設計問題。
  1. 除錯訊息 (Debug Messages)
  • 使用 display 語句輸出除錯資訊,確認訊號的數值或狀態:
   initial begin
       $display("Initial state: %b", state); // 輸出除錯資訊
   end

 

5. 學習 Verilog 的資源與工具

推薦的 Verilog 學習資源

初學者推薦書籍與線上教學

對於初次學習 Verilog 的人來說,使用可靠的教材非常重要。以下是推薦給初學者的資源:

  1. 書籍
  • 《HDL によるデジタル設計入門》
    • 這是一本經典的日文書籍,透過比較 Verilog 和 VHDL 的基本概念來學習。
  • 《Verilog HDL: A Guide to Digital Design and Synthesis》
    • 雖然是英文書,但內容從基礎到實踐,結構完整,是一本優秀的書籍。
  • 《Digital Design and Verilog HDL Fundamentals》
    • 針對初學者到中級程度的讀者,詳細解說使用 Verilog 進行數位電路設計。
  1. 線上教學 (Online Tutorials)
  • YouTube
    • 提供許多免費的日語和英語教學影片。可以直接操作程式碼來學習,這是一大優點。
    • 例如:「Verilog 入門」、「FPGA 設計的基本」等系列影片。
  • 網站
    • EDA Playground: 一個可以在瀏覽器上測試 Verilog 程式碼的線上環境。
    • ASIC World: 可以學習 Verilog 的基本語法到實用的設計範例。

影片課程與實踐教材介紹

  1. Udemy
  • 提供「Verilog for Beginners」和「學習 FPGA 設計」等課程,透過影片和實作來學習。
  • 雖然需要付費,但內容豐富,適合初學者系統性地學習。
  1. Coursera
  • 提供專注於硬體設計的大學程度線上課程。可以從基礎學習到進階設計。

支援開發的工具

模擬與合成工具(ModelSim、Vivado 等)

  1. ModelSim
  • 是 Verilog 模擬的經典工具。用於確認訊號的行為和波形。
  • 特色
    • 介面易於使用,即使是初學者也能輕鬆上手。
    • 波形檢視器直觀,非常適合除錯。
  1. Vivado
  • Xilinx 提供的 FPGA 設計工具,支援使用 Verilog 進行設計。
  • 特色
    • 整合支援 RTL 設計、模擬、合成到實現。
    • 與 FPGA 開發板(例如:Zynq、Artix 等)連結順暢。

合成工具的選擇與導入方法

  1. Quartus Prime
  • Intel 製造的 FPGA 開發工具。針對初學者提供免費版本。
  • 優點
    • 工具內可以視覺化電路圖。
    • 與 Cyclone 系列的 FPGA 連結簡單。
  1. ISE Design Suite
  • 用於較舊的 Xilinx FPGA 的工具,也適合教育機構使用。
  • 優點
    • 非常適合使用學習板(例如:Basys 2)進行設計。

6. 關於 Verilog 的常見問題 (FAQ)

Verilog 初學者的學習方法?

問題: 我剛開始學習 Verilog,應該如何進一步學習?

回答:

  1. 從基礎開始:
  • 先從簡單的電路(例如:AND 閘、OR 閘)設計開始。理解基本語法和模組的使用方法非常重要。
  1. 善用模擬工具:
  • 使用 ModelSim 或 Vivado 等工具確認編寫的程式碼是否如預期運作。透過實際進行模擬,可以加深理解。
  1. 利用可靠的資源:
  • 建議利用書籍或線上教學,系統性地學習(請參閱「5. 學習 Verilog 的資源與工具」)。
  1. 挑戰專案:
  • 學習基礎後,可以嘗試簡單的專案(例如:4 位元計數器或 FSM),培養實踐技能。

應該選擇 VHDL 還是 Verilog?

問題: 應該學習 VHDL 還是 Verilog?在哪些情境下會區別使用?

回答:

  1. 選擇 Verilog 的情況:
  • Verilog 語法簡單,對於初學者或有 C 語言經驗的人來說較易學習。
  • 廣泛用於原型開發和 FPGA 設計。
  1. 選擇 VHDL 的情況:
  • 適用於關鍵任務系統或需要大型且嚴謹設計的情況。
  • 嚴謹的型別檢查和語法在防止設計錯誤方面具有優勢。
  1. 選擇標準:
  • 學習難易度: 初學者最適合 Verilog。
  • 專案需求: 根據專案使用的語言選擇。
  • 工具支援: 大多數工具都支援這兩種語言,但建議根據設計目標(FPGA 或 ASIC)選擇最適合的語言。

初學者應避免的錯誤是什麼?

問題: 初學者在學習 Verilog 時常犯的錯誤是什麼?如何避免?

回答:

  1. 初始化不足:
  • 模擬時訊號常常變為 x(未定義值)。
  • 對策: 務必設定初始值,或在測試平台中進行初始化。
   initial begin
       signal = 0; // 訊號初始化
   end
  1. 混淆阻塞式與非阻塞式賦值:
  • 混淆 =(阻塞式賦值)和 <=(非阻塞式賦值)可能導致結果不如預期。
  • 對策: 在時脈同步的 always 區塊中,使用非阻塞式賦值(<=)。
  1. 混淆可合成程式碼與模擬用程式碼:
  • 將僅用於模擬的描述(例如 initial 區塊)包含在可合成程式碼中會導致錯誤。
  • 對策: 明確區分可合成程式碼與僅用於模擬的程式碼。
  1. 對平行處理理解不足:
  • Verilog 用於描述平行運作的電路,容易與軟體的依序處理混淆。
  • 對策: 學習平行處理的基本概念,並意識到多個 always 區塊是獨立運作的。

7. 學習 Verilog 邁向下一步

Verilog 學習回顧與下一步準備

回顧

  • 理解基本語法: 確認是否已能描述模組、資料型別和控制結構。
  • 掌握實踐範例: 透過計數器和 FSM 設計,是否已能建構基本的數位電路,這一點很重要。
  • 善用工具: 確認是否已掌握使用 ModelSim 或 Vivado 等工具進行模擬和除錯的基本操作。

下一步準備

  • 如果目前已理解基礎,就代表已準備好進入更進階的主題。
  • 按照以下步驟,獲取新的技能和知識。

進入 FPGA 設計領域

學習 FPGA 基礎

FPGA(Field-Programmable Gate Array)是應用 Verilog 技能的理想平台。FPGA 是一種可程式設計的硬體,可以應對各種設計需求。

  1. 準備 FPGA 開發板
  • 初學者推薦開發板: 建議使用 Digilent 公司的 Basys 3 或 Nexys A7。
  • 原因: 教材資源豐富,且可以輕鬆與 Vivado 等工具連結。
  1. 挑戰基礎專案
  • 從 LED 閃爍、按鈕控制等簡單專案開始。
  • 透過時脈分頻電路和多輸入控制,學習 FPGA 設計的基礎。
  1. 挑戰複雜系統
  • 嘗試設計整合多個 FSM 的控制系統或記憶體介面,擴展技能。

轉向 SystemVerilog

學習 SystemVerilog 的原因

  • SystemVerilog 作為 Verilog 的擴充版而設計,支援進階的驗證功能和物件導向的描述。
  • 特別是在測試平台建立和大型系統設計中發揮強大作用。

應學習的主題

  1. 基於類的測試平台 (Class-based Testbenches)
  • 使用 SystemVerilog 可以進行隨機測試和覆蓋率分析。
  1. 介面的活用 (Utilization of Interfaces)
  • 可以簡潔地描述複雜的模組間通訊。
  1. 擴充的控制結構 (Extended Control Structures)
  • 學習 uniquepriority 等提高設計安全性的關鍵字。

參與實際專案

參與開源專案

參與 GitHub 等平台上公開的開源數位設計專案,可以累積實踐經驗。例如:

  • RISC-V 處理器設計
  • 簡易 DSP(數位訊號處理)模組

啟動原創專案

  • 嘗試在感興趣的領域進行原創數位設計。
  • 例如:數位時鐘、音訊處理器、訊號濾波電路等。

下一步學習建議

學習進階設計技能

  1. 流水線設計 (Pipeline Design)
  • 學習高速處理器和訊號處理電路中使用的流水線設計基礎。
  1. 時脈域理解 (Understanding Clock Domains)
  • 學習如何在不同時脈速度的模組之間正確傳遞訊號。
  1. 低功耗設計 (Low-Power Design)
  • 導入考慮電力效率的設計方法,以獲得更實用的技能。