Re: Fwd: Verilog Races in Combinatorial Logic

From: Daryl Stewart (Daryl.Stewart@cl.cam.ac.uk)
Date: Fri Sep 22 2000 - 08:18:08 PDT


Shalom Bresticker:
> I believe I have given an example of a common programming practice
> which all behavioral Verilog coders will use. No one has ever
> feared to use such a structure. It is forbidden for us to cause
> such code to be "broken". It is not a pathological example.

Maybe common practice but the code was never correct according to the old
standard(s). See section 5.4.1 of October 1995, or Chapter 8 page 1 of the old
LRM. As James implies, these are shared variable in a multithreading
environment. It just so happens the simulators choose an execution order which
made it appear to work. The original code is flawed even though the simulators
are correct.

The for loops should use different variables, local variables or should be in
the same initial block if you want them not to interfere.
Give Ginger a #0 if she really must allow Fred to finish first.

Since the discussion seems to be thrashing around the problem I'd like to
suggest a possible solution.
If you really want to ensure that parallel blocks sensitive to events in their
neighbours run after their neighbour completes, you could alter the semantics
of @. (In the terminology of Section 5 Oct9:) Introduce a new region to the
Verilog event queue of "activated" events, somewhere between "active" and
"inactive".
Make the simulation cycle execute all active events, adding threads whose
event guard is triggered as "activated" events.
When no active events remain, make all activated events active and repeat.
When no activated events remain, make all inactive events active
etc...

This makes Joseph's Fred and Ginger example deterministic for y.
But leaves simultaneously active threads free to interleave.

Is there anything this would break? Since the order of execution of parallel
blocks was never intended to be relied on, I think not.

I am not proposing this restriction should be made. It's awful. I still
believe that both examples should be non-deterministic since they use shared
variables with no protection in a multi-threaded environment.

Steve Meyer comments:
> Otherwise, the number of alternative states
> becomes in my view too large and too hard to understand.
but that's what happens in parallel systems.

I would also like to point out something that John Fiskio-Lasseter
(http://www.cs.uoregon.edu/~johnfl/) noted in his MS Thesis (A Formal
Description of Behavioral Verilog Based on Axiomatic Semantics. Tech. Rep.
TR-98-04, University of Oregon, Computer and
Information Science Department. 1998)
namely that the statement:
"At any time while evaluating a behavioural statement, the simulator may
suspend execution and place the partially completed event as a pending active
event on the event queue."
allows a compliant simulator to interleave AT ANY TIME, even at the level of
expression evaluation.

Could (jfl's example:)
initial begin x = 1; if ((!x) || x) some_statement; end
initial x = 0;
fail to execute some_statement?

cheers
Daryl



This archive was generated by hypermail 2.1.4 : Mon Jul 08 2002 - 12:54:14 PDT and
sponsored by Boyd Technology, Inc.