Skip to main content

Verilog Control Flow: if, case, loops & RTL Guidelines

· loading · loading · ·
Hardware Design Verilog Control Flow Verilog If-Else Verilog Case Verilog Loops RTL Design
Hardware Design
Axolot Logic
Author
Axolot Logic
Digital Design Engineer
Table of Contents
Verilog HDL Series - This article is part of a series.
Part 7: This Article

🔄 Control Flow Statements in Verilog
#

Control flow statements define decision-making and iteration logic inside always, initial, or generate blocks. They are essential for writing RTL or testbench logic.


✅ Conditional Branching: if / else
#

Used for simple binary decisions.

always @(posedge clk) begin
  if (reset)
    count <= 0;
  else if (enable)
    count <= count + 1;
  else
    count <= count;
end

📌 RTL-safe structure: ensures a deterministic output on every clock.


🔄 Multi-way Selection: case
#

More readable than chained if for multi-condition logic.

always @(*) begin
  case (opcode)
    4'b0001: alu_out = a + b;
    4'b0010: alu_out = a - b;
    4'b0011: alu_out = a & b;
    4'b0100: alu_out = a | b;
    default: alu_out = 0;
  endcase
end

✅ Use default to avoid latches in combinational blocks.


🔸 Special Variants: casez and casex
#

TypeWildcard TreatedUse Case Example
casezzMatching with unknown bits in addresses
casexx, zMatching don’t-care conditions (not synth-safe!)
casez (instr[7:0])
  8'b1??_?????: result = R_type;
  8'b0000_0001: result = NOP;
  default:      result = ILLEGAL;
endcase

⚠️ casex may lead to non-determinism in synthesis — prefer casez or regular case.


🔁 Looping Constructs
#

Loops are powerful in testbenches and generate blocks, but should be used carefully in RTL.


🔁 for Loop
#

Used for initialization or array access.

integer i;
initial begin
  for (i = 0; i < 8; i = i + 1)
    mem[i] = 8'hFF;
end

✅ Synthesizable if bounds are static.


🔁 while Loop
#

Loops until a condition becomes false. Often used in testbenches.

initial begin
  while (!done)
    @(posedge clk);
  $display("Operation completed!");
end

⚠️ Avoid in RTL unless the number of iterations is known and bounded.


🔁 repeat Loop
#

Repeat a block a fixed number of times.

initial begin
  repeat (10) @(posedge clk);
  $finish;
end

Ideal for clock delay loops in simulations.


forever Loop
#

Creates an infinite loop. Use only with caution (testbenches, clocks).

initial begin
  forever #5 clk = ~clk;
end

⚠️ Never use in synthesizable RTL!


🧠 Summary Table
#

StatementRTL FriendlyTestbench UseSynth Notes
if/elseFully synthesizable
caseUse default to avoid latches
for✅**Bounds must be constant
while⚠️Avoid in RTL, use only if bounded
repeatSimulation only
foreverNever synthesize!

💡 Tip: Use always_comb, always_ff, and always_latch (SystemVerilog) for more explicit intent.


Verilog HDL Series - This article is part of a series.
Part 7: This Article

Related

Verilog Assignments: Procedural vs. Continuous Explained
· loading · loading
Hardware Design Verilog Assignments Continuous Assignment Procedural Assignment RTL Design Hardware Description Language
Hardware Design
Verilog Synthesis: From RTL to Gate-Level Netlist
· loading · loading
Hardware Design Verilog Synthesis RTL Design Gate Level Netlist FPGA Design ASIC Design
Hardware Design
Hardware Design Abstraction Levels in Verilog
·238 words·2 mins· loading · loading
Hardware Design Hardware Abstraction RTL Design Gate Level Transistor Level Digital Design
Hardware Design
Verilog Blocking vs. Non-Blocking Assignments
· loading · loading
Hardware Design Verilog Assignments Blocking Assignment NonBlocking Assignment RTL Design Sequential Logic
Hardware Design
Verilog Namespaces: Understanding Scope and Modularity
· loading · loading
Hardware Design Verilog Namespace Verilog Scope Modularity RTL Design Hardware Description Language
Hardware Design
Verilog Parameters: Making Modules Reusable & Configurable
· loading · loading
Hardware Design Verilog Parameters Reusable Design Configurable Modules RTL Design Hardware Description Language
Hardware Design