This really shouldn't be this difficult.
I want to read raw 64-bit IEEE 754 double-precision floating-point data from a file, and use it in a std_logic_vector(63 downto 0)
. I'm using ModelSim ALTERA 10.1b.
I tried to just read the raw binary data into the 64-bit vector:
type double_file is file of std_logic_vector(63 downto 0);
file infile1: double_file open read_mode is "input1.bin";
variable input1 : std_logic_vector(63 downto 0) := (others => '0');
read(infile1, input1);
But this doesn't work. Apparently ModelSim tries to interpret each byte of the input data as a std_logic
('U'
, 'Z'
, '-'
, etc.).
I can however, successfully read the data into real
variables:
type real_file is file of real;
file infile1: real_file open read_mode is "input1.bin";
variable input1 : real;
read(infile1, input1);
But at this point, I cannot figure out how to convert that real
variable to a std_logic_vector(63 downto 0)
. Pretty much all of the Google results just say "you can't do this; real
isn't synthesizable". I completely understand that - this is just for simulation.
The key is the ieee.float_pkg
.
First, you use to_float
to convert the real
to a floating-point:
variable in1_r : real;
variable in1_f : float64;
in1_f := to_float(in1_r, in1_f); -- in1_f passed for sizing
Then, you simply convert the float64
to an slv:
variable in1_slv : std_logic_vector(63 downto 0);
in1_slv := to_std_logic_vector( in1_f );
This can also be done with a one-liner, eliminating the intermediate float64
:
in1_slv <= to_std_logic_vector( to_float(in1_r, float64'high, -float64'low) );
The key there is that to_float
needs to know the target size. Since we don't have an intermediate float64
value, we can just pass the exponent_width
and fraction_width
parameters directly, using the definition of float64
. Looking at the definition of to_float64
helped.
This question was of some help: IEEE Float type to std_logic_vector conversion