Menu

#1029 Reals are incorrectly rounded to ints

devel
closed-fixed
nobody
None
5
2018-05-19
2018-05-12
No

This one seems a bit surprising. The 2005 LRM is clear that 'ties shall be rounded away from zero' (3.5.3, 4.8.2). Icarus actually does round-half-to-even (for positive numbers, anyway - I haven't checked negtive).
Test code attached. EDA Playground won't let me run VCS or Incisive, for some reason, but Riviera, Veriwell, and Cver all round away from zero.

1 Attachments

Discussion

  • Martin Whitaker

    Martin Whitaker - 2018-05-12

    It appears to be an issue with the $write call. If you assign the values to integers before writing them, you get the correct behaviour.

     
  • Martin Whitaker

    Martin Whitaker - 2018-05-12

    Verilog-XL considers this to be illegal. Incisive outputs warnings but converts to integers as per the standard rounding rules. As Icarus is converting to integers, I think it too should adhere to the rounding rules.

     
  • Martin Whitaker

    Martin Whitaker - 2018-05-12
    • status: open --> closed-fixed
     
  • Martin Whitaker

    Martin Whitaker - 2018-05-12

    Fix pushed to both the master and v10 branches.

     
  • Evan Lavelle

    Evan Lavelle - 2018-05-13

    Hi Martin - that's great - thanks. It's not quite complete, unfortunately, but I'm not sure how far it's worth going with this.

    The attached is a slightly modified version of the test, which adds two further $writes.

    $write #3 has a function call ('foo(0)') as the actual parameter, where the function returns a real, and $write expects '%d'. The real it returns is 2.5, so this should be rounded to 3.

    $write #4 is the same, except that the the actual parameter is now '$signed(foo(0))'. This is probably unlikely to be found in real code, but I can't immediately see anything in the LRM that prohibits this.

    All simulators now show the expected result for the first two $writes (thanks).
    The results for #3 and #4 are now (I can run Incisive and VCS today, for some reason):

    $write #3:

    Icarus and VCS round to 2, the others round to 3

    $write #4:

    Icarus: crashes
    VCS: compiles Ok, produces '2'
    Incisive: syntax error ("real argument supplied to abval parameter")
    Riviera: syntax error ("Argument of $signed/$unsigned functions must have integer, bit or string type.")
    Cver: compiles Ok, produces 'Z'
    Veriwell: pre-2001, doesn't support $signed

    It's not obvious (to me, anyway) that #4 actually is a syntax error. The 2005 LRM doesn't really cover this. The actual to a function can be any expression, and tasks "shall pass input values from the expressions listed in the enabling statement to the arguments specified within the task". There's no definitive statement such as the common "arguments are passed as if by assignment", and the type of the input to $signed isn't specified. So, I guess you can do what you want (apart from crash :))

    Interesting about XL. I guess this is one of the things they forgot about, rather than specifically being added in the 2001 LRM.

     
    • Martin Whitaker

      Martin Whitaker - 2018-05-13

      The 2012 standard says "The $signed and $unsigned system functions can be used to cast the signedness (but not the type) of expressions." I think "but not the type" is meant to indicate that the input value must be a bit vector. Elsewhere $signed and $unsigned are defined as returning a bit vector with the same number of bits and bit pattern as the input. So prohibiting real input values doesn't seem unreasonable. $rtoi and $realtobits provide the means to convert/cast real values to bit vectors.

      The 2012 standard also expands on what %d can be used with, saying "The integer format specifiers, %h, %x, %d, %o, %b, %c, %u, and %z (uppercase or lowercase), may be used with any of the SystemVerilog integral data types, including enumerated types and packed aggregate data types." so again I think they are excluding real values. However, as all modern simulators allow them, I think we should ignore that.

       
  • Martin Whitaker

    Martin Whitaker - 2018-05-14

    Further fixes pushed to both the master and the v10 branches. $write #3 should now pass. $write #4 should now be rejected as illegal.

     
  • Evan Lavelle

    Evan Lavelle - 2018-05-19

    Thanks very much - my Icarus regressions all now pass.

     

Log in to post a comment.