I want to convert a real number to his bit representation, with the fields of sign, exponent and mantissa in a VHDL TB for testing purposses (as a STD_LOGIC_VECTOR of 32 bits). Is there anyway to convert a real number to this representation directly in VHDL?
I know that in C is possible use a struct to achieve it, but I don't know if it's possible in VHDL.
Thank you.
Edit:
I've found this solution:
https://www.edaplayground.com/x/gQiN
But the synthesizer throw this error:
[XSIM 43-4187] File "/proj/xbuilds/2021.2_INT_0504_1926/installs/all_platforms/Vivado/2021.2/data/vhdl/src/ieee_2008/float_pkg.vhdl" Line 45 : The "Vhdl 2008 Package Instantiation Declaration" is not supported yet for simulation.
Then, I think the best solution is build a VHDL function that convert a real number to their IEEE-754 bit representation.
At the end, I created this VHDL function that convert a real number to his IEEE-754 integer representation:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
use ieee.math_real.all;
package Help is
type t_vector is array (natural range <>) of integer;
type data_t is array (natural range <>, natural range <>) of real;
function float_2_slv
(
num : real := 0.0
)
return std_logic_vector;
end package Help;
package body Help is
----------------------------------------------------------------------------------------------------
function float_2_slv
(
num : real := 0.0
)
return std_logic_vector is
constant bits_exponent : integer := 8;
constant bits_mantissa : integer := 23;
variable abs_num : real;
variable sign : std_logic;
variable exponent : real;
variable exponent_norm : std_logic_vector(bits_exponent-1 downto 0);
variable mantissa : real;
variable mantissa_norm : std_logic_vector(bits_mantissa - 1 downto 0);
variable quotient : real;
variable slv : std_logic_vector(31 downto 0);
begin
sign := '0';
abs_num := abs(num);
if num < 0.0 then
sign := '1';
end if;
exponent := floor(log2(abs_num));
quotient := 2.0 ** exponent;
mantissa := abs_num / quotient;
exponent_norm := std_logic_vector(to_unsigned(natural(127.0+exponent), bits_exponent));
mantissa_norm := std_logic_vector(to_signed(natural(round(mantissa*(2.0**(bits_mantissa)))), bits_mantissa));
slv := sign & exponent_norm & mantissa_norm;
return slv;
end;
end package body Help;
If it's required the conversion from a float to an IEEE-754 integer in Vitis, then, could be do it as in C:
uint32_t get_IEEE754(float d)
{
uint32_t bits;
memcpy(&bits, &d, sizeof(d));
return bits;
}