Verilog Procedural Blocks: initial and always
Behavioural Verilog lives inside procedural blocks. There are two kinds: initial, which runs once at time zero, and always, which runs again every time its trigger fires. Everything you assign inside them must be declared reg.
initial — runs once
initial blocks are used almost entirely in testbenches to set up stimulus; they are generally not synthesisable. The block below drives a sequence of values and finishes:
module tb;
reg [3:0] x;
initial begin
x = 4'd0; $display("t=%0t x=%0d", $time, x);
#5 x = 4'd7; $display("t=%0t x=%0d", $time, x);
#5 x = 4'd15; $display("t=%0t x=%0d", $time, x);
#5 $finish;
end
endmodulet=0 x=0 t=5 x=7 t=10 x=15
always — runs on a trigger
An always block repeats whenever an event in its sensitivity list occurs. The two canonical forms are combinational logic and clocked (sequential) logic:
always @(*)— combinational. Re-evaluates when any input changes. Use blocking=assignments.always @(posedge clk)— sequential. Fires on the clock edge and infers flip-flops. Use non-blocking<=assignments.
module counter_demo;
reg clk, rst;
reg [3:0] count;
// sequential: one flip-flop per bit of count
always @(posedge clk or posedge rst)
if (rst) count <= 4'd0;
else count <= count + 4'd1;
// clock generator
always #5 clk = ~clk;
initial begin
clk = 0; rst = 1;
#12 rst = 0; // release reset after a couple of edges
#40 $finish;
end
always @(posedge clk) $display("t=%0t count=%0d", $time, count);
endmodulet=5 count=0 t=15 count=0 t=25 count=1 t=35 count=2 t=45 count=3
The golden rule
Combinational always @(*) → blocking =. Clocked always @(posedge clk) → non-blocking <=. Mixing them is the most common source of simulation-vs-synthesis mismatches — the subject of the next chapter, blocking vs non-blocking assignments.
▶ Try it in the ChipXpert Lab
Paste the counter above and hit Simulate — step through the clock edges and confirm count only updates on posedge clk.
Check yourself
Which assignment operator belongs in <code>always @(posedge clk)</code>?
Non-blocking <=. It models the parallel, edge-triggered update of real flip-flops, so every right-hand side is sampled before any left-hand side is updated.
Can you synthesise an <code>initial</code> block?
Generally no. initial is a simulation construct for testbench setup. Some FPGA flows honour it for memory/register initialisation, but ASIC synthesis ignores it — use a reset instead.
Share your question in comments or talk to our mentor team for batch guidance.
Learn Verilog with mentors, labs and placement support
This free series is maintained by the ChipXpert training team in Hyderabad & Bengaluru. Go deeper with instructor-led courses on real EDA tools.
Explore VLSI Courses