ISSUE 344

Add Proposal  Edit Analysis  Edit Class, Environment, or Release
Number 344
Category errata
Synopsis 9.5: Case Statements with Real Expressions
State analyzed
Class doc-bug
Arrival-DateMay 07 2003
Originator Stephen Williams <steve@icarus.com>
Release 2001b: 9.5
Environment
Description
I received this bit of code in a bug report:

parameter PARM = 2.0;
reg r;

initial begin
case (PARM)
1.5 : r <= 'd0;
2.0 : r <= 'd1;
default:;
endcase
// [...]
end

This begs the question, are real valued expressions allowed in
case expressions like this. My guess is not, and my reasoning
comes from Section 4.1.1 Operators with real operands, where
table 11 explicitly lists the case compare operators as not
valid with real operands.

I would prefer to accept the clues in table 11 and say that
case statement expressions were not meant to carry real valued
expressions. Exactly Equals is not a reliable thing when it
comes to real values, especially if the user used 1.1 in this
example instead of 1.5.

For what it's worth, C switch expressions are required to be
integral.

On the other hand, this came from vendor code, suggesting that
a variety of existing Verilog compilers do accept this in spite
of the comments in Section 4.1.1. If it was intended that this
be legal (I doubt it) the exception should be made explicit in
Section 9.5, where the case statement is described, including
any rounding that should happen.
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
steve at picturel.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."


Fix
Audit-Trail
From: Steven Sharp <sharp@cadence.com>
To: etf-bugs@boyd.com, steve@icarus.com
Cc:
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Thu, 8 May 2003 19:04:30 -0400 (EDT)

The standard is not specific on this. However, Verilog-XL allows it,
and NC-Verilog follows suit.

The behavior seems to follow naturally from normal case statements. If
any of the case item expressions or case expression are real, then all
get converted to real. The case expression is compared to each of the
case item expressions in turn, using "==" since "===" doesn't apply to
reals.

There might indeed be issues with roundoff errors causing failure to
match if the expressions involve floating point operations. However,
there are situations where this is not an issue and where this kind of
case statement would be useful. For example, if there is a predefined
set of real values that a variable could be set to (e.g. a choice of
different input clock frequencies), the case could determine which one
it had been set to. The input conversion of inexactly represented constants
such as 1.1 should be the same in all places, so the compare should work.

Since this is allowed by Verilog-XL, and probably most other simulators,
and there are situations where it could be handy, I don't see any reason
not to allow it and document it.

I also tested casex and casez in XL and NC, and reals are allowed there
too. Since any X or Z bits disappear during conversion to real, this
behaves exactly as if case had been used instead. Since it doesn't add
any capabilities beyond case, there is less argument in favor of allowing
reals with casex and casez.

Steven Sharp
sharp@cadence.com


From: Michael McNamara <mac@verisity.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Thu, 8 May 2003 16:24:01 -0700

Steven Sharp writes:
> Precedence: bulk
>
> The following reply was made to PR errata/344; it has been noted by GNATS.
>
> From: Steven Sharp <sharp@cadence.com>
> To: etf-bugs@boyd.com, steve@icarus.com
> Cc:
> Subject: Re: errata/344: Case Statements with Real Expressions
> Date: Thu, 8 May 2003 19:04:30 -0400 (EDT)
>
> The standard is not specific on this. However, Verilog-XL allows it,
> and NC-Verilog follows suit.
>
> The behavior seems to follow naturally from normal case statements. If
> any of the case item expressions or case expression are real, then all
> get converted to real. The case expression is compared to each of the
> case item expressions in turn, using "==" since "===" doesn't apply to
> reals.
>
> There might indeed be issues with roundoff errors causing failure to
> match if the expressions involve floating point operations. However,
> there are situations where this is not an issue and where this kind of
> case statement would be useful. For example, if there is a predefined
> set of real values that a variable could be set to (e.g. a choice of
> different input clock frequencies), the case could determine which one
> it had been set to. The input conversion of inexactly represented constants
> such as 1.1 should be the same in all places, so the compare should work.
>
> Since this is allowed by Verilog-XL, and probably most other simulators,
> and there are situations where it could be handy, I don't see any reason
> not to allow it and document it.
>
> I also tested casex and casez in XL and NC, and reals are allowed there
> too. Since any X or Z bits disappear during conversion to real, this
> behaves exactly as if case had been used instead. Since it doesn't add
> any capabilities beyond case, there is less argument in favor of allowing
> reals with casex and casez.
>
> Steven Sharp
> sharp@cadence.com
>

