From: James A. Markevitch (jam@magic.com)
Date: Mon May 05 2003 - 07:55:35 PDT
Precedence: bulk
Issue 140, passed by the ETF, had some controversy with respect to how
negative exponents of integers should be handled. The options discussed
were: convert exponent to unsigned, truncate result to 0, indicate that the
result is unspecified.
This note proposes that the definition of i**n (integer to negative power)
be truncated to 0.
1. Compatibility with division truncation: integer division, i/j, results
in truncation. In particular, 1/2 is defined to be 0 in Verilog. One
might expect that 2**(-1) would also result in 0.
2. Signed vs. unsigned exponents: one can take the position that a designer
must intentionally choose to use signed variables in the exponent. By
default, variables in Verilog are unsigned. If the designer has intentionally
chosen to use signed variables, then it makes sense to assume that
exponentiation using a negative exponent is intentional, not mere laziness
with the expectation that the signed variable will be converted to unsigned.
Although the ETF may not be able to come up with a killer-app for supporting
truncation to 0 with negative exponents of integers, we cannot forsee all
uses that will be made of exponentiation.
3. Compatibility with left shift: in 1364-2001, the definition of the left
shift operator indicates that the right-hand operand is treated as an
unsigned value, regardless of its signed-ness. Thus, 1<<(-3'sd1) is defined
to be the same as 1<<(3'd7), which has the result 128. This if unfortunate,
since if the exponent is a variable, then having a sudden discontinuity as
the exponent crosses from 0 to a negative value doesn't seem intuitive.
From other languages:
VHDL Left shifts (sll, sla, rol) with negative shift count are converted
to right shifts (srl, sra, ror)
C Result is undefined
C++ Result is undefined
Java Result uses the 5 LSBs (for type int) of the shift count, so that
negative shift counts are mapped into the range 0 to 31
If i**n truncates to 0, then 2**(-3'sd1) would be different from 1<<(-3'sd1).
One must trade off this difference against other compatibility and intuitive
behavior issues (such as integer division).
4. Compatibility with other languages: different languages have different
behavior with respect to i**n:
VHDL i**n, with negative n, is illegal
C No such concept: pow() is a floating-point function
Fortran Result is truncated to 0
LISP Result is converted to an exact rational number: (expt 2 3) is 1/8
5. Implementation simplicity: one argument made in favor of forcing
conversion of exponents to unsigned is that the resulting synthesized
logic is simpler. However, the "default" for variables is unsigned and the
user can always choose to use $unsigned() to force a signed variable to be
treated as unsigned. Therefore, the more complex logic only results in
a case where the user appears to have intended that the exponent be treated
as signed. The user loses nothing if negative exponents truncate to 0,
but gains the ability to explicitly control it by choosing to use signed/
unsigned variables and the $unsigned() function. If i**n is truncated to
0, then the user has the maximum flexbility to choose the behavior using
choice of variable signed-ness and the $signed() and $unsigned() functions.
Sincerely,
James Markevitch
This archive was generated by hypermail 2.1.4
: Mon May 05 2003 - 08:55:21 PDT
and
sponsored by Boyd Technology, Inc.