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

From: Steven Sharp <sharp@cadence.com>
Date: Thu Dec 09 2004 - 18:57:53 PST

>Date: Thu, 9 Dec 2004 23:35:47 +0200 (IST)
>From: Shalom.Bresticker@freescale.com

>When you write that always constructs should 'execute' before initial blocks
>and initializations at time 0, that term 'execute' could be misunderstood.

Yes, misunderstandings about how always blocks are defined to work are
widespread enough that I should be careful to be clear.

>You mean if you have
>
>always @(a or b) or always @(posedge clk), then you enter the always
>and start waiting on the @(a or b) or @(posedge clk).

Yes. The goal in executing the always blocks first is to get them
to reach the event control and start waiting there, so that if an
initial block causes one of those events, the always block will
be ready to respond.

The grouping in these partial examples might mislead someone into
thinking the event controls are somehow associated with the always,
when in fact they are associated with the statement that follows
the event control. This is part of the most common misunderstanding
about always blocks.

Executing the always block means to start executing the statement
inside the always block (which might be a sequential block). And
in these cases, the statement is preceded by an event control, so
execution would immediately suspend to wait for the event to occur.
If the statement were not preceded by an event control, execution
would continue until it reached an event control or delay control.

> For always_comb, you
>mean to wait on the implicit sensitivity list.

No, at least not the way you probably mean it.

The simplest way to view an always_comb, with its requirement to
execute the body once at time zero, is to recognize that this is
equivalent to putting the event control at the *bottom*, instead
of the top.

A typical Verilog combinational always block is coded like

always @(a)
  b = ~a;

which happens to be semantically equivalent to

initial
  forever begin
    @(a) b = ~a;
  end

A SystemVerilog always_comb, coded like

always_comb
  b = ~a;
  
is semantically almost equivalent to

initial
  forever begin
    b = ~a;
    @(a);
  end
  
Notice that here the event control appears at the bottom of
the loop implied by the always_comb. This means that it will
execute the always block body once before it starts waiting for
input changes. It is much like the difference between a while loop
and a do-while loop. The fancy wording about "triggering once at
time zero" just comes down to this change in the position of the
implicit event control from the top to the bottom.

The reason I wrote "almost equivalent" instead of "equivalent", is
that always_comb also has a special rule requiring it to execute
*after* all of the initial and always blocks. This rule is not
actually needed to make it behave like combinational logic. Putting
the event control at the bottom is sufficient to ensure that it will
behave correctly from time zero. If it executed before the initial
blocks, the worst that could happen is that evaluates again if an
initial block changes an input. And if it really is combinational
logic, that should not cause any harm.

So anyway, executing an always_comb would not involve immediately
waiting on the implicit "sensitivity list" or event control. It
would involve executing all of the statement inside the always_comb,
and then waiting on the implicit event control at the bottom. But
an always_comb doesn't need to be executed before initial blocks
anyway. It could be executed then, or when SystemVerilog says it
must be executed, and it will still work like combinational logic.

However, Verilog combinational always blocks, when coded the usual
way with the event control at the top, only work properly when inputs
change at time zero, if they start executing before the input changes.
It is the only way to make them act the way so many people believe
they do: sensitive to their inputs from the very start of simulation.

Steven Sharp
sharp@cadence.com
Received on Thu Dec 9 18:58:00 2004

This archive was generated by hypermail 2.1.8 : Thu Dec 09 2004 - 18:58:17 PST