Table 11 (page 42) specifically disallows using === and !== with
reals; from which one could conclude that case.. endcase can not
include reals; however 4.5.2 does have one coercing the type of each
operand to the type of the expression, which for case comparision, is
an unsigned integer.



From: Stephen Williams <steve@icarus.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Thu, 08 May 2003 16:36:36 -0700

sharp@cadence.com said:
> The behavior seems to follow naturally from normal case statements.
> If any of the case item expressions or case expression are real, then
> all get converted to real. The case expression is compared to each of
> the case item expressions in turn, using "==" since "===" doesn't
> apply to reals.

If that's what's intended, then that's what should be said explicitly.
Otherwise, the standard can be said to be vague, even contradictory.
And that's what I suppose I'll implement, since it seems to be what
everyone does.

However, I'll go on record saying I don't like it. Equality with real
numbers is a dodgy thing, especially when values are calculated or are
not nice neat powers of two. There is also the C precedent of the switch
statement, where real/double values are explicitly not allowed.
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
steve at picturel.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."



From: Stephen Williams <steve@icarus.com>
To: Michael McNamara <mac@verisity.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Thu, 08 May 2003 16:52:02 -0700

mac@verisity.com said:
> Table 11 (page 42) specifically disallows using === and !== with
> reals; from which one could conclude that case.. endcase can not
> include reals; however 4.5.2 does have one coercing the type of each
> operand to the type of the expression, which for case comparision, is
> an unsigned integer

I'm pretty certain this is *not* what tools do in the wild.
To wit (and the report I originally received had code like this):

case (1.5)
1.0: $display("1.0");
1.5: $display("1.5");
2.0: $display("2.0");
default: $display("Reals are real weird.");
endcase

If rounding were done, the output would be "2.0". We may need
to take a survey:-)

I agree that this is a valid interpretation if what should happen.
It's the third, now. One must be chosen and made explicit.
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
steve at picturel.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."



From: Steven Sharp <sharp@cadence.com>
To: Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Thu, 8 May 2003 19:57:35 -0400 (EDT)

>Table 11 (page 42) specifically disallows using === and !== with
>reals; from which one could conclude that case.. endcase can not
>include reals;

This is a fairly weak argument, since case statements are not actually
defined as using case equality.

Rather, case equality/inequality are defined by saying that they do
the comparison like case does. This allows the possibility that they
have additional restrictions that don't apply to case.

This text and the table also come directly from the Verilog-XL Reference
Manual. Since they were supposed to describe the behavior of Verilog-XL,
the correct interpretation is clearly one that matches that behavior.
There is no indication that the behavior of Verilog-XL in this situation
is unintentional.

At any rate, I don't think anyone that is allowing this is going to stop
doing so, no matter what the standard says. So I think that we should
acknowledge that this is the de facto standard behavior, and document it.

Steven Sharp
sharp@cadence.com


From: Shalom.Bresticker@motorola.com
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Fri, 9 May 2003 12:44:51 +0300 (IDT)

> I also tested casex and casez in XL and NC, and reals are allowed there
> too. Since any X or Z bits disappear during conversion to real, this
> behaves exactly as if case had been used instead. Since it doesn't add
> any capabilities beyond case, there is less argument in favor of allowing
> reals with casex and casez.

What does 'disappear' mean?


