I have a question regarding verilog assignment, nonblocking
versus blocking. Whenever a flip-flop is implied, a
D-flip-flop is coded as:
always @(posedge clock) dout <= din;
I've TA'd digital design courses, so I have enough
background that this seems quite natural. The nonblocking
assignment schedules the update of dout at the end of the
current delta-cycle. Granted, the notion of delta-cycles in
verilog isn't as explicit as in SystemC, it is still
implied. This is because any changes caused by updates from
nonblocking assignments can trigger additional processses,
in effect starting another delta-cycle at the same
simulation time as the current delta-cycle.
I started to question my understanding after seeing a
verilog example in the SystemC 2.0 User Guide.
Specifically, it is the 2nd last example, which deals with a
state machine for a fictitious voice-mail system. As with
the archetypal synchronous state machine, some combinational
logic generates next_state, which propagates to
current_state at every rising clock edge.
always@(posedge clk) current_state = next_state;
Here's the confusion: The assignment is blocking. I
compared it to the SystemC implementation (which I won't
duplicate here) and conceptually, it does the same thing.
Furthermore, based on my rather fresh grasp of SystemC, it
does the right thing (not surprising, since it is the
SystemC User Guide). The natural question that arises is
why it wouldn't do the right thing in verilog (most
propagation from inputs to outputs of flip-flops use
nonblocking assignment), considering that the implied
scheduling of updates is identical. My conclusion is that
the above *does* work in verilog.
Why, then, the sacredness of using nonblocking for
flip-flops? The reason for this question is more than just
a pondering. If there is a reason for that practice,
perhaps it should be mirrored when I go about mucking with
SystemC code. That is, if the reason is to ensure proper
behaviour in cases that are not as clear-cut as above, or
even if it's just a self-documentation practice i.e.
nonblocking assignments have come to mean D-flip-flop. If
the reason is the latter, then the merit of mirroring the
practice in my SystemC coding should be weighed against any
speed penalties. I'm not all that familiar with the best
practices in SystemC yet, but I imagine there is some
overhead with nonblocking, since it requires a scheduling of
the update somewhere upstream in time.
Thanks for any comments.
Fred
--
Fred Ma
Dept. of Electronics, Carleton University
1125 Colonel By Drive, Ottawa, Ontario
Canada, K1S 5B6
[...]
>
>Why, then, the sacredness of using nonblocking for
>flip-flops?
Like many sacred things, it's a grotesque
oversimplification by a certain part of the elite
in order to keep the average Joe from catching
up with them :-)
There is a VERY good reason for using nonblocking
assignment (NBA) to any flipflop whose value will
be used OUTSIDE the 'always' block in which it is
assigned. It makes for predictable synchronous
behaviour. In effect it gives every flipflop a
clock-to-output delay of one delta, in an RTL model
in which all flipflops have zero hold time. Without
NBA you have flipflops with zero clock-to-output delay
and zero hold time, which of course is a recipe for
disaster.
However, there is also a very good reason for using
blocking assignment to flipflops, PROVIDED that you
can guarantee that the value of such flipflops will
NEVER be used outside their assigning 'always' block.
In VHDL this is easy: any assignment to a signal is
nonblocking, and any assignment to a variable is
zero-delay blocking; variables are 100% invisible
outside the process in which they are declared.
In Verilog, it's impossible to enforce in principle,
although in practice it's OK if you use only locally
declared registers in a named begin...end, since
synthesis generally won't accept hierarchical
references - consequently, locally declared registers
in a named block are effectively invisible from outside.
Blocking assignment to local variables can be very
useful both to create intermediate terms in combinational
logic, and to create flipflops that are used only
locally within the always blocks - for example, it's
my preferred way to create a state register, which I
want to use inside a state machine, but don't want to
expose to the rest of the design. However, it's not
trivial to establish a design pattern that allows you
to use local variables with confidence.
Unfortunately, the high priesthood of nonblocking
assignment has got there before me and effectively
outlawed these techniques. At least one top-end
synthesis tool (when I last checked a few months
ago) does not permit it, and the OpenMORE RTL
coding style standard also outlaws it. And you will
find plenty of training material, appnotes and coding
style recommendations that tell you never to do it.
I have a plan to publish some notes about this on
our website, but it all takes time...
I can't comment on your extrapolation to SystemC,
but you are certainly correct to say that NBA implies
some overhead in simulation because it performs some
scheduling, whereas blocking assignment is simply the
act of dropping a value into a variable. Except that,
of course, in Verilog it isn't that easy because
someone might be waiting on a change of that variable.
--
Jonathan Bromley, Consultant
DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services
Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan...@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com
The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
If you have
always @(posedge clock) d1 = d0 ;
always @(posedge clock) d2 = d1 ;
there is a race condition.
It is indeterminate which of the two will execute first.
If d1=d0 executes first, then d2 will be assigned d0 on the same clock.
If d2=d1 executes first, then d2 will be assigned d0 after a one-clock delay.
The second possibility is what you want.
Nonblocking assignments ensure that delay.
Shalom
Fred Ma wrote:
--
Shalom Bresticker Shalom.B...@motorola.com
Design & Reuse Methodology Tel: +972 9 9522268
Motorola Semiconductor Israel, Ltd. Fax: +972 9 9522890
POB 2208, Herzlia 46120, ISRAEL Cell: +972 50 441478
[x]Motorola General Business Information
[ ]Motorola Internal Use Only
[ ]Motorola Confidential Proprietary
The implied scehduling of updates between blocking and non-blocking
assignments is *not* identical. As you mentioned, the non-blocking
update is guaranteed to happen one "delta-cycle" later. The wording
of the standard guarantees that non-blocking assignments don't get
into certain race conditions (because the update happens after the
evaluation). Therefore, it is simplest to always use an nba and not
think about whether the races can occur. It is more likely to match
what the circuit actually does, since in real-life the ciruits have
non-instantaneous actions (e.g. it takes a capacitor a certain time to
fill).
Hope this helps,
-Chris
*****************************************************************************
Chris Clark Internet : com...@world.std.com
Compiler Resources, Inc. Web Site : http://world.std.com/~compres
23 Bailey Rd voice : (508) 435-5016
Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)
------------------------------------------------------------------------------
Fred Ma wrote:
> Hello,
>
> I have a question regarding verilog assignment, nonblocking
> versus blocking. Whenever a flip-flop is implied, a
> D-flip-flop is coded as:
>
> always @(posedge clock) dout <= din;
[...]
> Thanks for any comments.
>
> Fred
Cliff Cummings has a couple of very good papers on blocking versus
nonblocking assignments in verilog.
You can probably find them on John Cooley's ESUNG page or at:
http://www.sunburst-design.com/papers/
Mihai
Thanks for your clarifications. I just lost sight of something they
teach in every(?) beginner's verilog course.
Fred
--
Fred Ma
Dept. of Electronics, Carleton U.
Ottawa, Ontario, Canada