Re: [sv-bc] [Fwd: Issues with IEEE 1364-2005]

From: Brad Pierce <Brad.Pierce_at_.....>
Date: Tue Aug 01 2006 - 07:46:35 PDT
-----Non-member submission-----
From: Will Adams [mailto:wadams@freescale.com] 
Sent: Tuesday, August 01, 2006 7:21 AM

A couple of further points on section 5.1.13 `Conditional operator'.

The first sentence is `The conditional operator, also known as ternary
operator, shall be ...'. This is wrong. A ternary operator is one that
requires three operands, just as a binary operator requires two. The
conditional operator is _a_ ternary operator (possibly the only one
defined in Verilog), but the terms are not synonymous.

The `condition' is defined to be a comparison of `expression1' with
zero, using logical equality (which should be logical inequality to
define the intended behaviour). The logical equality and inequality
operators return 0, 1 or X. They can never return Z. So it is redundant,
and possibly confusing, to state `If the condition evaluates to an
ambiguous value (x or z)'. The `or z' should be removed.

will


Brad Pierce wrote:
> -----Non-member submission-----
> From: Will Adams [mailto:wadams@freescale.com] 
> Sent: Friday, July 28, 2006 1:15 PM
> Subject: Re: [sv-bc] [Fwd: Issues with IEEE 1364-2005]
> 
> I agree that functions with side effects are a programming practice to
> be avoided. But the Standard itself requires the implementation of
> functions that have side effects (for example `$fgetc()'). Functions
can
> only be called in an expression context. A user would likely be
> surprised to discover (I know I was!) that the statement `b =
$fgetc(fd)
> + a' is not guaranteed to read a character from file `fd'.
> 
> The `contradictory desirable behaviors' that I describe are the
behavior
> shown by the C language for the syntax given. In C the operands of a
> logical operator are always evaluated left-to-right, stopping as soon
as
> the result is known; all operands of an arithmetic operator are
> evaluated, in any order. C has been in use for over 30 years, and its
> semantics are well known by a large community of programmers.
> 
> I think it is unfortunate that Verilog uses the same operator symbols
as
> C, but allows them to be implemented with different semantics. It is
> particularly unfortunate that the change in semantics is optional, so
> users must be aware of all the different, legal, ways that a statement
> may be executed to fully understand if it will behave as they desire
on
> any Standard-conforming implementation.
> 
> will
> 
> 
> Bresticker, Shalom wrote:
>> Side-effects are in general an undesirable programming practice.
>>
>> Will's two examples produce two contradictory desirable behaviors:
>>
>> In the example "p != null && p.data > 0", one would desire that the 
>> expression be short-circuited.
>>
>> On the other hand, in the expression "f( ) + a", one would normally 
>> want the side-effect to occur regardless of a, especially because
most
> 
>> users don't even know that short-circuiting can occur.
>>
>> I do agree that the description of the condition evaluation in 5.1.13

>> appears to be reversed.
>>
>> Shalom
>>
>>> -----Original Message-----
>>> From: owner-sv-bc@server.eda-stds.org
[mailto:owner-sv-bc@server.eda-
> 
>>> stds.org] On Behalf Of Brad Pierce
>>> Sent: Wednesday, July 26, 2006 8:13 PM
>>> To: Will Adams
>>> Cc: sv-bc@server.eda-stds.org; michael.burns@freescale.com
>>> Subject: RE: [sv-bc] [Fwd: Issues with IEEE 1364-2005]
>>>
>>> See also --
>>>
>>>     http://www.boyd.com/1364_btf/report/full_pr/449.html
>>>     http://www.boyd.com/1364_btf/report/full_pr/288.html
>>>
>>> -- Brad
>>>
>>> -----Original Message-----
>>> From: Will Adams [mailto:wadams@freescale.com]
>>> Sent: Wednesday, July 26, 2006 9:31 AM
>>> To: Bresticker, Shalom
>>> Cc: Brad Pierce; sv-bc@eda-stds.org; michael.burns@freescale.com
>>> Subject: Re: [sv-bc] [Fwd: Issues with IEEE 1364-2005]
>>>
>>> On the evaluation of the conditional operator, IEEE 1364-2005, 
>>> section
>>> 5.1.13 `Conditional operator', states the following.
>>>
>>>    conditional_expression ::= (From A.8.3)
>>>      expression1 ? { attribute_instance } expression2 : expression3
>>>    expression1 ::= expression
>>>    expression2 ::= expression
>>>    expression3 ::= expression
>>>
>>>    The evaluation of a conditional operator shall begin with a
> logical
>>>    equality comparison (see 5.1.8) of expression1 with zero, termed
>> the
>>>    condition. If the condition evaluates to false (0), then
>> expression3
>>>    shall be evaluated and used as the result of the conditional
>>>    expression. If the condition evaluates to true (1), then
>> expression2
>>>    is evaluated and used as the result. If the condition evaluates
to
>> an
>>>    ambiguous value (x or z), then both expression2 and expression3
>> shall
>>>    be evaluated; and their results shall be combined, bit by bit,
>> using
>>>    Table 5-21 to calculate the final result unless expression2 or
>>>    expression3 is real, in which case the result shall be 0.
>>>
>>> I am not sure why this defines `condition' as `a logical equality 
>>> comparison of expression1 with zero', since this means that
>> `condition'
>>> is the negation of `expression1' (`expression1 == 0' is 1 when 
>>> `expression1' is 0, 0 when it is 1, and X when it is X or Z), and, 
>>> applying the rest of the definition, when `expression1' is 1, 
>>> `condition' is 0, and so `expression3' is evaluated as the result of
>> the
>>> conditional expression. Similarly, if `expression1' is 0, then 
>>> `expression2' is evaluated as the result of the conditional
>> expression.
>>> This seems to give the semantics of an `if else then' operator, 
>>> rather than an `if then else', which I doubt is what is intended.
>>>
>>> Regardless, it does state that `expression1' must be evaluated
first,
> 
>>> and only one of `expression2' and `expression3' is evaluated when 
>>> `condition' is 1 or 0, and both are evaluated when `condition' is X 
>>> or Z. It also clearly states that evaluation of the conditional 
>>> operator `shall begin with' the evaluation of the condition, and
only
> 
>>> after
>> this
>>> is evaluated does it start evaluating `expression2' or
`expression3'.
>>>
>>> Given this, my question about the order of evaluation of the two 
>>> conditional operators in `a ? b : c ? d : e' remains. In cases where
>> the
>>> right-hand conditional operator is evaluated, the evaluation of the 
>>> left-hand conditional operator begins before, and ends after, the 
>>> evaluation of the right-hand operator, so in what sense is this 
>>> right-to-left evaluation of the operators?
>>>
>>> There is, in my mind, a problem with the statement in section 5.1.4,

>>> `However, if the final result of an expression can be determined
>> early,
>>> the entire expression need not be evaluated.' This refers only to
the
> 
>>> _result_ of an expression, and not to any side-effects, which leaves
>> us
>>> in a position where side-effects of potentially unevaluated
arguments
> 
>>> may or may not occur. This in turn requires excessively careful 
>>> coding to avoid code that may give different results on different 
>>> Standard-conforming implementations.
>>>
>>> If this section is read strictly, then we must write code as though
>> all
>>> operands may be evaluated, and may not be if other operands are 
>>> sufficient to determine the result of the expression. Thus my
example
> 
>>> `p != null && p.data > 0' is illegal, since `p.data' is illegal when
>> `p'
>>> is null, and a Standard-conforming implementation may evaluate the 
>>> second operand when `p' is null. (We can, of course, rewrite this as

>>> `p != null ? p.data > 0 : 0', to give an expression that is 
>>> guaranteed not to evaluate `p.data' when `p' is null.)
>>>
>>> Also, we should never write `f( ) + a' if function call `f( )' has a

