RE: errata/82: Section 9.7.5: Description of @*, @(*) incomplete

From: Michael McNamara (mac@verisity.com)
Date: Tue Jul 30 2002 - 17:30:03 PDT


Precedence: bulk

The following reply was made to PR errata/82; it has been noted by GNATS.

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
>



This archive was generated by hypermail 2.1.4 : Thu Oct 10 2002 - 09:24:27 PDT and
sponsored by Boyd Technology, Inc.