Non Blocking Proceduaral assignments
The non-blocking assignment statement starts its execution by evaluating the RHS operand at the beginning of a time slot and schedules its update to the LHS operand at the end of a time slot. Other Verilog statements can be executed between the evaluation of the RHS operand and the update of the LHS operand. As it does not block other Verilog statement assignments, it is called a non-blocking assignment.
A less than or equal to ‘<=’ is used as a symbol for the non-blocking assignment operator.
- If <= symbol is used in an expression then it is interpreted as a relational operator.
- If <= symbol is used in an assignment then it is interpreted as a non blocking operator.
module nonblocking; reg [3:0] data = 4'h4; real r_value; integer i_value; time T; initial begin $monitor("At time T = %0t: data = %0d, r_value = %0f, i_value = %0h", T, data, r_value, i_value); r_value <= 3.14; i_value <= 4; #2 data <= 4'h5; data <= #3 'd7; i_value <= 10; i_value <= 6; #4 $finish; end always #1 T = $time; endmodule
At time T = 0: data = 4, r_value = 3.140000, i_value = 4 At time T = 1: data = 4, r_value = 3.140000, i_value = 4 At time T = 2: data = 5, r_value = 3.140000, i_value = 6 At time T = 3: data = 5, r_value = 3.140000, i_value = 6 At time T = 4: data = 5, r_value = 3.140000, i_value = 6 At time T = 5: data = 7, r_value = 3.140000, i_value = 6 $finish called from file "design.sv", line 16. $finish at simulation time 6
How race around condition is resolved in a nonblocking assignment?
If a variable is used in LHS of blocking assignment in one procedural block and the same variable is used in RHS of another blocking assignment in another procedural block.
module nonblocking; reg [3:0] data = 4'h5; reg [3:0] y = 4'h3; initial begin // first initial block y <= data; #1 $display("1st block: data = %0h and y = %0h", data, y); end initial begin // second initial block data <= y; #1 $display("2nd block: data = %0h and y = %0h", data, y); end endmodule
1st block: data = 3 and y = 5 2nd block: data = 3 and y = 5
In this example,
Since procedural blocks (both initial and always) can be executed in any order.
In a non-blocking assignment statement no matter what is the order of execution, both RHS of the assignments (y <= data and data <= y) are evaluated at the beginning of the timeslot and LHS operands are updated at the end of a time slot. Thus, race around condition is avoided as there is no dependency on execution order and the order of execution of these two statements can be said to happen parallelly.
Verilog procedural assignment guidelines
For a beginner in Verilog, blocking and non-blocking assignments may create confusion. If are used blindly, it may create race conditions or incorrect synthesizable design. Hence, it is important to understand how to use them. To achieve synthesized RTL correctly, Verilog coding guidelines for blocking and non-blocking assignments are mentioned below
- Use non-blocking assignments for modeling flip flops, latches, and sequential logic.
- Use blocking assignment to implement combinational logic in always block.
- Use non-blocking assignment to implement sequential logic in always block.
- Do not mix blocking and non-blocking assignments in single always block i.e. For the implementation of sequential and combination logic in a single ‘always’ block, use non-blocking assignments.
- Do not assign value to the same variable in the different procedural blocks.
- Use non-blocking assignments while modeling both combination and sequential logic within the same always block.
- Avoid using #0 delay in the assignments.