>>> side-effect, because a Standard-conforming implementation may choose
>> not
>>> to evaluate the first operand if `a' evaluates to X (and thus the
>> result
>>> of the expression is X, regardless of the value of `f( )').
>>>
>>> My preference is for a rule that mandates which operands are
>> evaluated,
>>> and in which order (where this is important), together with a rule 
>>> similar to the `as if' rule of the C standard, which allows 
>>> implementations to break the rules as long as the observable effect 
>>> is as if they had been followed. So, for example, if the rule is
that
> 
>>> all operands in an arithmetic expression must be evaluated, using
the
> 
>>> `as if' rule, an implementation is allowed not to evaluate `a' in `a
> + X'
>>> provided that it can determine that the evaluation of `a' has no 
>>> observable side-effects.
>>>
>>> will adams
>>>
>>>
>>> Bresticker, Shalom wrote:
>>>
>>>> 1. As Brad points out, 1364 does relate to short-circuiting by
>> saying
>>>>  that an implementation may optionally implement short-circuiting, 
>>>> but is not required to do so.
>>>>
>>>> 2. In the given example,
>>>>> a ? b : c ? d : e
>>>> which is parsed as
>>>>> a ? b : ( c ? d : e )
>>>> Will says, " If `a' is 1, then the RH `?:' operator is not
>> evaluated"
>>>>  .
>>>>
>>>> That is not at all clear. Will himself says, " The operand
>> evaluation
>>>>  order only really needs to be defined
>>>>> when the result of evaluating one operand affects how the
remaining
> 
>>>>> operands are evaluated."
>>>> I don't know what implementations actually do. But at least in most

