-----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