Re: Section 5.3 Modeling level-sensitive storage devices

Jayaram Bhasker (jbhasker@Cadence.COM)
Wed, 24 Feb 1999 16:37:52 -0500 (EST)

Shalom:

Thanks for your feedback. See meeting minutes for resolutions.

- bhasker

----- Begin Included Message -----

X-Authentication-Warning: server.eda.org: majordom set sender to owner-vlog-synth@eda.org using -f
Comments: ( Received on motgate.mot.com from client pobox.mot.com, sender shalom@msil )
Date: Mon, 22 Feb 1999 11:27:34 +0200
From: shalom@msil.sps.mot.com (Shalom Bresticker)
To: vlog-synth@eda.org
Subject: Section 5.3 Modeling level-sensitive storage devices
X-Sun-Charset: US-ASCII
Sender: owner-vlog-synth@eda.org
Content-Type: text
Content-Length: 4970

I have not had time to review the draft document in detail,
but I do want to submit what I feel is an important input regarding latch modelling.

First, though, a different comment:

Section 5.3 says that

"a level-sensitive storage device may be modeled ... when all the following apply:
...
2. There are executions of the always statement in which the value of the variable is read before its assignment."

That does not sound right,

Jayaram Bhasker submitted the following wording in October:

" 2. There are executions of the always statement in which there is no explicit
assignment to the variable."

That sounds much more correct.

But mainly I want to discuss modeling latches with blocking vs. non-blocking assignments.

A recent project of ours encountered a race in Verilog simulation in a case
where the output of a transparent latch feeds the input of an
edge-triggered flip-flop. The race does not exist in reality,
but only in simulation.

If we have the following:

always @(clk or in)
if (clk)
latch_out = in ;

always @(posedge clk)
ff_out <= latch_out ;


Note that the flip-flop is written with a non-blocking assignment (<=)
whereas the latch is written with a blocking assignment. This is what causes
the race.

The explanation is:

When clk rises from 0 to 1, both always blocks are triggered.
If the first always block, the latch, is triggered first, then
latch_out is updated immediately.

When the second always block, the flip-flop, is executed,
the sampled input data, latch_out, has already changed,
and the new value of latch_out is used instead of the old value.

If the second always block is triggered first, then this does not occur.
The simulator is free to execute the always block in any order,
so the behavior is non-deterministic.

The output of synthesis is OK, a latch and a flip-flop.
Formal verification tools also understand the logic correctly.

As far as simulators are concerned, VCS executed the code as intended (which is why the
problem was not detected immediately), but Verilog-XL did not.
In principle, however, it could have been the opposite.

Note that the Verilog language definition permits both possibilities.
Both are legal and equally legitimate.

The problem occurs not because of the blocking assignment, nor because of
the non-blocking assignment, but because the two styles are mixed.

What is the solution ?

The best solution we found was:

Write the latch also with non-blocking assignments (<=):

always @(clk or in)
if (clk)
latch_out <= in ;

Originally, we thought that Synopsys does not support non-blocking assignments in latches.
(More exactly, we saw that Synopsys documentation describes latches with blocking assignments.)

It turns out that's not true.

(In point of fact, the Synopsys HDL Compiler for Verilog describes flip-flops
with blocking assignments as well as latches. The first versions of
Synopsys came out before Cadence added non-blocking assignments to
Verilog-XL, and so Synopsys had to support blocking assignments for everything.)

On the contrary, the only specific reference to this is in a recent
Synopsys document called "Designing with Verilog", revision 1.0.

There, the following guideline appears:

"Use non-blocking assignments for all inferred registers (flip-flops, latches);
and use blocking assignments for combinatorial outputs and intermediate local
variable assignments.
...
What happens if non-blocking assignments are used instead of blocking assignments
for combinational outputs of processes? The logic will still simulate and synthesize
correctly, but simulation performance may suffer."

The reason that "simulation performance may suffer" is that non-blocking assignments
simulate more slowly than blocking assignments, both in Verilog-XL and in VCS.

An experiment gave identical results with both styles of latch.

The best guess we have heard so far is that originally Synopsys did not
support non-blocking assignments in latches and they added it later.

Although it is true that non-blocking assignments simulate more slowly
than blocking assignments, and the difference is noticeable,
I think that it is well tolerable, and worth the added confidence of correctness.

In summary:

Purely latch-based designs can use blocking or non-blocking assignments to describe the latches,
and it will be OK.

In a mixed latch-based and FF-based design, writing latches with blocking assignments is liable
to cause simulation errors.

The best, safest solution is to write all latches with non-blocking assignments.

Sincerely,
Shalom Bresticker

******************************************************************************
Shalom Bresticker email: shalom@msil.sps.mot.com
Motorola Semiconductor Israel, Ltd. Tel #: +972 9 9522268
P.O.B. 2208, Herzlia 46120, ISRAEL Fax #: +972 9 9522444
http://www.motorola-semi.co.il/
******************************************************************************

----- End Included Message -----