I know people who swear by blocking and some who swear by non-blocking.
So here are some thoughts.
There is very little difference between non-blocking and blocking in speed and no errors if done correctly either way.
The main differences are:
Some people like non-blocking because you can tell that a reg on the left hand side of <= is going to be a flip flop after synthesis.
/* example 1a */
reg a,b,c;
always @(posedge clock)
begin b <= a;
/* b and c will be flip flops */
c <= b;
end
/* example 1b */
reg a,b,c;
always @(posedge clock)
begin
c <= b;
b <= a;
/* b and c will be flip flops */
end
/* example 2a */
reg a,b,c;
always @(posedge clock)
begin
b = a;
c = b;
/* Only c will be a flip flop,b will go away after synthesis. */
/* We could delete the 2 above assignments and replace it with c=a;b=a; In fact, b is the same as c and can be eliminated.*/
end
/* example 2b */
reg a,b,c;
always @(posedge clock)
begin
c = b;
b = a;
/* Both b and c will be flip flops, because these 2 lines are reversed.*/
end
Example 1a, 1b and 2b are functionally the same.
Example 2a is functionally different from 2b just because the order of the statements.
Some people like blocking because it takes less memory in the simulator.
/* example NON-BLOCKING_MEMORY */
reg a,b,c;
always @(posedge clock)
begin
/* b will require 2 memory locations*/
b <= a;
/*<---because this b memory location will hold value of a */
c <= b;
/*<---and this b memory location will hold value of b before the posedge*/
end
/* example BLOCKING_MEMORY */
reg a,b,c;
always @(posedge clock)
begin
// b will require ONLY 1 memory location
c = b;
b = a;
end
Note that I am talking about SIMULATOR memory, not flip-flop count after synthesis. In most cases, the simulator has to remember the value before and after posedge clock if a reg goes between modules in order in order to "execute modules in parallel", so there may be no savings.
Some people like blocking because you can see sharing of resources more readily.
// example 5
reg [15:0] a,b,c,d,e,f,j,k,g,h;
reg [16:0] x,y,z;
always @(posedge clock)
begin
x = a + b + c + d + e + f + j + k;
y = x + g;
z = x + h;
end
// example 6
reg [15:0] a,b,c,d,e,f,j,k,g,h;
reg [16:0] y,z;
always @(posedge clock)
begin
y <= (a + b + c + d + e + f + j + k) + g;
z <= (a + b + c + d + e + f + j + k) + h;
end
Even the cheapest synthesizer should share adder logic in example 5, but a slightly smarter synthesizer is required in example 6.
You will have fewer problems with race conditions in SIMULATION if you always use non-blocking assignments inside always @(posedge clock) blocks where you want to have flip-flops.
file xyz.v :
module xyz(a,b,clk);
input b,clk;
output a;
reg a;
always @(posedge clk)
a = b;
endmodule
file abc.v :
module abc(b,c,clk);
input c, clk;
output b;
reg b;
always @(posedge clk)
b = c;
endmodule
Some of the simulators out there will execute module abc first and then module xyx.
This effectively transfers contents of c to a in ONE clk cycle. This is what some people refer to as a simulator race conditon. Other simulators will execute module xyz and then module abc giving a different simulation result. In some simulators, order of execution cannot be controlled by users.
Post a Comment
1Comments
Your comments will be moderated before it can appear here. Win prizes for being an engaged reader.
Post a Comment
Nice examples.
ReplyDeleteI have seen people asking situations of only race conditions in verilog assignments. This is comprehensive in the sense that both simulator and synthesizer are discussed.
Great job!