ISSUE 82

Add Proposal  Add Analysis  Edit Class, Environment, or Release
Number 82
Category errata
Synopsis 9.7.5: Description of @*, @(*) incomplete
State open
Class errata-discuss
Arrival-DateJul 30 2002
Originator Dennis Marsa
Release 2001b: 9.7.5
Environment


http://boydtechinc.com/btf/archive/btf_2002/1739.html
http://boydtechinc.com/btf/archive/btf_2002/1804.html
http://boydtechinc.com/btf/archive/btf_2002/1818.html
http://boydtechinc.com/btf/archive/btf_2002/1828.html
http://boydtechinc.com/etf/archive/etf_2002/0012.html
Description
The description of the behavior of @* and @(*) in section
9.7.5 is incomplete.

Previous discussion of the issues can be found in the
following threads from the BTF/ETF archives:

http://boydtechinc.com/btf/archive/btf_2002/1739.html
http://boydtechinc.com/btf/archive/btf_2002/1804.html
http://boydtechinc.com/btf/archive/btf_2002/1818.html
http://boydtechinc.com/btf/archive/btf_2002/1828.html
http://boydtechinc.com/etf/archive/etf_2002/0012.html

A detailed algorithmic description of how to compute
the set of events that an @* is equivalent to is needed
in this section.

The description should address how *all* types of statements
and expressions should be processed when under the control
of an @*.

Some (but probably not all) specific issues that are not
clearly addressed in Section 9.7.5 include:

1) When a bit or part select of a vector is used within
an @*, is the event control sensitive to just the
bit or part selected, or the entire vector?

reg [31:0] vector;

