The case statement in Verilog is a powerful tool that helps to make decisions based on an expression’s value. It’s often used in designs like multiplexers, where different inputs are routed based on a selection signal. In this guide, we will explore how the Verilog case statement works, its syntax, and how it compares to if-else statements.
What is a Verilog Case Statement?
The case statement checks if a given expression matches one of the predefined values or alternatives and performs actions accordingly. It’s ideal for situations where you need to handle many different conditions in a clean and efficient way.
This statement is commonly used for creating multiplexers. When you have many possible conditions to check, the if-else construct might not be as efficient and could lead to priority encoders, not multiplexers.
Syntax of the Case Statement
In Verilog, the case statement begins with the keyword case and ends with endcase. Here’s the basic syntax:
case (<expression>)
case_item1 : <single statement>;
case_item2, case_item3 : <single statement>;
case_item4 : begin
<multiple statements>;
end;
default : <statement>;
endcase- The expression inside the
caseis evaluated once and compared to eachcase_item. - If there’s a match, the corresponding statement or block of statements is executed.
- If no match occurs, the
defaultblock is executed (if provided). If thedefaultblock is not specified, no action is taken if no match is found.
Key Points:
- Matching Expressions: The
casechecks each bit of the expression against the alternatives (e.g.,0,1,x,z). - Default Block: The
defaultstatement is optional but helps handle unexpected cases. - Nested Cases: Case statements can be nested within other case statements.
Example: Simple Multiplexer Using Case Statement
Let’s look at an example of how the case statement is used to implement a 4-to-1 multiplexer. We have three 3-bit inputs, and we use a 2-bit select signal (sel) to choose which input gets routed to the output (out).
module my_mux (
input [2:0] a, b, c, // Three 3-bit inputs
input [1:0] sel, // 2-bit select signal
output reg [2:0] out // 3-bit output signal
);
always @ (a, b, c, sel) begin
case(sel)
2'b00 : out = a; // If sel=00, output is a
2'b01 : out = b; // If sel=01, output is b
2'b10 : out = c; // If sel=10, output is c
default : out = 3'b000; // If sel is 11 or invalid, output is 0
endcase
end
endmoduleHardware Schematic
This code generates a 4-to-1 multiplexer. It ensures that the output is 0 when the select signal (sel) is 3. For other values, the output corresponds to the selected input (a, b, or c).

Simulation Log:
Here is what the simulation log might look like for various values of sel:
[0] a=0x4 b=0x1 c=0x1 sel=0b11 out=0x0
[10] a=0x5 b=0x5 c=0x5 sel=0b10 out=0x5
[20] a=0x1 b=0x5 c=0x6 sel=0b01 out=0x5
[30] a=0x5 b=0x4 c=0x1 sel=0b10 out=0x1
[40] a=0x5 b=0x2 c=0x5 sel=0b11 out=0x0Handling x and z Values in Case Statements
In Verilog, the case statement compares each bit of the expression with the alternatives, including x (unknown) and z (high impedance). If the expression contains x or z, and no case_item matches, the default statement will be executed.
Example:
If sel contains x or z, the output will default to zero since none of the case items will match.
ncsim> run
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x0
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x0
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x0Case with x and z in Case Items
You can also include x and z in the case items themselves. This can be useful for matching unknown or high-impedance values. For example:
module my_mux (
input [2:0] a, b, c,
input [1:0] sel,
output reg [2:0] out
);
always @ (a, b, c, sel) begin
case(sel)
2'bxz : out = a; // Match if sel is x or z
2'bzx : out = b; // Match if sel is zx
2'bxx : out = c; // Match if sel is xx
default : out = 0; // Default to zero
endcase
end
endmoduleSimulation Log:
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x1
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x5
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x1
[30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x6Case vs. If-Else: What’s the Difference?
The main difference between a case statement and an if-else block lies in how they match conditions:
- Case Statement:
- A single expression is compared to a list of possible alternatives.
- It provides precise results, especially when dealing with
xandzvalues.
- If-Else:
- It can check multiple expressions and is more flexible but may be less efficient when handling many conditions.
If-elsemight be synthesized into a priority encoder instead of a multiplexer in some cases.
Conclusion
The Verilog case statement is an essential tool for handling multiple conditions efficiently. Whether you’re building a simple multiplexer or handling unknown values (x and z), the case statement ensures clean, readable, and predictable logic. By understanding how to use the case statement, you can design more complex digital circuits with ease.

