Evaluation order not specified in LRM?

E

Evan Lavelle

Guest
The LRM doesn't seem to have much to say on evaluation order. 4.1.4
just says that "the operators shall follow the associativity rules",
an expression "need not" be evaluated if short-circuiting is possible,
and that the operands of '&' might be evaluated left-to-right.

Have I missed something? Are there any requirements on the evaluation
order of the operands of an operator, on argument lists, or anything
else? Or any specific short-circuit requirements?

I've run a quick test (below) on 3 sims; 2 of them produce a result of
12 (ie. the operands of '+' are evaluated left-to-right), and the
other one produces 6 (right-to-left).

Thanks -

Evan

-------------------------------------------------------------------
module test;
integer b;

initial
main;

function integer assign_b;
input val;
integer val;
begin
b = val;
assign_b = val;
end
endfunction

task main;
begin
b = 9;
b = b + assign_b(3);
$display("b is %0d\n", b);
end
endtask
endmodule
 
Evan Lavelle wrote:

I've run a quick test (below) on 3 sims; 2 of them produce a result of
12 (ie. the operands of '+' are evaluated left-to-right), and the
other one produces 6 (right-to-left).
I get:

# b is 6

for ModelSim SE 6.2a using

vlog -vlog01compat

Same result using

vlog -vlog95compat

-- Mike Treseler
 
On Fri, 27 Apr 2007 23:23:27 +0100, Evan Lavelle <nospam@nospam.com>
wrote:

The LRM doesn't seem to have much to say on evaluation order. 4.1.4
just says that "the operators shall follow the associativity rules",
an expression "need not" be evaluated if short-circuiting is possible,
and that the operands of '&' might be evaluated left-to-right.

Have I missed something? Are there any requirements on the evaluation
order of the operands of an operator, on argument lists, or anything
else? Or any specific short-circuit requirements?
I don't think so. It is, I believe, intentionally undefined.
Consequently it is <cough> a good idea not to do anything that
has side-effects in a non-trivial expression.

In Verilog, this would only be a problem if you call a function
(or system-function) with side-effects as part of an expression:

reg a, b;
function f(input c);
b = c;
return 1;
endfunction
....
begin
a = 0;
if (a && f(a)) // f() might not be executed,
// so we don't know whether b is updated
...

I've run a quick test (below) on 3 sims; 2 of them produce a result of
12 (ie. the operands of '+' are evaluated left-to-right), and the
other one produces 6 (right-to-left).
AFAIK you'll also find differences among simulators about
whether they do short-circuit evaluation.

The problem is far worse in SystemVerilog, where the
temptation to use ++ and -- in complicated expressions
is irresistible to C programmers. But at least the
1800 LRM explicitly warns you about it - see the
"here be dragons" note at the end of clause 8.3.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
As per V2K or Verilog-2005 LRM,
All operators shall associate left to right with the exception of the
conditional operator, which shall associate
right to left. Associativity refers to the order in which the
operators having the same precedence are
evaluated. Thus, in the following example, B is added to A, and then C
is subtracted from the result of A+B.
A + B - C

Note that the concept of short-circuiting is only applicable for
logical expressions. [&& or ||]. Plz don't get confused in this case.

IMHO, the result should be 12.

-- Karthik
 
On Sat, 28 Apr 2007 10:27:21 +0100, Jonathan Bromley
<jonathan.bromley@MYCOMPANY.com> wrote:

I don't think so. It is, I believe, intentionally undefined.
Consequently it is <cough> a good idea not to do anything that
has side-effects in a non-trivial expression.
Or possibly *un*intentionally undefined?
:)
 
On Fri, 27 Apr 2007 15:49:44 -0700, Mike Treseler
<mike_treseler@comcast.net> wrote:


# b is 6

for ModelSim SE 6.2a using
Thanks - I'd just tried the free sims:

Icarus, Veriwell 12
ModelSim, ISE 6
 
On 29 Apr 2007 03:57:32 -0700, karthik <karthikeyan.isha@gmail.com>
wrote:

As per V2K or Verilog-2005 LRM,
All operators shall associate left to right with the exception of the
conditional operator, which shall associate
right to left. Associativity refers to the order in which the
operators having the same precedence are
evaluated. Thus, in the following example, B is added to A, and then C
is subtracted from the result of A+B.
A + B - C
Associativity is only one (smallish) part of evaluation order. At the
top level, you have the precedence rules; then associativity among
operators of the same precedence; and then operand evaluation order.
There's also the issue of the evaluation order of subprogram
parameters, concatenations, and so on, which are equally important.
Saying that "the operators shall follow the associativity rules" in
4.1.4 is simply a statement of the obvious.

Note that the concept of short-circuiting is only applicable for
logical expressions. [&& or ||]. Plz don't get confused in this case.
In C, at least, you can add the conditional operator ('?') to that
list. The Verilog LRM actually says that "if the final result of an
expression can be determined early, the entire expression need not be
evaluated", so you could potentially add various other operators as
well (x = 0 * y, x = y - y, x = y / y, and so on). In any event,
short-circuiting is only relevant because it tells you when
side-effects will be evaluated, and when they mustn't be evaluated,
and I don't think the LRM says anything about this (it uses "need not"
rather than "must not", so 4.1.4 actually says nothing of any value).

IMHO, the result should be 12.
It's 12 in, for example, Java and C#, and undefined in, for example,
C. In Verilog, it seems to be undefined by omission, rather than
specification.

Evan
 
Evan Lavelle wrote:
The LRM doesn't seem to have much to say on evaluation order. 4.1.4
just says that "the operators shall follow the associativity rules",
an expression "need not" be evaluated if short-circuiting is possible,
and that the operands of '&' might be evaluated left-to-right.
I think this is partly a result of Verilog's history as a hardware
description language. If an expression is expected to represent
a piece of combinational logic, then it doesn't make sense to
talk about the evaluation order. The operators are being evaluated
in parallel with separate hardware. If the expression does
represent cominational logic, then the order of evaluation is
irrelevant. Conversely, if the order of evaluation or short-
circuiting
matters, you must have done something inappropriate for logic
and are in dangerous territory.

There are other places where using functions that have side
effects will get you into trouble. It is effectively discouraged, but
is not disallowed.

Have I missed something? Are there any requirements on the evaluation
order of the operands of an operator, on argument lists, or anything
else?
I don't think so.

Or any specific short-circuit requirements?
In the Verilog LRM, the allowance for short-circuiting appears
to be for the benefit of optimizations in simulators. And since
there are very few run-time errors in Verilog, the traditional uses
of guaranteed short-circuiting are not that important. If you
accidentally divide by 0 because you didn't short-circuit after
the check for 0, no harm is done.

In SystemVerilog, you start running into situations that can lead
to run-time errors. The most obvious case is referencing null
class handles. Here you would want to be able to use the
classic C coding style of

if (handle != null && handle.whatever)

which requires && to be a short-circuiting operator. But
Verilog does not guarantee that (though implementations
may do it anyway). This is something that has been brought
up in the SV LRM committees.
 

Welcome to EDABoard.com

Sponsor

Back
Top