Representing INF in a real?

P

Paul Johnson

I've got the following legacy (VHDL) code, which is meant to detect an
INF condition and store it in 'result':

variable result : real;
....
result := 1.0 / 0.0;

However, when this runs on Modelsim, I get this fatal error:

** Fatal: (vsim-3421) Value inf is out of range 1e+308 to -1e+308.

Well, that makes sense, except that this code is known to work (unless
this line was never executed; I'm not sure). It ran on Modelsim (and
compiled on DC), although on an older version of Modelsim.

Could this code have ever worked? And how? A quick look through the
Modelsim manuals doesn't give any hits on INF or NAN.

Many thanks -

Paul

[I've copied comp.lang.verilog as I don't think that this is
language-specific].
 
B

Ben Jones

Paul Johnson said:
I've got the following legacy (VHDL) code, which is meant to detect an
INF condition and store it in 'result':

variable result : real;
...
result := 1.0 / 0.0;

However, when this runs on Modelsim, I get this fatal error:

** Fatal: (vsim-3421) Value inf is out of range 1e+308 to -1e+308.

Well, that makes sense, except that this code is known to work

So now, it's also know *not* to work. :)

A quick glance at the VHDL LRM, e.g.:

http://www.microlab.ch/courses/vlsi/vhdl-ieee/TUTORIAL/IEEE/HTML/1076_3.HTM#
3.1.4

....tells me that implementations are not required to support any
"meta-values" such as NaNs or infinities, nor any exceptional conditions nor
denormalized numbers.

I guess this doesn't really answer your question, but it looks like
Modelsim's implementation of "real" is basically double-precision
floating-point but shorn of its meta-values.

I can imagine possibly creating a record type containing a real and a small
"tag" to hold FP metadata (inf,nan,exceptions), then overloading all the
operators to make it look like a real IEEE floating-point implementation -
but I think I'd rather remove my own corneas with a sharp implement :)

-Ben-
 
S

sharp

Your machine's floating point hardware presumably supports full IEEE
floating point, including Inf. So I would guess that Modelsim must be
explicitly testing for such values and producing an error, for some
reason. I don't know whether there is anything in the VHDL definition
that requires software intervention in the floating point calculations,
which might have prompted them to simplify them this way, or whether
this was an arbitrary decision on their part. It may be that they
didn't do this in an older version.
 
M

Mike Treseler

Ben said:
Modelsim's implementation of "real" is basically double-precision
floating-point but shorn of its meta-values.

That is the case. See below.

Paul:

I expect that the statement
result := 1.0 / 0.0;
was never compiled on modelsim and if it
got by DC, that is a bug.
Just add a test for zero to your code.

-- Mike Treseler
_____________________________

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
-- Fri Jan 27 10:25:29 2006 M.Treseler
entity test_real_big is
end test_real_big;

architecture sim of test_real_big
is
-- constant infinity : real := 1.0/0.0;
-- ** Error: Static divide by zero.
-- (vcom-1144) Value inf is out of real range -1e+308 to 1e+308.
-- (Quartus 5.1 says: "Value cannot contain divisor of zero.")
------------------------------------------------------------------
constant real_right : real := real'right;
constant real_right_str : string := real'image(real'right);
begin
process is
begin
report "maximum real value is " & real_right_str;
assert real_right = 1.0e+308 report "real_right not 1.0e+308";
wait;
end process;
end sim;

--------------------------------------------------------------------
--# 6.1c
--# vsim -c test_real_big
--# Loading /flip/usr1/modeltech/linux/../std.standard
--# Loading /flip/usr1/modeltech/linux/../ieee.std_logic_1164(body)
--# Loading /flip/usr1/modeltech/linux/../ieee.numeric_std(body)
--# Loading /flip/usr1/modeltech/linux/../ieee.math_real(body)
--# Loading work.test_real_big(sim)

--VSIM 1> run
--# ** Note: maximum real value is 1.000000e+308
--# Time: 0 ns Iteration: 0 Instance: /test_real_big
 
P

Paul Johnson

That is the case. See below.

Paul:

I expect that the statement
result := 1.0 / 0.0;
was never compiled on modelsim and if it
got by DC, that is a bug.
Just add a test for zero to your code.

The idea behind the original code was to store INF in 'result'. The FP
code in this chip handles infinities so this is, in principle, a
reasonable thing to do. The LRM doesn't prohibit this - it just
doesn't require it.

Noted that Quartus doesn't like this, but DC didn't complain. It would
be nice to see what logic it generated, but unfortunately I can't do
that.

BTW, the code compiles and elaborates on Modelsim without problems;
the error is a run-time range-checking error.

Paul
 
P

Paul Johnson

Your machine's floating point hardware presumably supports full IEEE
floating point, including Inf. So I would guess that Modelsim must be
explicitly testing for such values and producing an error, for some
reason. I don't know whether there is anything in the VHDL definition
that requires software intervention in the floating point calculations,
which might have prompted them to simplify them this way, or whether
this was an arbitrary decision on their part. It may be that they
didn't do this in an older version.

I think you're basically right. The LRM doesn't require them to detect
values outside whatever range they support, but they've obviously
decided to do so. In principle, I can turn off all range checking with
a -nocheck flag in compilation, but I haven't yet got this to work
(and I don't want to, because the original code doesn't appear to do
this).

The original code ran on SPARC, and I'm now on x86. I guess it's
possible that the FPUs were set up differently, and Modelsim is using
an exception from the FPU to detect this condition on x86, but not on
SPARC.

Paul
 
S

sharp

I know of one area where the x86 floating point unit doesn't comply
with the IEEE floating point standard (specifically, in rounding).
This requires some extra software adjustment of the results if
compliant results are required. So it is certainly possible that
Modelsim is handling floating point differently on x86 and SPARC.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top