1. 前言:Verilog中case語句的重要性
Verilog HDL(硬體描述語言)是數位電路設計中廣泛使用的語言。其中的「case語句」以能夠簡潔表達複雜條件分支的便利結構而聞名。對數位電路設計工程師而言,依據條件來定義訊號處理與行為是日常挑戰,而case語句正好能有效率地解決這些需求。
case語句的角色是什麼?
case語句是一種根據特定條件實現不同操作的結構。例如,它適用於簡單的解碼器設計,或是複雜的狀態轉換電路(FSM)。在Verilog中使用case語句,不僅能提升程式碼的可讀性,還能將電路資源的消耗降到最低。
為什麼case語句很重要
- 高效率的條件分支
若使用if-else語句描述多個條件,程式碼容易變得冗長。利用case語句,可以更有條理地管理多重分支,使程式碼更清晰。 - 針對數位電路設計
Verilog的case語句是以硬體實作為考量設計的,若正確使用,可達到電路最佳化。 - 防止錯誤
case語句能指定「default分支」,以涵蓋所有條件,避免出現未預期的行為。

2. 基本語法:Verilog case語句的寫法
在Verilog中,case語句是用來高效且簡潔地表達條件分支的基本結構。以下將透過範例來說明其語法與用法。
case語句的基本語法
以下是Verilog中最基本的case語句語法:
case (表達式)
條件1: 動作1;
條件2: 動作2;
...
default: 預設動作;
endcase
- 表達式:要被評估的值(變數或訊號)。
- 條件:根據表達式的值所執行的動作。
- default:當不符合任何條件時所執行的動作。
基本範例:2位元解碼器
以下以2位元解碼器為例,展示如何使用case語句進行設計。
module decoder(
input [1:0] in, // 2位元輸入訊號
output reg [3:0] out // 4位元輸出訊號
);
always @(in) begin
case (in)
2'b00: out = 4'b0001; // 當輸入為00
2'b01: out = 4'b0010; // 當輸入為01
2'b10: out = 4'b0100; // 當輸入為10
2'b11: out = 4'b1000; // 當輸入為11
default: out = 4'b0000; // 其他情況
endcase
end
endmodule
動作說明
- 依據輸入訊號
in
的值,設定輸出訊號out
。 - 透過default分支,即使遇到未預期的輸入也能設定安全值(此例為
4'b0000
)。
case、casex、casez的差異
在Verilog中,有以下三種類型的case語句。理解各自的特點與用途非常重要。
1. case
- 使用完全比對來判斷條件。
x
與z
的值也會被納入比對。
2. casex
- 忽略萬用字元(
x
或z
)進行條件比對。 - 主要用於模擬階段的測試案例。
- 注意:在實際電路合成時不建議使用(某些綜合工具可能會產生未預期的行為)。
3. casez
- 忽略
z
(高阻抗)的條件來進行比對。 - 常用於解碼邏輯或匯流排設計。
以下示範不同語句的範例:
casex (input_signal)
4'b1xx1: action = 1; // 忽略x
endcase
casez (input_signal)
4'b1zz1: action = 1; // 忽略z
endcase
常見錯誤:省略default分支
若省略default分支,當輸入不符合任何條件時,可能會輸出不定值(x
)。這將導致模擬與實際硬體設計出現不一致的問題,因此建議一定要明確撰寫default分支。

