Re: More issues


Subject: Re: More issues
From: Michael McNamara (mac@verisity.com)
Date: Thu Dec 26 2002 - 16:39:02 PST


Dave Rich writes:
> Steven,
>
> As I mentioned in an earlier post, for good or bad, SystemVerilog
> follows all the semantics of an established and well documented ANSI C
> standard except pointers and bit fields. Trying to place restrictions on
> certain features will only make matters more complicated for the user.
>
> See my comments below. Where I think everyone will agree, I will
> propose LRM changes in separate posts so we can quickly get them out of
> the way.
>
> Dave
>
> Steven Sharp wrote:
>
> >I finally got around to continuing my review of SV 3.0 beyond Section 5.
> >
> >Steven Sharp
> >sharp@cadence.com
> >
> >
> >------------------------------------------------------------------------
> >
> >Issues with System Verilog Specification (cont.)
> >
> >
> >Comments on Section 7
> >
> >1. Treating assignments as expressions is a bad idea. Just because something
> > is done in C doesn't mean it has to be copied. Expression side-effects
> > are undesirable in Verilog because they mess up the combinational behavior
> > of continuous assignments. We should not be deliberately adding more
> > side-effects to cause problems.
> >
> This feature is frequently used in while loops to test the return value
> of a function.

 [presumably in some other language; not Verilog].

 Further, allowing

  while ( more_work(a) ) begin

  end

 would make it no longer possible to detect the call of a function
 from the call of a task syntactically. The benefits are not yet
 compelling.

> Also used to set a group of variables to the same value.

 This is not of huge value, IMHO.

> Combinational behavior is a matter of synthesis style. Those tools are
> free to accept or reject assignments as expressions.

 And then System Verilog isn't a standard, but a guideline. Ladies
 and Gentlemen, it is not a feature that only a subset of Verilog is
 synthesizable. To introduce a construct that would very naturally be
 used in the design part of Verilog, and not demand that it be
 sythesized is not helping the world, IMHO. So we end up with two
 less than compelling arguments in favor of this new feature; and then
 also an indications that the supported would be willing to make this
 non sythesizable? Seems pretty weak. My recollection had the
 original CoDesign donation being the Sythesizable Subset of
 SuperLog. Was this intended to be sythesizable or not?

> >2. The increment and decrement operators also introduce side-effects, as
> > defined in the 3.0 document. This is bad. Treating them as assignment
> > statements instead of expressions would solve this. It would still allow
> > their use in for-loop increments, which is the main place they would be
> > useful. Most of the "clever" uses of increment operators in C code are
> > poor programming style. Only allowing these as statements would also
> > resolve all the issues of evaluation order that have arisen over these
> > as operators.
> >
> >
> What about as a bit select index?:
> word = mem[i++];

 This is a perfect example that shows the bad side effect. By
 incrementing 'i' in the statement, it is easy to overlook that the
 index has been moved, making possible a common bug. Let us say
 subsequent code examines word, makes some decisons, and occasionally
 desires to update mem[i] based on those decisions. Should one update
 mem[i-1] ? Or instead perhaps other code may have incremented i, so
 is it mem[i-2]..?

 Much better style is:

 for (i = 0; i < 10; i++ ) begin
   word = mem[i];
   if (word < max && word > min ) begin
     prev = mem[i-1];
   ...
   end
   mem[i] = new_word;
 end

 This way the loop bookkeeping is all in one place, so the body of the
 loop can be written and managed without requiring careful ordering of
 the source.

> Someone had suggested earlier that we allow only one assignment to the
> same variable per statement unit.

 What is a statement unit?

 How would this help?

 Wouldn't this outlaw 'word = mem[i++];'

 Already in Verilog you can type:

 update_cache(addr, line, word, index, count); which quite possibly
 could change the value of every arguement.

