0

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.

Diego Ruiz
  • 187
  • 2
  • 11
  • 2
    From the mid 2000's all simulators including Xilinx ISIM/Vivado Simulator have a 64 bit real. Vivado Sim support lags. See [Fixed and Floating Point Packages](https://docs.xilinx.com/r/2021.1-English/ug900-vivado-logic-simulation/Fixed-and-Floating-Point-Packages). The simulator uses packages found in library ieee_proposed. Consider using another simulator. Xilinx Synthesis (UG901) supports -2008 packages without jumping through hoops. – user16145658 Dec 23 '22 at 14:58
  • 2
    The source and documentation for the ieee_proposed library for simulators not natively supporting enough of the -2008 standard (package instantiations) is found on [github](https://github.com/FPHDL/fphdl). The VHDL source for IEEE -2008 packages is available from download [here](https://standards.ieee.org/downloads/). – user16145658 Dec 23 '22 at 15:14

2 Answers2

0

Chapter 5.2.5.2 of the standard VHDL-2008 says:

The only predefined floating-point type is the type REAL. The range of REAL is host-dependent, but it is guaranteed to be the largest allowed by the chosen representation.

However, functions of the package IEEE.float_pkg are described in chapter G.5.4.3 and include this functions:

To_slv Inputs: arg (float). Converts a floating-point number to a std_logic_vector of the same length.

To_std_logic_vector Alias for to_slv.

To_stdlogicvector Alias for to_slv.

To_sulv Inputs: arg (float). Converts a floating-point number to a std_ulogic_vector of the same length.

To_std_ulogic_vector Alias for to_sulv.

To_stdulogicvector Alias for to_sulv.

the busybee
  • 10,755
  • 3
  • 13
  • 30
0

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;
}
Diego Ruiz
  • 187
  • 2
  • 11