Re: Arithmetic shift operators: signedness

From: Steven Sharp (sharp@cadence.com)
Date: Fri May 17 2002 - 13:34:08 PDT


Precedence: bulk

>Sec 4.1.12 says that a 0 or a signbit is filled in based on the signedness of
the
>result type. Later it says "The result signedness is .... and the remainder of
the
>expression as outlined in sec 4.5.1". However, I do not see the arith shift
operators
>listed in Table 29.

They should be in the same entry as the other shifts. I believe this
erratum was reported but not fixed before printing.

>Nor any mention of how the signedness of an arith shift op is
>determined in sec 4.5.1.

It is determined by the general rules in that section. If all of the
operands in the expression are signed, then the result is signed, else
it is unsigned (with all the caveats involving self-determined expressions).

>So how is the signedness determined based on the remainder of the expression?

As stated in section 4.5.1. It is at least as clear as the documentation
on bit widths, which admittedly isn't saying much.

>Is there a case where the result type is unsigned (dont know how yet) and if
>you have
>
>$signed (4'b1101) >>> 2
>
>then 0's are shifted in?

Yes. If there are unsigned operands elsewhere, then the result type is
unsigned, and 0's are shifted in. For example

4'b0 + ($signed (4'b1101) >>> 2)

This has the odd effect that $signed does not have the desired effect
unless everything else in the expression is signed also. If not, then
the result of $signed is immediately converted back to unsigned to match
the rest of the expression. The biggest effect of $signed and $unsigned
turns out to be that it makes its argument's signedness independent of the
rest of the expression. And for this purpose, it doesn't matter which one
is used. So you can get the desired effect by making all the operands
signed, such as

4'sb0 + ($signed(4'b1101) >>> 2)

or by shielding the subexpression from the unsignedness of other operands,
like

4'b0 + $unsigned($signed(4'b1101) >>> 2)

or

4'b0 + $signed($signed(4'b1101) >>> 2)

This "shielding" effect wasn't the major intent of $signed/$unsigned,
but it turns out to be very handy in mixed expressions.

>I would have thought that whether a 0 or a signbit is filled based solely on
>the signedness of the first operand and nothing else.

So will many other people. This is likely to lead to much misunderstanding
of the behavior of signed arithmetic, but that is how it is defined. The
behavior of sign-conversion matches the behavior of width-conversion, where
all operands are converted before any operators are applied. This makes all
conversions consistent within the language. The only problem is that most
users don't know how the width conversion works to start with. It was
designed to work the way it does precisely so they could get away with
not knowing how it works and still get the expected results. The same is
not true when the same conversion order is applied to signedness, but that
is how it is.

For those who have trouble with the rules for mixed expressions, I would
suggest sticking with purely signed or unsigned expressions.

>Maybe the last sentence on pg 50 was intended to be just "The result signedness
is
>determined by the left-hand operand.".

No, it was not. It was intended to be exactly what it is.

If you want to see the correct behavior, try it in NC-Verilog. You can
try Verilog-XL instead, though I am not as confident of its correctness.

Steven Sharp
sharp@cadence.com



This archive was generated by hypermail 2.1.4 : Mon Jul 08 2002 - 12:55:37 PDT and
sponsored by Boyd Technology, Inc.