>
> >3. Section 7.7 does not explain the signedness of an assignment statement
> > when used as an expression. If a signed expression is assigned to an
> > unsigned variable, what is the result type of the assignment?
> >
> I agree this is unclear. ANSI C says that the lvalue is used as the type
> of the expression. SystemVerilog should do the same.
>
> >3. Section 8.4 states that a local variable declared within a for-loop
> > can be referenced hierarchically by adding a statement label before
> > the for-loop. And yet section 8.6 states that a statement label does
> > not create a hierarchy scope. This is a contradiction. If it is a
> > special exception, then it is a nasty kludge.
> >
> I agree there is a contradiction here. The original Superlog donation
> explicitly said that:
>
> A: statement;
>
> is equivalent to:
>
> begin: A statement; end
>
> I believe that is the way it is supposed to be. I did not see any
> discussion in the Verilog++ committee so I am going under the assumption
> that this is typo.
>
> >
> >4. If a local variable is declared within a for-loop without a statement
> > label, then it has no hierarchical name. This is a problem which has
> > been raised for declarations in unnamed blocks too.
> >
> This is no different than for unnamed instances. Tools can automatically
> generate block names for debugging. However, the source code will not be
> able to cross reference these identifiers in unnamed blocks.
>
> >5. Statement labels don't allow anything that named blocks don't already
> > allow. Disables should be discouraged, not encouraged by adding another
> > way of doing the same thing.
> >
> Statement labels are useful for assertions and process control. By
> printing out scope information, assertion failures or other errors would
> be more useful then just file/line#. You don't want to end up with code
> that looks like
> begin // or fork
> begin :A
> statement;
> end
> begin : B
> statement;
> end
> end //or join
>
> >6. Section 8.8 states that disables shall not affect any nonblocking
> > assignments which have been started. This is incompatible with the
> > IEEE 1364 standard, which allows either behavior. Verilog-XL disables
> > nonblocking assignments which were started in the disabled block.
> > Apparently some simulators failed to do so, and the IEEE standard
> > relaxed the requirements to allow those simulators to be compliant.
> > If the rules are being tightened up, then it should be standardized
> > on the original de facto standard behavior. It is fine for continue
> > and break to be simple jumps, since this is not a backward compatibility
> > issue.
> >
> I agree this should be tightened up. As the author of the non-blocking
> assignment operator, I would love to see this fixed. Disables should
> kill off all pending assignments. NBAs are supposed to eliminate
> ambiguity. If a disable occurs on the same clock edge as the NBA, you
> want to have unambiguous behavior.

As the author of the simulator that did not follow XL's lead in
hunting down and disabling Non Blocking Assigns that were started by a
context which was later disabled, let me say 1) I was unaware that XL
did that, and 2) when I was made aware, I considered it to then be a
bug in my implementation, which I intended to fix, but 3) current
customer models depended on this behavior, and then the IEEE
standardized the ambiguousness. So, as I had other very high
priorities, then world was left as it was.

> >7. Section 8.8 says nothing about the effect of disables (or breaks and
> > continues) on other subprocesses like procedural continuous assigns
> > and forces. Verilog-XL disables all of them, and IEEE 1364 leaves
> > the behavior unspecified.
> >
> SystemVerilog does not change the behavior of disable(other than #6
> above). The LRM was only trying to relate the behavior of break and
> continue to an equivalent disable statement, but failed.
>
> >8. What happens when a break or continue is executed from a fork-join
> > subprocess inside a loop? Execution is not allowed to continue from
> > the fork-join until all subprocesses are complete. Does this require
> > that the fork-join be effectively disabled? Or is something else
> > required?
> >
> I agree that this is unclear. I suggest two possible solutions. One
> solution is to define break, continue, and return in terms of their
> equivalent disable representation. This would take care of all the
> situation you describe. For example:
> SV: loop_statement break;
> V: begin: _break loop_statement disable _break; end
>
> SV: loop_statement continue;
> V: loop_statement begin: _continue disable _continue; end
>
> SV: task mytask; return; endtask
> V: task mytask begin: _return disable _return end endtask
>
> An alternative is to define break, continue and return as just branching
> statements. Then you will have to put restrictions like break can only
> be invoked from the same thread as the original loop. The situation you
> describe would have to be illegal.
>
> >9. What happens if a break or continue is executed from a dynamic process
> > inside a loop? Execution is supposed to terminate when reaching the
> > end of the process. Is this illegal, or does it cause termination of
> > the process, or something else?
> >
> Same issue as #8
>
> >10. Is the iff qualifier really useful? The example uses can be done
> > just as well with an if-test around the body of the always block.
> >
> This feature will have more benefits in the SV3.1 spec for declaring
> gated clocking domains.
>
> >
> >11. Section 8.9 defines posedge and negedge in a manner incompatible
> > with IEEE 1364. SV defines them as transitions from and to a value
> > of 0. IEEE 1364 defines them as transitions on the lowest bit of
> > a multi-bit value, not based on all bits.
> >
> It sounds like 1364-2001 make it useless to have a multi-bit value
> qualified by posedge/negedge.

