Mixed Blocking/Nonblocking assignments

A

ARH

Guest
Is it true to use mixed Blocking and Nonblocking assignments in the
same always block ?

I have found this verilog code in SystemC 2.0 User's Guide at page
191:
http://www.cse.iitd.ernet.in/~cs5030223/UserGuide20.pdf

//////////////////////////////////////////////////////////////////////////////////////////////
module dffa(clock, reset, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (reset)
dout <= 1’b0; //nonblocking assignment
else
dout = din; // blocking assignment
end
endmodule
/////////////////////////////////////////////////////////////////////////////////////////////////

But one of the Coding style in the famous paper for nonblocking
assigment mentioned as follow:
Guideline #5: Do not mix blocking and nonblocking assignments in the
same always block.
http://csg.csail.mit.edu/6.375/papers/cummings-nonblocking-snug99.pdf
 
ARH wrote:
Is it true to use mixed Blocking and Nonblocking assignments in the
same always block ?
It's true that I do it.
It's true that most don't.
http://groups.google.com/groups/search?q=%22single+always+block%22+Cliff+hits+nail

-- Mike Treseler
 
ARH wrote:
Is it true to use mixed Blocking and Nonblocking assignments in the
same always block ?

I have found this verilog code in SystemC 2.0 User's Guide at page
191:
http://www.cse.iitd.ernet.in/~cs5030223/UserGuide20.pdf

//////////////////////////////////////////////////////////////////////////////////////////////
module dffa(clock, reset, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (reset)
dout <= 1’b0; //nonblocking assignment
else
dout = din; // blocking assignment
end
endmodule
/////////////////////////////////////////////////////////////////////////////////////////////////

But one of the Coding style in the famous paper for nonblocking
assigment mentioned as follow:
Guideline #5: Do not mix blocking and nonblocking assignments in the
same always block.
http://csg.csail.mit.edu/6.375/papers/cummings-nonblocking-snug99.pdf

It's not against the rules to mix. It's prudent to avoid mixing them.
Also, you'll find that many synthesizers won't allow you to mix them.
-Kevin
 
Kevin Neilson wrote:

It's not against the rules to mix. It's prudent to avoid mixing them.
Also, you'll find that many synthesizers won't allow you to mix them.
Really?
Which one.

-- Mike Treseler
 
On May 7, 11:59 pm, Mike Treseler <mike_trese...@comcast.net> wrote:
Kevin Neilson wrote:
It's not against the rules to mix. It's prudent to avoid mixing them.
Also, you'll find that many synthesizers won't allow you to mix them.

Really?
Which one.

-- Mike Treseler

Take a brief look at the content of " Nonblocking Assignments in
Verilog Synthesis, Coding Styles That Kill!" about this topic:

module ba_nba6 (q, a, b, clk, rst_n);
output q;
input a, b, rst_n;
input clk;
reg q, tmp;

always @(posedge clk or negedge rst_n)
if (!rst_n) q = 1'b0; // blocking assignment to "q"
else begin
tmp = a & b;
q <= tmp; // nonblocking assignment to "q"
end
endmodule

Above example will most likely simulate correctly most of the time,
but Synopsys tools will report a syntax error because the blocking
assignment is assigned to the same variable as one of the nonblocking
assignments. This code must be modified to be synthesizable.
 
On May 7, 11:13 pm, Kevin Neilson
<kevin_neil...@removethiscomcast.net> wrote:
ARH wrote:
Is it true to use mixed Blocking and Nonblocking assignments in the
same always block ?

I have found this verilog code in SystemC 2.0 User's Guide at page
191:
http://www.cse.iitd.ernet.in/~cs5030223/UserGuide20.pdf

//////////////////////////////////////////////////////////////////////////////////////////////
module dffa(clock, reset, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (reset)
dout <= 1’b0; //nonblocking assignment
else
dout = din; // blocking assignment
end
endmodule
/////////////////////////////////////////////////////////////////////////////////////////////////

But one of the Coding style in the famous paper for nonblocking
assigment mentioned as follow:
Guideline #5: Do not mix blocking and nonblocking assignments in the
same always block.
http://csg.csail.mit.edu/6.375/papers/cummings-nonblocking-snug99.pdf

It's not against the rules to mix. It's prudent to avoid mixing them.
Also, you'll find that many synthesizers won't allow you to mix them.
-Kevin

Yes, of course, but I was refer it from part of a code from a SystemC
2.0 User's Guide which was wrote by Experts in OSCI, I just want to
know is it a simple mistake or there are any idea behind it.

Regards
ARH
 
Kevin wrote:

Also, you'll find that many synthesizers won't allow you to mix them.
Mike wrote:
Really?
Which one.

ARH wrote:
Above example will most likely simulate correctly most of the time,
but Synopsys tools will report a syntax error because the blocking
assignment is assigned to the same variable as one of the nonblocking
assignments. This code must be modified to be synthesizable.
That would be an appropriate error.
I understood Kevin to mean that some synthesizer disallows all such
assignments. This is not the case for quartus, xst or mentor.

-- Mike Treseler
 
ARH <haghdoost@gmail.com> writes:

Yes, of course, but I was refer it from part of a code from a SystemC
2.0 User's Guide which was wrote by Experts in OSCI, I just want to
know is it a simple mistake or there are any idea behind it.

Regards
ARH
Assigning a non-blocking and a blocking assignment to the same variable
is generally quite bad style because it increases the possiblities of
races, glitches, and other nasty behaviours (upto the synthesized code
doing something different than the simulated code, which is the worst
thing of all in my book). Moreover, some of these effects are
simulator and synthesizer dependent, meaning you are potentially
writing non-portable code.

However, to answer your more important question, in the example
provided it is probably a typographical error. I have never seen a
case where mixing blocking and non-blocking assignments to the same
variable on different legs of an if serves any useful purpose. Either
the code works with both assignments one of the two directions or the
simulated code has an artifact that is likely not supported portably
by all synthesizers.

In particular, if one uses a non-blocking assignment, the semantics of
Verilog generally describe a flop (or some other kind of register).
In conrast, a blocking assignment has semantics more approriate to
combinatorial code without a clocked element. Now, these are general
statements and not strictly true, e.g. one can desicribe blocks that
are flops using blocking assignments and vice-versa, so some typos
don't matter and you can use the "wrong" type of assignment and get
correctly syntehsized results. Still, a variable is probably either
clocked or not, and you should use the type of assignment which
represents its usage for most reliable results.

Hope this helps,
-Chris

******************************************************************************
Chris Clark Internet: christopher.f.clark@compiler-resources.com
Compiler Resources, Inc. or: compres@world.std.com
23 Bailey Rd Web Site: http://world.std.com/~compres
Berlin, MA 01503 voice: (508) 435-5016
USA fax: (978) 838-0263 (24 hours)
------------------------------------------------------------------------------
 
Mike Treseler wrote:
Kevin Neilson wrote:

It's not against the rules to mix. It's prudent to avoid mixing them.
Also, you'll find that many synthesizers won't allow you to mix them.

Really?
Which one.

-- Mike Treseler
Synplify gives me an error if I mix blocking and nonblocking assignments
in the same process.

One moment--I just looked this up in the Synplify documentation, and it
actually says you can't use blocking and nonblocking for the same
register. So perhaps you can mix them in the same process as long as
you don't for the same reg.

-Kevin
 
However, to answer your more important question, in the example
provided it is probably a typographical error. I have never seen a
case where mixing blocking and non-blocking assignments to the same
variable on different legs of an if serves any useful purpose. Either
the code works with both assignments one of the two directions or the

Hope this helps,
-Chris
------------------------------------------------------------------------------
Thanks Chris, I have similar idea about this error in SystemC 2.0
official documentations, but I didn't sure about it. So I should point
it in SystemC forum for correction in the future releases. But isn't
it strange if this guide have a error and no one see it since 2002 ?

Regards
-ARH
 
On Wed, 7 May 2008 09:59:25 -0700 (PDT),
ARH <haghdoost@gmail.com> wrote:


I have found this verilog code in SystemC 2.0 User's Guide at page
191:
http://www.cse.iitd.ernet.in/~cs5030223/UserGuide20.pdf

//////////////////////////////////////////////////////////////////////////////////////////////
module dffa(clock, reset, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (reset)
dout <= 1’b0; //nonblocking assignment
else
dout = din; // blocking assignment
end
endmodule
It's a typo; as simple as that. Both assignments should
be nonblocking. No doubt, no argument.

I hate to harp on and be boring and all that stuff, but
this issue is really, really simple and people seem to
make a big deal about it when there's no need. I and
others have chewed over this issue at great length here
and elsewhere, but the same old canards keep on coming up:

CANARD #1: Nonblocking assignment implies a flop.
~~~~
Nope. See below.

CANARD #2: You shouldn't ever use blocking assignment in
a clocked always block.
~~~~
Nope. See below. This one is especially pernicious because
it has received a "seal of approval" from one throwaway (and,
I believe, self-evidently wrong) comment in an otherwise
excellent, authoritative and widely-quoted paper by Cliff
Cummings.

CANARD #3: Blocking assignment implies combinational logic.
~~~~
Nope. See below.


THE ONLY RULES THAT MATTER for synthesis are...

1) In a Verilog clocked always block, you must NEVER use
blocking assignment to write to a variable that will be
read (used) in any other block clocked by the same clock.
Failure to observe this rule will yield mysterious
read/write races and consequent mismatches between
simulation and synthesis.

2) In a Verilog clocked always block, you must NEVER
mix blocking and nonblocking assignment to the same
variable. Failure to observe this rule will confuse
the hell out of synthesis tools, and quite right too.

~~~~~~~~~~~~

There are also some RECOMMENDATIONS - not rules - that
will make it easier to reason about what you are doing,
and are very strongly urged on beginners to keep them
out of trouble:

a) Use nonblocking assignments ONLY in clocked always
blocks, nowhere else. In combinational logic there is
generally no need for nonblocking assignments; if you
need to use them, you've almost certainly got a sensitivity
list wrong, or perhaps you've mistakenly created
combinational feedback. Note that nonblocking assignment
in a combinational block does NOT imply storage.

b) It is easier to reason about your clocked logic if
you use only nonblocking assignments in it. Registers
thus assigned-to are sure to imply flops. Registers
written using blocking assignment may or may not imply
flops depending on how you used them. You can exploit
this to do various creative things, and ALL credible
synthesis tools support such use, but it takes a good
level of understanding of synthesis to be able to do it
with confidence.

