Blocking vs Non-Blocking
Operators = vs <=, scheduling semantics.
The distinction between blocking and non-blocking assignments is one of the most important and frequently misunderstood concepts in Verilog. Getting this wrong leads to simulation results that do not match synthesized hardware behavior, which is a critical failure in digital design. This topic appears consistently in GATE examinations and university assessments.
Core Concept: The Two Assignment Operators
Inside a Verilog procedural block, two assignment operators exist. The blocking assignment uses the = operator. The non-blocking assignment uses the <= operator. Although both operators appear inside always blocks and both assign values to reg variables, their execution semantics are fundamentally different and model entirely different types of hardware.
A blocking assignment executes immediately. When the simulator encounters a = b, it evaluates b right now, assigns it to a right now, and only then moves to the next statement. The next statement sees the updated value of a. This behavior is sequential and software-like, which makes it appropriate for modeling combinational logic where signal values must be propagated through a chain of computations in the correct order.
A non-blocking assignment uses a two-phase mechanism. When the simulator encounters a <= b, it evaluates the right-hand side immediately and stores the result in a temporary holding area, but it does not update a yet. It moves on to the next statement without waiting. Only after all non-blocking assignments in the current time step have been evaluated does the simulator update all left-hand side variables simultaneously. This models the behavior of flip-flops sampling their inputs on a clock edge: all inputs are captured at the same moment, and all outputs update together.
Mathematical and Scheduling Model
Verilog simulation operates on a stratified event queue. Within a single simulation time step, events are processed in defined regions: the Active region, the NBA (Non-Blocking Assignment update) region, and others. Blocking assignments execute and update in the Active region. Non-blocking assignments evaluate their RHS in the Active region but schedule the LHS update in the NBA region, which occurs after all active events are processed.
This scheduling model ensures that when multiple flip-flops are clocked simultaneously, each flip-flop captures the value its input had before the clock edge, not the value another flip-flop may have just written. This is exactly the correct behavior for a synchronous digital circuit. If blocking assignments were used for flip-flops, the order of the always blocks in the file would affect the simulation result, causing nondeterminism.
Practical Understanding: Which to Use Where
The golden rule followed universally in professional RTL design is: use blocking assignments (=) inside always @(*) blocks for combinational logic, and use non-blocking assignments (<=) inside always @(posedge clk) blocks for sequential logic. Mixing the two inside the same always block is legal but strongly discouraged because it produces confusing and often incorrect behavior.
A concrete illustration: if you have two flip-flops A and B connected in series, where B should capture the old value of A on each clock edge, and you write A = D; B = A; using blocking assignments in the same always block, then B gets the new value of A (just written in the same step), not the old value. The circuit behaves like only one flip-flop exists. With non-blocking assignments A <= D; B <= A;, both right-hand sides are evaluated before any left-hand side is updated, so B correctly captures the previous value of A.
Given:
Two flip-flops in series: Q1 captures D on posedge clk, Q2 captures Q1 on posedge clk.
Initial state: Q1=0, Q2=0, D=1
Why this formula applies:
Sequential pipeline: each FF captures old value. Non-blocking required.
Formula:
always @(posedge clk) begin
Q1 <= D; // captures D before update
Q2 <= Q1; // captures OLD Q1 before update
end
Substitution:
At posedge clk with D=1, Q1=0, Q2=0:
RHS evaluated: Q1_new = D = 1, Q2_new = Q1 = 0 (old value)
LHS updated: Q1 = 1, Q2 = 0
Calculation:
Next posedge clk: D=1, Q1=1, Q2=0
RHS: Q1_new=1, Q2_new=Q1=1
After update: Q1=1, Q2=1
Correct 2-cycle pipeline delay.
Final Answer with units:
After 2 clock edges, Q2 follows D with a 2-cycle delay. This is correct behavior.Exam Tip: GATE frequently shows a code snippet with blocking assignments in a clocked always block and asks what Q1 and Q2 will be. Remember: = in sequential logic causes the second FF to see the updated value, effectively collapsing the pipeline. <= preserves the old values. Identify the operator first, then trace the waveform.
Mechanism: Two-Phase Non-Blocking Execution
- Blocking (=): RHS evaluated, LHS updated immediately. Next statement sees new value. Used in combinational always blocks.
- Non-blocking (<=): RHS evaluated immediately, LHS updated in NBA region after all active events. All updates happen simultaneously.
- Non-blocking preserves old values across all FFs in the same clock edge, preventing false data propagation.
- Mixing = and <= in the same sequential always block is a common source of subtle simulation bugs.
- The order of non-blocking statements within a block does not affect the final result; order of blocking statements does.
Quick Revision
- = (blocking): immediate update, software-like, use in always @(*) for combinational logic.
- <= (non-blocking): deferred update, hardware-like, use in always @(posedge clk) for sequential logic.
- Non-blocking evaluates RHS in Active region, updates LHS in NBA region.
- Series pipeline FFs must use <= to avoid one FF seeing another's updated output in the same clock cycle.
- Order matters for =, does not matter for <=.
- Exam trap: blocking assignment in clocked block collapses multi-stage pipelines into one stage.
- Do not mix = and <= in the same always block. Use consistently per block type.
Procedural Assignment Semantics
Test your knowledge on this topic.
Q1.Which assignment operator must be used to model sequential logic flip-flops?
Related Articles
Block Statements
Begin-end, fork-join parallel blocks.
9 min read
Generate Blocks
Conditional and loop generate for scalable structures.
12 min read
FSM Behavioral Modeling
Mealy vs Moore coding styles.
11 min read
Loops in Verilog
For, while, repeat, forever loops.
8 min read
Timing Controls
Delay control #, event control @, wait statement.
4 min read