Verilog case 語句完整教學:基本語法、範例與注意事項

1. 前言

Verilog 是一種硬體描述語言(HDL),被廣泛應用於數位電路的設計。其中,case 語句是一個 用來高效率描述條件分支 的重要語法。特別是在 狀態轉換(State Machine)以及多工器(Multiplexer) 的設計中經常使用。

本文將詳細解說 Verilog 的 case 語句,從基本語法到進階應用,以及使用時需要注意的要點。文中會搭配具體的程式範例,讓初學者也能輕鬆理解,請務必閱讀到最後!

2. Verilog case 語句的基本語法

case 語句是什麼?

Verilog 的 case 語句是一種 根據給定條件(選擇器)執行不同處理的語法。它的功能類似於 C 語言的 switch-case,但仍有一些獨特的差異。

基本語法如下:

case (表達式)
    條件1: 敘述1;
    條件2: 敘述2;
    條件3: 敘述3;
    default: 敘述4;  // 當沒有任何條件符合時
endcase

case 語句的基本用法

以下範例展示了一個簡單的 case 語句,根據 2 位元輸入 sel 的值來指定不同的輸出 out

module case_example(input [1:0] sel, output reg [3:0] out);
    always @(*) begin
        case (sel)
            2'b00: out = 4'b0001;
            2'b01: out = 4'b0010;
            2'b10: out = 4'b0100;
            2'b11: out = 4'b1000;
            default: out = 4'b0000;  // 預設值,避免例外情況
        endcase
    end
endmodule

在這段程式中,sel 的值會決定 out 的輸出。加入 default 分支能確保 即使遇到未預期的輸入,仍能保持穩定的行為

case vs casex vs casez 的差異

Verilog 提供了 casexcasez 作為 case 的擴充版本,它們允許忽略特定位元,類似萬用字元的功能。

語法特徵
case要求完全匹配(預設行為)
casex忽略 X(未定義值)與 Z(高阻抗)
casez僅忽略 Z

例如,以下是 casez 的範例:

casez (sel)
    2'b1?: out = 4'b1111; // 最高位為 1 時符合,不論低位元
    2'b01: out = 4'b0001;
    default: out = 4'b0000;
endcase

在這裡,1? 表示只要最高位元是 1,就會符合條件,而不考慮低位元的值。

3. case 語句的實際應用範例

基本條件分支

以下範例展示了一個簡單的 CPU 解碼器,根據 8 位元輸入 opcode 的值執行不同處理。

module decoder(input [7:0] opcode, output reg [3:0] control_signal);
    always @(*) begin
        case (opcode)
            8'h00: control_signal = 4'b0001; // NOP
            8'h01: control_signal = 4'b0010; // ADD
            8'h02: control_signal = 4'b0100; // SUB
            default: control_signal = 4'b0000; // 未定義指令
        endcase
    end
endmodule

狀態機中的應用

case 語句常用於 有限狀態機(FSM:Finite State Machine) 的設計。

typedef enum reg [1:0] {IDLE, RUN, STOP} state_t;
state_t current_state, next_state;

always @(posedge clk) begin
    if (reset)
        current_state <= IDLE;
    else
        current_state <= next_state;
end

always @(*) begin
    case (current_state)
        IDLE: next_state = RUN;
        RUN:  next_state = STOP;
        STOP: next_state = IDLE;
        default: next_state = IDLE;
    endcase
end

這段程式實現了一個三狀態的 FSM。在需要狀態控制的電路中,使用 case 語句能讓程式碼更清晰易懂

4. 使用 case 語句時的注意事項

在 Verilog 中使用 case 語句時,必須注意以下幾點:

1. 一定要撰寫 default 分支

case 語句需要 覆蓋所有可能的輸入情況。特別是在 FPGA 或 ASIC 綜合時,如果沒有 default可能會意外產生鎖存器(latch)

2. 小心使用 casexcasez

使用 casexcasez 時,有可能會產生不必要的匹配。因此必須 透過模擬確認其行為是否符合設計意圖

casez (sel)
    2'b1?: out = 4'b1111; // 最高位為 1 即符合
    2'b01: out = 4'b0001;
    default: out = 4'b0000;
endcase

在這種情況下,要特別確認是否會出現預期外的匹配。

3. 避免濫用 case 語句

若是小規模的條件分支,if-else 可能 更直觀易懂case 語句比較適合 多選一的情境

5. 總結

本文解說了 Verilog case 語句的以下重點:

case 語句的基本語法與行為
casecasexcasez 的差異
case 的實際應用範例(條件分支、狀態機)
✅ 使用 case 語句時的注意事項

在 Verilog 電路設計中,適當使用 case 語句能 提升程式可讀性並降低設計錯誤。請善加運用於未來的設計中!

接下來應該學習的 Verilog 重要概念

在理解了 Verilog case 語句之後,建議進一步學習 「always 語句」以及「組合邏輯與時序邏輯」,能讓你對 Verilog 有更深入的掌握!