VHDL real numbers

N

Niv

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.
 
N

Niv

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.
 
H

HT-Lab

Niv said:
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
 
K

KJ

Niv said:
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
 
K

KJ

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
 
M

Mike Treseler

KJ said:
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
 
J

Jonathan Bromley

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
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
D

David Bishop

Jonathan said:
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.
 
K

KJ

David Bishop said:
Jonathan said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top