From: Shalom.Bresticker@motorola.com
To: Michael McNamara <mac@verisity.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Fri, 9 May 2003 13:08:11 +0300 (IDT)

Why an unsigned integer?

> Table 11 (page 42) specifically disallows using === and !== with
> reals; from which one could conclude that case.. endcase can not
> include reals; however 4.5.2 does have one coercing the type of each
> operand to the type of the expression, which for case comparision, is
> an unsigned integer.

--
Shalom Bresticker Shalom.Bresticker@motorola.com
Design & Reuse Methodology Tel: +972 9 9522268
Motorola Semiconductor Israel, Ltd. Fax: +972 9 9522890
POB 2208, Herzlia 46120, ISRAEL Cell: +972 50 441478


From: Michael McNamara <mac@verisity.com>
To: Shalom.Bresticker@motorola.com
Cc: Michael McNamara <mac@verisity.com>, etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Fri, 9 May 2003 10:22:52 -0700

Shalom.Bresticker@motorola.com writes:
> Why an unsigned integer?
>
> > Table 11 (page 42) specifically disallows using === and !== with
> > reals; from which one could conclude that case.. endcase can not
> > include reals; however 4.5.2 does have one coercing the type of each
> > operand to the type of the expression, which for case comparision, is
> > an unsigned integer.
>
> --
> Shalom Bresticker Shalom.Bresticker@motorola.com
> Design & Reuse Methodology Tel: +972 9 9522268
> Motorola Semiconductor Israel, Ltd. Fax: +972 9 9522890
> POB 2208, Herzlia 46120, ISRAEL Cell: +972 50 441478

It is a ambiguous area, as I indicated. But one line of reasoning
would take Sentence 3 of 4.5.2, which says:

"Coerce the type of each operand of the expression (excepting those
which are self determined) to the type of the expression."

and sentence 9 of Section 4.5.1, which states: "Comparison results
(1,0) are unsigned, regardless of the operands."

and the fact that section 9.5 defines the case rather loosely:

"The case statement is a multiway decision statement that test whether
an expression matches one of a number of other expressions and
branches accordingly"

No information on whether types are self determined is given in
section 9.5, afaict.

In section 4.1.8, however, 'case equality' and 'case inequality'
operators are defined, and further it is stated that these shall
behave just as in the procedural case statement. Further it states
that the results shall always be a known value.

While I can not find a definition of 'Comparison operators,' one might
assume that they are made up of the relational and equality operators.

Hence my rather tenuous logic takes 4.5.1, with 4.1.8 implying that
case is the same as '===', and 4.5.2 to say that we should coerce the
argumenmts to === and !=== to unsigned, absent other statements (note
that other statements do exist specifing the type coercion for the <,
>, <= and >= operators, in section 4.1.7)

Have you followed me all the way through the bramble bush??? :-)

-mac




From: Steven Sharp <sharp@cadence.com>
To: etf-bugs@boyd.com, mac@verisity.com
Cc:
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Fri, 9 May 2003 15:20:27 -0400 (EDT)

> Hence my rather tenuous logic takes 4.5.1, with 4.1.8 implying that
> case is the same as '===', and 4.5.2 to say that we should coerce the
> argumenmts to === and !=== to unsigned, absent other statements (note
> that other statements do exist specifing the type coercion for the <,
> >, <= and >= operators, in section 4.1.7)

This argument is invalid. The fact that the result of the compare is
an unsigned value does not imply that the inputs are coerced to unsigned,
any more than the fact that the result of the compare is 1 bit wide
implies that the inputs are coerced to 1 bit wide before the compare.

Note that the result of '==' is also 1 bit unsigned, but it can still
be used to perform compares between real values, which do not get
converted to unsigned integers before the compare.

Steven Sharp
sharp@cadence.com


From: Michael McNamara <mac@verisity.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com, mac@verisity.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Fri, 9 May 2003 14:05:43 -0700

