blocking assignment in a block

Guest
Hi

I'm trying deduce a rule that would correctly produce same behavior for
synthisis and simulation. Here is what I come up with. Please comment.

reg a,b,c,d,e,f,....;
always @(posedge clk)
statement1;
statement2;
statement3;
.......
end

Now assume all the statements are simple 3 regs assignment like
a=b+c;
b=3+c;
c=2;
d=a+c;
....
....

Now is it true, so long as the "left hand sides" do not repeat like:
a=b+c;
a=3+c;
I would get correct and same behavior from both simulation and
synthesis?

Thanks.
 
glen herrmannsfeldt wrote:
John_H wrote:

"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:d29vdv$ttq$1@gnus01.u.washington.edu...

paulw@mmail.ath.cx wrote:

snip

You should also not change any variables used later in the same
block.

a=b+c;
d=a+b;

Why not?
Blocking and non-blocking operators should both be synthesizeable.
Simulation and synthesis results should match.

It's *typical* for the designer to produce always blocks without
the
blocking operator so everything has a previous-state/next-state
relationship
at the clock edge. When blocking operators are used in this
(@posedge clk)
blocks, the results tend not to be as expected, at least to the
engineer
debugging the code later.

I think you are right, but it will at least be confusing to
people. I pretty much always use non-blocking assignment, but
still put the statements in order, such that later ones don't
use regs changed earlier. Partly that comes from writing C code
with similar function.

-- glen

What would happed if using regs changed earlier? synch and simulation
mismatch? Thanks.
 
John_H wrote:
paulw@mmail.ath.cx> wrote in message
news:1112136777.540743.317340@g14g2000cwa.googlegroups.com...

snip

What would happed if using regs changed earlier? synch and
simulation
mismatch? Thanks.

Don't use regs changed earlier !!

For synthesizeable logic, non-blocking operators where a reg is
assigned in
one always block is the way to go.
In simulation where synthesis isn't expected, changing a reg at
discrete
points in time is great - just don't try to change the reg in
multiple
blocks at the same time.
Let's make this easy for me. What if I have only one always block in
the enitre module. Is will no longer be a problem then? Ie. I can use
regs changed earlier, so long as I don't change the same reg twice.
Right? And for goodness sake, don't seperate simulation and synthesis,
no one want two kind of behaviors. We know no circuit can be clocked
beyond a certain speed and be expected to work. <-- No matter how
correct your design is. All we want is that it will work for both
simulation and synthesis, at clock rate low enough.!! Thanks.
 
Jonathan Bromley wrote:
On 30 Mar 2005 01:50:18 -0800, paulw@mmail.ath.cx wrote:

Let's make this easy for me.

At present, you seem to be making it quite hard for yourself :)

What if I have only one always block in the enitre module.
Is will no longer be a problem then? Ie. I can use regs
changed earlier, so long as I don't change the same reg twice.

As someone's already said, simulation and synthesis WILL match
because that's what synthesis tools do - they build logic with
the same behaviour as the simulation behaviour of your Verilog.
Sometimes you can write Verilog for which the synth tool can't
build equivalent logic, and it will then complain to you.

HOWEVER, it is very easy to make race conditions in Verilog.
These race conditions have a direct equivalent in hardware:
they correspond to hold time violations. Simulation will
show you just one of the possible outcomes of the race
condition; it may or may not be the same outcome as you get
in the synthesised hardware. This, of course, is a Bad Thing.
It is not a simulation/synthesis mismatch; it is an
indeterminacy in the Verilog description, and the
indeterminate results that you see in simulation may differ
from the indeterminate results you see in hardware.

Avoiding these race conditions is almost as easy as making them.
The golden rule for synthesisable code:

In a clocked "always", use NONBLOCKING assignment to write
to any variable whose value is used outside the "always".

Elaborating on that golden rule, with a few cases that
sometimes cause confusion:

Variables used only within the "always" can be written
with either blocking or nonblocking assignment (but not
a mixture of the two!) as you please - the effects will
be different, but in both cases the effects will be
entirely predictable and there will be neither race
conditions nor simulation/synthesis mismatches.

