99 lines
3.3 KiB
VHDL
99 lines
3.3 KiB
VHDL
-- Library of functions to work with unsigned FP numbers
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
|
|
package pkg_ufp is
|
|
-- Format
|
|
-- [ ee ][ mm ]
|
|
-- with total BW bits, and BE exponent bits and offset of exponent EO
|
|
-- b(ee) in EO-[0..2**BE-1]
|
|
-- b(mm) in [0..2**(BW-BE)-1]/2**(BW-BE)
|
|
|
|
-- Convert a number if unsigned floating point to real
|
|
function ufp_to_real (
|
|
ee_mm : std_logic_vector; -- Data in format exponent_mantissa as bits
|
|
BW : natural; -- Bit width
|
|
BE : natural; -- Number of bits used for exponent
|
|
EO : natural) -- Offset of exponent
|
|
return real;
|
|
|
|
-- Convert a real number to unsigned floating point
|
|
function real_to_ufp (
|
|
r : real; -- Real number to convert
|
|
BW : natural; -- Bit width
|
|
BE : natural; -- Number of bits used for exponent
|
|
EO : natural) -- Offset of exponent
|
|
return std_logic_vector;
|
|
|
|
|
|
|
|
end package pkg_ufp;
|
|
|
|
library ieee;
|
|
use ieee.numeric_std.all;
|
|
use ieee.math_real.all;
|
|
|
|
package body pkg_ufp is
|
|
|
|
function ufp_to_real (
|
|
ee_mm : std_logic_vector; -- Data in format exponent_mantissa as bits
|
|
BW : natural; -- Bit width
|
|
BE : natural; -- Number of bits used for exponent
|
|
EO : natural) -- Offset of exponent
|
|
return real
|
|
is
|
|
variable mm : unsigned(BW-BE-1 downto 0);
|
|
variable ee : unsigned(BE-1 downto 0);
|
|
variable d : real;
|
|
begin
|
|
ee := unsigned(ee_mm(BW-1 downto BW-BE));
|
|
mm := unsigned(ee_mm(BW-BE-1 downto 0));
|
|
d := real(to_integer(mm)) * 2.0**real(EO-to_integer(ee)-(BW-BE));
|
|
return d;
|
|
end function ufp_to_real;
|
|
|
|
|
|
function real_to_ufp (
|
|
r : real; -- Real number to convert
|
|
BW : natural; -- Bit width
|
|
BE : natural; -- Number of bits used for exponent
|
|
EO : natural) -- Offset of exponent
|
|
return std_logic_vector
|
|
is
|
|
variable BO, MAX_EXP, BM : integer;
|
|
variable R_MIN, BM_LIM : real;
|
|
variable mm : unsigned(BW-BE-1 downto 0);
|
|
variable ee : unsigned(BE-1 downto 0);
|
|
variable aa : integer; -- Scaling to normalize r into ufp representation
|
|
variable mm_id : integer;
|
|
begin
|
|
BO := BW-BE-EO; -- Exponent of Scaling factor
|
|
BM := BW - BE; -- Bits for mantissa
|
|
BM_lim := log2(2.0**BM-1.0); -- A bit less than BM
|
|
MAX_EXP := 2**BE-1; -- Max exponent
|
|
R_MIN := 2.0**(-MAX_EXP-BO); -- Min value (not equal zero)
|
|
if r<R_MIN then -- If too small, set to zero
|
|
ee := (others => '1');
|
|
mm := (others => '0');
|
|
else
|
|
--aa := BM - integer(ceil(log2(r)));
|
|
aa := integer(floor(BM_LIM - log2(r)));
|
|
if aa < BO then
|
|
aa := BO;
|
|
end if;
|
|
if aa > MAX_EXP+BO then
|
|
aa := MAX_EXP+BO;
|
|
end if;
|
|
--report "[TST] aa=" & integer'image(aa) severity note;
|
|
--report "[TST] rr=" & real'image( r * 2.0**aa ) severity note;
|
|
|
|
mm_id := integer(round(r * 2.0**aa));
|
|
--mm_id := integer(floor(r * 2.0**aa)); -- ????
|
|
ee := to_unsigned(aa-BO, ee'length);
|
|
mm := to_unsigned(mm_id, mm'length);
|
|
end if;
|
|
return std_logic_vector(ee) & std_logic_vector(mm);
|
|
end function real_to_ufp;
|
|
|
|
|
|
end package body pkg_ufp;
|