>>>> cases, there is no problem in principle in defining that the second
>>>> ?: is evaluated first. If an implementation optimizes by
identifying
> 
>>>> that it is unnecessary, that is not a problem as long as it does
not
> 
>>>> change the result.
>>>>
>>>> Shalom
>>>>
>>>>
>>>>
>>>>> -----Original Message----- From: owner-sv-bc@server.eda-stds.org
>>>>> [mailto:owner-sv-bc@server.eda- stds.org] On Behalf Of Brad Pierce
>>>>>  Sent: Tuesday, July 25, 2006 9:26 PM To:
sv-bc@server.eda-stds.org
>>>>>  Cc: michael.burns@freescale.com; WADAMS@freescale.com Subject:
Re:
>>>>>  [sv-bc] [Fwd: Issues with IEEE 1364-2005]
>>>>>
>>>>> See http://www.eda-stds.org/sv-ac/hm/2501.html .
>>>>>
>>>>> -- Brad
>>>>>
>>>>> -----Original Message----- From: owner-sv-bc@eda-stds.org 
>>>>> [mailto:owner-sv-bc@eda-stds.org] On Behalf Of Brad Pierce Sent:
>>>>> Tuesday, July 25, 2006 11:20 AM To: sv-bc@eda-stds.org Cc:
>>>>> michael.burns@freescale.com; WADAMS@freescale.com Subject: [sv-bc]
>>>>> [Fwd: Issues with IEEE 1364-2005]
>>>>>
>>>>> -----Non-member submission-----
>>>>>
>>>>> Date: Tue, 25 Jul 2006 09:19:24 -0700 From: Michael Burns 
>>>>> <michael.burns@freescale.com> CC: William Adams 
>>>>> <WADAMS@freescale.com>
>>>>>
>>>>> Hi folks,
>>>>>
>>>>> A comment on precedence definitions in Verilog from one of our 
>>>>> engineers.
>>>>>
>>>>> --Mike
>>>>>
>>>>> -------- Original Message -------- Subject: Issues with IEEE
>>>>> 1364-2005 Date: Mon, 24 Jul 2006 09:34:24 -0500 From: Will Adams 
>>>>> <wadams@freescale.com> To: Michael Burns 
>>>>> <michael.burns@freescale.com>
>>>>>
>>>>> There is a misstatement in the IEEE 1364-2005 standard, which has 
>>>>> been there for a while (it was in 1364-2001, and perhaps in
earlier
> 
>>>>> versions of the Standard). Do you know how to get it fixed?
>>>>>
>>>>> The error is in section 5.1.2 `Operator precedence'. There it 
>>>>> states
>>>>>
>>>>> 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.
>>>>>
>>>>> This is wrong. It does not make a lot of sense to talk about `the
>>>> order
>>>>> in which operators ... are evaluated', since I do not think this
is
> 
>>>>> well-defined in all circumstances (see below). What can be defined
> 
>>>>> is the order of _operand_ evaluation.
>>>>>
>>>>> This clause confuses associativity, which concerns the parsing of 
>>>>> expressions that are not fully parenthesized, with evaluation 
>>>>> order. I think what this may be getting at is that if `a + b + c'
>>>>> is parsed as `(a + b) + c', then the LH `+' operator is evaluated 
>>>>> before the RH `+' operator, since subexpression must be evaluated 
>>>>> before a containing expression. This definition fails to
adequately
> 
>>>>> describe the intended evaluation of the conditional operator,
which
> 
>>>>> associates
>>>> right-to-left,
>>>>> but whose operands are evaluated left-to-right.
>>>>>
>>>>> The right-to-left associativity of the conditional operator means 
>>>>> that the expression
>>>>>
>>>>> a ? b : c ? d : e
>>>>>
>>>>> is parsed as
>>>>>
>>>>> a ? b : ( c ? d : e )
>>>>>
>>>>> and not as
>>>>>
>>>>> ( a ? b : c ) ? d : e
>>>>>
>>>>> This is the same as in C, and allows the writing of `if ... else
if
>>>>>
>>>>>
>>>> ...
>>>>> else ...' constructs using the conditional operator without 
>>>>> excessive parentheses.
>>>>>
>>>>> However, the conditional operator is evaluated left-to-right.
First
>>>>>
>>>>>
>>>> the
>>>>> condition is evaluated, and then one or both branches is
evaluated.
>>>>>
>>>>>
>>>>>
>>>>> To see that the order of _operator_ evaluation is not always well 
>>>>> defined, consider the evaluation of this expression. Operand `a'
>>>> (which
>>>>> is an operand of the LH `?:' operator) is evaluated first. If `a'
>>>>> is
>>>> 1,
>>>>> then the RH `?:' operator is not evaluated; if `a' is 0, then the
>>>> `else'
>>>>> expression (ie, `c ? d : e') is evaluated, and its value is the 
>>>>> value
>>>> of
>>>>> the whole expression (ie, of the LH `?:' operator); and if `a' is
X
> 
>>>>> or Z, then the RH `?:' is evaluated, and its result is combined 
>>>>> bitwise with the result of evaluating `b' to yield the overall 
>>>>> result of the whole expression. So, in cases where the RH `?:'
>>>>> operator is
>>>> evaluated,
>>>>> the evaluation of the LH `?:' operator begins before, and ends 
>>>>> after, the evaluation of the RH `?:' operator. So what is the 
>>>>> operator evaluation order?
>>>>>
>>>>> I have seen similar mistakes in several C++ textbooks. As far as I

>>>>> can tell, it is necessary to have three concepts to clearly define

>>>>> how expressions are parsed and evaluated: precedence, 
>>>>> associativity, and operand evaluation order. The first two
together
> 
>>>>> allow the
>>>> construction
>>>>> of a unique parse tree for any expression, and the third then 
>>>>> mandates how this parse tree is to be evaluated.
>>>>>
>>>>> For most operators, there should be no operand evaluation order.
>>>>> For
>>>> the
>>>>> expression `a + b', an implementor should be free to evaluate `a'
>>>> first,
>>>>> `b' first, or both simultaneously, and they should be free to 
>>>>> choose a different order each time the expression is evaluated, if

>>>>> it suits
>>>> them
>>>>> to do so. The operand evaluation order only really needs to be 
>>>>> defined when the result of evaluating one operand affects how the 
>>>>> remaining operands are evaluated (the only exception to this I can

>>>>> think of is
>>>> the
>>>>> `,' sequencing operator in C).
>>>>>
>>>>> On a related issue, Section 5.1.9 `Logical operators' does not 
>>>>> state
>>>> if
>>>>> `&&' and `||' are evaluated in a short-circuit fashion, as they
are
> 
>>>>> in C. That is, for the C expression `a && b', `a' is evaluated 
>>>>> first,
>>>> and,
>>>>> if it is 0, `b' is not evaluated, since the value of the
expression
> 
>>>>> is
>>>> 0
>>>>> regardless of the value of `b'. If this is not the case, then
>>>> different
>>>>> coding idioms are required. In C, to test if integer pointer `p'
is
> 
>>>>> non-null, and points to a positive value, we write `p != 0 && *p >
> 
>>>>> 0'. This never leads to segfault, since `p' is not dereferenced if
> 
>>>>> it is null. An equivalent expression in SystemVerilog, `p != null 
>>>>> && p->data > 0' will cause a null object access error if
>>>> both
>>>>> operands are evaluated when `p' is null.
>>>>>
>>>>> Keeping the concepts of associativity and evaluation order
separate
> 
>>>>> allows for a clearer statement of the requirements. We can 
>>>>> distinguish `&&', which associates left-to-right, and whose 
>>>>> operands (I am
>>>> assuming)
>>>>> are evaluated left-to-right, from `+', which associates 
>>>>> left-to-right, but has no required evaluation order. Operator `?:'
>>>>> associates right-to-left, and evaluates left-to-right.
>>>>>
>>>>> I appreciate that these are minor issues, but I think the Standard
> 
>>>>> should be fixed to precisely define the requirements on 
>>>>> implementors.
>>>>>
>>>>> will
> 
Received on Tue Aug 1 07:46:50 2006

This archive was generated by hypermail 2.1.8 : Tue Aug 01 2006 - 07:46:55 PDT