Verilog 10 : Conditional Statement in Verilog

 The Conditional Statement in Verilog: if-else, case, casex, and casez Explained

In digital design, conditional statements are the backbone of decision-making in hardware description languages like Verilog. They control the flow of execution in your code, determining which set of statements should execute when certain conditions are met.

In this post, we’ll explore the if-else, nested if, parallel if, and case statements — including their special forms casez and casex — with clear syntax, examples, and simulation outputs.



๐Ÿ”น Understanding Conditional Statements in Verilog

Conditional statements help you control when and how certain parts of your Verilog code execute.
These are mainly used inside procedural blocks such as always or initial.

The key conditional statements are:

  • if and if-else

  • nested if-else

  • parallel if

  • case, casez, and casex


⚙️ 1. The if-else Statement in Verilog

The if-else statement is used to make decisions based on conditions.
If the condition evaluates to true, Verilog executes one set of statements; otherwise, it executes another.

๐Ÿงฉ Syntax

✅ Simple if

if (condition) statement;

if-else

if (condition) statement; else statement;

✅ Nested if-else-if

if (condition1) statement; else if (condition2) statement; else statement;

When you want to execute multiple statements, wrap them inside begin and end.


๐Ÿ’ก Example 1 – Simple if

module simple_if(); reg latch; wire enable, din; always @ (enable or din) if (enable) begin latch <= din; end endmodule

๐Ÿ’ก Example 2 – if-else

module if_else(); reg dff; wire clk, din, reset; always @ (posedge clk) if (reset) begin dff <= 0; end else begin dff <= din; end endmodule

๐Ÿ’ก Example 3 – Nested if-else-if