Steven Sharp writes:
>
> > Hence my rather tenuous logic takes 4.5.1, with 4.1.8 implying that
> > case is the same as '===', and 4.5.2 to say that we should coerce the
> > argumenmts to === and !=== to unsigned, absent other statements (note
> > that other statements do exist specifing the type coercion for the <,
> > >, <= and >= operators, in section 4.1.7)
>
> This argument is invalid. The fact that the result of the compare is
> an unsigned value does not imply that the inputs are coerced to unsigned,
> any more than the fact that the result of the compare is 1 bit wide
> implies that the inputs are coerced to 1 bit wide before the compare.
>
> Note that the result of '==' is also 1 bit unsigned, but it can still
> be used to perform compares between real values, which do not get
> converted to unsigned integers before the compare.
>
> Steven Sharp
> sharp@cadence.com

Don't get me wrong -- I know the right answer -- it is just that the
standard is silent on whether reals can be used in case statements,
and there is ambiguous language in various places that _might_ lead
you down various paths.

From: Steven Sharp <sharp@cadence.com>
To: mac@verisity.com
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Sat, 10 May 2003 13:29:31 -0400 (EDT)

I agree with you (and Stephen) that this is not specified and that
someone reading the standard might come up with a variety of different
interpretations. I just want to be sure that nobody is suggesting
one of the alternate interpretations is right.

Steven Sharp
sharp@cadence.com


From: Stephen Williams <steve@icarus.com>
To: etf-bugs@boyd.com
Cc:
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Tue, 13 May 2003 08:54:25 -0700

case (PARM)
1.5 : r <= 'd0;
2.0 : r <= 'd1;
default:;
endcase

steve@icarus.com said:
> This begs the question, are real valued expressions allowed in case
> expressions like this.

OK, so now faced with implementing this I find further vagueness
that needs to be explicitly clarified. In particular, what if only
some of the expressions are real valued? Some examples:

case (1.5)
1 : $display("1");
2 : $display("2");
default: $display("other");
endcase

In this case, all the guards are integral. Should the case expression
be rounded, or should all the guards be compared as reals? I can
imagine a user expecting a "1" or "2" output from this example.

casex (2)
1.5 : $display("1.5");
2.5 : $display("2.5");
2'b1x : $display("2");
default: $display("other");
endcase

Only some guard statements are real. Should all the comparisons be
done as real expressions? In this case, there are likely no surprises.

The intent is most likely that if there are any real valued expressions
in the case expression or the guards, then all the comparisons are
done as real==real. However, that would cause the second example above
to print "other" instead of "2". (Note the x.)

So perhaps the rule is that each comparison pair is independently
checked to determine the operand pairs, and thus whether to use
integral === or == with reals. This is consistent with the string-
of-if-then-else that defines case behavior.
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
steve at picturel.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."



From: Steven Sharp <sharp@cadence.com>
To: etf-bugs@boyd.com, steve@icarus.com
Cc:
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Tue, 13 May 2003 12:50:17 -0400 (EDT)

> OK, so now faced with implementing this I find further vagueness
> that needs to be explicitly clarified. In particular, what if only
> some of the expressions are real valued?

If you look at how cases work with integers, you will find that they
are treated as a compare that has all of the expressions as operands.
So all expressions are evaluated at the width of the widest expression.
Similarly, if any is real, they all get converted to real. It is all
consistent with the way operands of any operator work; it is just
an "operator" with a lot of operands in this case.

> case (1.5)
> 1 : $display("1");
> 2 : $display("2");
> default: $display("other");
> endcase
>
> In this case, all the guards are integral. Should the case expression
> be rounded, or should all the guards be compared as reals? I can
> imagine a user expecting a "1" or "2" output from this example.

Then they would be wrong, since they will get "other".

> casex (2)
> 1.5 : $display("1.5");
> 2.5 : $display("2.5");
> 2'b1x : $display("2");
> default: $display("other");
> endcase
>
> Only some guard statements are real. Should all the comparisons be
> done as real expressions? In this case, there are likely no surprises.

