How to Use Case Statement in Verilog: Syntax and Examples
In Verilog, the
case statement is used to select one of many code blocks based on the value of an expression. It works like a switch-case in other languages, matching the expression against multiple case items and executing the matching block. Use case inside procedural blocks like always to implement multi-way branching.Syntax
The case statement syntax in Verilog is:
case (expression): Evaluates the expression once.case_item:Each possible value to match against the expression.statements;Code to run if the case item matches.default:Optional block if no case matches.endcase: Ends the case statement.
This is used inside procedural blocks like always or initial.
verilog
always @(*) begin case (expression) case_item1: statements1; case_item2: statements2; // ... default: default_statements; endcase end
Example
This example shows a 2-bit input sel controlling a 4-bit output out. The case statement selects which value to assign based on sel.
verilog
module case_example( input wire [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
Common Pitfalls
Common mistakes when using case in Verilog include:
- Not covering all possible values, which can cause latches if synthesis infers incomplete assignments.
- Forgetting the
defaultcase, which helps avoid unintended behavior. - Using blocking assignments (
=) incorrectly inside sequential logic. - Mixing signal widths or types in case items.
Always ensure all cases are covered or use default to prevent synthesis issues.
verilog
/* Wrong: Missing default and incomplete cases can cause latches */ always @(*) begin case(sel) 2'b00: out = 4'b0001; 2'b01: out = 4'b0010; // Missing cases for 2'b10 and 2'b11 endcase end /* Right: Include default to cover all cases */ 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
Quick Reference
Tips for using case in Verilog:
- Use
caseinsidealwaysorinitialblocks. - Always include a
defaultcase to avoid unintended latches. - Match the width and type of the expression and case items.
- Use
casezorcasexfor wildcard matching if needed. - Use non-blocking assignments (
<=) in sequential logic.
Key Takeaways
Use the
case statement inside procedural blocks to select code based on an expression.Always include a
default case to cover unmatched values and avoid latches.Ensure all case items match the expression's width and type for correct synthesis.
Use
casez or casex for pattern matching with wildcards.Avoid incomplete case statements to prevent unintended hardware behavior.