🔄 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
#
Type | Wildcard Treated | Use Case Example |
---|---|---|
casez | z | Matching with unknown bits in addresses |
casex | x , z | Matching 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 — prefercasez
or regularcase
.
🔁 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#
Statement | RTL Friendly | Testbench Use | Synth Notes |
---|---|---|---|
if/else | ✅ | ✅ | Fully synthesizable |
case | ✅ | ✅ | Use default to avoid latches |
for | ✅* | ✅ | *Bounds must be constant |
while | ⚠️ | ✅ | Avoid in RTL, use only if bounded |
repeat | ❌ | ✅ | Simulation only |
forever | ❌ | ✅ | Never synthesize! |
💡 Tip: Use
always_comb
,always_ff
, andalways_latch
(SystemVerilog) for more explicit intent.