VHDL real numbers

Discussion in 'VHDL' started by Niv, Dec 21, 2007.

  1. Niv

    Niv Guest

    I want to a number calculated in my test bench.
    I have, for instance, two processes, which each increment a counter
    when they are executed.
    I would like to compare the amount the processes are run, so x(real)
    <= cntr1/cntr2, where cntr are both unsigned 32 bit vectors (unlikely
    to reach 2^32 iterations!).

    [ or, x(real) <= cntr1/(cntr1 + cntr2) ]

    But numeric_std has no real maths in it (that I can find)

    Any ideas please?

    TIA, Niv.
    Niv, Dec 21, 2007
    #1
    1. Advertising

  2. Niv

    Niv Guest

    On 21 Dec, 09:46, Niv <> wrote:
    > I want to a number calculated in my test bench.
    > I have, for instance, two processes, which each increment a counter
    > when they are executed.
    > I would like to compare the amount the processes are run, so x(real)
    > <= cntr1/cntr2, where cntr are both unsigned 32 bit vectors (unlikely
    > to reach 2^32 iterations!).
    >
    > [ or, x(real) <= cntr1/(cntr1 + cntr2) ]
    >
    > But numeric_std has no real maths in it (that I can find)
    >
    > Any ideas please?
    >
    > TIA, Niv.


    I meant to say "I want to calculate a number....."

    And no, it isn't too much Christmas spirit (yet).

    Happy Christmas to all fellow VHDLers, (& Tcl'ers)
    especially all those with the helpful replies.

    Niv.
    Niv, Dec 21, 2007
    #2
    1. Advertising

  3. Niv

    HT-Lab Guest

    "Niv" <> wrote in message
    news:...
    >I want to a number calculated in my test bench.
    > I have, for instance, two processes, which each increment a counter
    > when they are executed.
    > I would like to compare the amount the processes are run, so x(real)
    > <= cntr1/cntr2, where cntr are both unsigned 32 bit vectors (unlikely
    > to reach 2^32 iterations!).
    >
    > [ or, x(real) <= cntr1/(cntr1 + cntr2) ]
    >
    > But numeric_std has no real maths in it (that I can find)


    If you have access to Modelsim then check out the floating point package in
    .../floatfixlib/float_pkg

    Works great except that the waveform can't display fp and looking at 64bits
    fp numbers in binary/hex is a real pain.

    Hans
    www.ht-lab.com



    >
    > Any ideas please?
    >
    > TIA, Niv.
    HT-Lab, Dec 21, 2007
    #3
  4. Niv

    KJ Guest

    "Niv" <> wrote in message
    news:...
    >I want to a number calculated in my test bench.
    > I have, for instance, two processes, which each increment a counter
    > when they are executed.
    > I would like to compare the amount the processes are run, so x(real)
    > <= cntr1/cntr2, where cntr are both unsigned 32 bit vectors (unlikely
    > to reach 2^32 iterations!).
    >
    > [ or, x(real) <= cntr1/(cntr1 + cntr2) ]
    >
    > But numeric_std has no real maths in it (that I can find)
    >
    > Any ideas please?
    >
    > TIA, Niv.


    Use the ieee.math_real package. Then

    x <= real(to_integer(cntr1))/real(to_integer(cntr1 + cntr2));

    Note: You'll want to convert the numerator and denominator to reals before
    the divide (as I've shown) to prevent round off error because of things
    like...

    3 / 2 = 1
    real(3) / real(2) = 1.5

    KJ
    KJ, Dec 21, 2007
    #4
  5. Niv

    KJ Guest

    Actually, I don't think the "ieee.math_real" package is needed...casting
    from integers to reals is already part of the language and 'to_integer' is
    part of numeric_std.

    KJ
    KJ, Dec 21, 2007
    #5
  6. KJ wrote:
    > Actually, I don't think the "ieee.math_real" package is needed...casting
    > from integers to reals is already part of the language and 'to_integer' is
    > part of numeric_std.


    I'll be darned.
    Integer casts of real are built in as well.
    Let's see if they round ...

    assert natural(2.49) = 2 report "cast rounding error";
    assert natural(2.50) = 3 report "cast rounding error";
    assert natural(2.51) = 3 report "cast rounding error";
    report "cast of 2.49 is " & natural'image(natural(2.49));
    report "cast of 2.50 is " & natural'image(natural(2.50));
    report "cast of 2.51 is " & natural'image(natural(2.51));

    -->
    # run -all
    # Note: cast of 2.49 is 2
    # Note: cast of 2.50 is 3
    # Note: cast of 2.51 is 3

    Yup!
    Thanks for the idea KJ.
    I can remove lots of math_real.round functions
    from my rtl and testbench code.

    -- Mike Treseler
    Mike Treseler, Dec 22, 2007
    #6
  7. On Sat, 22 Dec 2007 13:56:19 -0800, Mike Treseler wrote:

    > assert natural(2.50) = 3 report "cast rounding error";

    [...]
    >I can remove lots of math_real.round functions
    >from my rtl and testbench code.


    Yes; real and integer are "closely related types" and
    can be mutually type-converted as you showed.

    I *think* (too much Christmas idleness to check the LRM)
    that the rounding of exact halves from REAL to INTEGER
    is indeterminate (might go up or down), whereas
    math_real.trunc() and math_real.round() have precisely
    defined behaviour. For the overwhelming majority of
    applications that doesn't matter, of course.
    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

    Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Dec 28, 2007
    #7
  8. Niv

    David Bishop Guest

    Jonathan Bromley wrote:
    > On Sat, 22 Dec 2007 13:56:19 -0800, Mike Treseler wrote:
    >
    >> assert natural(2.50) = 3 report "cast rounding error";

    > [...]
    >> I can remove lots of math_real.round functions
    >>from my rtl and testbench code.

    >
    > Yes; real and integer are "closely related types" and
    > can be mutually type-converted as you showed.
    >
    > I *think* (too much Christmas idleness to check the LRM)
    > that the rounding of exact halves from REAL to INTEGER
    > is indeterminate (might go up or down), whereas
    > math_real.trunc() and math_real.round() have precisely
    > defined behaviour. For the overwhelming majority of
    > applications that doesn't matter, of course.



    The rule (according to IEEE 754) rounding has to do with the bottom bit
    of the integer portion.

    If the remainder is greater than 0.5, round up
    If the remainder is less than 0.5, round down
    If the remainder IS 0.5, then look at the bottom bit of the integer
    portion. If it is a "1" (odd) round up, if it is a "0" (even) round down.

    This is the functionality of "round nearest", which should be the
    default rounding style for all floating point numbers.

    I think that math_real function is "floor" though.
    David Bishop, Dec 29, 2007
    #8
  9. Niv

    KJ Guest

    "David Bishop" <> wrote in message
    news:47765e53$0$24271$...
    > Jonathan Bromley wrote:
    >> On Sat, 22 Dec 2007 13:56:19 -0800, Mike Treseler wrote:
    >>
    >>> assert natural(2.50) = 3 report "cast rounding error";

    >> [...]
    >>> I can remove lots of math_real.round functions
    >>>from my rtl and testbench code.

    >>
    >> Yes; real and integer are "closely related types" and
    >> can be mutually type-converted as you showed.
    >>
    >> I *think* (too much Christmas idleness to check the LRM)
    >> that the rounding of exact halves from REAL to INTEGER
    >> is indeterminate (might go up or down), whereas
    >> math_real.trunc() and math_real.round() have precisely
    >> defined behaviour. For the overwhelming majority of
    >> applications that doesn't matter, of course.

    >
    >
    > The rule (according to IEEE 754) rounding has to do with the bottom bit of
    > the integer portion.
    >
    > If the remainder is greater than 0.5, round up
    > If the remainder is less than 0.5, round down
    > If the remainder IS 0.5, then look at the bottom bit of the integer
    > portion. If it is a "1" (odd) round up, if it is a "0" (even) round down.
    >
    > This is the functionality of "round nearest", which should be the default
    > rounding style for all floating point numbers.
    >
    > I think that math_real function is "floor" though.


    Per Modelsim (too lazy for LRM also).... 'round' does the same thing as a
    simple cast but it doesn't appear that the decision to round 'up' or 'down'
    depends on the least significant bit of the integer. Instead it depends on
    the sign of the integer and pushes it 'away' from 0 towards the next largest
    (in absolute value) integer.

    KJ

    begin
    assert FALSE
    report "i=" & integer'image(i) & LF &
    "integer'image(integer(real(i)+ 0.5))=" &
    integer'image(integer(real(i)+ 0.5)) & LF &
    "real'image(ieee.math_real.round(real(i)+0.5))" &
    real'image(ieee.math_real.round(real(i)+0.5)) & LF &
    "real'image(ieee.math_real.ceil(real(i) + 0.5))" &
    real'image(ieee.math_real.ceil(real(i) + 0.5)) & LF &
    "real'image(ieee.math_real.floor(real(i) + 0.5))" &
    real'image(ieee.math_real.floor(real(i) + 0.5)) & LF
    severity NOTE;
    end generate G_TEST;

    # ** Note: i=3
    # integer'image(integer(real(i)+ 0.5))=4
    # real'image(ieee.math_real.round(real(i)+0.5))4.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))4.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))3.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__3
    # ** Note: i=2
    # integer'image(integer(real(i)+ 0.5))=3
    # real'image(ieee.math_real.round(real(i)+0.5))3.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))3.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))2.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__2
    # ** Note: i=1
    # integer'image(integer(real(i)+ 0.5))=2
    # real'image(ieee.math_real.round(real(i)+0.5))2.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))2.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))1.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__1
    # ** Note: i=0
    # integer'image(integer(real(i)+ 0.5))=1
    # real'image(ieee.math_real.round(real(i)+0.5))1.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))1.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))0.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__0
    # ** Note: i=-1
    # integer'image(integer(real(i)+ 0.5))=-1
    # real'image(ieee.math_real.round(real(i)+0.5))-1.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))0.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))-1.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__-1
    # ** Note: i=-2
    # integer'image(integer(real(i)+ 0.5))=-2
    # real'image(ieee.math_real.round(real(i)+0.5))-2.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))-1.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))-2.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__-2
    # ** Note: i=-3
    # integer'image(integer(real(i)+ 0.5))=-3
    # real'image(ieee.math_real.round(real(i)+0.5))-3.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))-2.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))-3.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__-3
    # ** Note: i=-4
    # integer'image(integer(real(i)+ 0.5))=-4
    # real'image(ieee.math_real.round(real(i)+0.5))-4.000000e+000
    # real'image(ieee.math_real.ceil(real(i) + 0.5))-3.000000e+000
    # real'image(ieee.math_real.floor(real(i) + 0.5))-4.000000e+000
    #
    # Time: 0 ns Iteration: 0 Instance: /tiff_test_area/g_test__-4
    KJ, Dec 30, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. senthil
    Replies:
    5
    Views:
    1,377
    senthil
    Jan 24, 2004
  2. hari
    Replies:
    2
    Views:
    9,805
    Charles Bailey
    May 12, 2004
  3. hari
    Replies:
    2
    Views:
    9,118
    Ajeetha Kumari
    Apr 23, 2004
  4. Curious Trigger
    Replies:
    2
    Views:
    1,810
    Curious Trigger
    Sep 9, 2006
  5. canadianJaouk

    VHDL switch in real numbers

    canadianJaouk, Sep 28, 2006, in forum: VHDL
    Replies:
    9
    Views:
    2,912
    Paul Uiterlinden
    Oct 29, 2006
Loading...

Share This Page