A variable whose value goes to an output port of the
module is, of course, a 'variable whose value is used
outside the "always"'. So any such variable MUST be
written using nonblocking assignment.

Combinational "always" blocks should use blocking
assignment in any case.

Now, let's go back to your "using a reg that was changed
earlier". It's probably best to look at a specific
example....

// primary inputs: clk, a, b, c
// local variables: reg v
// primary output: reg r
//
always @(posedge clk) begin
v = a & b;
if (c) v = ~v;
r <= v;
end

I've changed "v" twice. This is OK! "v" is a temporary
variable representing intermediate stages in a calculation.
In the synthesised hardware there will be two quite separate
places corresponding to "v": the output of the AND gate for
v = a & b;
and the output of an XOR gate for
if (c) v = ~v;
The result is a single flip-flop "r" whose D input is fed with
the Boolean expression ((a & b) ^ c).

Note, however, that I am obliged to use a NONBLOCKING assignment
to "r" because it's a primary output that will be used in
other parts of the code. No excuses. Don't even think about
making blocking assignment to "r".

As a thought-experiment (and for synthesis and simulation too)
consider how my "always" block would behave if I were to use
nonblocking assignment throughout. It is still a completely
valid piece of code (although it probably needs a reset now):

always @(posedge clk) begin
v <= a & b;
if (c) v <= ~v;
r <= v;
end

Now we have two flip-flops "v" and "r". The D input of "v"
is fed with the expression

((a & b) & ~c) | (c & ~v)

Note that the flip-flop's output is used in this expression;
that's OK of course. The D input of "r" is connected to the
output of flip-flop "v".

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

Just don't EVER write to primary outputs of a clocked "always"
using blocking assignment. Never. Not even on feast-days.
Not even if you think your "always" block is the only one in
the world - perhaps it is today, but it won't be tomorrow.
--
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.bromley@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.

Thank you Jonathan. This is what I needed. Most of my circuit will be
lots of temporary regs with very little input and output. So all I need
to take care are when interfacing input and output. Thanks again.
 
plugh wrote:
On Wed, 30 Mar 2005 17:09:37 +0100, Jonathan Bromley wrote:

On 30 Mar 2005 05:42:09 -0800, paulw@mmail.ath.cx wrote:
Most of my circuit will be
lots of temporary regs with very little input and output. So all I
need
to take care are when interfacing input and output.

Gulp....

Gulp indeed. Especially if you're investing $1/2M or more to see if
your
ASIC will work right.
If you are interfacing multi-gigia-bit device or bus, then you need to
know each clock what you module is doing... Actually, every interfacing
requires thought, however slow...

You don't need million dollars to prove a design concept, an fpga board
would do. The difference in speed is at best 100 times.

Let's assume my module (chip) has only one input wire, and one output
wire, plus one clock, and one reference ground. That's 4 wires, and
that's all there is to say about digital design... If I am adventurous,
I can start thinking about asyncronous design within... One does not
have to make every combination of mistakes to succeed. Well, most
people do. :)
 
If you are interfacing multi-gigia-bit device or bus, then you need
to
know each clock what you module is doing... Actually, every
interfacing
requires thought, however slow...
I sometimes find that, I have to clarify myself.
I am only doing number crunching within my module. Not worry about IO
right now. It can be serialized to 1 input and 1 output later. or bus.
Ie, my application is algorithmic, not your high speed IO stuff.

You don't need million dollars to prove a design concept, an fpga
board
would do. The difference in speed is at best 100 times.

Let's assume my module (chip) has only one input wire, and one output
wire, plus one clock, and one reference ground. That's 4 wires, and
that's all there is to say about digital design... If I am
adventurous,
I can start thinking about asyncronous design within...
You only need clock, when you are interfacing with clocked device--
which is every degital design today :) In theory, you can have an
asyncronous design inside without any clock, and only a small part
that's clocked to interface with outside world.

One does not
have to make every combination of mistakes to succeed. Well, most
people do. :)
Don't mean to be cheeky here. I've made enough mistakes to ask the
questions I asked.
 

Welcome to EDABoard.com

Sponsor

Back
Top