Search code examples
floating-pointvhdlieee-754

Convert real to IEEE double-precision std_logic_vector(63 downto 0)


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.). enter image description here


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.


Solution

  • 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