3. case語句的應用:範例與設計效率提升
Verilog的case語句不僅適用於簡單的解碼器設計,也能應用於複雜的狀態轉換電路(FSM)或多條件分支的設計。本節將透過實例說明如何利用case語句提升設計效率。
應用範例1:4位元算術邏輯單元(ALU)
算術邏輯單元(ALU)是執行加法、減法、邏輯運算等基本運算的電路。以下展示如何利用case語句設計一個簡單的ALU:
module alu(
input [1:0] op, // 運算種類選擇
input [3:0] a, b, // 運算輸入
output reg [3:0] result // 運算結果
);
always @(op, a, b) begin
case (op)
2'b00: result = a + b; // 加法
2'b01: result = a - b; // 減法
2'b10: result = a & b; // AND運算
2'b11: result = a | b; // OR運算
default: result = 4'b0000; // 預設值
endcase
end
endmodule
動作說明
- 依據選擇信號
op
執行不同運算。 - 利用default分支,避免產生未知值,確保設計安全。
應用範例2:狀態轉換電路(FSM)設計
有限狀態機(FSM: Finite State Machine)是數位設計的核心要素,case語句在此應用特別常見。
以下是一個包含三種狀態(IDLE、LOAD、EXECUTE)的FSM範例:
module fsm(
input clk, // 時脈訊號
input reset, // 重置信號
input start, // 啟動訊號
output reg done // 完成訊號
);
// 狀態定義
typedef enum reg [1:0] {
IDLE = 2'b00,
LOAD = 2'b01,
EXECUTE = 2'b10
} state_t;
reg [1:0] current_state, next_state;
// 狀態轉換邏輯
always @(posedge clk or posedge reset) begin
if (reset)
current_state <= IDLE; // 重置時回到IDLE
else
current_state <= next_state;
end
// 下一狀態判斷
always @(current_state or start) begin
case (current_state)
IDLE:
if (start)
next_state = LOAD;
else
next_state = IDLE;
LOAD:
next_state = EXECUTE;
EXECUTE:
next_state = IDLE;
default:
next_state = IDLE;
endcase
end
// 輸出邏輯
always @(current_state) begin
case (current_state)
IDLE: done = 0;
LOAD: done = 0;
EXECUTE: done = 1;
default: done = 0;
endcase
end
endmodule
動作說明
- 狀態轉換:根據目前狀態(
current_state
)與輸入訊號(start
),決定下一狀態(next_state
)。 - 輸出邏輯:依據狀態控制輸出訊號
done
。
提升設計效率的小技巧
1. 狀態數量增加時的管理
當狀態數量增加時,若使用巢狀case語句會使程式碼複雜。建議使用列舉型別(typedef enum
),能讓描述更簡潔並提升可讀性。
2. 善用default分支
明確撰寫default分支,可以避免未定義的行為。特別是在FSM設計中,有助於防止非預期的狀態轉換。
3. 善用模擬
利用模擬確認case語句的行為是否如設計預期運作,特別是檢查條件的完整性以及default分支是否正確執行。

4. 疑難排解:正確使用case語句的注意事項
Verilog的case語句非常便利,但若使用不當,可能導致設計錯誤或非預期的行為。本節將介紹常見的錯誤與解決方法。
常見錯誤與原因
1. 省略default分支
若省略default分支,當輸入條件不符合任何分支時,電路可能輸出不定值(x
)。在模擬中或許不會出問題,但在實際硬體上可能導致異常。
錯誤範例:
case (sel)
2'b00: out = 4'b0001;
2'b01: out = 4'b0010;
2'b10: out = 4'b0100;
2'b11: out = 4'b1000;
// 缺少default,可能出現不定值
endcase
解決方式:
一定要加上default分支,並指定安全值。
default: out = 4'b0000;
2. 條件重複
若case條件有重複,即使模擬能通過,也可能在綜合時產生警告或錯誤。
錯誤範例:
case (sel)
2'b00: out = 4'b0001;
2'b00: out = 4'b0010; // 重複條件
endcase
解決方式:
刪除重複條件,確保條件唯一。
3. 模擬與綜合行為差異
在模擬時運作正常,但在綜合後的實體電路卻可能出錯,尤其是使用casex
或casez
時。
問題範例:
- 在
casex
中使用萬用字元(x
)可能導致綜合後出現非預期行為。
解決方式:
- 盡量避免使用
casex
與casez
,優先選擇標準case
。 - 撰寫時考慮電路可綜合性。
4. 未定義的輸入條件
若條件未完整涵蓋,可能導致警告或非預期的設計結果。
錯誤範例:
case (sel)
2'b00: out = 4'b0001;
2'b01: out = 4'b0010;
// 2'b10 與 2'b11 未定義
endcase
解決方式:
完整涵蓋所有條件,或使用default分支補齊。
疑難排解重點
1. 善用靜態分析工具
設計時透過靜態分析工具,可以檢測case語句的潛在問題(如未定義條件、缺少default分支等)。
2. 建立測試平台(Testbench)
利用測試平台模擬所有輸入情況,確保case語句行為正確。
測試平台範例:
module testbench;
reg [1:0] sel;
wire [3:0] out;
decoder uut (.sel(sel), .out(out));
initial begin
sel = 2'b00; #10;
sel = 2'b01; #10;
sel = 2'b10; #10;
sel = 2'b11; #10;
$finish;
end
endmodule
設計指引:避免問題的方法
- 一定要寫default分支
- default分支能確保未定義條件時的安全行為。
- 確認條件完整性
- 設計時要確認所有輸入條件都有涵蓋。
- 最小化萬用字元的使用
- 避免過度依賴casex與casez,專注於明確條件。
- 同時驗證模擬與綜合
- 確認設計在模擬與綜合後的硬體行為一致。