All should be done as real.

> The intent is most likely that if there are any real valued expressions
> in the case expression or the guards, then all the comparisons are
> done as real==real. However, that would cause the second example above
> to print "other" instead of "2". (Note the x.)

Actually, you will get "2", but because an x bit turns into zero when an
integer is converted to a real, not because casex is treating it as a don't
care.

> So perhaps the rule is that each comparison pair is independently
> checked to determine the operand pairs, and thus whether to use
> integral === or == with reals. This is consistent with the string-
> of-if-then-else that defines case behavior.

But not with the behavior of integer case statements.

Note that such a rule could require evaluating the case expression more
than once, as different types. This is never done. All expressions are
evaluated once, as the "highest" type/width required by any compare.

It is quite simple and consistent.

Steven Sharp
sharp@cadence.com


From: Shalom Bresticker <Shalom.Bresticker@motorola.com>
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Wed, 14 May 2003 11:52:59 +0300

> > So perhaps the rule is that each comparison pair is independently
> > checked to determine the operand pairs, and thus whether to use
> > integral === or == with reals. This is consistent with the string-
> > of-if-then-else that defines case behavior.
>
> But not with the behavior of integer case statements.
>
> Note that such a rule could require evaluating the case expression more
> than once, as different types. This is never done. All expressions are
> evaluated once, as the "highest" type/width required by any compare.

Reevaluating the case expression could also mean that its value could change
between or as a result of the evaluations.

Come to think of it, this raises an interesting scheduling semantics question.

Suppose I have, for example,
case ( expr )
(a + 1) : ...
(a + 2) : ...
...
endcase

What guarantees that the execution of the case is atomic and uses the same value
of a for all the case items?
That the process executing the case does not suspend in the middle and go off to
do something else in the active queue in the meantime which by chance also
changes the value of a?

Shalom

--
Shalom Bresticker Shalom.Bresticker@motorola.com
Design & Reuse Methodology Tel: +972 9 9522268
Motorola Semiconductor Israel, Ltd. Fax: +972 9 9522890
POB 2208, Herzlia 46120, ISRAEL Cell: +972 50 441478




From: Steven Sharp <sharp@cadence.com>
To: sharp@cadence.com, Shalom.Bresticker@motorola.com
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Wed, 14 May 2003 16:45:48 -0400 (EDT)

>Reevaluating the case expression could also mean that its value could change
>between or as a result of the evaluations.

Yes, if there were function calls with side effects in some of the expressions.
Presumably all implementations will behave equivalently to evaluating the case
expression, and then the case item expressions in sequential order, until one
matches. That is how the semantics are described. Re-evaluating the case
expression could change the result, as you point out. This is not a problem
with a correct implementation.

>Come to think of it, this raises an interesting scheduling semantics question.
>
>Suppose I have, for example,
> case ( expr )
> (a + 1) : ...
> (a + 2) : ...
> ...
> endcase
>
>What guarantees that the execution of the case is atomic and uses the same
value
>of a for all the case items?
>That the process executing the case does not suspend in the middle and go off
to
>do something else in the active queue in the meantime which by chance also
>changes the value of a?

Under the overly loose rules of Section 5, nothing officially prevents this.
I'm not a fan of Section 5, but I'm not willing to try to rewrite it either.

In a real simulator, this isn't going to happen. There is no performance
advantage to be gained from it. Multiprocessing could have this effect, but
trying to use multiprocessing on conventional machines makes simulators
slower.

Steven Sharp
sharp@cadence.com


From: Shalom.Bresticker@motorola.com
To: Steven Sharp <sharp@cadence.com>
Cc: etf-bugs@boyd.com
Subject: Re: errata/344: Case Statements with Real Expressions
Date: Thu, 15 May 2003 05:51:22 +0300 (IDT)

> In a real simulator, this isn't going to happen.

Unless it is deliberately done for the purpose of exposing races.

Unformatted

Hosted by Boyd Technology