Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we use Blocking statement in Combinatorial Circuits designed using Always Block in Verilog/Systemverilog ? Why not Nonblocking?

Everywhere it is mentioned this as a guideline, but after lot of thought i want to know what harm will it cause if we use Nonblocking statement inside Always Block for Combinatorial also. I won't be mixing the two together. But what i feel is when we use Nonblocking for Combinatorial statements in Always Block it represents the hardware more accurately. Does it not...?

For Example, if we take the following circuit: Small sample circuit diagram

In this diagram when the inputs a,b,c are supplied the outputs x1 and x will not be available instantly. There will be gate delays. first x1 will be available and then x will be available. If we use blocking statements both are available instantly. If we use nonblocking, it resembles the hardware more accurately.

For Example, if we take the following code based on the above diagram

module block_nonblock(output logic x,x1,y,y1,input logic a,b,c);

always@* begin : BLOCKING
    x1 = a & b;
    x  = x1 & c; 
end

always@* begin : NONBLOCKING
    y1 <= a & b;
    y  <= y1 & c; 
end

endmodule

This synthesizes as: RTL Diagram of Non Blocking and Blocking Code

Both are synthesized as And gates, and give same simulation results but when we check for the changes in output in delta time, i feel the Non blocking matches the hardware more accurately as compared to the Blocking.

Also i went through : IEEE P1364.1 / D1.6 Draft Standard for Verilog® Register Transfer Level Synthesis, which specifies the use of non blocking for Sequential modeling but doesn't specify specifically using blocking for Combinational modeling using Always Block. It says don't mix the two(Blocking and Nonblocking) in Combinational statements.

So, shouldn't we use nonblocking for combinational statements in always blocks which are dealing with pure combi logic (non sequential/ no clocks involved)

like image 587
Edwin Joseph Avatar asked Mar 12 '23 18:03

Edwin Joseph


2 Answers

The harm is in simulation; in performance, and in race conditions.

Your NONBLOCKING code executes twice for every change in a or b. Non-blocking assignment updates are scheduled into a later queue of events, and this causes a much bigger rippling effect where blocks get repeatedly executed.

When you simulate RTL code, you are doing so in the absence of physical delays and synthesis tools understand how the logic is going to be implemented. But simulation tools cannot do this and also need to work with non-synthesizable code. They have to execute the code exactly as written. And they also have to deal with massive amounts of concurrency executing code on a processor with a single or limited number of threads. So simulation introduces race condition in software that would not exist in real hardware. Non-blocking assignments are there to prevent those race conditions when writing sequential logic. But they can have the opposite affect if you use them in combinational logic, especially when used in the combinational logic involved in the generation of clocks.

like image 134
dave_59 Avatar answered Apr 29 '23 06:04

dave_59


You ask "So, shouldn't we use nonblocking for combinational statemnts in Sequential?" The answer is No.

If you use non-blocking assignments for combinational logic in clocked always blocks, you will get more flip-flops than you expect. Basically, non-blocking assignments in clocked always blocks will behave like flip-flops when you simulate and infer flip-flops when you synthesise.

So,

1 - use blocking assignments for gates and

2 - use non-blocking assignments for flip-flops.

like image 37
Matthew Taylor Avatar answered Apr 29 '23 06:04

Matthew Taylor