5. 比較:if-else語句與case語句的差異與應用
在Verilog中,條件分支可以透過if-else語句
或case語句
來實現。兩者各有優勢,若能理解差異並合理選用,將能提升設計效率。本節將解釋if-else語句與case語句的不同之處及使用時機。
if-else語句與case語句的差異
1. 結構與可讀性
- if-else語句:條件會依序層級式判斷,適合用於強調條件優先順序的情境。但若條件過多,程式碼容易冗長,降低可讀性。
- case語句:能將條件平行列出,適合處理多重條件。即使條件數量增加,程式碼仍保持簡潔。
範例:if-else語句
if (sel == 2'b00) begin
out = 4'b0001;
end else if (sel == 2'b01) begin
out = 4'b0010;
end else if (sel == 2'b10) begin
out = 4'b0100;
end else begin
out = 4'b0000; // 預設值
end
範例:case語句
case (sel)
2'b00: out = 4'b0001;
2'b01: out = 4'b0010;
2'b10: out = 4'b0100;
default: out = 4'b0000;
endcase
2. 條件評估方式
- if-else語句:條件由上而下依序檢查,第一個符合的條件會被執行,其後條件會被忽略。適合處理有明確優先順序的情況。
- case語句:所有條件會以並列方式檢查,適合同一訊號需要判斷多種可能性的情境。
3. 硬體實現的影響
- if-else語句
- 在電路中通常被實現為多層的多工器(MUX)。
- 當條件數量增加時,延遲也會隨之增加。
- case語句
- 條件會被平坦化,通常實現為並列結構。
- 延遲相對固定,資源效率較高。
使用指引
適合使用if-else語句的情況
- 條件具有明顯優先順序。
例:控制訊號需依優先級處理。
if (priority_high) begin
action = ACTION_HIGH;
end else if (priority_medium) begin
action = ACTION_MEDIUM;
end else begin
action = ACTION_LOW;
end
- 條件數量少(3~4個以內)。
- 此時if-else語句足以應付,且程式碼不會太複雜。
適合使用case語句的情況
- 條件僅依賴單一訊號。
例:解碼器或狀態轉換電路(FSM)。
case (state)
IDLE: next_state = LOAD;
LOAD: next_state = EXECUTE;
EXECUTE: next_state = IDLE;
endcase
- 條件數量多(超過5個)。
- case語句在條件數量多時可保持良好的可讀性與高效實現。
效能比較
以下比較if-else語句與case語句在設計中的表現:
比較項目 | if-else語句 | case語句 |
---|---|---|
條件數量 | 少數(3~4個)較適合 | 多數(5個以上)更高效 |
可讀性 | 條件過多時下降 | 條件增加仍可維持清晰 |
延遲 | 隨條件數量增加而變長 | 延遲固定 |
電路資源 | 多層多工器,資源耗用較高 | 平坦結構,資源效率更佳 |

6. FAQ:關於case語句的常見問題
本節將回答設計人員在使用Verilog的case語句時,常見的疑問與問題,提供初學者到中級工程師都能參考的資訊。
Q1. case語句一定要有default分支嗎?
A. 是的,建議一定要加上。
default分支的作用是處理所有未被定義的條件。若省略,當輸入值不符合任何條件時,訊號可能會變為不定值(x
),導致模擬或合成時出現非預期行為。因此,建議在每個case語句中都明確包含default分支。
範例:使用default分支
case (sel)
2'b00: out = 4'b0001;
2'b01: out = 4'b0010;
default: out = 4'b0000; // 處理未定義輸入
endcase
Q2. casex與casez有什麼不同?
A. casex會忽略x
與z
,而casez只會忽略z
。
- casex:
- 忽略
x
(未定義)與z
(高阻抗),使比對更彈性。 - 常用於模擬測試,但不建議在實際電路合成中使用。
- casez:
- 僅忽略
z
,仍將x
視為比對條件。 - 常用於解碼器或匯流排設計。
範例:casex與casez比較
casex (input_signal)
4'b1xx1: action = 1; // 忽略x
endcase
casez (input_signal)
4'b1zz1: action = 1; // 忽略z
endcase
注意事項
- casex可能在合成後造成非預期行為,因此僅適合用於模擬。
Q3. case語句與if-else語句要如何選擇?
A. 根據條件的特性與數量來決定。
- if-else語句:適合條件有優先順序或條件數量少的情況。
- case語句:適合條件基於單一訊號,且條件數量多的情況。
Q4. case語句最適合用在哪些設計?
A. 適用於需要依多種條件決定行為的情境,例如FSM或解碼器。
- FSM(狀態轉換電路):能簡潔描述狀態之間的轉換。
- 解碼器:能依輸入信號輸出對應的結果。
Q5. 如果需要指定優先順序,該怎麼辦?
A. case語句是並列判斷,若要明確指定優先順序,應使用if-else語句。
範例:利用if-else設定優先順序
if (high_priority) begin
action = ACTION_HIGH;
end else if (medium_priority) begin
action = ACTION_MEDIUM;
end else begin
action = ACTION_LOW;
end
Q6. 有方法可以最佳化case語句嗎?
A. 可以,以下是幾個常見的最佳化方式:
- 完整覆蓋條件
確保涵蓋所有可能的輸入,避免未定義行為。 - 明確撰寫default分支
為未知情況提供安全輸出。 - 使用列舉型態(typedef enum)
在FSM等設計中,能提升可讀性並減少錯誤。 - 謹慎使用萬用字元
避免過度依賴casex或casez。

7. 總結與後續學習建議
Verilog的case語句是一個能簡潔且高效描述條件分支的強大工具。本文從基本語法、應用範例、疑難排解、與if-else語句的比較,到常見問題(FAQ),全面介紹了case語句的使用方法。以下整理重點,並提供後續學習方向。
case語句的重點整理
- 基本語法
- case語句能平行管理多重條件,提高可讀性。
- 務必加上default分支,確保未定義條件時能有安全輸出。
- case語句的應用
- 常用於ALU與FSM等數位設計。
- 結合列舉型別(
typedef enum
)與default分支,可進一步提升效率與安全性。
- 疑難排解
- 避免省略default分支。
- casex與casez僅建議於模擬使用,合成設計需謹慎。
- 與if-else語句的比較
- 若需要優先順序,選擇if-else。
- 若條件多且基於單一訊號,選擇case。
後續學習與設計建議
1. 深入學習Verilog
- 推薦主題:
- FSM的進階設計技巧。
- HDL設計中可合成程式碼的撰寫方式。
- Verilog的其他條件分支結構(if-else、三元運算子)。
- 推薦資源:
- 《Verilog HDL: A Guide to Digital Design and Synthesis》(Samir Palnitkar著)。
- IEEE官方文件與相關論文。
2. 實作專案練習
- 小型專案:
- 設計2~4位元的簡單解碼器或編碼器。
- 設計時脈分頻器等基礎電路。
- 中型專案:
- 以FSM設計自動販賣機或電梯控制系統。
- 設計簡單ALU並進行優化。
- 大型專案:
- 利用FPGA進行即時系統設計。
- 開發多處理器間的通訊控制單元。
3. 模擬與驗證
使用ModelSim、Vivado等模擬工具反覆驗證程式碼,特別要確認case語句條件的完整性與default分支的行為。
4. HDL設計最佳實務
- 保持程式碼可讀性,適度加上註解。
- 避免冗長的條件分支,注重電路效率。
- 建立測試平台(Testbench),在模擬中確認行為是否符合設計。