Of course, when writing testbench code these "rules"
are no longer so important and you can do anything you
want; and, of course, that brings with it a burden of
understanding.

So, please, please, no more speculation... it's easy.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Kevin Neilson wrote:
(snip)

One moment--I just looked this up in the Synplify documentation, and it
actually says you can't use blocking and nonblocking for the same
register. So perhaps you can mix them in the same process as long as
you don't for the same reg.
Using one each for the two halves of an if-then-else is
just weird. Actually, I might not believe that for an
asynchronous reset. Hmmm.

(from another post)

module dffa(clock, reset, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (reset)
dout <= 1’b0; //nonblocking assignment
else
dout = din; // blocking assignment
end
endmodule

Of course asynchronous reset isn't a good idea, but I am
not sure I believe this should be illegal. On the other hand,


module dffa(clock, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (din)
dout <= 1’b1; //nonblocking assignment
else
dout = 1’b0; // blocking assignment
end
endmodule

now, that is just weird.

-- glen
 
Chris F Clark wrote:
(snip)

In particular, if one uses a non-blocking assignment, the semantics of
Verilog generally describe a flop (or some other kind of register).
In conrast, a blocking assignment has semantics more approriate to
combinatorial code without a clocked element. Now, these are general
statements and not strictly true, e.g. one can desicribe blocks that
are flops using blocking assignments and vice-versa, so some typos
don't matter and you can use the "wrong" type of assignment and get
correctly syntehsized results. Still, a variable is probably either
clocked or not, and you should use the type of assignment which
represents its usage for most reliable results.
But an asynchronous reset to a FF is not clocked logic!

(and also I agree that the statements aren't strictly true.)

-- glen
 
On May 8, 11:25 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
Of course asynchronous reset isn't a good idea, but I am
not sure I believe this should be illegal. On the other hand,

module dffa(clock, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (din)
dout <= 1’b1; //nonblocking assignment
else
dout = 1’b0; // blocking assignment
end
endmodule

now, that is just weird.

-- glen
Hi Glen

According to Jonathan's post, your code isn't true because it still
have mixed assignment. did you think there is different between
assigning Logic Bits and signals to "dout" ? you clearly delete
asynchronous reset functionality in this code and I think it isn't
equivalent with my one !
 
On May 8, 11:25 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
Kevin Neilson wrote:

(snip)

One moment--I just looked this up in the Synplify documentation, and it
actually says you can't use blocking and nonblocking for the same
register. So perhaps you can mix them in the same process as long as
you don't for the same reg.

Using one each for the two halves of an if-then-else is
just weird. Actually, I might not believe that for an
asynchronous reset. Hmmm.

(from another post)

module dffa(clock, reset, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (reset)
dout <= 1’b0; //nonblocking assignment
else
dout = din; // blocking assignment
end
endmodule

Of course asynchronous reset isn't a good idea, but I am
not sure I believe this should be illegal. On the other hand,

module dffa(clock, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (din)
dout <= 1’b1; //nonblocking assignment
else
dout = 1’b0; // blocking assignment
end
endmodule

now, that is just weird.

-- glen
Hi Glen

According to Jonathan's post, your code isn't true because it still
have mixed assignment. did you think there is different between
assigning Logic Bits and signals to "dout" ? you clearly delete
asynchronous reset functionality in this code and I think it isn't
equivalent with my one !

--ARH
 
ARH wrote:
(I posted)

module dffa(clock, din, dout);
input clock, reset, din;
output dout;
reg dout;
always @(posedge clock or reset)
begin
if (din)
dout <= 1’b1; //nonblocking assignment
else
dout = 1’b0; // blocking assignment
end
endmodule

According to Jonathan's post, your code isn't true because it still
have mixed assignment. did you think there is different between
assigning Logic Bits and signals to "dout" ? you clearly delete
asynchronous reset functionality in this code and I think it isn't
equivalent with my one !
Yes, this is different and maybe should be illegal.

Asynchronous reset is fundamentally different from clocked
logic, so should not be illegal.

I was trying to show two different ways to mix the assignment
operators. Though my preference is to use continuous assign
except for registers.

Also I would have to check the references, but I thought that
the only difference was internal to an always block.
Some posts seemed to disagree with that.

-- glen
 
On May 8, 2:27 am, ARH <haghdo...@gmail.com> wrote:
Take a brief look at the content of " Nonblocking Assignments in
Verilog Synthesis, Coding Styles That Kill!" about this topic:

module ba_nba6 (q, a, b, clk, rst_n);
 output q;
 input a, b, rst_n;
 input clk;
   reg q, tmp;

   always @(posedge clk or negedge rst_n)
        if (!rst_n) q = 1'b0; // blocking assignment to "q"
        else begin
          tmp = a & b;
          q <= tmp; // nonblocking assignment to "q"
   end
endmodule

Above example will most likely simulate correctly most of the time,
but Synopsys tools will report a syntax error because the blocking
assignment is assigned to the same variable as one of the nonblocking
assignments. This code must be modified to be synthesizable.
This is a poor example to use. The problem is with the non-blocking
assign to q in the reset clause. The non-blocking assign to tmp is
completely OK.
 
sndbndr@gmail.com wrote:

On May 8, 2:27 am, ARH <haghdo...@gmail.com> wrote:

Take a brief look at the content of " Nonblocking Assignments in
Verilog Synthesis, Coding Styles That Kill!" about this topic:

module ba_nba6 (q, a, b, clk, rst_n);
output q;
input a, b, rst_n;
input clk;
reg q, tmp;

always @(posedge clk or negedge rst_n)
if (!rst_n) q = 1'b0; // blocking assignment to "q"
else begin
tmp = a & b;
q <= tmp; // nonblocking assignment to "q"
end
endmodule

Above example will most likely simulate correctly most of the time,
but Synopsys tools will report a syntax error because the blocking
assignment is assigned to the same variable as one of the nonblocking
assignments. This code must be modified to be synthesizable.
Maybe, but I don't see any reason it can't be synthesized.

To me, the real difference between blocking and non-blocking
comes when a reg is assigned and referenced in the same block.
(That is, both left and right sides of an assignment.)
That doesn't occur here.

This is a poor example to use. The problem is with the non-blocking
assign to q in the reset clause. The non-blocking assign to tmp is
completely OK.
I agree. Especially since it does an asynchronous reset.

It gets complicated if reset and clock occur on the same edge,
but that complicates real logic, too.

Also, if I do write blocking assignment, I always write them
in the reverse order such that no reg is used after it is
changed. That is, the way one would do it in C.


-- glen
 
glen herrmannsfeldt wrote:
To me, the real difference between blocking and non-blocking
comes when a reg is assigned and referenced in the same block.
(That is, both left and right sides of an assignment.)
That doesn't occur here.
Another real difference is when reg is assigned in one block and
referenced in another, when both both blocks are sensitive to same clock
(e.g., a pipeline). With blocking assignment, the reading block, on
same cycle, could see either the old or new. With non-blocking, the
reader always sees old value, as desired. While they could synthesize
the same, blocking assignments can cause simulation / synthesis mismatches.

-- Bill
 
Bill Warner wrote:

glen herrmannsfeldt wrote:

To me, the real difference between blocking and non-blocking
comes when a reg is assigned and referenced in the same block.
(That is, both left and right sides of an assignment.)
That doesn't occur here.

Another real difference is when reg is assigned in one block and
referenced in another, when both both blocks are sensitive to same clock
(e.g., a pipeline). With blocking assignment, the reading block, on
same cycle, could see either the old or new. With non-blocking, the
reader always sees old value, as desired. While they could synthesize
the same, blocking assignments can cause simulation / synthesis mismatches.
Are you sure about that? I was writing verilog for a while before
I even learned about non-blocking assignment and never had that
problem. At that point I only put one register per module
(mostly structural model except for registers).

Looking at Sternheim & Singh, all the example code uses blocking
assignment. I don't see any discussion that this could be
a problem.

Do you have any examples of legal verilog code with multiple
clocked always blocks that evaluate in the wrong order?

There might be cases with non-clocked (combinatorial) always
blocks, but in that case, as with continuous assignment,
the block/assignment will be executed again in the same time
step if needed. As far as I know, that isn't true for
clocked always blocks. In hardware terms, registers have
zero hold time such that any data changed during a clock
cycle are not used as input to other registers (in different
always blocks) in the same clock cycle.

-- glen
 

Welcome to EDABoard.com

Sponsor

Back
Top