library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package float is constant SIGN : std_logic_vector( 31 downto 31 ) := ( others => '0' ); constant EXP : std_logic_vector( 30 downto 23 ) := ( others => '0' ); constant MANTISSA : std_logic_vector( 22 downto 0 ) := ( others => '0' ); function find_leftmost( arg : unsigned; value : std_ulogic ) return integer; function count_leading_digits( arg : unsigned; value : std_ulogic ) return integer; function to_float( arg : std_logic_vector ) return std_logic_vector; function to_fixed( arg : std_logic_vector ) return std_logic_vector; end package float; package body float is function find_leftmost( arg : unsigned; value : std_ulogic ) return integer is begin for i in arg'left downto arg'right loop if ( arg( i ) = value ) then return i; end if; end loop; return -1; end function find_leftmost; function count_leading_digits( arg : unsigned; value : std_ulogic ) return integer is variable left_most_value : integer range -1 to arg'high; variable leading_values : integer range 0 to arg'high; begin left_most_value := find_leftmost( arg, not value ); leading_values := 0; if ( left_most_value /= -1 ) then leading_values := arg'high - left_most_value; end if; return leading_values; end function count_leading_digits; function to_float( arg : std_logic_vector ) return std_logic_vector is variable y : std_logic_vector( 31 downto 0 ); variable s : std_logic; variable e : unsigned( 7 downto 0 ); variable m : unsigned( 22 downto 0 ); variable value : unsigned( 30 downto 0 ); variable leading_sign_digits : integer range 0 to value'high; variable reminding : integer range 0 to value'high; begin s := arg( 31 ); if ( s = '0' ) then value := unsigned( arg( 30 downto 0 ) ); else value := not unsigned( arg( 30 downto 0 ) ); value := value +1; end if; leading_sign_digits := count_leading_digits( value, '0' ); reminding := value'high - leading_sign_digits; e := to_unsigned( 126 - leading_sign_digits, e'length ); if ( reminding > m'length ) then m := value( reminding - 1 downto reminding - m'length ); elsif ( reminding > 1 ) then m := ( others => '0' ); m( m'high downto m'high - reminding + 1 ) := value( reminding - 1 downto 0 ); else m := ( others => '0' ); end if; if (arg = x"00000000") then y := (others => '0'); else y := s & std_logic_vector( e ) & std_logic_vector( m ); end if; return y; end function to_float; function to_fixed( arg : std_logic_vector ) return std_logic_vector is variable y : unsigned( 31 downto 0 ); variable s : std_logic; variable e : unsigned( 7 downto 0 ); variable m_index_max : integer range -127 to 128; begin s := arg( 31 ); e := unsigned(arg(30 downto 23)); m_index_max := to_integer(signed(30-(126-e))); if (arg = x"00000000") then y := (others => '0'); else y := (others => '0'); case m_index_max is when 30 => y(30 downto 7):= '1' & unsigned( arg(22 downto 0) ); when 29 => y(29 downto 6):= '1' & unsigned( arg(22 downto 0) ); when 28 => y(28 downto 5):= '1' & unsigned( arg(22 downto 0) ); when 27 => y(27 downto 4):= '1' & unsigned( arg(22 downto 0) ); when 26 => y(26 downto 3):= '1' & unsigned( arg(22 downto 0) ); when 25 => y(25 downto 2):= '1' & unsigned( arg(22 downto 0) ); when 24 => y(24 downto 1):= '1' & unsigned( arg(22 downto 0) ); when 23 => y(23 downto 0):= '1' & unsigned( arg(22 downto 0) ); when 22 => y(22 downto 0):= '1' & unsigned( arg(22 downto 1) ); when 21 => y(21 downto 0):= '1' & unsigned( arg(22 downto 2) ); when 20 => y(20 downto 0):= '1' & unsigned( arg(22 downto 3) ); when 19 => y(19 downto 0):= '1' & unsigned( arg(22 downto 4) ); when 18 => y(18 downto 0):= '1' & unsigned( arg(22 downto 5) ); when 17 => y(17 downto 0):= '1' & unsigned( arg(22 downto 6) ); when 16 => y(16 downto 0):= '1' & unsigned( arg(22 downto 7) ); when 15 => y(15 downto 0):= '1' & unsigned( arg(22 downto 8) ); when 14 => y(14 downto 0):= '1' & unsigned( arg(22 downto 9) ); when 13 => y(13 downto 0):= '1' & unsigned( arg(22 downto 10) ); when 12 => y(12 downto 0):= '1' & unsigned( arg(22 downto 11) ); when 11 => y(11 downto 0):= '1' & unsigned( arg(22 downto 12) ); when 10 => y(10 downto 0):= '1' & unsigned( arg(22 downto 13) ); when 9 => y(9 downto 0):= '1' & unsigned( arg(22 downto 14) ); when 8 => y(8 downto 0):= '1' & unsigned( arg(22 downto 15) ); when 7 => y(7 downto 0):= '1' & unsigned( arg(22 downto 16) ); when 6 => y(6 downto 0):= '1' & unsigned( arg(22 downto 17) ); when 5 => y(5 downto 0):= '1' & unsigned( arg(22 downto 18) ); when 4 => y(4 downto 0):= '1' & unsigned( arg(22 downto 19) ); when 3 => y(3 downto 0):= '1' & unsigned( arg(22 downto 20) ); when 2 => y(2 downto 0):= '1' & unsigned( arg(22 downto 21) ); when 1 => y(1 downto 0):= '1' & unsigned( arg(22 downto 22) ); when 0 => y(0):= '1'; when others => null; end case; if ( s = '1' ) then y := not(y); y:= y + x"00000001"; end if; end if; return std_logic_vector( y ); end function to_fixed; end package body float;