Re: [sv-bc] Errata: variable initializers don't match Verilog-2001

From: Steven Sharp <sharp@cadence.com>
Date: Wed Dec 15 2004 - 18:01:28 PST

>From: Shalom.Bresticker@freescale.com

>(Strictly speaking, that might not be enough. 1364-2001 5.4.2 says,
>"At any time while evaluating a behavioral statement, the simulator may suspend
execution and place the partially completed event as a pending active event on
the event queue. The effect of this is to allow the interleaving of process
execution."

Agreed. However, if that statement is taken at face value, there are other
kinds of code that become almost impossible to write correctly. Fortunately,
real tools do not suspend process execution arbitrarily, so such code works
in practice.

>If we activated all the always blocks, but including always_comb, at the start
>(and the other stuff
>we talked about, like continuous assignments, port connections, etc.)
>and then did the initializations, wouldn't that be enough?

I am not clear whether you are suggesting that always_comb still evaluate
once at time zero. If so, then yes, it is OK to execute them at the same
time as other always blocks. However, I assume that you are suggesting
that they start execution early but not evaluate unconditionally at time zero.

It would cover most designs. However, you could still contrive situations
where an always_comb block would not behave like combinational logic. For
example, if the always block reads only constants, it has no sensitivity
and will never wake up. Activating it early would not help. It needs to
execute once unconditionally, like an always_comb does.

And while it would be weird, there is nothing to prevent someone from
replacing all of their initial blocks with always blocks that have the
same behavior (i.e. waiting on a constant at the end so that they don't
loop back). In this case, the ordering requirements between initial and
always blocks would not ensure that combinational always blocks worked
properly. This is an artificial situation, but there may be realistic
ones that have similar effects. For example, always blocks are sometimes
used for clock generators, and there may be other situations where always
blocks are used to provide stimulus to combinational always blocks.

>And then there would be no need to treat always_comb specially?

I don't regard the "evaluation at time zero" part of always_comb as treating
them specially. As I noted, it is just the same as regarding an always_comb
as an ordinary always block where the event control has been put at the
bottom. Since the event control is implicit anyway, putting it there is
just as reasonable as putting it at the top. I think it is the fault of the
LRM text for making this part of always_comb sound like special treatment.
In fact, they act like any other always block would if you put the event
control at the bottom.

The part about always_comb executing after other blocks is special treatment,
and is also unnecessary to make them behave properly. That part could be
eliminated. If always blocks were required to execute early, always_comb
blocks could be executed at the same time. The only effect might be that
they might get evaluated twice at time zero, but the final values would
still be the same.

>Conceptually, it does not make sense to treat always_comb and always @*
>and continous assignments differently.

Well, unfortunately there are conceptual differences. An always with an
@* at the top has an event control at a specified place in the procedural
code, and is required to stop and wait at that exact place. It is a special
kind of event control, but it is still at a specific location. The
advantage of always_comb is that there is no explicit event control, just
an implicit one that is part of the construct. There is no syntax to say
where it must be inserted in the procedural code. It is associated with
the always_comb looping construct as a whole, which surrounds the body of
the always_comb. It can be inserted in the bottom part of that looping
construct just as readily as in the top part.

Using a special kind of always block instead of a special kind of event
control was simply a better way to design this capability. It is
unfortunate that this was not proposed for the 1364-2001 standard instead
of @*.

A continuous assignment also has implicit sensitivity, so it can also
be implemented to execute once and wait for input changes at the bottom
before looping back to the top to evaluate again.

This waiting at the bottom instead of the top makes both always_comb and
continuous assignments work properly like combinational logic, even if
the inputs change at the start of simulation or are constants. The best
that can be done for ordinary always blocks is to execute them as early
as possible, hopefully before those initial input changes. Unfortunately,
SystemVerilog forbids executing them before initializers, which could break
existing Verilog-2001 code.

There are other differences between always_comb and @* or continuous
assignments, but bringing those up would be digressions in this discussion.

Steven Sharp
sharp@cadence.com
Received on Wed Dec 15 18:01:35 2004

This archive was generated by hypermail 2.1.8 : Wed Dec 15 2004 - 18:01:45 PST