module nested_if(); reg [3:0] counter; reg clk, reset, enable, up_en, down_en; always @ (posedge clk) if (reset == 1'b0) begin counter <= 4'b0000; end else if (enable && up_en) begin counter <= counter + 1'b1; end else if (enable && down_en) begin counter <= counter - 1'b1; end else begin counter <= counter; end endmodule

๐Ÿงช Simulation Log (Nested If-Else)

@0ns Driving all inputs to known state @1ns reset=0 enable=0 up=0 down=0 count=0000 @3ns De-asserting reset @7ns enable=1 count=0000 @11ns Up count mode → count=0001 @13ns count=0010 @15ns count=0011 @21ns Down count mode → count=0100 @23ns count=0011 @27ns count=0001

๐Ÿ”ธ 2. Priority vs Parallel if-else Statements

In nested if-else structures, priority is assigned from top to bottom.
The first condition that evaluates to true executes, and the rest are skipped.
This is known as priority logic.

However, if the input conditions are mutually exclusive (only one can be true at a time), then using parallel if is more efficient, since it doesn’t create unnecessary priority chains.


⚙️ Example – Parallel if

module parallel_if(); reg [3:0] counter; wire clk, reset, enable, up_en, down_en; always @ (posedge clk) if (reset == 1'b0) begin counter <= 4'b0000; end else begin if (enable && up_en) counter <= counter + 1'b1; if (enable && down_en) counter <= counter - 1'b1; end endmodule

๐Ÿง  Note:

  • Use nested if-else when you want priority logic.

  • Use parallel if when conditions are mutually exclusive, saving hardware resources.


๐ŸŸฃ 3. The case Statement

The case statement provides a clean and efficient way to select one of many possible execution paths, similar to a “switch-case” in C language.

๐Ÿ”ง Syntax

case (expression) case1 : statement; case2 : statement; ... default : statement; endcase

Multiple statements can be grouped using begin and end.


๐Ÿ’ก Example 1 – Normal case

module mux (a,b,c,d,sel,y); input a, b, c, d; input [1:0] sel; output reg y; always @ (a or b or c or d or sel) case (sel) 0 : y = a; 1 : y = b; 2 : y = c; 3 : y = d; default : $display("Error: Invalid SEL"); endcase endmodule

๐Ÿ’ก Example 2 – Case Without Default

module mux_without_default (a,b,c,d,sel,y); input a, b, c, d; input [1:0] sel; output reg y; always @ (a or b or c or d or sel) case (sel) 0 : y = a; 1 : y = b; 2 : y = c; 3 : y = d; 2'bxx, 2'bzz : $display("Error: SEL unknown or floating"); endcase endmodule

Here, multiple case items can trigger the same action — a useful feature in Verilog.


๐Ÿ’ก Example 3 – Case with x and z Conditions

module case_xz(enable); input enable; always @ (enable) case(enable) 1'bz : $display("Enable is floating"); 1'bx : $display("Enable is unknown"); default : $display("Enable = %b", enable); endcase endmodule

๐Ÿ”ต 4. Special Forms: casez and casex

casez and casex are enhanced versions of case that allow you to treat unknown (x) or high-impedance (z) values as don’t care conditions.

TypeDon’t Care forUse Case
casezz onlyFor tri-state logic
casexx and zFor simulation or incomplete inputs

๐Ÿ’ก Example – casez

module casez_example(); reg [3:0] opcode; reg [1:0] a,b,c,out; always @ (opcode or a or b or c) casez(opcode) 4'b1zzx : begin out = a; $display("Matched 4'b1zzx"); end 4'b01?? : begin out = b; $display("Matched 4'b01??"); end 4'b001? : begin out = c; $display("Matched 4'b001?"); end default : $display("Default selected"); endcase endmodule

Simulation Output:

@0ns default selected @2ns 4'b1zzx selected @4ns 4'b01?? selected @6ns 4'b001? selected

๐Ÿ’ก Example – casex

module casex_example(); reg [3:0] opcode; reg [1:0] a,b,c,out; always @ (opcode or a or b or c) casex(opcode) 4'b1zzx : begin out = a; $display("Matched 4'b1zzx"); end 4'b01?? : begin out = b; $display("Matched 4'b01??"); end 4'b001? : begin out = c; $display("Matched 4'b001?"); end default : $display("Default selected"); endcase endmodule

๐Ÿงฉ Comparing case, casez, and casex

module case_compare; reg sel; initial begin #1 sel = 0; #1 sel = 1; #1 sel = 1'bx; #1 sel = 1'bz; #1 $finish; end always @ (sel) case (sel) 1'b0: $display("Normal: 0"); 1'b1: $display("Normal: 1"); 1'bx: $display("Normal: x"); 1'bz: $display("Normal: z"); endcase always @ (sel) casex (sel) 1'b0: $display("CASEX: 0"); 1'b1: $display("CASEX: 1"); 1'bx: $display("CASEX: x"); 1'bz: $display("CASEX: z"); endcase always @ (sel) casez (sel) 1'b0: $display("CASEZ: 0"); 1'b1: $display("CASEZ: 1"); 1'bx: $display("CASEZ: x"); 1'bz: $display("CASEZ: z"); endcase endmodule

๐Ÿ” Simulation Output

Driving 0: Normal : 0 CASEX : 0 CASEZ : 0 Driving 1: Normal : 1 CASEX : 1 CASEZ : 1 Driving x: Normal : x CASEX : 0 (x treated as don’t care) CASEZ : x Driving z: Normal : z CASEX : 0 (z treated as don’t care) CASEZ : 0 (z treated as don’t care)

Summary Table

Statement

Priority

Don’t Care Support

Common Use

if-else

Yes

No

Control logic

case

No

No

Multiplexers

casez

No

z as don’t care

Decoders

casex

No

x, z as don’t care

Encoders & Simulation

Understanding how if-else, case, casez, and casex statements work is crucial for writing clean, synthesizable Verilog code.
Use them wisely based on your design needs — for priority logic, parallel decisions, or don’t care conditions — to make your hardware design both efficient and easy to debug.

Comments

Popular posts from this blog

Fundamental of python : 1.Python Numbers