always @* /* @(vector) or @(vector[5])?
out = vector[5];

What if a non-constant bit is selected?

always @* /* @(vector) or @(vector[i]) or @(vector or i)?
out = vector[i];

2) How are array references handled within an @*?

reg [31:0] array[1:100];

always @* // @(array) or @(array[10])
out = array[10];

and, what if the index is non-constant?

always @* // @(array) or @(array[i]) or @(array or i)?
out = array[i]

Can an event control be sensitive *any* change
to an array??

3) How are named-begin/fork blocks handled when under
the control of a @*?

always @*
begin : named
...
end

Presumably, names defined and used within the named
block would not be included the @*?

5) The syntax description of @* allows @* to be used
as an intra-assigment event control:

a <= @* b;

Section 9.7.5 does not define any semantics for this
contruct. Is it meaningful/useful? Should it be
considered a semantic error?

6) Tokenization of @* and @(*). 1364-2001 does not
state anywhere how @* and @(*) should be tokenized.

Is @* 1 token '@*' or 2 tokens '@' '*'?
Is @(*) 1 token '@(*)' or 4 tokens '@' '(' '*' ')'

If these are to be considered multiple tokens, then
one must also consider how the attribute tokens
'(*' and '*)' interact. Thus, @(*) could also
be *three* tokens:

'@' '(*' ')
or '@' '(' '*)'
Fix

Audit-Trail

From: Michael McNamara <mac@verisity.com>
To: drm@xilinx.com
Cc: etf-bugs@boyd.com
Subject: RE: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Tue, 30 Jul 2002 09:59:15 -0700

drm@xilinx.com writes:
> Precedence: bulk
>
>
> >Number: 82
> >Category: errata
> >Originator: Dennis Marsa
> >Description:
>
> The description of the behavior of @* and @(*) in section
> 9.7.5 is incomplete.
>
> Previous discussion of the issues can be found in the
> following threads from the BTF/ETF archives:
>
> http://boydtechinc.com/btf/archive/btf_2002/1739.html
> http://boydtechinc.com/btf/archive/btf_2002/1804.html
> http://boydtechinc.com/btf/archive/btf_2002/1818.html
> http://boydtechinc.com/btf/archive/btf_2002/1828.html
> http://boydtechinc.com/etf/archive/etf_2002/0012.html
>
> A detailed algorithmic description of how to compute
> the set of events that an @* is equivalent to is needed
> in this section.
>
> The description should address how *all* types of statements
> and expressions should be processed when under the control
> of an @*.
>
> Some (but probably not all) specific issues that are not
> clearly addressed in Section 9.7.5 include:
>
> 1) When a bit or part select of a vector is used within
> an @*, is the event control sensitive to just the
> bit or part selected, or the entire vector?
>
> reg [31:0] vector;
>
> always @* /* @(vector) or @(vector[5])?
> out = vector[5];
>

--> Handle the same way as

assign out = vector[5];

I.E., one is sensitive just to a change in the value of the expression
vector[5]; (See 5.6.1, 9.7.2)

> What if a non-constant bit is selected?
>
> always @* /* @(vector) or @(vector[i]) or @(vector or i)?
> out = vector[i];

--> Handle the same way as

assign out = vector[i];

I.E., one is sensitive just to a change in value of evaluating the
expression vector[i]; (See 5.6.1, 9.7.2)

>
> 2) How are array references handled within an @*?
>
> reg [31:0] array[1:100];
>
> always @* // @(array) or @(array[10])
> out = array[10];

--> Handle the same way as

assign out = array[10];

I.E., one is sensitive just to a change in the value of the expression
array[10]; (See 5.6.1, 9.7.2)

>
> and, what if the index is non-constant?
>
> always @* // @(array) or @(array[i]) or @(array or i)?
> out = array[i]
>
> Can an event control be sensitive *any* change
> to an array??

--> Handle the same way as

assign out = array[i];

I.E., one is sensitive just to a change in value of evaluating the
expression array[i]; (See 5.6.1, 9.7.2)

>
> 3) How are named-begin/fork blocks handled when under
> the control of a @*?
>
> always @*
> begin : named
> ...
> end
>
> Presumably, names defined and used within the named
> block would not be included the @*?

There is no way to be sensitive to values declared inside the block
as:

1) they have no existance outside the block;

2) an @(exp) statement is only 'energized' by having the flow of
control flow to the statement @(exp). Only then is the statement
guarded by the event control placed on a queue for execution when the
value of exp evaluates to something other than it's current value.

I just searched through 1364-2001 and did not find a coherent
description of this; I had thought it would be in either Section 5 or
Section 9, but I did not find this.

> 5) The syntax description of @* allows @* to be used
> as an intra-assigment event control:
>
> a <= @* b;
>
> Section 9.7.5 does not define any semantics for this
> contruct. Is it meaningful/useful? Should it be
> considered a semantic error?

I believe you are right. Because intraassigment delay evaluates the
RHS, and then place the value aside, and waits for the event
expression to fire, after which it assigns the value to the lHS, it
makes no sense for the event expression to be derived from the value
of the rhs expression.

>
> 6) Tokenization of @* and @(*). 1364-2001 does not
> state anywhere how @* and @(*) should be tokenized.
>
> Is @* 1 token '@*' or 2 tokens '@' '*'?
> Is @(*) 1 token '@(*)' or 4 tokens '@' '(' '*' ')'
>
> If these are to be considered multiple tokens, then
> one must also consider how the attribute tokens
> '(*' and '*)' interact. Thus, @(*) could also
> be *three* tokens:
>
> '@' '(*' ')
> or '@' '(' '*)'

I believe that tokenization discussion this is outside the scope of
the IEEE 1364-2001 specification. There is no discussion of
tokenization of anything else in the specification, except perhaps the
notes in the BNF that talk about making illegal the use of spaces
between $ and display, or in general the use of spaces in a name.

Inany case, where we are, the standard says that @(*) must be treated
as the implict event control; and without any special rules, this also
allows

@ ( * )
@ (* )
@(*)

I submit that there is no ambiguity that a LALR(1) parser (like Yacc &
bison) used in conjunction with lex (or flex) could not handle, as the
only problem case is [Note '.' indicates where the parsers eye ball is
focusing right now]

@ (* . )

versus

@ (* . exp *)

which the parser can disabiguate by looking ahead one token (this is
what LALR statnds for ['L'ook'A'head 'L'eft to right scanning of
input, constructing a 'R'ight most derivation in reverse, with
lookahead limited to just '(1)' token]; ref Section 4.7 of Aho Sethi &
Ulmman 'Compilers: Principles, techniques and tools, 1988), to see if
the next token is a ')' or is part of an expression.

-mac




From: Dennis Marsa <drm@xilinx.com>
To: mac@verisity.com
Cc: etf-bugs@boyd.com
Subject: Re: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Tue, 30 Jul 2002 11:29:49 -0600

Michael McNamara wrote:
>
> drm@xilinx.com writes:
>
> > 6) Tokenization of @* and @(*). 1364-2001 does not
> > state anywhere how @* and @(*) should be tokenized.
> >
> > Is @* 1 token '@*' or 2 tokens '@' '*'?
> > Is @(*) 1 token '@(*)' or 4 tokens '@' '(' '*' ')'
> >
> > If these are to be considered multiple tokens, then
> > one must also consider how the attribute tokens
> > '(*' and '*)' interact. Thus, @(*) could also
> > be *three* tokens:
> >
> > '@' '(*' ')
> > or '@' '(' '*)'
>
> I believe that tokenization discussion this is outside the scope of
> the IEEE 1364-2001 specification. There is no discussion of
> tokenization of anything else in the specification, except perhaps the
> notes in the BNF that talk about making illegal the use of spaces
> between $ and display, or in general the use of spaces in a name.

What about Section 2 "Lexical Convensions"?

> Inany case, where we are, the standard says that @(*) must be treated
> as the implict event control; and without any special rules, this also
> allows
>
> @ ( * )
> @ (* )
> @(*)
>
> I submit that there is no ambiguity that a LALR(1) parser (like Yacc &
> bison) used in conjunction with lex (or flex) could not handle, as the
> only problem case is [Note '.' indicates where the parsers eye ball is
> focusing right now]
>
> @ (* . )
>
> versus
>
> @ (* . exp *)
>
> which the parser can disabiguate by looking ahead one token (this is
> what LALR statnds for ['L'ook'A'head 'L'eft to right scanning of
> input, constructing a 'R'ight most derivation in reverse, with
> lookahead limited to just '(1)' token]; ref Section 4.7 of Aho Sethi &
> Ulmman 'Compilers: Principles, techniques and tools, 1988), to see if
> the next token is a ')' or is part of an expression.


I agree, handling @* and @(*) as multiple tokens can be handled.

I would just like to see a statement somewhere in the standard that
says whether they are, in fact, multiple tokens, or one token.

Dennis Marsa
Xilinx, Inc.

From: Steven Sharp <sharp@cadence.com>
To: etf-bugs@boyd.com
Cc:
Subject: RE: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Tue, 30 Jul 2002 18:04:46 -0400 (EDT)

> > always @* /* @(vector) or @(vector[5])?
> > out = vector[5];
> >
>
> --> Handle the same way as
>
> assign out = vector[5];
>
> I.E., one is sensitive just to a change in the value of the expression
> vector[5]; (See 5.6.1, 9.7.2)

I don't see where those references imply this. However, 9.7.5 clearly states
"All net and variable identifiers which appear in the statement will be
automatically added to the event expression with these exceptions:..."

Note that vector is an identifier and vector[5] is not an identifier.
Section 9.7.5 therefore says to add vector and not vector[5]. I see no
ambiguity here. Someone can claim it is wrong, but it is not unclear.

> > What if a non-constant bit is selected?
> >
> > always @* /* @(vector) or @(vector[i]) or @(vector or i)?
> > out = vector[i];
>
> --> Handle the same way as
>
> assign out = vector[i];
>
> I.E., one is sensitive just to a change in value of evaluating the
> expression vector[i]; (See 5.6.1, 9.7.2)

Again, section 9.7.5 says to add identifiers appearing in the statement.
That makes the answer @(vector or i). I see no ambiguity here.

Furthermore, as I have pointed out before, there are situations that
will not behave properly with @(vector[i]). They require @(vector or i)
in order to act like combinational logic. So not only does the letter
of the standard require it, so does the intent.

> > 2) How are array references handled within an @*?
> >
> > reg [31:0] array[1:100];
> >
> > always @* // @(array) or @(array[10])
> > out = array[10];
>
> --> Handle the same way as
>
> assign out = array[10];
>
> I.E., one is sensitive just to a change in the value of the expression
> array[10]; (See 5.6.1, 9.7.2)

Again, this doesn't match the standard.

However, expanding as specified by the standard results in being equivalent
to something illegal and undefined. My view is that this makes the user's
code illegal. Someone could take a different view, but then they will need
to define what the behavior is, since there is no legal equivalent.

> >
> > and, what if the index is non-constant?
> >
> > always @* // @(array) or @(array[i]) or @(array or i)?
> > out = array[i]
> >
> > Can an event control be sensitive *any* change
> > to an array??
>
> --> Handle the same way as
>
> assign out = array[i];
>
> I.E., one is sensitive just to a change in value of evaluating the
> expression array[i]; (See 5.6.1, 9.7.2)

Again, this is not what the standard says, nor will it give the correct
results in all cases.

> >
> > 3) How are named-begin/fork blocks handled when under
> > the control of a @*?
> >
> > always @*
> > begin : named
> > ...
> > end
> >
> > Presumably, names defined and used within the named
> > block would not be included the @*?
>
> There is no way to be sensitive to values declared inside the block
> as:
>
> 1) they have no existance outside the block;

Not true. They exist just fine, and can be read or written from outside
the block by using the hierarchical name named.variable_name.

> 2) an @(exp) statement is only 'energized' by having the flow of
> control flow to the statement @(exp). Only then is the statement
> guarded by the event control placed on a queue for execution when the
> value of exp evaluates to something other than it's current value.

Since they exist at that point, there is no reason they can't be waited on.

This one is a little sticky, since the only "equivalent" way to add the
identifier to the event list is with a hierarchical reference. But that
is a way that the identifier can be added.

You could argue that the named block is an attempt to keep the variables
local, so they shouldn't go into the list. However, hierarchical names
in Verilog mean that no variables are really local. Someone could write
to them from outside the block, and the event control would need to include
them in order to implement combinational logic.

> > 5) The syntax description of @* allows @* to be used
> > as an intra-assigment event control:
> >
> > a <= @* b;
> >
> > Section 9.7.5 does not define any semantics for this
> > contruct. Is it meaningful/useful? Should it be
> > considered a semantic error?
>
> I believe you are right. Because intraassigment delay evaluates the
> RHS, and then place the value aside, and waits for the event
> expression to fire, after which it assigns the value to the lHS, it
> makes no sense for the event expression to be derived from the value
> of the rhs expression.

You are right that this is unclear, and I don't see any reasonable
interpretation that makes sense or is useful. The easiest thing would
be to make it illegal.

> > 6) Tokenization of @* and @(*). 1364-2001 does not
> > state anywhere how @* and @(*) should be tokenized.
> > ...
>
> I believe that tokenization discussion this is outside the scope of
> the IEEE 1364-2001 specification. There is no discussion of
> tokenization of anything else in the specification, except perhaps the
> notes in the BNF that talk about making illegal the use of spaces
> between $ and display, or in general the use of spaces in a name.

Section 2, and particularly 2.1 discuss tokens.

> Inany case, where we are, the standard says that @(*) must be treated
> as the implict event control; and without any special rules, this also
> allows
>
> @ ( * )
> @ (* )
> @(*)

Not true if '(*)' is a token, which is not clear.

> I submit that there is no ambiguity that a LALR(1) parser (like Yacc &
> bison) used in conjunction with lex (or flex) could not handle

It is painful, and normally one would try to avoid it in the language.
However, it is resolvable with some extra work.

Steven Sharp
sharp@cadence.com


From: Michael McNamara <mac@verisity.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: RE: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Tue, 30 Jul 2002 17:22:41 -0700

Steven Sharp writes:
> Precedence: bulk
>
> The following reply was made to PR errata/82; it has been noted by GNATS.
>
> From: Steven Sharp <sharp@cadence.com>
> To: etf-bugs@boyd.com
> Cc:
> Subject: RE: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
> Date: Tue, 30 Jul 2002 18:04:46 -0400 (EDT)
>
> > > always @* /* @(vector) or @(vector[5])?
> > > out = vector[5];
> > >
> >
> > --> Handle the same way as
> >
> > assign out = vector[5];
> >
> > I.E., one is sensitive just to a change in the value of the expression
> > vector[5]; (See 5.6.1, 9.7.2)
>
> I don't see where those references imply this. However, 9.7.5 clearly states
> "All net and variable identifiers which appear in the statement will be
> automatically added to the event expression with these exceptions:..."
>
> Note that vector is an identifier and vector[5] is not an identifier.
> Section 9.7.5 therefore says to add vector and not vector[5]. I see no
> ambiguity here. Someone can claim it is wrong, but it is not
> unclear.

Again, you are right; It is (in my opinion) quite _clearly_ _wrong_.

I would much rather have always @* out = vector[5] behave as if it
were coded as assign out = vector[5], and so on.

The standard does not support my desire.

The result is that
module
reg out;
reg [2047:0] vector;
always @* begin
out = vector[5];
$display ("triggered: out %b");
end
initial for (vector = 0; vector < 2**2046; vector = vector + 1) #10;
endmodule

while _massively_ overprint the word triggered.

So, I would like to have the word 'variable_identifier' replaced with
'primary' in the standard.

I may not get you all to agree, either now, or while you might agree,
you won't agree to do this as an errata.

-mac

>
> > > What if a non-constant bit is selected?
> > >
> > > always @* /* @(vector) or @(vector[i]) or @(vector or i)?
> > > out = vector[i];
> >
> > --> Handle the same way as
> >
> > assign out = vector[i];
> >
> > I.E., one is sensitive just to a change in value of evaluating the
> > expression vector[i]; (See 5.6.1, 9.7.2)
>
> Again, section 9.7.5 says to add identifiers appearing in the statement.
> That makes the answer @(vector or i). I see no ambiguity here.
>
> Furthermore, as I have pointed out before, there are situations that
> will not behave properly with @(vector[i]). They require @(vector or i)
> in order to act like combinational logic. So not only does the letter
> of the standard require it, so does the intent.

This I do not understand.

combinatorial logic, as specified by

assign out = vector[j]; will make it so out always has the value of
the expression vector[j];

It is a waste of simulator resources to reassign to out the value of
vector[j] if that is the same as the current value of out.

It is the case in Verilog-XL that always @(vector[j]) is fired only
when the value of the expression 'vector[j]' changes; not when 'j'
changes, or when a bit of vector not selected by 'j' changes.

Consider:
module foo;
integer i,j;
reg [5:0] vector, array[0:512];

always @(vector[3]) $display(" always @(vector[3]) triggered");
always @(vector[2]) $display(" always @(vector[2]) triggered");
always @(vector[1]) $display(" always @(vector[1]) triggered");
always @(vector[0]) $display(" always @(vector[0]) triggered");
always @(vector[j]) $display(" always @(vector[j]) triggered");
always @(vector) $display(" always @(vector) triggered");

initial begin
for (i = 0; i < 32; i = i + 1) begin
vector = i;
$display($stime,,"%d: vector is %b",i,vector);
#10;
end
$finish;
end
always begin
for (j = 0; j < 5; j = j + 1) begin
#1;
$display($stime,,"vector is %b j is %d",vector,j);
end
end

endmodule

Using Verilog-XL, I get:

VERILOG-XL 3.10.s010 Jul 30, 2002 17:16:15

Compiling source file "fgh.v"
Highest level modules:
foo

0 0: vector is 000000
always @(vector) triggered
always @(vector[0]) triggered
always @(vector[1]) triggered
always @(vector[2]) triggered
always @(vector[3]) triggered
always @(vector[j]) triggered
1 vector is 000000 j is 0
2 vector is 000000 j is 1
3 vector is 000000 j is 2
4 vector is 000000 j is 3
5 vector is 000000 j is 4
6 vector is 000000 j is 0
7 vector is 000000 j is 1
8 vector is 000000 j is 2
9 vector is 000000 j is 3
10 1: vector is 000001
10 vector is 000001 j is 4
always @(vector[0]) triggered
always @(vector) triggered
always @(vector[j]) triggered
11 vector is 000001 j is 0
always @(vector[j]) triggered
12 vector is 000001 j is 1
13 vector is 000001 j is 2
14 vector is 000001 j is 3
15 vector is 000001 j is 4
always @(vector[j]) triggered
16 vector is 000001 j is 0
always @(vector[j]) triggered
17 vector is 000001 j is 1
18 vector is 000001 j is 2
19 vector is 000001 j is 3
20 2: vector is 000010
20 vector is 000010 j is 4
always @(vector) triggered
always @(vector[0]) triggered
always @(vector[1]) triggered
21 vector is 000010 j is 0
always @(vector[j]) triggered
22 vector is 000010 j is 1
always @(vector[j]) triggered
23 vector is 000010 j is 2
24 vector is 000010 j is 3
25 vector is 000010 j is 4
26 vector is 000010 j is 0
always @(vector[j]) triggered
27 vector is 000010 j is 1
always @(vector[j]) triggered
28 vector is 000010 j is 2
29 vector is 000010 j is 3
30 3: vector is 000011
30 vector is 000011 j is 4
always @(vector[0]) triggered
always @(vector) triggered
always @(vector[j]) triggered
31 vector is 000011 j is 0
32 vector is 000011 j is 1
always @(vector[j]) triggered
33 vector is 000011 j is 2
34 vector is 000011 j is 3
35 vector is 000011 j is 4
always @(vector[j]) triggered
36 vector is 000011 j is 0
37 vector is 000011 j is 1
always @(vector[j]) triggered
38 vector is 000011 j is 2
39 vector is 000011 j is 3
40 4: vector is 000100
40 vector is 000100 j is 4
always @(vector) triggered
always @(vector[0]) triggered
always @(vector[1]) triggered
always @(vector[2]) triggered
41 vector is 000100 j is 0
42 vector is 000100 j is 1
always @(vector[j]) triggered
43 vector is 000100 j is 2
always @(vector[j]) triggered
44 vector is 000100 j is 3
45 vector is 000100 j is 4
46 vector is 000100 j is 0
47 vector is 000100 j is 1
always @(vector[j]) triggered
48 vector is 000100 j is 2
always @(vector[j]) triggered
49 vector is 000100 j is 3
50 5: vector is 000101
50 vector is 000101 j is 4
always @(vector[0]) triggered
always @(vector) triggered
always @(vector[j]) triggered
51 vector is 000101 j is 0
always @(vector[j]) triggered
52 vector is 000101 j is 1
always @(vector[j]) triggered
53 vector is 000101 j is 2
always @(vector[j]) triggered
54 vector is 000101 j is 3
55 vector is 000101 j is 4
always @(vector[j]) triggered
56 vector is 000101 j is 0
always @(vector[j]) triggered
57 vector is 000101 j is 1
always @(vector[j]) triggered
58 vector is 000101 j is 2
always @(vector[j]) triggered
59 vector is 000101 j is 3
60 6: vector is 000110
60 vector is 000110 j is 4
always @(vector) triggered
always @(vector[0]) triggered
always @(vector[1]) triggered
61 vector is 000110 j is 0
always @(vector[j]) triggered
62 vector is 000110 j is 1
63 vector is 000110 j is 2
always @(vector[j]) triggered
64 vector is 000110 j is 3
65 vector is 000110 j is 4
66 vector is 000110 j is 0
always @(vector[j]) triggered
67 vector is 000110 j is 1
68 vector is 000110 j is 2
always @(vector[j]) triggered
69 vector is 000110 j is 3
70 7: vector is 000111
70 vector is 000111 j is 4
always @(vector[0]) triggered
always @(vector) triggered
always @(vector[j]) triggered
71 vector is 000111 j is 0
72 vector is 000111 j is 1
73 vector is 000111 j is 2
always @(vector[j]) triggered
74 vector is 000111 j is 3
75 vector is 000111 j is 4
always @(vector[j]) triggered
76 vector is 000111 j is 0
77 vector is 000111 j is 1
78 vector is 000111 j is 2
always @(vector[j]) triggered
79 vector is 000111 j is 3
L18 "fgh.v": $finish at simulation time 80
0 simulation events (use +profile or +listcounts option to count)
CPU time: 0.1 secs to compile + 0.0 secs to link + 0.0 secs in simulation
End of VERILOG-XL 3.10.s010 Jul 30, 2002 17:16:16

> > > 2) How are array references handled within an @*?
> > >
> > > reg [31:0] array[1:100];
> > >
> > > always @* // @(array) or @(array[10])
> > > out = array[10];
> >
> > --> Handle the same way as
> >
> > assign out = array[10];
> >
> > I.E., one is sensitive just to a change in the value of the expression
> > array[10]; (See 5.6.1, 9.7.2)
>
> Again, this doesn't match the standard.
>
> However, expanding as specified by the standard results in being equivalent
> to something illegal and undefined. My view is that this makes the user's
> code illegal. Someone could take a different view, but then they will need
> to define what the behavior is, since there is no legal equivalent.
>
> > >
> > > and, what if the index is non-constant?
> > >
> > > always @* // @(array) or @(array[i]) or @(array or i)?
> > > out = array[i]
> > >
> > > Can an event control be sensitive *any* change
> > > to an array??
> >
> > --> Handle the same way as
> >
> > assign out = array[i];
> >
> > I.E., one is sensitive just to a change in value of evaluating the
> > expression array[i]; (See 5.6.1, 9.7.2)
>
> Again, this is not what the standard says, nor will it give the correct
> results in all cases.
>
> > >
> > > 3) How are named-begin/fork blocks handled when under
> > > the control of a @*?
> > >
> > > always @*
> > > begin : named
> > > ...
> > > end
> > >
> > > Presumably, names defined and used within the named
> > > block would not be included the @*?
> >
> > There is no way to be sensitive to values declared inside the block
> > as:
> >
> > 1) they have no existance outside the block;
>
> Not true. They exist just fine, and can be read or written from outside
> the block by using the hierarchical name named.variable_name.
>
> > 2) an @(exp) statement is only 'energized' by having the flow of
> > control flow to the statement @(exp). Only then is the statement
> > guarded by the event control placed on a queue for execution when the
> > value of exp evaluates to something other than it's current value.
>
> Since they exist at that point, there is no reason they can't be waited on.
>
> This one is a little sticky, since the only "equivalent" way to add the
> identifier to the event list is with a hierarchical reference. But that
> is a way that the identifier can be added.
>
> You could argue that the named block is an attempt to keep the variables
> local, so they shouldn't go into the list. However, hierarchical names
> in Verilog mean that no variables are really local. Someone could write
> to them from outside the block, and the event control would need to include
> them in order to implement combinational logic.
>
> > > 5) The syntax description of @* allows @* to be used
> > > as an intra-assigment event control:
> > >
> > > a <= @* b;
> > >
> > > Section 9.7.5 does not define any semantics for this
> > > contruct. Is it meaningful/useful? Should it be
> > > considered a semantic error?
> >
> > I believe you are right. Because intraassigment delay evaluates the
> > RHS, and then place the value aside, and waits for the event
> > expression to fire, after which it assigns the value to the lHS, it
> > makes no sense for the event expression to be derived from the value
> > of the rhs expression.
>
> You are right that this is unclear, and I don't see any reasonable
> interpretation that makes sense or is useful. The easiest thing would
> be to make it illegal.
>
> > > 6) Tokenization of @* and @(*). 1364-2001 does not
> > > state anywhere how @* and @(*) should be tokenized.
> > > ...
> >
> > I believe that tokenization discussion this is outside the scope of
> > the IEEE 1364-2001 specification. There is no discussion of
> > tokenization of anything else in the specification, except perhaps the
> > notes in the BNF that talk about making illegal the use of spaces
> > between $ and display, or in general the use of spaces in a name.
>
> Section 2, and particularly 2.1 discuss tokens.
>
> > Inany case, where we are, the standard says that @(*) must be treated
> > as the implict event control; and without any special rules, this also
> > allows
> >
> > @ ( * )
> > @ (* )
> > @(*)
>
> Not true if '(*)' is a token, which is not clear.
>
> > I submit that there is no ambiguity that a LALR(1) parser (like Yacc &
> > bison) used in conjunction with lex (or flex) could not handle
>
> It is painful, and normally one would try to avoid it in the language.
> However, it is resolvable with some extra work.
>
> Steven Sharp
> sharp@cadence.com
>

From: Steven Sharp <sharp@cadence.com>
To: sharp@cadence.com, mac@verisity.com
Cc: etf-bugs@boyd.com
Subject: RE: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Tue, 30 Jul 2002 21:20:55 -0400 (EDT)

> > Furthermore, as I have pointed out before, there are situations that
> > will not behave properly with @(vector[i]). They require @(vector or i)
> > in order to act like combinational logic. So not only does the letter
> > of the standard require it, so does the intent.
>
>This I do not understand.
>
>combinatorial logic, as specified by
>
>assign out = vector[j]; will make it so out always has the value of
>the expression vector[j];
>
>It is a waste of simulator resources to reassign to out the value of
>vector[j] if that is the same as the current value of out.

All the efficiency in the world is of no use if you don't get the
right answer. If you really don't mind wrong results, I can give
you a simulator that is as fast as you like.

My earlier description of this situation appears at

http://boydtechinc.com/btf/archive/btf_2002/1825.html

but I will give another example here. Start with

always @*
out = vector[j];

This will work with @(vector[j]). It will also work with @(vector or j).
It will not work with @(vector).

Now try

always @*
for (j = 0; j < WIDTH; j = j + 1)
out[j] = vector[j];

This will not work with @(vector[j]). It must wait on all of vector,
since out depends on all of vector. It will work with @(vector).
It will also work with @(vector or j).

To make both situations work, @* must expand a reference to vector[j]
into @(vector or j). There is nothing else it can be expanded to that
will work in all situations.

An implementation would be free to optimize this as long as the results
are equivalent to using @(vector or j). It is not the job of the standard
to dictate exactly how it must be implemented, only how it must behave.
For the case of a reference to vector[j], @* needs to be equivalent to
@(vector or j), so that is what the standard should specify.

Steven Sharp
sharp@cadence.com


From: Gordon Vreugdenhil <gvreugde@synopsys.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Wed, 31 Jul 2002 08:08:13 -0700

Steven Sharp wrote:
>
> Precedence: bulk
>
> The following reply was made to PR errata/82; it has been noted by GNATS.
>
> From: Steven Sharp <sharp@cadence.com>
> To: sharp@cadence.com, mac@verisity.com
> Cc: etf-bugs@boyd.com
> Subject: RE: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
> Date: Tue, 30 Jul 2002 21:20:55 -0400 (EDT)
>
> > > Furthermore, as I have pointed out before, there are situations that
> > > will not behave properly with @(vector[i]). They require @(vector or i)
> > > in order to act like combinational logic. So not only does the letter
> > > of the standard require it, so does the intent.
> >
> >This I do not understand.
> >
> >combinatorial logic, as specified by
> >
> >assign out = vector[j]; will make it so out always has the value of
> >the expression vector[j];
> >
> >It is a waste of simulator resources to reassign to out the value of
> >vector[j] if that is the same as the current value of out.
>
> All the efficiency in the world is of no use if you don't get the
> right answer. If you really don't mind wrong results, I can give
> you a simulator that is as fast as you like.
>
> My earlier description of this situation appears at
>
> http://boydtechinc.com/btf/archive/btf_2002/1825.html
>
> but I will give another example here. Start with
>
> always @*
> out = vector[j];
>
> This will work with @(vector[j]). It will also work with @(vector or j).
> It will not work with @(vector).


Assuming that "j" has an unknown value, I agree. However, if j
is a genvar or similar, one may be able to optimize this and
requiring events on any change to vector is *very* expensive.
Consider something like:

always @*
out = big_mem[genvar1][genvar2][i];

Do you really want to be sensitive to any change on big_mem?

This area is very touchy -- if we *require* simulators to be sensitive
to the entire memory, some very reasonable design methodologies will
end up being unusable due to performance issues.

> Now try
>
> always @*
> for (j = 0; j < WIDTH; j = j + 1)
> out[j] = vector[j];
>
> This will not work with @(vector[j]). It must wait on all of vector,
> since out depends on all of vector. It will work with @(vector).
> It will also work with @(vector or j).
>
> To make both situations work, @* must expand a reference to vector[j]
> into @(vector or j). There is nothing else it can be expanded to that
> will work in all situations.
>
> An implementation would be free to optimize this as long as the results
> are equivalent to using @(vector or j). It is not the job of the standard
> to dictate exactly how it must be implemented, only how it must behave.

Yes and no. There are clearly implementation implications in dictating
behavior. In some cases, a simulator may be able to optimize away
certain sensitivities if it can determine that "skipping" some events would
not be a visible change, but I still don't like this in the context of
pli calls etc which can not be analyzed in this way.

I would prefer to have the standard include language that explicitly gives
the "optimization" as an acceptable behavior. Something like:
If an implementation can determine that only some portion of a memory
or vector can not be read in the related statement, the simulator may
choose to ignore changes to the unread portion of the vector or memory.

This is a "visible" behavior change in the context of pli calls and
things such as $display, but if we don't explicitly allow such behavior,
we are going to significantly curtain the adoption of this feature.

As a side note, this will be even more of an issue once the SystemVerilog
always_comb, etc. come into play.

> For the case of a reference to vector[j], @* needs to be equivalent to
> @(vector or j), so that is what the standard should specify.

I agree that this is the "cleanest" solution in terms of an easy
semantic statement, but I do not think that it is a viable solution
in terms of giving designers what they really need. If anything,
we should *require* behavior that does the analysis I mention since
the user could more easily add the "identifiers" to an explicit
sensitivity list.

Gord.
--
----------------------------------------------------------------------
Gord Vreugdenhil gvreugde@synopsys.com
Staff Engineer, VCS (Verification Tech. Group) (503) 547-6054
Synopsys Inc., Beaverton OR

From: Shalom Bresticker <Shalom.Bresticker@motorola.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Mon, 19 Aug 2002 09:13:00 +0300

I'm changing the subject of this subject to errata/82, because it really belongs
there.

Now that I am back at work, I have had a chance to look at the standard,
and Steven is correct (not that he needed my confirmation).

In fact, Example 2 shows exactly this case:

always @* begin // equivalent to @(a or b or c or d or tmp1 or tmp2)
tmp1 = a & b ;
tmp2 = c & d ;
y = tmp1 | tmp2 ;
end

As one of my action items, I looked at the
IEEE-SA Standards Board Operations Manual
and the IEEE Standards Companion.

Briefly, in addition to "Errata" and "Corrigenda",
there is in the middle something called "Interpretations".

The key rule about Interpretations is that they cannot change what
is written (except for fixing an erratum). That is, you cannot say in an
Interpretation that "red" means "green".

So, since Example 2 explicitly shows that intermediate values are
included

Steven Sharp wrote:

> > > There is no such exception in the standard.
> >
> > Really? Are you sure?
> > I was sure I had read it.
> > I don't have it with me to check.
>
> I have the print copy in front of me. Section 9.7.5 is less than a page
> long, so it would be hard to miss.
>
> > Not in the general case.
> > But there are cases where it is trivial.
>
> It is not as trivial as you think. And how much analysis should a tool do?
> You either have to provide a precise algorithm for all tools to use, or a
> general statement that tools can eliminate variables from the list if they
> can guarantee that they never read a value set by any other process. The
> latter would allow for optional optimization, at the cost of differences
> in the behavior of different tools.
>
> Of course, if the code is purely combinational, there should be no visible
> differences. But I've wasted a lot of time trying to track down race
> conditions in designs and trying to explain to customers that the standard
> allows different behavior in different simulators in those cases. Stating
> in the standard that differences are legal and usually indicate faulty Verilog
> code does not mean that those differences don't cause problems.
>
> > E.g.,
> > always @*
> > begin
> > a = b ;
> > c = a ;
> > end
> >
> > It is trivial to see that a is always assigned before being used.
>
> And you are incorrect in seeing that. What if a is forced or
> quasi-continuous-assigned somewhere else? Then the assignment to a has
> no effect and c will be set to the value forced/assigned. Perhaps you
> would never do that, but the fact is that a is not guaranteed to be
> assigned before being used, even in such a trivial case.
>
> Steven Sharp
> sharp@cadence.com
>

--
Shalom Bresticker Shalom.Bresticker@motorola.com
Design & Reuse Methodology Tel: +972 9 9522268
Motorola Semiconductor Israel, Ltd. Fax: +972 9 9522890
POB 2208, Herzlia 46120, ISRAEL Cell: +972 50 441478

"The devil is in the details."




From: Shalom Bresticker <Shalom.Bresticker@motorola.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Mon, 19 Aug 2002 09:12:56 +0300

I'm changing the subject of this subject to errata/82, because it really
belongs there.

Now that I am back at work, I have had a chance to look at the standard,
and Steven is correct (not that he needed my confirmation).

In fact, Example 2 shows exactly this case:

always @* begin // equivalent to @(a or b or c or d or tmp1 or tmp2)
tmp1 = a & b ;
tmp2 = c & d ;
y = tmp1 | tmp2 ;
end

As one of my action items, I looked at the
IEEE-SA Standards Board Operations Manual
and the IEEE Standards Companion.

Briefly, in addition to "Errata" and "Corrigenda",
there is in the middle something called "Interpretations".

The key rule about Interpretations is that they cannot change what
is written (except for fixing an erratum). That is, you cannot say in an
Interpretation that "red" means "green".

So, since Example 2 explicitly shows that intermediate values are
included, Option 2 that Steven mentions below would seem to be a
"substantive change" which would belong to a corrigendum and require
re-balloting.

Option 3, since it does not really invalidate Example 2, might
be able to pass in an Interpretation.

I'll try to prepare fuller descriptions of errata, interpretations, and
corrigenda
for the next meeting.

Shalom


Steven Sharp wrote:

> We cannot define the behavior of the language in terms of an algorithm
> that does not and cannot exist. That leaves several choices:
>
> 1. Leave the sensitivity list independent of whether variables could
> get values from outside the block. That is how it is now.
> 2. Specify the exact algorithm to be used to approximate the computation
> of whether a variable can get its value from outside the block.
> 3. Specify that simulators can leave variables out of the sensitivity
> list if they can determine that they never get a value from outside
> the block, by whatever algorithm they like. This could result in
> different simulators producing different results if the block has
> side effects.
>
> Note that if the block has no visible side effects (which should be true
> of any truly combinational code), a simulator can already optimize the
> sensitivity list if it likes, using whatever conservative approximation
> it likes. Its behavior would be equivalent to the standard behavior and
> therefore legal. The only advantage of option 3 above is if there are a
> significant number of blocks which have side effects or which the compiler
> can't be sure don't have side effects (since this is uncomputable too).
> I don't know how common this will be.

--
Shalom Bresticker Shalom.Bresticker@motorola.com
Design & Reuse Methodology Tel: +972 9 9522268
Motorola Semiconductor Israel, Ltd. Fax: +972 9 9522890
POB 2208, Herzlia 46120, ISRAEL Cell: +972 50 441478

"The devil is in the details."




From: Shalom.Bresticker@motorola.com
To: etf-bugs@boyd.com
Cc:
Subject: Re: errata/82: Section 9.7.5: Description of @*, @(*) incomplete
Date: Thu, 18 Sep 2003 12:30:14 +0300 (IDT)

Previous discussion of this issue in threads starting at:

http://boydtechinc.com/btf/archive/btf_1998/0297.html
http://boydtechinc.com/btf/archive/btf_1999/0467.html
http://boydtechinc.com/btf/archive/btf_1999/0629.html
http://boydtechinc.com/btf/archive/btf_1999/0631.html
http://boydtechinc.com/btf/archive/btf_2001/1498.html
http://boydtechinc.com/btf/archive/btf_2002/1739.html
http://boydtechinc.com/btf/archive/btf_2002/1804.html
http://boydtechinc.com/btf/archive/btf_2002/1818.html
http://boydtechinc.com/btf/archive/btf_2002/1946.html
http://boydtechinc.com/etf/archive/etf_2002/0043.html
http://boydtechinc.com/etf/archive/etf_2002/0313.html

Unformatted


Hosted by Boyd Technology