1364-2001 merely codified what it was believed by the members of the
committee that Verilog-XL did with multibit valued expressions as
arguments to change/posedge/negedge: convert them to scalar via
truncation, and then apply the change/posedge/negedge operation.

Apparently this is (no longer/not) what Verilog-XL does; however it is
what VCS did, and still does; consider:

module foo;
  reg [3:0] a;

  always @(posedge a) $display($time,,"POSEDGE a: %b",a);
  always @(negedge a) $display($time,,"NEGEDGE a: %b",a);
  always @(a) $display($time,,"CHANGE a: %b",a);

  initial for (a = 0; a < 7; a = a + 1) #10;
   
endmodule

Verilog-XL 3.10 does:
foo

                   0 CHANGE a: 0000
                   0 NEGEDGE a: 0000
                  10 CHANGE a: 0001
                  10 POSEDGE a: 0001
                  20 CHANGE a: 0010
                  30 CHANGE a: 0011
                  40 CHANGE a: 0100
                  50 CHANGE a: 0101
                  60 CHANGE a: 0110
                  70 CHANGE a: 0111
0 simulation events (use +profile or +listcounts option to count)
CPU time: 0.2 secs to compile + 0.0 secs to link + 0.0 secs in simulation
End of VERILOG-XL 3.10.s010

where as VCS does:
Compiler version 6.2_Comp64; Runtime version 6.2_Comp64; Dec 26 16:24 2002

                   0 CHANGE a: 0000
                   0 NEGEDGE a: 0000
                  10 CHANGE a: 0001
                  10 POSEDGE a: 0001
                  20 CHANGE a: 0010
                  20 NEGEDGE a: 0010
                  30 CHANGE a: 0011
                  30 POSEDGE a: 0011
                  40 CHANGE a: 0100
                  40 NEGEDGE a: 0100
                  50 CHANGE a: 0101
                  50 POSEDGE a: 0101
                  60 CHANGE a: 0110
                  60 NEGEDGE a: 0110
                  70 CHANGE a: 0111
                  70 POSEDGE a: 0111
           V C S S i m u l a t i o n R e p o r t
Time: 70

A lesson to us: more participation by Cadence back then, or a more
definitive inital technology donation, would have helped.

> >12. The "changed" keyword is unnecessary and meaningless. The situation
> > that it supposedly avoids is non-existent. Perhaps someone was aware
> > of an old bug in Verilog-XL that would trigger on changes to operands
> > that did not change the expression value. That bug was fixed eons ago.
> > This keyword should be thrown away.
> >
> I agree. "changed" should be removed
>
> >13. Section 8.9 notes that assignment expressions are allowed in an event
> > control. It does not specify at what times the assignment will be
> > executed. Presumably it will be evaluated whenever an operand of the
> > RHS has changed, to determine whether its value has changed. Different
> > simulators may evaluate the RHS in different circumstances, as long as
> > they all guarantee to wake the event control up if the RHS value changes.
> > This construct would make this unspecified behavior visible to the user
> > through the side effect of changing the value of the LHS. This is another
> > situation where the side-effects of assignments within expressions causes
> > a problem.
> >
> Same issue as #1
>
> --
> Dave Rich
> Principal Engineer, CAE, VTG
> Tel: 650-584-4026
> Cell: 510-589-2625
> DaveR@Synopsys.com
>
>



This archive was generated by hypermail 2b28 : Thu Dec 26 2002 - 16:39:34 PST