1364 issue 140 and negative exponents

From: James A. Markevitch (jam@magic.com)
Date: Mon May 05 2003 - 07:55:35 PDT

  • Next message: James A. Markevitch: "errata/340: /210"

    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.