# How to convert single precision floating point numbers in a file into their 32 bit representation in VHDL

Test data consists of single precision floating point numbers in a text file. These must be read into testbench and applied to a 32 bit std_logic_vector input port. The numbers can be read in as "real" type but how does one obtain their 32 bit representation to store in a std_logic_vector?

Floating point numbers consist of mantissa and exponent. Here the floating point number shall be reversed to get its actual representation inside the hardware and that will be stored in an std_logic_vector.

Here are a few numbers in the text file: -0.951835638, -0.154052139, 0.007186272. I need to convert these into their 32 bit binary representation and store it into std_logic_vector. These numbers are originally floating point with 8 bit exponent and 23 bit mantissa. I want them to be binary represented in this way when I store them into the std_logic_vector.

• You should begin by deciding exactly what floating-point format you are going to use. Then, explain why this conversion should be done in the VHDL rather than by a short python program if you have the data in a text file. – Elliot Alderson Jun 26 '19 at 12:15
• The floating point numbers are contained in a text file. They are IEEE 754 compliant i.e 8 bit exponent and 23 bit mantissa. – Quantum0xE7 Jun 26 '19 at 12:19
• IEEE 754 does not define the text representation of a floating-point number. Can you show us a few lines of your text file, along with how you think they should be represented in your VHDL code? – Dave Tweed Jun 26 '19 at 12:28
• @Quantum0xE7 Dave's point still stands: that's no valid IEEE 754 representation. The correctness of the text representation will be dependent on the program that wrote these to text, rather than doing a binary representation dump. – DonFusili Jun 26 '19 at 12:36
• See, I have no control over what is in the text file. This just data that I must use to in the verification process. My question is simple, if I store these numbers into VHDL real type, how do I then goto then convert them to std_logic_vector with 8 bit exponent and 23 bit mantissa? – Quantum0xE7 Jun 26 '19 at 12:40

The testbench below is answer to my question. The result of conversion is stored in slv. The input file contains a column of real numbers of the type I mentioned in the question i.e single preciousion floating point numbers generated from a program probably written in C or C++. As expected, there is difference between real1 and real2 which is another thing I wanted to check.

The float_generic_pkg which is basis for the float_pkg defines the float32 as follows:

subtype float32 is float (8 downto -23);


Where the float type is:

subtype float is (resolved) UNRESOLVED_float;


Where the UNRESOLVED_float is actually:

type UNRESOLVED_float is array (INTEGER range <>) of STD_ULOGIC;


This means that the floating point type is fundamentally just a std_logic_vector and thus not the same thing as a real!

Anyway, the code sample below is answer to the question.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.MATH_REAL.ALL;
use IEEE.float_pkg.all;

library std;
use std.textio.all;

entity t_real_to_slv is
end  t_real_to_slv;

architecture beh of  t_real_to_slv is

-- real number read from file
signal real1: real;
-- float resulting from conversion of real1
signal float1: float32;
-- slv resulting from conversion of float1
signal slv: std_logic_vector(31 downto 0);
-- float resulting from conversion of slv
signal float2: float32;
-- real number resulted from conversion of float type
signal real2: real;
-- difference between the real1 and real2
signal real_delta: real;

begin

process

file text_in  : text open read_mode  is "../../../real_in.txt";
file text_out : text open write_mode is "../../dump_out.txt";

variable line_in, line_out : line;
variable r_in, r_out : real;

begin

for i in 1 to 10 loop

if(NOT ENDFILE(text_in)) then

-- read the real number from input file line
real1 <= r_in;
wait for 1 ns;

-- convert the real number to float32, the float32
-- is merely a float with limits 8, -23
float1 <= to_float(real1);
wait for 1  ns;

-- convert the float into std_logic_vector so we can
-- have the binary representation of real1
slv <= std_logic_vector(float1);
wait for 1 ns;

-- now convert slv into float32
float2 <= to_float(slv);
wait for 1 ns;

-- now convert float32 into real type
real2 <= to_real(float2);
wait for 1 ns;

-- calculate the difference between the real number found
-- in the input text file and the real number
real_delta <= real2 - real1;
wait for 0 ns;

-- write the original real number
r_out := real1;
write(line_out, r_out);
write(line_out, ht);
-- write the real number resulting from conversions
r_out := real2;
write(line_out, r_out);
write(line_out, ht);
-- write difference between the original real number
-- and the one generated from conversions
r_out := real_delta;
write(line_out, r_out);
writeline(text_out, line_out);

-- verify that the floating point numbers are equal
-- i.e no information is lost in conversion
-- floa32->slv->float32; expected to pass
assert float2 = float1
report "floating point values do not match"
severity warning;

-- verify that the floating point number read from the
-- file is equal to the number resulting from conversions
-- i.e no information is lost in conversion
-- real->floa32->slv->float32->real; expected to fail
assert real2 = real1
report "real values do not match"
severity warning;

end if;
end loop;

assert false
report "end of test"
severity failure;
wait;
end process;

end architecture;


The gist of all this is these two lines:

real_to_slv := std_logic_vector(to_float(real_number));
slv_to_real_number := to_real(to_float(real_to_slv));


The slv must be declared as a 32 bit vector. Else, the conversions will fail at runtime. We need to use the float_pkg but not the float type itself in this case.