From 4430b4eb37233e9ed55d42c9f60bfda7868df0ca Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Wed, 23 Jul 2014 20:08:46 +0000 Subject: [PATCH] CRLF git-svn-id: http://moon:8086/svn/vhdl/trunk@1048 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/fixed_ja/fixed_ja.vhd | 644 +++--- lib/fixed_ja/fixed_ja_body.vhd | 3842 ++++++++++++++++---------------- 2 files changed, 2243 insertions(+), 2243 deletions(-) diff --git a/lib/fixed_ja/fixed_ja.vhd b/lib/fixed_ja/fixed_ja.vhd index bcd2700..ce77a75 100644 --- a/lib/fixed_ja/fixed_ja.vhd +++ b/lib/fixed_ja/fixed_ja.vhd @@ -1,322 +1,322 @@ - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use ieee.numeric_std.all; - -package fixed_ja is - - - type ufixed_t is array (integer range <>) of STD_LOGIC; - type sfixed_t is array (integer range <>) of STD_LOGIC; - type ufixed_array_t is array (natural range <>, integer range <>) of STD_LOGIC; - type sfixed_array_t is array (natural range <>, integer range <>) of STD_LOGIC; - - type round_mode_t is (none, round_to_zero, round_pos_infinity, round_neg_infinity, round_half_up, round_half_down, round_nearest, round_convergent); - type saturate_mode_t is (none, saturate); - - -- Declare functions and procedure - - constant ASSERT_NO_WARN : boolean := false; - constant default_round_mode : round_mode_t := none; - constant default_saturate_mode : saturate_mode_t := none; - - -- null array constants - constant NAUF : ufixed_t (0 downto 1) := (others => '0'); - constant NASF : sfixed_t (0 downto 1) := (others => '0'); - constant NSLV : STD_LOGIC_VECTOR (0 downto 1) := (others => '0'); - - -- Constructor helpers - -- Use: variable v8u2 : ufixed_t(ufixed(8,2)'range); - function uproto (nbits : integer; nbits_int : integer) return ufixed_t; - - -- Use: variable v8s2 : sfixed_t(sfixed(8,2)'range); - function sproto (nbits : integer; nbits_int : integer) return sfixed_t; - - function uproto (a : ufixed_t; op : character; b : ufixed_t) return ufixed_t; - function sproto (a : sfixed_t; op : character; b : sfixed_t) return sfixed_t; - - -- Conversion Functions - function to_ufixed(src : ufixed_t) return ufixed_t; - function to_sfixed(src : sfixed_t) return sfixed_t; - function to_ufixed(src : sfixed_t) return ufixed_t; - function to_sfixed(src : ufixed_t) return sfixed_t; - - function to_ufixed - ( - src : ufixed_t; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t; - - function to_ufixed - ( - src : ufixed_t; - proto : ufixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t; - - function to_sfixed - ( - src : sfixed_t; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t; - - function to_sfixed - ( - src : sfixed_t; - proto : sfixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t; - - -- fixed <= integer - function to_ufixed (src : integer; nbits : integer; nbits_int : integer) return ufixed_t; - function to_ufixed (src : integer; proto : ufixed_t) return ufixed_t; - - -- fixed <= integer - function to_sfixed (src : integer; nbits : integer; nbits_int : integer) return sfixed_t; - function to_sfixed (src : integer; proto : sfixed_t) return sfixed_t; - - -- ufixed <= unsigned - function to_ufixed (src : unsigned; nbits : integer; nbits_int : integer) return ufixed_t; - function to_ufixed (src : unsigned; proto : ufixed_t) return ufixed_t; - - -- sfixed <= signed - function to_sfixed (src : signed; nbits : integer; nbits_int : integer) return sfixed_t; - function to_sfixed (src : signed; proto : sfixed_t) return sfixed_t; - - -- fixed <= slv - function to_ufixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return ufixed_t; - function to_ufixed (src : STD_LOGIC_VECTOR; proto : ufixed_t) return ufixed_t; - function to_sfixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return sfixed_t; - function to_sfixed (src : STD_LOGIC_VECTOR; proto : sfixed_t) return sfixed_t; - - -- ufixed <= real - function to_ufixed - ( - src : real; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t; - - function to_ufixed - ( - src : real; - proto : ufixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t; - - -- sfixed <= real - function to_sfixed - ( - src : real; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t; - - function to_sfixed - ( - src : real; - proto : sfixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t; - - -- Slicing functions for unconstrained array types - function to_ufixed(src : ufixed_array_t; index : integer) return ufixed_t; - function to_sfixed(src : sfixed_array_t; index : integer) return sfixed_t; - - -- ufixed <= string - function to_ufixed (src : string) return ufixed_t; - - -- sfixed <= string - function to_sfixed (src : string) return sfixed_t; - - -- real <= ufixed - function to_real(src : ufixed_t) return real; - - -- real <= sfixed - function to_real(src : sfixed_t) return real; - - -- slv <= ufixed - function to_slv(src : ufixed_t) return std_logic_vector; - - -- slv <= sfixed - function to_slv(src : sfixed_t) return std_logic_vector; - - -- UNSIGNED <= ufixed - function to_unsigned (src : ufixed_t) return UNSIGNED; - - -- SIGNED <= sfixed - function to_signed (src : sfixed_t) return SIGNED; - - -- integer <= ufixed - function to_integer (src : ufixed_t) return integer; - - -- integer <= sfixed - function to_integer (src : sfixed_t) return integer; - - function to_string(src : ufixed_t) return string; - function to_string(src : sfixed_t) return string; - function to_string(src : std_logic_vector) return string; - - ------------------------------------------------------------- - -- Arithmetic shift left - ------------------------------------------------------------- - function "sla" (src : ufixed_t; count : integer) return ufixed_t; - function "sla" (src : sfixed_t; count : integer) return sfixed_t; - - ------------------------------------------------------------- - -- Arithmetic shift right - ------------------------------------------------------------- - function "sra" (src : ufixed_t; count : integer) return ufixed_t; - function "sra" (src : sfixed_t; count : integer) return sfixed_t; - - ------------------------------------------------------------- - -- Multiplication - ------------------------------------------------------------- - function "*" (a : ufixed_t; b : ufixed_t) return ufixed_t; - function "*" (a : sfixed_t; b : sfixed_t) return sfixed_t; - function "*" (a : ufixed_t; b : sfixed_t) return sfixed_t; - function "*" (a : sfixed_t; b : ufixed_t) return sfixed_t; - - ------------------------------------------------------------- - -- Sum - ------------------------------------------------------------- - function "+" (a : ufixed_t; b : integer) return ufixed_t; - function "+" (a : sfixed_t; b : integer) return sfixed_t; - function "+" (a : ufixed_t; b : unsigned) return ufixed_t; - function "+" (a : sfixed_t; b : signed) return sfixed_t; - function "+" (a : ufixed_t; b : ufixed_t) return ufixed_t; - function "+" (a : sfixed_t; b : sfixed_t) return sfixed_t; - function "+" (a : ufixed_t; b : sfixed_t) return sfixed_t; - function "+" (a : sfixed_t; b : ufixed_t) return sfixed_t; - function "+" (a : ufixed_t; b : std_logic) return ufixed_t; - function "+" (a : sfixed_t; b : std_logic) return sfixed_t; - - - ------------------------------------------------------------- - -- Difference - ------------------------------------------------------------- - function "-" (a : ufixed_t; b : integer) return ufixed_t; - function "-" (a : sfixed_t; b : integer) return sfixed_t; - function "-" (a : ufixed_t; b : unsigned) return ufixed_t; - function "-" (a : sfixed_t; b : signed) return sfixed_t; - function "-" (a : ufixed_t; b : ufixed_t) return ufixed_t; - function "-" (a : sfixed_t; b : sfixed_t) return sfixed_t; - function "-" (a : ufixed_t; b : sfixed_t) return sfixed_t; - function "-" (a : sfixed_t; b : ufixed_t) return sfixed_t; - function "-" (a : ufixed_t; b : std_logic) return ufixed_t; - function "-" (a : sfixed_t; b : std_logic) return sfixed_t; - - ------------------------------------------------------------- - -- Equality - ------------------------------------------------------------- - function "=" (a : ufixed_t; b : ufixed_t) return boolean; - function "=" (a : sfixed_t; b : sfixed_t) return boolean; - function "=" (a : ufixed_t; b : sfixed_t) return boolean; - function "=" (a : sfixed_t; b : ufixed_t) return boolean; - - ------------------------------------------------------------- - -- Inequality - ------------------------------------------------------------- - function "/=" (a : ufixed_t; b : ufixed_t) return boolean; - function "/=" (a : sfixed_t; b : sfixed_t) return boolean; - function "/=" (a : ufixed_t; b : sfixed_t) return boolean; - function "/=" (a : sfixed_t; b : ufixed_t) return boolean; - - ------------------------------------------------------------- - -- Less than - ------------------------------------------------------------- - function "<" (a : ufixed_t; b : ufixed_t) return boolean; - function "<" (a : sfixed_t; b : sfixed_t) return boolean; - function "<" (a : ufixed_t; b : sfixed_t) return boolean; - function "<" (a : sfixed_t; b : ufixed_t) return boolean; - - ------------------------------------------------------------- - -- Greater than - ------------------------------------------------------------- - function ">" (a : ufixed_t; b : ufixed_t) return boolean; - function ">" (a : sfixed_t; b : sfixed_t) return boolean; - function ">" (a : ufixed_t; b : sfixed_t) return boolean; - function ">" (a : sfixed_t; b : ufixed_t) return boolean; - - ------------------------------------------------------------- - -- Less or equal than - ------------------------------------------------------------- - function "<=" (a : ufixed_t; b : ufixed_t) return boolean; - function "<=" (a : sfixed_t; b : sfixed_t) return boolean; - function "<=" (a : ufixed_t; b : sfixed_t) return boolean; - function "<=" (a : sfixed_t; b : ufixed_t) return boolean; - - ------------------------------------------------------------- - -- Greater or equal than - ------------------------------------------------------------- - function ">=" (a : ufixed_t; b : ufixed_t) return boolean; - function ">=" (a : sfixed_t; b : sfixed_t) return boolean; - function ">=" (a : ufixed_t; b : sfixed_t) return boolean; - function ">=" (a : sfixed_t; b : ufixed_t) return boolean; - - ------------------------------------------------------------- - -- Unary Arithmetic Operators - ------------------------------------------------------------- - function "abs" (src : sfixed_t) return sfixed_t; - function "-" (src : ufixed_t) return sfixed_t; - function "-" (src : sfixed_t) return sfixed_t; - - ------------------------------------------------------------- - -- Misc. Operators - ------------------------------------------------------------- - function ipart (src : ufixed_t) return ufixed_t; - function fpart (src : ufixed_t) return ufixed_t; - function ipart (src : sfixed_t) return sfixed_t; - function fpart (src : sfixed_t) return sfixed_t; - - ------------------------------------------------------------- - -- Print function - ------------------------------------------------------------- - procedure print_info(src : in ufixed_t; prefix : in string); - procedure print_info(src : in sfixed_t; prefix : in string); - procedure print_info(src : in string; prefix : in string); - - ------------------------------------------------------------- - -- Helpers - ------------------------------------------------------------- - function cmsb(src : ufixed_t) return integer; - function clsb(src : ufixed_t) return integer; - - function MIN (X, Y: INTEGER) return INTEGER; - function MAX (X, Y: INTEGER) return INTEGER; - - function "MOD" (X, Y: in REAL ) return REAL; - function ipart(src : real) return real; - function fpart(src : real) return real; - - function and_red(arg : ufixed_t) return STD_ULOGIC; - function nand_red(arg : ufixed_t) return STD_ULOGIC; - function or_red(arg : ufixed_t) return STD_ULOGIC; - function nor_red(arg : ufixed_t) return STD_ULOGIC; - function xor_red(arg : ufixed_t) return STD_ULOGIC; - function xnor_red(arg : ufixed_t) return STD_ULOGIC; - function and_red(arg : sfixed_t) return STD_ULOGIC; - function nand_red(arg : sfixed_t) return STD_ULOGIC; - function or_red(arg : sfixed_t) return STD_ULOGIC; - function nor_red(arg : sfixed_t) return STD_ULOGIC; - function xor_red(arg : sfixed_t) return STD_ULOGIC; - function xnor_red(arg : sfixed_t) return STD_ULOGIC; - - -------------------------------------------------------------- - -end; -- package fixed_ja; - + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use ieee.numeric_std.all; + +package fixed_ja is + + + type ufixed_t is array (integer range <>) of STD_LOGIC; + type sfixed_t is array (integer range <>) of STD_LOGIC; + type ufixed_array_t is array (natural range <>, integer range <>) of STD_LOGIC; + type sfixed_array_t is array (natural range <>, integer range <>) of STD_LOGIC; + + type round_mode_t is (none, round_to_zero, round_pos_infinity, round_neg_infinity, round_half_up, round_half_down, round_nearest, round_convergent); + type saturate_mode_t is (none, saturate); + + -- Declare functions and procedure + + constant ASSERT_NO_WARN : boolean := false; + constant default_round_mode : round_mode_t := none; + constant default_saturate_mode : saturate_mode_t := none; + + -- null array constants + constant NAUF : ufixed_t (0 downto 1) := (others => '0'); + constant NASF : sfixed_t (0 downto 1) := (others => '0'); + constant NSLV : STD_LOGIC_VECTOR (0 downto 1) := (others => '0'); + + -- Constructor helpers + -- Use: variable v8u2 : ufixed_t(ufixed(8,2)'range); + function uproto (nbits : integer; nbits_int : integer) return ufixed_t; + + -- Use: variable v8s2 : sfixed_t(sfixed(8,2)'range); + function sproto (nbits : integer; nbits_int : integer) return sfixed_t; + + function uproto (a : ufixed_t; op : character; b : ufixed_t) return ufixed_t; + function sproto (a : sfixed_t; op : character; b : sfixed_t) return sfixed_t; + + -- Conversion Functions + function to_ufixed(src : ufixed_t) return ufixed_t; + function to_sfixed(src : sfixed_t) return sfixed_t; + function to_ufixed(src : sfixed_t) return ufixed_t; + function to_sfixed(src : ufixed_t) return sfixed_t; + + function to_ufixed + ( + src : ufixed_t; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t; + + function to_ufixed + ( + src : ufixed_t; + proto : ufixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t; + + function to_sfixed + ( + src : sfixed_t; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t; + + function to_sfixed + ( + src : sfixed_t; + proto : sfixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t; + + -- fixed <= integer + function to_ufixed (src : integer; nbits : integer; nbits_int : integer) return ufixed_t; + function to_ufixed (src : integer; proto : ufixed_t) return ufixed_t; + + -- fixed <= integer + function to_sfixed (src : integer; nbits : integer; nbits_int : integer) return sfixed_t; + function to_sfixed (src : integer; proto : sfixed_t) return sfixed_t; + + -- ufixed <= unsigned + function to_ufixed (src : unsigned; nbits : integer; nbits_int : integer) return ufixed_t; + function to_ufixed (src : unsigned; proto : ufixed_t) return ufixed_t; + + -- sfixed <= signed + function to_sfixed (src : signed; nbits : integer; nbits_int : integer) return sfixed_t; + function to_sfixed (src : signed; proto : sfixed_t) return sfixed_t; + + -- fixed <= slv + function to_ufixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return ufixed_t; + function to_ufixed (src : STD_LOGIC_VECTOR; proto : ufixed_t) return ufixed_t; + function to_sfixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return sfixed_t; + function to_sfixed (src : STD_LOGIC_VECTOR; proto : sfixed_t) return sfixed_t; + + -- ufixed <= real + function to_ufixed + ( + src : real; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t; + + function to_ufixed + ( + src : real; + proto : ufixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t; + + -- sfixed <= real + function to_sfixed + ( + src : real; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t; + + function to_sfixed + ( + src : real; + proto : sfixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t; + + -- Slicing functions for unconstrained array types + function to_ufixed(src : ufixed_array_t; index : integer) return ufixed_t; + function to_sfixed(src : sfixed_array_t; index : integer) return sfixed_t; + + -- ufixed <= string + function to_ufixed (src : string) return ufixed_t; + + -- sfixed <= string + function to_sfixed (src : string) return sfixed_t; + + -- real <= ufixed + function to_real(src : ufixed_t) return real; + + -- real <= sfixed + function to_real(src : sfixed_t) return real; + + -- slv <= ufixed + function to_slv(src : ufixed_t) return std_logic_vector; + + -- slv <= sfixed + function to_slv(src : sfixed_t) return std_logic_vector; + + -- UNSIGNED <= ufixed + function to_unsigned (src : ufixed_t) return UNSIGNED; + + -- SIGNED <= sfixed + function to_signed (src : sfixed_t) return SIGNED; + + -- integer <= ufixed + function to_integer (src : ufixed_t) return integer; + + -- integer <= sfixed + function to_integer (src : sfixed_t) return integer; + + function to_string(src : ufixed_t) return string; + function to_string(src : sfixed_t) return string; + function to_string(src : std_logic_vector) return string; + + ------------------------------------------------------------- + -- Arithmetic shift left + ------------------------------------------------------------- + function "sla" (src : ufixed_t; count : integer) return ufixed_t; + function "sla" (src : sfixed_t; count : integer) return sfixed_t; + + ------------------------------------------------------------- + -- Arithmetic shift right + ------------------------------------------------------------- + function "sra" (src : ufixed_t; count : integer) return ufixed_t; + function "sra" (src : sfixed_t; count : integer) return sfixed_t; + + ------------------------------------------------------------- + -- Multiplication + ------------------------------------------------------------- + function "*" (a : ufixed_t; b : ufixed_t) return ufixed_t; + function "*" (a : sfixed_t; b : sfixed_t) return sfixed_t; + function "*" (a : ufixed_t; b : sfixed_t) return sfixed_t; + function "*" (a : sfixed_t; b : ufixed_t) return sfixed_t; + + ------------------------------------------------------------- + -- Sum + ------------------------------------------------------------- + function "+" (a : ufixed_t; b : integer) return ufixed_t; + function "+" (a : sfixed_t; b : integer) return sfixed_t; + function "+" (a : ufixed_t; b : unsigned) return ufixed_t; + function "+" (a : sfixed_t; b : signed) return sfixed_t; + function "+" (a : ufixed_t; b : ufixed_t) return ufixed_t; + function "+" (a : sfixed_t; b : sfixed_t) return sfixed_t; + function "+" (a : ufixed_t; b : sfixed_t) return sfixed_t; + function "+" (a : sfixed_t; b : ufixed_t) return sfixed_t; + function "+" (a : ufixed_t; b : std_logic) return ufixed_t; + function "+" (a : sfixed_t; b : std_logic) return sfixed_t; + + + ------------------------------------------------------------- + -- Difference + ------------------------------------------------------------- + function "-" (a : ufixed_t; b : integer) return ufixed_t; + function "-" (a : sfixed_t; b : integer) return sfixed_t; + function "-" (a : ufixed_t; b : unsigned) return ufixed_t; + function "-" (a : sfixed_t; b : signed) return sfixed_t; + function "-" (a : ufixed_t; b : ufixed_t) return ufixed_t; + function "-" (a : sfixed_t; b : sfixed_t) return sfixed_t; + function "-" (a : ufixed_t; b : sfixed_t) return sfixed_t; + function "-" (a : sfixed_t; b : ufixed_t) return sfixed_t; + function "-" (a : ufixed_t; b : std_logic) return ufixed_t; + function "-" (a : sfixed_t; b : std_logic) return sfixed_t; + + ------------------------------------------------------------- + -- Equality + ------------------------------------------------------------- + function "=" (a : ufixed_t; b : ufixed_t) return boolean; + function "=" (a : sfixed_t; b : sfixed_t) return boolean; + function "=" (a : ufixed_t; b : sfixed_t) return boolean; + function "=" (a : sfixed_t; b : ufixed_t) return boolean; + + ------------------------------------------------------------- + -- Inequality + ------------------------------------------------------------- + function "/=" (a : ufixed_t; b : ufixed_t) return boolean; + function "/=" (a : sfixed_t; b : sfixed_t) return boolean; + function "/=" (a : ufixed_t; b : sfixed_t) return boolean; + function "/=" (a : sfixed_t; b : ufixed_t) return boolean; + + ------------------------------------------------------------- + -- Less than + ------------------------------------------------------------- + function "<" (a : ufixed_t; b : ufixed_t) return boolean; + function "<" (a : sfixed_t; b : sfixed_t) return boolean; + function "<" (a : ufixed_t; b : sfixed_t) return boolean; + function "<" (a : sfixed_t; b : ufixed_t) return boolean; + + ------------------------------------------------------------- + -- Greater than + ------------------------------------------------------------- + function ">" (a : ufixed_t; b : ufixed_t) return boolean; + function ">" (a : sfixed_t; b : sfixed_t) return boolean; + function ">" (a : ufixed_t; b : sfixed_t) return boolean; + function ">" (a : sfixed_t; b : ufixed_t) return boolean; + + ------------------------------------------------------------- + -- Less or equal than + ------------------------------------------------------------- + function "<=" (a : ufixed_t; b : ufixed_t) return boolean; + function "<=" (a : sfixed_t; b : sfixed_t) return boolean; + function "<=" (a : ufixed_t; b : sfixed_t) return boolean; + function "<=" (a : sfixed_t; b : ufixed_t) return boolean; + + ------------------------------------------------------------- + -- Greater or equal than + ------------------------------------------------------------- + function ">=" (a : ufixed_t; b : ufixed_t) return boolean; + function ">=" (a : sfixed_t; b : sfixed_t) return boolean; + function ">=" (a : ufixed_t; b : sfixed_t) return boolean; + function ">=" (a : sfixed_t; b : ufixed_t) return boolean; + + ------------------------------------------------------------- + -- Unary Arithmetic Operators + ------------------------------------------------------------- + function "abs" (src : sfixed_t) return sfixed_t; + function "-" (src : ufixed_t) return sfixed_t; + function "-" (src : sfixed_t) return sfixed_t; + + ------------------------------------------------------------- + -- Misc. Operators + ------------------------------------------------------------- + function ipart (src : ufixed_t) return ufixed_t; + function fpart (src : ufixed_t) return ufixed_t; + function ipart (src : sfixed_t) return sfixed_t; + function fpart (src : sfixed_t) return sfixed_t; + + ------------------------------------------------------------- + -- Print function + ------------------------------------------------------------- + procedure print_info(src : in ufixed_t; prefix : in string); + procedure print_info(src : in sfixed_t; prefix : in string); + procedure print_info(src : in string; prefix : in string); + + ------------------------------------------------------------- + -- Helpers + ------------------------------------------------------------- + function cmsb(src : ufixed_t) return integer; + function clsb(src : ufixed_t) return integer; + + function MIN (X, Y: INTEGER) return INTEGER; + function MAX (X, Y: INTEGER) return INTEGER; + + function "MOD" (X, Y: in REAL ) return REAL; + function ipart(src : real) return real; + function fpart(src : real) return real; + + function and_red(arg : ufixed_t) return STD_ULOGIC; + function nand_red(arg : ufixed_t) return STD_ULOGIC; + function or_red(arg : ufixed_t) return STD_ULOGIC; + function nor_red(arg : ufixed_t) return STD_ULOGIC; + function xor_red(arg : ufixed_t) return STD_ULOGIC; + function xnor_red(arg : ufixed_t) return STD_ULOGIC; + function and_red(arg : sfixed_t) return STD_ULOGIC; + function nand_red(arg : sfixed_t) return STD_ULOGIC; + function or_red(arg : sfixed_t) return STD_ULOGIC; + function nor_red(arg : sfixed_t) return STD_ULOGIC; + function xor_red(arg : sfixed_t) return STD_ULOGIC; + function xnor_red(arg : sfixed_t) return STD_ULOGIC; + + -------------------------------------------------------------- + +end; -- package fixed_ja; + diff --git a/lib/fixed_ja/fixed_ja_body.vhd b/lib/fixed_ja/fixed_ja_body.vhd index a85b626..1f99a0e 100644 --- a/lib/fixed_ja/fixed_ja_body.vhd +++ b/lib/fixed_ja/fixed_ja_body.vhd @@ -1,1921 +1,1921 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use ieee.numeric_std.all; -use ieee.math_real.all; -use std.textio.all; - -package body fixed_ja is - - ------------------------------------------------------------- - -- Local Procedures - ------------------------------------------------------------- - -- adds 1 to the LSB of the number - procedure round_up - ( - src : in ufixed_t; - result : out ufixed_t; - overflowx : out BOOLEAN ) is - - variable srcuns, resuns : UNSIGNED (src'high-src'low+1 downto 0) := (others => '0'); - begin -- round_up - srcuns (srcuns'high-1 downto 0) := to_unsigned (src); - resuns := srcuns + 1; - - result := to_ufixed(resuns(src'high-src'low downto 0), src); - overflowx := (resuns(resuns'high) = '1'); - - end procedure round_up; - - ------------------------------------------------------------- - -- adds 1 to the LSB of the number - procedure round_up - ( - src : in sfixed_t; - result : out sfixed_t; - overflowx : out BOOLEAN ) is - - variable srcs, ress : SIGNED (src'high-src'low+1 downto 0); - begin -- round_up - srcs (srcs'high-1 downto 0) := to_signed (src); - srcs(srcs'high) := src(src'high); -- sign extend - ress := srcs + 1; - - result := to_sfixed(ress (ress'high-1 downto 0), src); - overflowx := ((src(src'high) /= ress(ress'high-1)) and (or_red (sfixed_t(ress)) /= '0')); - - end procedure round_up; - - ------------------------------------------------------------- - -- Local functions - ------------------------------------------------------------- - -- round_fixed() --- function round_fixed --- ( --- src : ufixed_t; --- remainder : ufixed_t; --- rnd_mode : round_mode_t := default_round_mode --- ) return ufixed_t is --- variable res : ufixed_t(src'range); --- begin --- return res; --- --- end round_fixed; - - ------------------------------------------------------------- --- function round_fixed --- ( --- src : sfixed_t; --- remainder : sfixed_t; --- rnd_mode : round_mode_t := default_round_mode --- ) return sfixed_t is --- variable res : signed(src'length-1 downto 0); --- begin --- return src; --- --- end round_fixed; - - ------------------------------------------------------------- - function reshape - ( - src : ufixed_t; - proto : ufixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t is - - variable RemainLow : ufixed_t (proto'low-1 downto src'low) := (others => '0'); - variable RemainHigh : ufixed_t (src'high downto proto'high+1) := (others => '0'); - variable dst, tmp : ufixed_t (proto'high downto proto'low) := (others => '0'); - variable ovf, isTruncLo, isTruncHi : boolean := false; - begin - - if proto'high < -1 then - assert false report "U: reshape: Bad dual point (Upper bound < (-1))" severity error; - end if; - - -- Check for high and low truncation - isTruncLo := (src'low < dst'low); - isTruncHi := (src'high > dst'high); - - -- Reshape - dst := (others => '0'); - dst(min(src'high, dst'high) downto max(src'low, dst'low)) := src(min(src'high, dst'high) downto max(src'low, dst'low)); - tmp := dst; - - -- Get low remainder - if isTruncLo then - RemainLow := src(RemainLow'range); - end if; - - -- Get high remainder - if isTruncHi then - RemainHigh := src(RemainHigh'range); - end if; - - ovf := false; - - -- Rounding - if isTruncLo then - - case rnd_mode is - - -- Round to positive infinity (round ceiling) - when round_pos_infinity => - if or_red(RemainLow) = '1' then - round_up(tmp, dst, ovf); - end if; - - -- Round Half-up - -- Round nearest - when round_half_up | round_nearest => - if (RemainLow(RemainLow'high) = '1') then - round_up(tmp, dst, ovf); - end if; - - -- Round convergent - when round_convergent => - if RemainLow(RemainLow'high) = '1' then - if or_red(RemainLow(RemainLow'high-1 downto RemainLow'low)) = '1' then - round_up(tmp, dst, ovf); - elsif tmp(dst'low) = '1' then - round_up(tmp, dst, ovf); - end if; - end if; - - -- Round to zero - when round_to_zero | none => null; - - when others => - assert false report "Reshape(U): Rounding mode (" & round_mode_t'image(rnd_mode) & ") not implemented!" severity error; - - end case; - end if; - - -- Saturating - if sat_mode = saturate then - - -- Check overflow - if isTruncHi then - ovf := ovf or or_red(RemainHigh) = '1'; - end if; - - -- Saturate - if ovf then - dst := (others => '1'); - end if; - - end if; - - return dst; - - end reshape; - - ------------------------------------------------------------- - function reshape - ( - src : ufixed_t; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t is - - begin - return reshape(src, uproto(nbits, nbits_int), rnd_mode, sat_mode); - - end reshape; - - ------------------------------------------------------------- - function reshape - ( - src : sfixed_t; - proto : sfixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t is - - variable RemainLow : sfixed_t (proto'low-1 downto src'low) := (others => '0'); - variable RemainHigh : sfixed_t (src'high-1 downto proto'high) := (others => '0'); - variable dst, tmp : sfixed_t (proto'high downto proto'low) := (others => '0'); - variable ovf, isTruncLo, isTruncHi : boolean := false; - variable sign : std_logic; - begin - - if proto'high < 0 then - assert false report "Reshape(S): Bad dual point (Upper bound < (0))" severity error; - end if; - - -- Check for high and low truncation - isTruncLo := (src'low < dst'low); - isTruncHi := (src'high > dst'high); - - -- Reshape - sign := src(src'high); - dst := (others => '0'); - dst(dst'high downto max(src'low, dst'low)) := (dst'high downto min(src'high, dst'high) => sign) & src(min(src'high, dst'high)-1 downto max(src'low, dst'low)); - tmp := dst; - - -- Get low remainder - if isTruncLo then - RemainLow := src(RemainLow'range); - end if; - - -- Get high remainder - if isTruncHi then - RemainHigh := src(RemainHigh'range); - end if; - - ovf := false; - - -- Rounding - if isTruncLo then - - case rnd_mode is - - -- Round to positive infinity (round ceiling) - when round_pos_infinity => - round_up(tmp, dst, ovf); - if ovf then - dst(dst'high) := '0'; - end if; - - -- Round Half-up - when round_half_up => - if RemainLow(RemainLow'high) = '1' then - round_up(tmp, dst, ovf); - end if; - - -- Round nearest - when round_nearest => - if RemainLow(RemainLow'high) = '1' then - if RemainLow'length = 1 then - if sign = '0' then - round_up(tmp, dst, ovf); - end if; - elsif sign = '0' or (sign and or_red(RemainLow(RemainLow'high-1 downto RemainLow'low))) = '1' then - round_up(tmp, dst, ovf); - end if; - end if; - - -- Round convergent - when round_convergent => - if RemainLow(RemainLow'high) = '1' then - if or_red(RemainLow(RemainLow'high-1 downto RemainLow'low)) = '1' then - round_up(tmp, dst, ovf); - elsif tmp(dst'low) = '1' then - round_up(tmp, dst, ovf); - end if; - end if; - - -- Round to zero - when round_to_zero => - if (or_red(RemainLow) = '1' and sign = '1') then - round_up(tmp, dst, ovf); - end if; - - -- No Round - when none => - -- Same as RoundToZero but overflow detection is omitted - dst := tmp + (or_red(RemainLow) and sign); - - when others => - assert false report "Reshape(S): Rounding mode (" & round_mode_t'image(rnd_mode) & ") not implemented!" severity error; - - end case; - - -- Check negative zero - if dst(dst'high) = '1' then - if or_red(dst(dst'high-1 downto dst'low)) = '0' then - dst(dst'high) := '0'; - -- assert false report "Reshape(S): -0 detected" severity note; - end if; - end if; - end if; - - -- Saturating - if sat_mode = saturate then - - -- Check overflow - if isTruncHi then - ovf := ovf or - (sign = '1' and src(dst'high) = '0' and or_red(tmp(dst'high-1 downto dst'low)) = '1') or - (sign = '1' and src(dst'high) = '1' and or_red(tmp(dst'high-1 downto dst'low)) = '0') or - (sign = '0' and or_red(RemainHigh) = '1'); - end if; - - -- Saturate - if ovf then - if (sign = '1') then - dst := '1' & (dst'high-1 downto dst'low+1 => '0') & '1'; - else - dst := '0' & (dst'high-1 downto dst'low => '1'); - end if; - end if; - - end if; - - return dst; - - end reshape; - - ------------------------------------------------------------- - function reshape - ( - src : sfixed_t; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t is - - begin - return reshape(src, sproto(nbits, nbits_int), rnd_mode, sat_mode); - - end reshape; - - ------------------------------------------------------------- - -- Constuctor helpers - ------------------------------------------------------------- - function uproto (nbits : integer; nbits_int : integer) return ufixed_t is - constant result : ufixed_t (nbits_int-1 downto nbits_int-nbits) := (others => '0'); - begin - return result(nbits_int-1 downto nbits_int-nbits); - end uproto; - - ------------------------------------------------------------- - function sproto (nbits : integer; nbits_int : integer) return sfixed_t is - constant result : sfixed_t (nbits_int downto nbits_int-nbits+1) := (others => '0'); - begin - return result(nbits_int downto nbits_int-nbits+1); - end sproto; - - ------------------------------------------------------------- - function uproto (a : ufixed_t; op : character; b : ufixed_t) return ufixed_t is - constant result : ufixed_t(a'high + b'high + 4 downto a'low + b'low - 4) := (others => '0'); - variable hi, lo : integer := 0; - - begin - - case op is - when '+' => - hi := max(a'high, b'high); - if a'high = b'high then - hi := hi + 1; - end if; - lo := min(a'low, b'low); - - when '-' => - hi := max(a'high, b'high); - lo := min(a'low, b'low); - - when '*' => - hi := a'high + b'high + 1; - if (a'high < 0 or b'high < 0) then - if (hi > -1) then - hi := hi-1; - end if; - end if; - lo := hi - a'length - b'length + 1; - - when others => null; - - end case; - - return result(hi downto lo); - end uproto; - - ------------------------------------------------------------- - function sproto (a : sfixed_t; op : character; b : sfixed_t) return sfixed_t is - constant result : sfixed_t(a'high + b'high + 4 downto a'low + b'low - 4) := (others => '0'); - variable hi, lo : integer := 0; - - begin - - case op is - when '+' => - hi := max(a'high, b'high); - if a'high = b'high then - hi := hi + 1; - end if; - lo := min(a'low, b'low); - - when '-' => - hi := max(a'high, b'high); - lo := min(a'low, b'low); - - when '*' => - hi := a'high + b'high; - if (a'high = 0 or b'high = 0) then - if (hi > 0) then - hi := hi-1; - end if; - end if; - lo := hi - a'length - b'length + 1; - - when others => null; - - end case; - - return result(hi downto lo); - end sproto; - - ------------------------------------------------------------- - -- Type conversions - ------------------------------------------------------------- - -- ufixed <= ufixed - function to_ufixed(src : ufixed_t) return ufixed_t is - begin - return to_ufixed(src, src); - - end to_ufixed; - - ------------------------------------------------------------- - -- ufixed <= sfixed - function to_ufixed(src : sfixed_t) return ufixed_t is - variable dst : ufixed_t(src'range) := (others => '0'); - begin - dst := ufixed_t(abs(src)); - return dst(src'high-1 downto src'low); - - end to_ufixed; - - ------------------------------------------------------------- - -- sfixed <= sfixed - function to_sfixed(src : sfixed_t) return sfixed_t is - begin - return src; - - end to_sfixed; - - ------------------------------------------------------------- - -- sfixed <= ufixed - function to_sfixed(src : ufixed_t) return sfixed_t is - variable dst : sfixed_t(src'high+1 downto src'low) := (others => '0'); - begin - dst(src'range) := sfixed_t(src); - return dst; - - end to_sfixed; - - ------------------------------------------------------------- - -- ufixed <= ufixed - function to_ufixed - ( - src : ufixed_t; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t is - begin - return reshape(src, nbits, nbits_int, rnd_mode, sat_mode); - - end to_ufixed; - - ------------------------------------------------------------- - -- ufixed <= ufixed - function to_ufixed - ( - src : ufixed_t; - proto : ufixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t is - begin - return reshape(src, proto, rnd_mode, sat_mode); - - end to_ufixed; - - ------------------------------------------------------------- - -- sfixed <= sfixed - function to_sfixed - ( - src : sfixed_t; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t is - begin - return reshape(src, nbits, nbits_int, rnd_mode, sat_mode); - - end to_sfixed; - - ------------------------------------------------------------- - -- sfixed <= sfixed - function to_sfixed - ( - src : sfixed_t; - proto : sfixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t is - begin - return reshape(src, proto, rnd_mode, sat_mode); - - end to_sfixed; - - ------------------------------------------------------------- - -- ufixed <= integer - function to_ufixed (src : integer; nbits : integer; nbits_int : integer) return ufixed_t is - begin - return to_ufixed(src, uproto(nbits, nbits_int)); - - end to_ufixed; - - function to_ufixed (src : integer; proto : ufixed_t) return ufixed_t is - begin - return to_ufixed(to_unsigned(src, proto'length), proto); - - end to_ufixed; - - ------------------------------------------------------------- - -- ufixed <= unsigned - function to_ufixed (src : unsigned; nbits : integer; nbits_int : integer) return ufixed_t is - begin - return to_ufixed(src, uproto(nbits, nbits_int)); - - end to_ufixed; - - ------------------------------------------------------------- - -- ufixed <= unsigned - function to_ufixed(src : unsigned; proto : ufixed_t) return ufixed_t is - variable dst : ufixed_t(proto'high downto proto'low) := (others => '0'); - begin - - dst(dst'low + min(dst'length, src'length)-1 downto dst'low) := ufixed_t(src(min(dst'length, src'length)-1 downto 0)); - - return dst; - - end to_ufixed; - - ------------------------------------------------------------- - -- sfixed <= integer - function to_sfixed (src : integer; nbits : integer; nbits_int : integer) return sfixed_t is - begin - return to_sfixed(src, sproto(nbits, nbits_int)); - - end to_sfixed; - - function to_sfixed (src : integer; proto : sfixed_t) return sfixed_t is - begin - - return to_sfixed(to_signed(src, proto'length), proto); - - end to_sfixed; - - ------------------------------------------------------------- - -- sfixed <= signed - function to_sfixed (src : signed; nbits : integer; nbits_int : integer) return sfixed_t is - begin - return to_sfixed(src, sproto(nbits, nbits_int)); - - end to_sfixed; - - ------------------------------------------------------------- - -- sfixed <= signed - function to_sfixed(src : signed; proto : sfixed_t) return sfixed_t is - variable dst : sfixed_t(proto'high downto proto'low) := (others => '0'); - begin - - dst(dst'low + min(dst'length, src'length)-2 downto dst'low) := sfixed_t(src(min(dst'length, src'length)-2 downto 0)); - dst(dst'high) := src(src'high); - - return dst; - - end to_sfixed; - - ------------------------------------------------------------- - function to_ufixed (src : STD_LOGIC_VECTOR; proto : ufixed_t) return ufixed_t is - variable result : ufixed_t (proto'left downto proto'right); - begin - if (result'length < 1) then - return result; - else - result := to_ufixed (unsigned(src), proto); - return result; - end if; - - end function to_ufixed; - - ------------------------------------------------------------- - function to_ufixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return ufixed_t is - begin - return to_ufixed(src, uproto(nbits, nbits_int)); - - end function to_ufixed; - - ------------------------------------------------------------- - function to_sfixed (src : STD_LOGIC_VECTOR; proto : sfixed_t) return sfixed_t is - variable result : sfixed_t (proto'left downto proto'right); - begin - if (result'length < 1) then - return result; - else - result := to_sfixed (signed(src), proto); - return result; - end if; - - end function to_sfixed; - - ------------------------------------------------------------- - function to_sfixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return sfixed_t is - begin - return to_sfixed(src, sproto(nbits, nbits_int)); - - end to_sfixed; - ------------------------------------------------------------- - - -- ufixed <= real - function to_ufixed - ( - src : real; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t is - - constant nbits_ext : integer := nbits + 1; - constant fix_hi : integer := nbits_int - 1; - constant fix_lo : integer := nbits_int - nbits_ext; - - variable dst : ufixed_t (fix_hi downto fix_lo) := (others => '0'); - variable i : integer := 0; - variable remain : real := 0.0; - - begin - - if (nbits_int < 0) then - assert false report "to_ufixed: Bad dual point (N integer bits < 0)" severity error; - end if; - - if ((2.0**nbits_int - 1.0) < ipart(abs(src))) then --- assert ASSERT_NO_WARN report "to_ufixed: Overflow (" & REAL'image(src) & ") " severity warning; --- print_info(dst, "dst: "); - end if; - - remain := abs(src); - for i in dst'range loop - if remain >= 2.0**i then - dst(i) := '1'; - remain := remain - 2.0**i; - else - dst(i) := '0'; - end if; - end loop; - - return to_ufixed(dst, nbits, nbits_int, rnd_mode, sat_mode); - - end to_ufixed; - - ------------------------------------------------------------- - -- sfixed <= real - function to_sfixed - ( - src : real; - proto : sfixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t is - - variable utmp : ufixed_t(proto'high-1 downto proto'low) := (others => '0'); - variable dst : sfixed_t(proto'high downto proto'low) := (others => '0'); - - begin - utmp := to_ufixed(src, utmp, rnd_mode, sat_mode); - if (src < 0.0) then - dst := -to_sfixed(utmp); - else - dst := to_sfixed(utmp); - end if; - - return dst; - end to_sfixed; - - ------------------------------------------------------------- - -- ufixed <= real - function to_ufixed - ( - src : real; - proto : ufixed_t; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return ufixed_t is - begin - return to_ufixed(src, proto'length, proto'high+1, rnd_mode, sat_mode); - end to_ufixed; - - ------------------------------------------------------------- - -- sfixed <= real - function to_sfixed - ( - src : real; - nbits : integer; - nbits_int : integer; - rnd_mode : round_mode_t := default_round_mode; - sat_mode : saturate_mode_t := default_saturate_mode - ) return sfixed_t is - begin - return to_sfixed(src, sproto(nbits, nbits_int), rnd_mode, sat_mode); - end to_sfixed; - - ------------------------------------------------------------------------------- - -- ufixed <= ufixed_array(i) - function to_ufixed(src : ufixed_array_t; index : integer) return ufixed_t is - variable dst : ufixed_t(src'range(2)); - begin - for j in src'range(2) loop - dst(j) := src(index, j); - end loop; - - return dst; - - end to_ufixed; - - ------------------------------------------------------------------------------- - -- sfixed <= sfixed_array(i) - function to_sfixed(src : sfixed_array_t; index : integer) return sfixed_t is - variable dst : sfixed_t(src'range(2)); - begin - for j in src'range(2) loop - dst(j) := src(index, j); - end loop; - - return dst; - - end to_sfixed; - - ------------------------------------------------------------- - -- ufixed <= string - function to_ufixed (src : string) return ufixed_t is - - variable i, j, nbits, nbits_int, nbits_frac : integer := 0; - variable dst : unsigned(src'length downto 0) := (others => '0'); - variable dp_found : boolean := false; - begin - - for i in src'reverse_range loop - case src(i) is - when '.' => - if dp_found then - assert false report "More than one DP not found." severity error; - else - dp_found := true; - nbits_frac := j; - end if; - - when '0' => dst(nbits) := '0'; nbits := nbits + 1; j := j + 1; - when '1' => dst(nbits) := '1'; nbits := nbits + 1; j := j + 1; - when others => - assert false report "Illegal character in binary string." severity error; - - end case; - - end loop ; - if not dp_found then - assert ASSERT_NO_WARN report "DP not found. Using left alignment." severity warning; - end if; - - nbits_int := nbits - nbits_frac; - - return to_ufixed(dst(nbits-1 downto 0), nbits, nbits_int); - - end to_ufixed; - - ------------------------------------------------------------- - -- sfixed <= string - function to_sfixed (src : string) return sfixed_t is - - variable i, j, nbits, nbits_int, nbits_frac : integer := 0; - variable dst : signed(src'length downto 0) := (others => '0'); - variable dp_found : boolean := false; - variable is_neg : boolean := false; - begin - - is_neg := src(src'left) = '-'; - - for i in src'reverse_range loop - case src(i) is - when '-' => null; - when '+' => null; - - when '.' => - if dp_found then - assert false report "More than one DP not found." severity error; - else - dp_found := true; - nbits_frac := j; - end if; - - when '0' => dst(nbits) := '0'; nbits := nbits + 1; j := j + 1; - when '1' => dst(nbits) := '1'; nbits := nbits + 1; j := j + 1; - when others => - assert false report "Illegal character in binary string." severity error; - end case; - end loop ; - nbits := nbits + 1; - - if not dp_found then - assert ASSERT_NO_WARN report "DP not found. Using left alignment." severity warning; - end if; - - nbits_int := nbits - nbits_frac-1; - - if is_neg then - dst(nbits-1 downto 0) := -dst(nbits-1 downto 0); - end if; - - return to_sfixed(dst(nbits-1 downto 0), nbits, nbits_int); - - end to_sfixed; - - ------------------------------------------------------------- - function to_unsigned (src : ufixed_t) return UNSIGNED is - subtype t is UNSIGNED(src'high - src'low downto 0); - variable slv : t; - begin - slv := t(src); - return UNSIGNED(to_X01(std_logic_vector(slv))); - - end function to_unsigned; - - ------------------------------------------------------------- - function to_signed (src : sfixed_t) return SIGNED is - subtype t is SIGNED(src'high - src'low downto 0); - variable slv : t; - begin - slv := t(src); - return SIGNED(to_X01(std_logic_vector(slv))); - - end function to_signed; - - ------------------------------------------------------------- - -- integer <= ufixed - function to_integer (src : ufixed_t) return integer is - begin - return to_integer(to_unsigned(src)); - end to_integer; - - ------------------------------------------------------------- - -- integer <= sfixed - function to_integer (src : sfixed_t) return integer is - begin - return to_integer(to_signed(src)); - end to_integer; - - ------------------------------------------------------------- - -- to_real - function to_real(src : ufixed_t) return real is - variable dst : real := 0.0; - begin - for i in src'range loop - if (src(i) = '1') then - dst := dst + real(2.0**i); - end if; - end loop; - return dst; - - end to_real; - - ------------------------------------------------------------- - function to_real(src : sfixed_t) return real is - variable dst : real := 0.0; - begin - dst := to_real(to_ufixed(src)); - - if (src(src'high) = '1') then - dst := -dst; - end if; - - return dst; - - end to_real; - - ------------------------------------------------------------- - -- to_slv - function to_slv (src : ufixed_t) return STD_LOGIC_VECTOR is - subtype t is STD_LOGIC_VECTOR (src'high - src'low downto 0); - variable slv : t; - begin - if src'length < 1 then - return NSLV; - end if; - slv := t (src); - return slv; - - end function to_slv; - - ------------------------------------------------------------- - -- to_slv - function to_slv (src : sfixed_t) return STD_LOGIC_VECTOR is - subtype t is STD_LOGIC_VECTOR (src'high - src'low downto 0); - variable slv : t; - begin - if src'length < 1 then - return NSLV; - end if; - slv := t (src); - return slv; - - end function to_slv; - - ------------------------------------------------------------- - function to_string(src : ufixed_t) return string is - variable str : string(src'length+1 downto 1) := (others => '0'); - variable i, j : integer := 0; - - begin - j := src'length+1; - for i in src'high downto 0 loop - if (src(i) = '1') then - str(j) := '1'; - end if; - j := j - 1; - end loop; - - str(j) := '.'; - j := j - 1; - - for i in -1 downto src'low loop - if (src(i) = '1') then - str(j) := '1'; - end if; - j := j - 1; - end loop; - - return str; - - end to_string; - - ------------------------------------------------------------- - function to_string(src : sfixed_t) return string is - variable str : string(src'length+1 downto 1) := (others => '0'); - variable i, j, start : integer := 0; - variable strlen : integer := 0; - variable src_abs : sfixed_t(src'range) := (others => '0'); - - begin - if (src'high < 0) then - assert false report "Illegal signed fix point number" severity error; - end if; - - start := src'high; - strlen := src'length; - - j := src'length+1; - if (src(start) = '1') then - str(j) := '-'; - j := j - 1; - start := start - 1; - strlen := strlen + 1; - end if; - - src_abs := abs(src); - - for i in start downto 0 loop - if (src_abs(i) = '1') then - str(j) := '1'; - end if; - j := j - 1; - end loop; - - str(j) := '.'; - j := j - 1; - - for i in -1 downto src'low loop - if (src_abs(i) = '1') then - str(j) := '1'; - end if; - j := j - 1; - end loop; - - return str(strlen downto 1); - - end to_string; - - ------------------------------------------------------------- - function to_string(src : std_logic_vector) return string is - variable str : string(src'length downto 1) := (others => '0'); - variable i : integer := 0; - - begin - for i in src'range loop - if (src(i) = '1') then - str(i+1) := '1'; - end if; - end loop; - - return str; - - end to_string; - - ------------------------------------------------------------- - -- Binary Operators - ------------------------------------------------------------- - function "sla" (src : ufixed_t; count : integer) return ufixed_t is - variable result : ufixed_t (src'high downto src'low) := (others => '0'); - - begin - if (count = 0) then - result := src; - elsif (count < 0) then - result := src sra -count; - elsif (count < src'length) then - result(src'high downto src'low) := src(src'high-count downto src'low) & (count-1 downto 0 => '0'); - end if; - return result; - - end "sla"; - - ------------------------------------------------------------- - function "sla" (src : sfixed_t; count : integer) return sfixed_t is - variable result : sfixed_t (src'high downto src'low) := (others => '0'); - variable sign : std_logic := '0'; - - begin - sign := src(src'high); - if (count = 0) then - result := src; - elsif (count < 0) then - result := src sra -count; - elsif (count < src'length-1) then - result(src'high downto src'low) := sign & src(src'high-count-1 downto src'low) & (count-1 downto 0 => '0'); - end if; - return result; - - end "sla"; - - ------------------------------------------------------------- - function "sra" (src : ufixed_t; count : integer) return ufixed_t is - variable result : ufixed_t (src'high downto src'low) := (others => '0'); - - begin - if (count = 0) then - result := src; - elsif (count < 0) then - result := src sla -count; - elsif (count < src'length) then - result(src'high downto src'low) := (count-1 downto 0 => '0') & src(src'high downto src'low + count); - end if; - return result; - - end "sra"; - - ------------------------------------------------------------- - function "sra" (src : sfixed_t; count : integer) return sfixed_t is - variable result : sfixed_t (src'high downto src'low) := (others => '0'); - variable res_slv, src_slv : signed (src'length-1 downto 0) := (others => '0'); - variable sign, do_sub : std_logic := '0'; - - begin - src_slv := to_signed(src); - sign := src(src'high); - do_sub := src(src'high) and src(src'low); - if (count = 0) then - result := src; - elsif (count < 0) then - result := src sla -count; - elsif (count < src'length-1) then - res_slv := (count downto 0 => sign) & src_slv(src'length-2 downto count); - if (do_sub = '1') then - result(src'high downto src'low) := to_sfixed(res_slv+1, result); - else - result(src'high downto src'low) := to_sfixed(res_slv, result); - end if; - end if; - return result; - - end "sra"; - - ------------------------------------------------------------- - function "*" (a : ufixed_t; b : ufixed_t) return ufixed_t is - variable result : ufixed_t (uproto(a,'*',b)'high downto uproto(a,'*',b)'low); - - begin - if (a'high < 0 and b'high >= 0) or (a'high >= 0 and b'high < 0) then - result := to_ufixed(to_unsigned(a) * to_unsigned(b), result) sla 1; - else - result := to_ufixed(to_unsigned(a) * to_unsigned(b), result); - end if; - return result; - - end "*"; - - ------------------------------------------------------------- - function "*" (a : sfixed_t; b : sfixed_t) return sfixed_t is - variable result : sfixed_t (sproto(a,'*',b)'high downto sproto(a,'*',b)'low); - - begin - if (a'high = 0 and b'high > 0) or (a'high > 0 and b'high = 0) then - result := to_sfixed(signed(a) * signed(b), result) sla 2; - else - result := to_sfixed(signed(a) * signed(b), result) sla 1; - end if; - return result; - - end "*"; - - ------------------------------------------------------------- - function "*" (a : ufixed_t; b : sfixed_t) return sfixed_t is - - begin - return to_sfixed(a) * b; - - end "*"; - - ------------------------------------------------------------- - function "*" (a : sfixed_t; b : ufixed_t) return sfixed_t is - - begin - return b * a; - - end "*"; - - ------------------------------------------------------------- - function "+" (a : ufixed_t; b : ufixed_t) return ufixed_t is - variable result : ufixed_t (uproto(a,'+',b)'high downto uproto(a,'+',b)'low); - - begin - result := ufixed_t(unsigned(reshape(a, result)) + unsigned(reshape(b, result))); - return result; - - end "+"; - - ------------------------------------------------------------- - function "+" (a : sfixed_t; b : sfixed_t) return sfixed_t is - variable result : sfixed_t (sproto(a,'+',b)'high downto sproto(a,'+',b)'low); - - begin - result := to_sfixed(signed(reshape(a,result)) + signed(reshape(b,result)), result); --- result := to_sfixed(signed(a) + signed(b), result); - return result; - - end "+"; - - ------------------------------------------------------------- - function "+" (a : ufixed_t; b : sfixed_t) return sfixed_t is - - begin - return to_sfixed(a) + b; - - end "+"; - - ------------------------------------------------------------- - function "+" (a : sfixed_t; b : ufixed_t) return sfixed_t is - - begin - return b + a; - - end "+"; - - ------------------------------------------------------------- - function "+" (a : ufixed_t; b : unsigned) return ufixed_t is - - begin - - return ufixed_t(unsigned(a) + b); - - end "+"; - - ------------------------------------------------------------- - function "+" (a : sfixed_t; b : signed) return sfixed_t is - - begin - - return sfixed_t(signed(a) + b); - - end "+"; - - ------------------------------------------------------------- - function "+" (a : ufixed_t; b : integer) return ufixed_t is - - begin - - return ufixed_t(unsigned(a) + to_unsigned(b, a'length)); - - end "+"; - - ------------------------------------------------------------- - function "+" (a : sfixed_t; b : integer) return sfixed_t is - - begin - - return sfixed_t(signed(a) + to_signed(b, a'length)); - - end "+"; - - ------------------------------------------------------------- - function "+" (a : ufixed_t; b : std_logic) return ufixed_t is - variable result : ufixed_t (a'high downto a'low); - variable buns : unsigned(a'length-1 downto 0); - - begin - buns := (a'length-1 downto 1 => '0') & b; - result := ufixed_t(to_unsigned(a) + buns); - return result; - - end "+"; - - ------------------------------------------------------------- - function "+" (a : sfixed_t; b : std_logic) return sfixed_t is - variable result : sfixed_t (a'high downto a'low); - variable bs : signed(a'length-1 downto 0); - - begin - bs := (a'length-1 downto 1 => '0') & b; - result := sfixed_t(to_signed(a) + bs); - return result; - - end "+"; - - ------------------------------------------------------------- - function "-" (a : ufixed_t; b : ufixed_t) return ufixed_t is - variable result : ufixed_t (uproto(a,'-',b)'high downto uproto(a,'-',b)'low); - begin - result := to_ufixed(to_sfixed(a) - to_sfixed(b)); - return result; - - end "-"; - - ------------------------------------------------------------- - function "-" (a : sfixed_t; b : sfixed_t) return sfixed_t is - variable result : sfixed_t (sproto(a,'-',b)'high downto sproto(a,'-',b)'low); - - begin - result := to_sfixed(signed(reshape(a,result)) - signed(reshape(b,result)), result); - return result; - - end "-"; - - ------------------------------------------------------------- - function "-" (a : ufixed_t; b : sfixed_t) return sfixed_t is - begin - return to_sfixed(a) - b; - - end "-"; - - ------------------------------------------------------------- - function "-" (a : sfixed_t; b : ufixed_t) return sfixed_t is - - begin - return a - to_sfixed(b); - - end "-"; - - ------------------------------------------------------------- - function "-" (a : ufixed_t; b : unsigned) return ufixed_t is - - begin - return ufixed_t(unsigned(a) - b); - - end "-"; - - ------------------------------------------------------------- - function "-" (a : sfixed_t; b : signed) return sfixed_t is - - begin - return sfixed_t(signed(a) - b); - - end "-"; - - ------------------------------------------------------------- - function "-" (a : ufixed_t; b : integer) return ufixed_t is - - begin - - return ufixed_t(unsigned(a) - to_unsigned(b, a'length)); - - end "-"; - - ------------------------------------------------------------- - function "-" (a : sfixed_t; b : integer) return sfixed_t is - - begin - - return sfixed_t(signed(a) - to_signed(b, a'length)); - - end "-"; - - ------------------------------------------------------------- - function "-" (a : ufixed_t; b : std_logic) return ufixed_t is - variable result : ufixed_t (a'high downto a'low); - variable buns : unsigned(a'length-1 downto 0); - - begin - buns := (a'length-1 downto 1 => '0') & b; - result := ufixed_t(unsigned(a) - buns); - return result; - - end "-"; - - ------------------------------------------------------------- - function "-" (a : sfixed_t; b : std_logic) return sfixed_t is - variable result : sfixed_t (a'high downto a'low); - variable bs : signed(a'length-1 downto 0); - - begin - bs := (a'length-1 downto 1 => '0') & b; - result := sfixed_t(signed(a) - bs); - return result; - - end "-"; - - ------------------------------------------------------------- - -- Unary Operators - ------------------------------------------------------------- - function "abs" (src : sfixed_t) return sfixed_t is - begin - return to_sfixed(abs(signed(src)), src); - - end "abs"; - - ------------------------------------------------------------- - function "-" (src : ufixed_t) return sfixed_t is - begin - return -to_sfixed(src); - - end "-"; - - ------------------------------------------------------------- - function "-" (src : sfixed_t) return sfixed_t is - begin - return to_sfixed(-signed(src), src); - - end "-"; - - ------------------------------------------------------------- - -- Binary Equality - ------------------------------------------------------------- - function "=" (a : ufixed_t; b : ufixed_t) return boolean is - variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low)); - begin - ta := (others => '0'); - tb := (others => '0'); - ta := to_ufixed(a, ta); - tb := to_ufixed(b, tb); - return to_unsigned(ta) = to_unsigned(tb); - - end "="; - - ------------------------------------------------------------- - function "=" (a : sfixed_t; b : sfixed_t) return boolean is - variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low)); - begin - ta := (others => '0'); - tb := (others => '0'); - ta := to_sfixed(a, ta); - tb := to_sfixed(b, tb); - return to_signed(ta) = to_signed(tb); - - end "="; - - ------------------------------------------------------------- - function "=" (a : ufixed_t; b : sfixed_t) return boolean is - begin - return to_sfixed(a) = b; - end "="; - - ------------------------------------------------------------- - function "=" (a : sfixed_t; b : ufixed_t) return boolean is - begin - return b = a; - end "="; - - ------------------------------------------------------------- - -- Binary Inequality - ------------------------------------------------------------- - function "/=" (a : ufixed_t; b : ufixed_t) return boolean is - begin - return not (a = b); - - end "/="; - - ------------------------------------------------------------- - function "/=" (a : sfixed_t; b : sfixed_t) return boolean is - begin - return not (a = b); - - end "/="; - - ------------------------------------------------------------- - function "/=" (a : ufixed_t; b : sfixed_t) return boolean is - begin - return not (a = b); - end "/="; - - ------------------------------------------------------------- - function "/=" (a : sfixed_t; b : ufixed_t) return boolean is - begin - return not (a = b); - end "/="; - - ------------------------------------------------------------- - -- Binary less than - ------------------------------------------------------------- - function "<" (a : ufixed_t; b : ufixed_t) return boolean is - variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low)); - begin - ta := (others => '0'); - tb := (others => '0'); - ta := to_ufixed(a, ta); - tb := to_ufixed(b, tb); - return to_unsigned(ta) < to_unsigned(tb); - - end "<"; - - ------------------------------------------------------------- - function "<" (a : sfixed_t; b : sfixed_t) return boolean is - variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low)); - begin - ta := (others => '0'); - tb := (others => '0'); - ta := to_sfixed(a, ta); - tb := to_sfixed(b, tb); - return to_signed(ta) < to_signed(tb); - - end "<"; - - ------------------------------------------------------------- - function "<" (a : ufixed_t; b : sfixed_t) return boolean is - begin - return to_sfixed(a) < b; - - end "<"; - - ------------------------------------------------------------- - function "<" (a : sfixed_t; b : ufixed_t) return boolean is - begin - return a < to_sfixed(b); - - end "<"; - - ------------------------------------------------------------- - -- Binary greater than - ------------------------------------------------------------- - function ">" (a : ufixed_t; b : ufixed_t) return boolean is - variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low)); - begin - ta := (others => '0'); - tb := (others => '0'); - ta := to_ufixed(a, ta); - tb := to_ufixed(b, tb); - return to_unsigned(ta) > to_unsigned(tb); - - end ">"; - - ------------------------------------------------------------- - function ">" (a : sfixed_t; b : sfixed_t) return boolean is - variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low)); - begin - ta := (others => '0'); - tb := (others => '0'); - ta := to_sfixed(a, ta); - tb := to_sfixed(b, tb); - return to_signed(ta) > to_signed(tb); - - end ">"; - - ------------------------------------------------------------- - function ">" (a : ufixed_t; b : sfixed_t) return boolean is - begin - return to_sfixed(a) > b; - end ">"; - - ------------------------------------------------------------- - function ">" (a : sfixed_t; b : ufixed_t) return boolean is - begin - return a > to_sfixed(b); - end ">"; - - ------------------------------------------------------------- - -- Binary less equal than - ------------------------------------------------------------- - function "<=" (a : ufixed_t; b : ufixed_t) return boolean is - begin - return not (a > b); - end "<="; - - function "<=" (a : sfixed_t; b : sfixed_t) return boolean is - begin - return not (a > b); - end "<="; - - function "<=" (a : ufixed_t; b : sfixed_t) return boolean is - begin - return not (a > b); - end "<="; - - function "<=" (a : sfixed_t; b : ufixed_t) return boolean is - begin - return not (a > b); - end "<="; - - ------------------------------------------------------------- - -- Binary greater or equal than - ------------------------------------------------------------- - function ">=" (a : ufixed_t; b : ufixed_t) return boolean is - begin - return not (a < b); - end ">="; - - function ">=" (a : sfixed_t; b : sfixed_t) return boolean is - begin - return not (a < b); - end ">="; - - function ">=" (a : ufixed_t; b : sfixed_t) return boolean is - begin - return not (a < b); - end ">="; - - function ">=" (a : sfixed_t; b : ufixed_t) return boolean is - begin - return not (a < b); - end ">="; - - ------------------------------------------------------------- - -- Misc. Operators - ------------------------------------------------------------- - function ipart (src : ufixed_t) return ufixed_t is - begin - return src(src'high downto 0); - end ipart; - - function fpart (src : ufixed_t) return ufixed_t is - begin - return src(-1 downto src'low); - end fpart; - - function ipart (src : sfixed_t) return sfixed_t is - begin - return src(src'high-1 downto 0); - end ipart; - - function fpart (src : sfixed_t) return sfixed_t is - begin - return src(-1 downto src'low); - end fpart; - - ------------------------------------------------------------- - -- Print functions - ------------------------------------------------------------- - procedure print_info(src : in ufixed_t; prefix : in string) is - variable L : line; - - begin - write (L, prefix & "'length = ");write (L, src'length); - writeline (output, L); - - write (L, prefix & "'high(left) = "); - write (L, src'high); - write (L, '('); - write (L, src'left); - write (L, ')'); - writeline (output, L); - - write (L, prefix & "'low(right) = "); - write (L, src'low); - write (L, '('); - write (L, src'right); - write (L, ')'); - writeline (output, L); - - write (L, prefix & "'value = B");write (L, to_string(src)); - writeline (output, L); - - write (L, prefix & "'value = ");write (L, to_real(src)); - writeline (output, L); - - -- write (L, prefix & "'cmsb = ");write (L, cmsb(src)); - -- writeline (output, L); - - -- write (L, prefix & "'clsb = ");write (L, clsb(src)); - -- writeline (output, L); - - writeline (output, L); - - end print_info; - - ------------------------------------------------------------- - procedure print_info(src : in sfixed_t; prefix : in string) is - variable L : line; - - begin - write (L, prefix & "'length = ");write (L, src'length); - writeline (output, L); - - write (L, prefix & "'high(left) = "); - write (L, src'high); - write (L, '('); - write (L, src'left); - write (L, ')'); - writeline (output, L); - - write (L, prefix & "'low(right) = "); - write (L, src'low); - write (L, '('); - write (L, src'right); - write (L, ')'); - writeline (output, L); - - write (L, prefix & "'value = B");write (L, to_string(src)); - writeline (output, L); - - write (L, prefix & "'value = ");write (L, to_real(src)); - writeline (output, L); - - -- write (L, prefix & "'cmsb = ");write (L, cmsb(src)); - -- writeline (output, L); - - -- write (L, prefix & "'clsb = ");write (L, clsb(src)); - -- writeline (output, L); - - writeline (output, L); - - end print_info; - - ------------------------------------------------------------- - procedure print_info(src : in string; prefix : in string) is - variable L : line; - - begin - write (L, prefix & "'length = ");write (L, src'length); - writeline (output, L); - - write (L, prefix & "'high(left) = "); - write (L, src'high); - write (L, '('); - write (L, src'left); - write (L, ')'); - writeline (output, L); - - write (L, prefix & "'low(right) = "); - write (L, src'low); - write (L, '('); - write (L, src'right); - write (L, ')'); - writeline (output, L); - - writeline (output, L); - - end print_info; - - ------------------------------------------------------------- - -- Helpers - ------------------------------------------------------------- - -- Count significant bits for integer part - function cmsb(src : ufixed_t) return integer is - variable j, i : integer := src'high; - begin - for i in src'range loop - if src(i) = '1' then - exit; - end if; - j := j - 1; - end loop; - - -- LRM nachlesen: hier is i=src'high re-initialisert - - return j; - - end cmsb; - - ------------------------------------------------------------- - -- Count significant bits for fractional part - function clsb(src : ufixed_t) return integer is - variable j, i : integer := src'low; - begin - for i in src'reverse_range loop - if src(i) = '1' then - exit; - end if; - j := j + 1; - end loop; - - -- LRM nachlesen: hier is i=src'low re-initialisert - - return j; - - end clsb; - - ------------------------------------------------------------- - function MIN (X, Y: INTEGER) return INTEGER is - variable res : integer := X; - begin - if Y < X then - res := Y; - end if; - - return res; - - end MIN; - - ------------------------------------------------------------- - function MAX (X, Y: INTEGER) return INTEGER is - variable res : integer := X; - begin - if Y > X then - res := Y; - end if; - - return res; - - end MAX; - - ------------------------------------------------------------- - function "MOD" (X, Y: in REAL ) return REAL is - -- Description: - -- See function declaration in IEEE Std 1076.2-1996 - -- Notes: - -- a) Returns 0.0 on error - - variable XNEGATIVE : BOOLEAN := X < 0.0; - variable YNEGATIVE : BOOLEAN := Y < 0.0; - variable VALUE : REAL; - begin - -- Check validity of input arguments - if (Y = 0.0) then - assert FALSE - report "MOD(X, 0.0) is undefined" - severity ERROR; - return 0.0; - end if; - - -- Compute value - if ( XNEGATIVE ) then - if ( YNEGATIVE ) then - VALUE := X + (FLOOR(ABS(X)/ABS(Y)))*ABS(Y); - else - VALUE := X + (CEIL(ABS(X)/ABS(Y)))*ABS(Y); - end if; - else - if ( YNEGATIVE ) then - VALUE := X - (CEIL(ABS(X)/ABS(Y)))*ABS(Y); - else - VALUE := X - (FLOOR(ABS(X)/ABS(Y)))*ABS(Y); - end if; - end if; - - return VALUE; - - end "MOD"; - - ------------------------------------------------------------- - -- misc. conversion - function ipart(src : real) return real is - begin - return floor(src); - - end ipart; - - ------------------------------------------------------------- - function fpart(src : real) return real is - begin - return src - floor(src); - - end fpart; - - ------------------------------------------------------------- - function or_red (arg : STD_LOGIC_VECTOR) - return STD_LOGIC is - variable Upper, Lower : STD_LOGIC; - variable Half : INTEGER; - variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0); - variable Result : STD_LOGIC; - begin - if (arg'length < 1) then -- In the case of a NULL range - Result := '0'; - else - BUS_int := to_ux01 (arg); - if (BUS_int'length = 1) then - Result := BUS_int (BUS_int'left); - elsif (BUS_int'length = 2) then - Result := BUS_int (BUS_int'right) or BUS_int (BUS_int'left); - else - Half := (BUS_int'length + 1) / 2 + BUS_int'right; - Upper := or_red (BUS_int (BUS_int'left downto Half)); - Lower := or_red (BUS_int (Half - 1 downto BUS_int'right)); - Result := Upper or Lower; - end if; - end if; - return Result; - - end function or_red; - - ------------------------------------------------------------- - function and_red (arg : STD_LOGIC_VECTOR) - return STD_LOGIC is - variable Upper, Lower : STD_LOGIC; - variable Half : INTEGER; - variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0); - variable Result : STD_LOGIC; - begin - if (arg'length < 1) then -- In the case of a NULL range - Result := '1'; - else - BUS_int := to_ux01 (arg); - if (BUS_int'length = 1) then - Result := BUS_int (BUS_int'left); - elsif (BUS_int'length = 2) then - Result := BUS_int (BUS_int'right) and BUS_int (BUS_int'left); - else - Half := (BUS_int'length + 1) / 2 + BUS_int'right; - Upper := and_red (BUS_int (BUS_int'left downto Half)); - Lower := and_red (BUS_int (Half - 1 downto BUS_int'right)); - Result := Upper and Lower; - end if; - end if; - return Result; - - end function and_red; - - ------------------------------------------------------------- - function xor_red (arg : STD_LOGIC_VECTOR) return STD_ULOGIC is - variable Upper, Lower : STD_ULOGIC; - variable Half : INTEGER; - variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0); - variable Result : STD_ULOGIC := '0'; -- In the case of a NULL range - begin - if (arg'length >= 1) then - BUS_int := to_ux01 (arg); - if (BUS_int'length = 1) then - Result := BUS_int (BUS_int'left); - elsif (BUS_int'length = 2) then - Result := BUS_int(BUS_int'right) xor BUS_int(BUS_int'left); - else - Half := (BUS_int'length + 1) / 2 + BUS_int'right; - Upper := xor_red (BUS_int (BUS_int'left downto Half)); - Lower := xor_red (BUS_int (Half - 1 downto BUS_int'right)); - Result := Upper xor Lower; - end if; - end if; - return Result; - - end function xor_red; - - ------------------------------------------------------------- - -- Reduction operators, same as numeric_std functions - function and_red(arg : ufixed_t) return STD_ULOGIC is - begin - return and_red (to_slv(arg)); - end function and_red; - - function nand_red(arg : ufixed_t) return STD_ULOGIC is - begin - return not and_red (to_slv(arg)); - end function nand_red; - - function or_red(arg : ufixed_t) return STD_ULOGIC is - begin - return or_red (to_slv(arg)); - end function or_red; - - function nor_red(arg : ufixed_t) return STD_ULOGIC is - begin - return not or_red (to_slv(arg)); - end function nor_red; - - function xor_red(arg : ufixed_t) return STD_ULOGIC is - begin - return xor_red (to_slv(arg)); - end function xor_red; - - function xnor_red(arg : ufixed_t) return STD_ULOGIC is - begin - return not xor_red (to_slv(arg)); - end function xnor_red; - - function and_red(arg : sfixed_t) return STD_ULOGIC is - begin - return and_red (to_slv(arg)); - end function and_red; - - function nand_red(arg : sfixed_t) return STD_ULOGIC is - begin - return not and_red (to_slv(arg)); - end function nand_red; - - function or_red(arg : sfixed_t) return STD_ULOGIC is - begin - return or_red (to_slv(arg)); - end function or_red; - - function nor_red(arg : sfixed_t) return STD_ULOGIC is - begin - return not or_red (to_slv(arg)); - end function nor_red; - - function xor_red(arg : sfixed_t) return STD_ULOGIC is - begin - return xor_red (to_slv(arg)); - end function xor_red; - - function xnor_red(arg : sfixed_t) return STD_ULOGIC is - begin - return not xor_red (to_slv(arg)); - end function xnor_red; - - ------------------------------------------------------------- - -end; -- package body fixed_ja; +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use ieee.numeric_std.all; +use ieee.math_real.all; +use std.textio.all; + +package body fixed_ja is + + ------------------------------------------------------------- + -- Local Procedures + ------------------------------------------------------------- + -- adds 1 to the LSB of the number + procedure round_up + ( + src : in ufixed_t; + result : out ufixed_t; + overflowx : out BOOLEAN ) is + + variable srcuns, resuns : UNSIGNED (src'high-src'low+1 downto 0) := (others => '0'); + begin -- round_up + srcuns (srcuns'high-1 downto 0) := to_unsigned (src); + resuns := srcuns + 1; + + result := to_ufixed(resuns(src'high-src'low downto 0), src); + overflowx := (resuns(resuns'high) = '1'); + + end procedure round_up; + + ------------------------------------------------------------- + -- adds 1 to the LSB of the number + procedure round_up + ( + src : in sfixed_t; + result : out sfixed_t; + overflowx : out BOOLEAN ) is + + variable srcs, ress : SIGNED (src'high-src'low+1 downto 0); + begin -- round_up + srcs (srcs'high-1 downto 0) := to_signed (src); + srcs(srcs'high) := src(src'high); -- sign extend + ress := srcs + 1; + + result := to_sfixed(ress (ress'high-1 downto 0), src); + overflowx := ((src(src'high) /= ress(ress'high-1)) and (or_red (sfixed_t(ress)) /= '0')); + + end procedure round_up; + + ------------------------------------------------------------- + -- Local functions + ------------------------------------------------------------- + -- round_fixed() +-- function round_fixed +-- ( +-- src : ufixed_t; +-- remainder : ufixed_t; +-- rnd_mode : round_mode_t := default_round_mode +-- ) return ufixed_t is +-- variable res : ufixed_t(src'range); +-- begin +-- return res; +-- +-- end round_fixed; + + ------------------------------------------------------------- +-- function round_fixed +-- ( +-- src : sfixed_t; +-- remainder : sfixed_t; +-- rnd_mode : round_mode_t := default_round_mode +-- ) return sfixed_t is +-- variable res : signed(src'length-1 downto 0); +-- begin +-- return src; +-- +-- end round_fixed; + + ------------------------------------------------------------- + function reshape + ( + src : ufixed_t; + proto : ufixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t is + + variable RemainLow : ufixed_t (proto'low-1 downto src'low) := (others => '0'); + variable RemainHigh : ufixed_t (src'high downto proto'high+1) := (others => '0'); + variable dst, tmp : ufixed_t (proto'high downto proto'low) := (others => '0'); + variable ovf, isTruncLo, isTruncHi : boolean := false; + begin + + if proto'high < -1 then + assert false report "U: reshape: Bad dual point (Upper bound < (-1))" severity error; + end if; + + -- Check for high and low truncation + isTruncLo := (src'low < dst'low); + isTruncHi := (src'high > dst'high); + + -- Reshape + dst := (others => '0'); + dst(min(src'high, dst'high) downto max(src'low, dst'low)) := src(min(src'high, dst'high) downto max(src'low, dst'low)); + tmp := dst; + + -- Get low remainder + if isTruncLo then + RemainLow := src(RemainLow'range); + end if; + + -- Get high remainder + if isTruncHi then + RemainHigh := src(RemainHigh'range); + end if; + + ovf := false; + + -- Rounding + if isTruncLo then + + case rnd_mode is + + -- Round to positive infinity (round ceiling) + when round_pos_infinity => + if or_red(RemainLow) = '1' then + round_up(tmp, dst, ovf); + end if; + + -- Round Half-up + -- Round nearest + when round_half_up | round_nearest => + if (RemainLow(RemainLow'high) = '1') then + round_up(tmp, dst, ovf); + end if; + + -- Round convergent + when round_convergent => + if RemainLow(RemainLow'high) = '1' then + if or_red(RemainLow(RemainLow'high-1 downto RemainLow'low)) = '1' then + round_up(tmp, dst, ovf); + elsif tmp(dst'low) = '1' then + round_up(tmp, dst, ovf); + end if; + end if; + + -- Round to zero + when round_to_zero | none => null; + + when others => + assert false report "Reshape(U): Rounding mode (" & round_mode_t'image(rnd_mode) & ") not implemented!" severity error; + + end case; + end if; + + -- Saturating + if sat_mode = saturate then + + -- Check overflow + if isTruncHi then + ovf := ovf or or_red(RemainHigh) = '1'; + end if; + + -- Saturate + if ovf then + dst := (others => '1'); + end if; + + end if; + + return dst; + + end reshape; + + ------------------------------------------------------------- + function reshape + ( + src : ufixed_t; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t is + + begin + return reshape(src, uproto(nbits, nbits_int), rnd_mode, sat_mode); + + end reshape; + + ------------------------------------------------------------- + function reshape + ( + src : sfixed_t; + proto : sfixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t is + + variable RemainLow : sfixed_t (proto'low-1 downto src'low) := (others => '0'); + variable RemainHigh : sfixed_t (src'high-1 downto proto'high) := (others => '0'); + variable dst, tmp : sfixed_t (proto'high downto proto'low) := (others => '0'); + variable ovf, isTruncLo, isTruncHi : boolean := false; + variable sign : std_logic; + begin + + if proto'high < 0 then + assert false report "Reshape(S): Bad dual point (Upper bound < (0))" severity error; + end if; + + -- Check for high and low truncation + isTruncLo := (src'low < dst'low); + isTruncHi := (src'high > dst'high); + + -- Reshape + sign := src(src'high); + dst := (others => '0'); + dst(dst'high downto max(src'low, dst'low)) := (dst'high downto min(src'high, dst'high) => sign) & src(min(src'high, dst'high)-1 downto max(src'low, dst'low)); + tmp := dst; + + -- Get low remainder + if isTruncLo then + RemainLow := src(RemainLow'range); + end if; + + -- Get high remainder + if isTruncHi then + RemainHigh := src(RemainHigh'range); + end if; + + ovf := false; + + -- Rounding + if isTruncLo then + + case rnd_mode is + + -- Round to positive infinity (round ceiling) + when round_pos_infinity => + round_up(tmp, dst, ovf); + if ovf then + dst(dst'high) := '0'; + end if; + + -- Round Half-up + when round_half_up => + if RemainLow(RemainLow'high) = '1' then + round_up(tmp, dst, ovf); + end if; + + -- Round nearest + when round_nearest => + if RemainLow(RemainLow'high) = '1' then + if RemainLow'length = 1 then + if sign = '0' then + round_up(tmp, dst, ovf); + end if; + elsif sign = '0' or (sign and or_red(RemainLow(RemainLow'high-1 downto RemainLow'low))) = '1' then + round_up(tmp, dst, ovf); + end if; + end if; + + -- Round convergent + when round_convergent => + if RemainLow(RemainLow'high) = '1' then + if or_red(RemainLow(RemainLow'high-1 downto RemainLow'low)) = '1' then + round_up(tmp, dst, ovf); + elsif tmp(dst'low) = '1' then + round_up(tmp, dst, ovf); + end if; + end if; + + -- Round to zero + when round_to_zero => + if (or_red(RemainLow) = '1' and sign = '1') then + round_up(tmp, dst, ovf); + end if; + + -- No Round + when none => + -- Same as RoundToZero but overflow detection is omitted + dst := tmp + (or_red(RemainLow) and sign); + + when others => + assert false report "Reshape(S): Rounding mode (" & round_mode_t'image(rnd_mode) & ") not implemented!" severity error; + + end case; + + -- Check negative zero + if dst(dst'high) = '1' then + if or_red(dst(dst'high-1 downto dst'low)) = '0' then + dst(dst'high) := '0'; + -- assert false report "Reshape(S): -0 detected" severity note; + end if; + end if; + end if; + + -- Saturating + if sat_mode = saturate then + + -- Check overflow + if isTruncHi then + ovf := ovf or + (sign = '1' and src(dst'high) = '0' and or_red(tmp(dst'high-1 downto dst'low)) = '1') or + (sign = '1' and src(dst'high) = '1' and or_red(tmp(dst'high-1 downto dst'low)) = '0') or + (sign = '0' and or_red(RemainHigh) = '1'); + end if; + + -- Saturate + if ovf then + if (sign = '1') then + dst := '1' & (dst'high-1 downto dst'low+1 => '0') & '1'; + else + dst := '0' & (dst'high-1 downto dst'low => '1'); + end if; + end if; + + end if; + + return dst; + + end reshape; + + ------------------------------------------------------------- + function reshape + ( + src : sfixed_t; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t is + + begin + return reshape(src, sproto(nbits, nbits_int), rnd_mode, sat_mode); + + end reshape; + + ------------------------------------------------------------- + -- Constuctor helpers + ------------------------------------------------------------- + function uproto (nbits : integer; nbits_int : integer) return ufixed_t is + constant result : ufixed_t (nbits_int-1 downto nbits_int-nbits) := (others => '0'); + begin + return result(nbits_int-1 downto nbits_int-nbits); + end uproto; + + ------------------------------------------------------------- + function sproto (nbits : integer; nbits_int : integer) return sfixed_t is + constant result : sfixed_t (nbits_int downto nbits_int-nbits+1) := (others => '0'); + begin + return result(nbits_int downto nbits_int-nbits+1); + end sproto; + + ------------------------------------------------------------- + function uproto (a : ufixed_t; op : character; b : ufixed_t) return ufixed_t is + constant result : ufixed_t(a'high + b'high + 4 downto a'low + b'low - 4) := (others => '0'); + variable hi, lo : integer := 0; + + begin + + case op is + when '+' => + hi := max(a'high, b'high); + if a'high = b'high then + hi := hi + 1; + end if; + lo := min(a'low, b'low); + + when '-' => + hi := max(a'high, b'high); + lo := min(a'low, b'low); + + when '*' => + hi := a'high + b'high + 1; + if (a'high < 0 or b'high < 0) then + if (hi > -1) then + hi := hi-1; + end if; + end if; + lo := hi - a'length - b'length + 1; + + when others => null; + + end case; + + return result(hi downto lo); + end uproto; + + ------------------------------------------------------------- + function sproto (a : sfixed_t; op : character; b : sfixed_t) return sfixed_t is + constant result : sfixed_t(a'high + b'high + 4 downto a'low + b'low - 4) := (others => '0'); + variable hi, lo : integer := 0; + + begin + + case op is + when '+' => + hi := max(a'high, b'high); + if a'high = b'high then + hi := hi + 1; + end if; + lo := min(a'low, b'low); + + when '-' => + hi := max(a'high, b'high); + lo := min(a'low, b'low); + + when '*' => + hi := a'high + b'high; + if (a'high = 0 or b'high = 0) then + if (hi > 0) then + hi := hi-1; + end if; + end if; + lo := hi - a'length - b'length + 1; + + when others => null; + + end case; + + return result(hi downto lo); + end sproto; + + ------------------------------------------------------------- + -- Type conversions + ------------------------------------------------------------- + -- ufixed <= ufixed + function to_ufixed(src : ufixed_t) return ufixed_t is + begin + return to_ufixed(src, src); + + end to_ufixed; + + ------------------------------------------------------------- + -- ufixed <= sfixed + function to_ufixed(src : sfixed_t) return ufixed_t is + variable dst : ufixed_t(src'range) := (others => '0'); + begin + dst := ufixed_t(abs(src)); + return dst(src'high-1 downto src'low); + + end to_ufixed; + + ------------------------------------------------------------- + -- sfixed <= sfixed + function to_sfixed(src : sfixed_t) return sfixed_t is + begin + return src; + + end to_sfixed; + + ------------------------------------------------------------- + -- sfixed <= ufixed + function to_sfixed(src : ufixed_t) return sfixed_t is + variable dst : sfixed_t(src'high+1 downto src'low) := (others => '0'); + begin + dst(src'range) := sfixed_t(src); + return dst; + + end to_sfixed; + + ------------------------------------------------------------- + -- ufixed <= ufixed + function to_ufixed + ( + src : ufixed_t; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t is + begin + return reshape(src, nbits, nbits_int, rnd_mode, sat_mode); + + end to_ufixed; + + ------------------------------------------------------------- + -- ufixed <= ufixed + function to_ufixed + ( + src : ufixed_t; + proto : ufixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t is + begin + return reshape(src, proto, rnd_mode, sat_mode); + + end to_ufixed; + + ------------------------------------------------------------- + -- sfixed <= sfixed + function to_sfixed + ( + src : sfixed_t; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t is + begin + return reshape(src, nbits, nbits_int, rnd_mode, sat_mode); + + end to_sfixed; + + ------------------------------------------------------------- + -- sfixed <= sfixed + function to_sfixed + ( + src : sfixed_t; + proto : sfixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t is + begin + return reshape(src, proto, rnd_mode, sat_mode); + + end to_sfixed; + + ------------------------------------------------------------- + -- ufixed <= integer + function to_ufixed (src : integer; nbits : integer; nbits_int : integer) return ufixed_t is + begin + return to_ufixed(src, uproto(nbits, nbits_int)); + + end to_ufixed; + + function to_ufixed (src : integer; proto : ufixed_t) return ufixed_t is + begin + return to_ufixed(to_unsigned(src, proto'length), proto); + + end to_ufixed; + + ------------------------------------------------------------- + -- ufixed <= unsigned + function to_ufixed (src : unsigned; nbits : integer; nbits_int : integer) return ufixed_t is + begin + return to_ufixed(src, uproto(nbits, nbits_int)); + + end to_ufixed; + + ------------------------------------------------------------- + -- ufixed <= unsigned + function to_ufixed(src : unsigned; proto : ufixed_t) return ufixed_t is + variable dst : ufixed_t(proto'high downto proto'low) := (others => '0'); + begin + + dst(dst'low + min(dst'length, src'length)-1 downto dst'low) := ufixed_t(src(min(dst'length, src'length)-1 downto 0)); + + return dst; + + end to_ufixed; + + ------------------------------------------------------------- + -- sfixed <= integer + function to_sfixed (src : integer; nbits : integer; nbits_int : integer) return sfixed_t is + begin + return to_sfixed(src, sproto(nbits, nbits_int)); + + end to_sfixed; + + function to_sfixed (src : integer; proto : sfixed_t) return sfixed_t is + begin + + return to_sfixed(to_signed(src, proto'length), proto); + + end to_sfixed; + + ------------------------------------------------------------- + -- sfixed <= signed + function to_sfixed (src : signed; nbits : integer; nbits_int : integer) return sfixed_t is + begin + return to_sfixed(src, sproto(nbits, nbits_int)); + + end to_sfixed; + + ------------------------------------------------------------- + -- sfixed <= signed + function to_sfixed(src : signed; proto : sfixed_t) return sfixed_t is + variable dst : sfixed_t(proto'high downto proto'low) := (others => '0'); + begin + + dst(dst'low + min(dst'length, src'length)-2 downto dst'low) := sfixed_t(src(min(dst'length, src'length)-2 downto 0)); + dst(dst'high) := src(src'high); + + return dst; + + end to_sfixed; + + ------------------------------------------------------------- + function to_ufixed (src : STD_LOGIC_VECTOR; proto : ufixed_t) return ufixed_t is + variable result : ufixed_t (proto'left downto proto'right); + begin + if (result'length < 1) then + return result; + else + result := to_ufixed (unsigned(src), proto); + return result; + end if; + + end function to_ufixed; + + ------------------------------------------------------------- + function to_ufixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return ufixed_t is + begin + return to_ufixed(src, uproto(nbits, nbits_int)); + + end function to_ufixed; + + ------------------------------------------------------------- + function to_sfixed (src : STD_LOGIC_VECTOR; proto : sfixed_t) return sfixed_t is + variable result : sfixed_t (proto'left downto proto'right); + begin + if (result'length < 1) then + return result; + else + result := to_sfixed (signed(src), proto); + return result; + end if; + + end function to_sfixed; + + ------------------------------------------------------------- + function to_sfixed (src : STD_LOGIC_VECTOR; nbits : integer; nbits_int : integer) return sfixed_t is + begin + return to_sfixed(src, sproto(nbits, nbits_int)); + + end to_sfixed; + ------------------------------------------------------------- + + -- ufixed <= real + function to_ufixed + ( + src : real; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t is + + constant nbits_ext : integer := nbits + 1; + constant fix_hi : integer := nbits_int - 1; + constant fix_lo : integer := nbits_int - nbits_ext; + + variable dst : ufixed_t (fix_hi downto fix_lo) := (others => '0'); + variable i : integer := 0; + variable remain : real := 0.0; + + begin + + if (nbits_int < 0) then + assert false report "to_ufixed: Bad dual point (N integer bits < 0)" severity error; + end if; + + if ((2.0**nbits_int - 1.0) < ipart(abs(src))) then +-- assert ASSERT_NO_WARN report "to_ufixed: Overflow (" & REAL'image(src) & ") " severity warning; +-- print_info(dst, "dst: "); + end if; + + remain := abs(src); + for i in dst'range loop + if remain >= 2.0**i then + dst(i) := '1'; + remain := remain - 2.0**i; + else + dst(i) := '0'; + end if; + end loop; + + return to_ufixed(dst, nbits, nbits_int, rnd_mode, sat_mode); + + end to_ufixed; + + ------------------------------------------------------------- + -- sfixed <= real + function to_sfixed + ( + src : real; + proto : sfixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t is + + variable utmp : ufixed_t(proto'high-1 downto proto'low) := (others => '0'); + variable dst : sfixed_t(proto'high downto proto'low) := (others => '0'); + + begin + utmp := to_ufixed(src, utmp, rnd_mode, sat_mode); + if (src < 0.0) then + dst := -to_sfixed(utmp); + else + dst := to_sfixed(utmp); + end if; + + return dst; + end to_sfixed; + + ------------------------------------------------------------- + -- ufixed <= real + function to_ufixed + ( + src : real; + proto : ufixed_t; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return ufixed_t is + begin + return to_ufixed(src, proto'length, proto'high+1, rnd_mode, sat_mode); + end to_ufixed; + + ------------------------------------------------------------- + -- sfixed <= real + function to_sfixed + ( + src : real; + nbits : integer; + nbits_int : integer; + rnd_mode : round_mode_t := default_round_mode; + sat_mode : saturate_mode_t := default_saturate_mode + ) return sfixed_t is + begin + return to_sfixed(src, sproto(nbits, nbits_int), rnd_mode, sat_mode); + end to_sfixed; + + ------------------------------------------------------------------------------- + -- ufixed <= ufixed_array(i) + function to_ufixed(src : ufixed_array_t; index : integer) return ufixed_t is + variable dst : ufixed_t(src'range(2)); + begin + for j in src'range(2) loop + dst(j) := src(index, j); + end loop; + + return dst; + + end to_ufixed; + + ------------------------------------------------------------------------------- + -- sfixed <= sfixed_array(i) + function to_sfixed(src : sfixed_array_t; index : integer) return sfixed_t is + variable dst : sfixed_t(src'range(2)); + begin + for j in src'range(2) loop + dst(j) := src(index, j); + end loop; + + return dst; + + end to_sfixed; + + ------------------------------------------------------------- + -- ufixed <= string + function to_ufixed (src : string) return ufixed_t is + + variable i, j, nbits, nbits_int, nbits_frac : integer := 0; + variable dst : unsigned(src'length downto 0) := (others => '0'); + variable dp_found : boolean := false; + begin + + for i in src'reverse_range loop + case src(i) is + when '.' => + if dp_found then + assert false report "More than one DP not found." severity error; + else + dp_found := true; + nbits_frac := j; + end if; + + when '0' => dst(nbits) := '0'; nbits := nbits + 1; j := j + 1; + when '1' => dst(nbits) := '1'; nbits := nbits + 1; j := j + 1; + when others => + assert false report "Illegal character in binary string." severity error; + + end case; + + end loop ; + if not dp_found then + assert ASSERT_NO_WARN report "DP not found. Using left alignment." severity warning; + end if; + + nbits_int := nbits - nbits_frac; + + return to_ufixed(dst(nbits-1 downto 0), nbits, nbits_int); + + end to_ufixed; + + ------------------------------------------------------------- + -- sfixed <= string + function to_sfixed (src : string) return sfixed_t is + + variable i, j, nbits, nbits_int, nbits_frac : integer := 0; + variable dst : signed(src'length downto 0) := (others => '0'); + variable dp_found : boolean := false; + variable is_neg : boolean := false; + begin + + is_neg := src(src'left) = '-'; + + for i in src'reverse_range loop + case src(i) is + when '-' => null; + when '+' => null; + + when '.' => + if dp_found then + assert false report "More than one DP not found." severity error; + else + dp_found := true; + nbits_frac := j; + end if; + + when '0' => dst(nbits) := '0'; nbits := nbits + 1; j := j + 1; + when '1' => dst(nbits) := '1'; nbits := nbits + 1; j := j + 1; + when others => + assert false report "Illegal character in binary string." severity error; + end case; + end loop ; + nbits := nbits + 1; + + if not dp_found then + assert ASSERT_NO_WARN report "DP not found. Using left alignment." severity warning; + end if; + + nbits_int := nbits - nbits_frac-1; + + if is_neg then + dst(nbits-1 downto 0) := -dst(nbits-1 downto 0); + end if; + + return to_sfixed(dst(nbits-1 downto 0), nbits, nbits_int); + + end to_sfixed; + + ------------------------------------------------------------- + function to_unsigned (src : ufixed_t) return UNSIGNED is + subtype t is UNSIGNED(src'high - src'low downto 0); + variable slv : t; + begin + slv := t(src); + return UNSIGNED(to_X01(std_logic_vector(slv))); + + end function to_unsigned; + + ------------------------------------------------------------- + function to_signed (src : sfixed_t) return SIGNED is + subtype t is SIGNED(src'high - src'low downto 0); + variable slv : t; + begin + slv := t(src); + return SIGNED(to_X01(std_logic_vector(slv))); + + end function to_signed; + + ------------------------------------------------------------- + -- integer <= ufixed + function to_integer (src : ufixed_t) return integer is + begin + return to_integer(to_unsigned(src)); + end to_integer; + + ------------------------------------------------------------- + -- integer <= sfixed + function to_integer (src : sfixed_t) return integer is + begin + return to_integer(to_signed(src)); + end to_integer; + + ------------------------------------------------------------- + -- to_real + function to_real(src : ufixed_t) return real is + variable dst : real := 0.0; + begin + for i in src'range loop + if (src(i) = '1') then + dst := dst + real(2.0**i); + end if; + end loop; + return dst; + + end to_real; + + ------------------------------------------------------------- + function to_real(src : sfixed_t) return real is + variable dst : real := 0.0; + begin + dst := to_real(to_ufixed(src)); + + if (src(src'high) = '1') then + dst := -dst; + end if; + + return dst; + + end to_real; + + ------------------------------------------------------------- + -- to_slv + function to_slv (src : ufixed_t) return STD_LOGIC_VECTOR is + subtype t is STD_LOGIC_VECTOR (src'high - src'low downto 0); + variable slv : t; + begin + if src'length < 1 then + return NSLV; + end if; + slv := t (src); + return slv; + + end function to_slv; + + ------------------------------------------------------------- + -- to_slv + function to_slv (src : sfixed_t) return STD_LOGIC_VECTOR is + subtype t is STD_LOGIC_VECTOR (src'high - src'low downto 0); + variable slv : t; + begin + if src'length < 1 then + return NSLV; + end if; + slv := t (src); + return slv; + + end function to_slv; + + ------------------------------------------------------------- + function to_string(src : ufixed_t) return string is + variable str : string(src'length+1 downto 1) := (others => '0'); + variable i, j : integer := 0; + + begin + j := src'length+1; + for i in src'high downto 0 loop + if (src(i) = '1') then + str(j) := '1'; + end if; + j := j - 1; + end loop; + + str(j) := '.'; + j := j - 1; + + for i in -1 downto src'low loop + if (src(i) = '1') then + str(j) := '1'; + end if; + j := j - 1; + end loop; + + return str; + + end to_string; + + ------------------------------------------------------------- + function to_string(src : sfixed_t) return string is + variable str : string(src'length+1 downto 1) := (others => '0'); + variable i, j, start : integer := 0; + variable strlen : integer := 0; + variable src_abs : sfixed_t(src'range) := (others => '0'); + + begin + if (src'high < 0) then + assert false report "Illegal signed fix point number" severity error; + end if; + + start := src'high; + strlen := src'length; + + j := src'length+1; + if (src(start) = '1') then + str(j) := '-'; + j := j - 1; + start := start - 1; + strlen := strlen + 1; + end if; + + src_abs := abs(src); + + for i in start downto 0 loop + if (src_abs(i) = '1') then + str(j) := '1'; + end if; + j := j - 1; + end loop; + + str(j) := '.'; + j := j - 1; + + for i in -1 downto src'low loop + if (src_abs(i) = '1') then + str(j) := '1'; + end if; + j := j - 1; + end loop; + + return str(strlen downto 1); + + end to_string; + + ------------------------------------------------------------- + function to_string(src : std_logic_vector) return string is + variable str : string(src'length downto 1) := (others => '0'); + variable i : integer := 0; + + begin + for i in src'range loop + if (src(i) = '1') then + str(i+1) := '1'; + end if; + end loop; + + return str; + + end to_string; + + ------------------------------------------------------------- + -- Binary Operators + ------------------------------------------------------------- + function "sla" (src : ufixed_t; count : integer) return ufixed_t is + variable result : ufixed_t (src'high downto src'low) := (others => '0'); + + begin + if (count = 0) then + result := src; + elsif (count < 0) then + result := src sra -count; + elsif (count < src'length) then + result(src'high downto src'low) := src(src'high-count downto src'low) & (count-1 downto 0 => '0'); + end if; + return result; + + end "sla"; + + ------------------------------------------------------------- + function "sla" (src : sfixed_t; count : integer) return sfixed_t is + variable result : sfixed_t (src'high downto src'low) := (others => '0'); + variable sign : std_logic := '0'; + + begin + sign := src(src'high); + if (count = 0) then + result := src; + elsif (count < 0) then + result := src sra -count; + elsif (count < src'length-1) then + result(src'high downto src'low) := sign & src(src'high-count-1 downto src'low) & (count-1 downto 0 => '0'); + end if; + return result; + + end "sla"; + + ------------------------------------------------------------- + function "sra" (src : ufixed_t; count : integer) return ufixed_t is + variable result : ufixed_t (src'high downto src'low) := (others => '0'); + + begin + if (count = 0) then + result := src; + elsif (count < 0) then + result := src sla -count; + elsif (count < src'length) then + result(src'high downto src'low) := (count-1 downto 0 => '0') & src(src'high downto src'low + count); + end if; + return result; + + end "sra"; + + ------------------------------------------------------------- + function "sra" (src : sfixed_t; count : integer) return sfixed_t is + variable result : sfixed_t (src'high downto src'low) := (others => '0'); + variable res_slv, src_slv : signed (src'length-1 downto 0) := (others => '0'); + variable sign, do_sub : std_logic := '0'; + + begin + src_slv := to_signed(src); + sign := src(src'high); + do_sub := src(src'high) and src(src'low); + if (count = 0) then + result := src; + elsif (count < 0) then + result := src sla -count; + elsif (count < src'length-1) then + res_slv := (count downto 0 => sign) & src_slv(src'length-2 downto count); + if (do_sub = '1') then + result(src'high downto src'low) := to_sfixed(res_slv+1, result); + else + result(src'high downto src'low) := to_sfixed(res_slv, result); + end if; + end if; + return result; + + end "sra"; + + ------------------------------------------------------------- + function "*" (a : ufixed_t; b : ufixed_t) return ufixed_t is + variable result : ufixed_t (uproto(a,'*',b)'high downto uproto(a,'*',b)'low); + + begin + if (a'high < 0 and b'high >= 0) or (a'high >= 0 and b'high < 0) then + result := to_ufixed(to_unsigned(a) * to_unsigned(b), result) sla 1; + else + result := to_ufixed(to_unsigned(a) * to_unsigned(b), result); + end if; + return result; + + end "*"; + + ------------------------------------------------------------- + function "*" (a : sfixed_t; b : sfixed_t) return sfixed_t is + variable result : sfixed_t (sproto(a,'*',b)'high downto sproto(a,'*',b)'low); + + begin + if (a'high = 0 and b'high > 0) or (a'high > 0 and b'high = 0) then + result := to_sfixed(signed(a) * signed(b), result) sla 2; + else + result := to_sfixed(signed(a) * signed(b), result) sla 1; + end if; + return result; + + end "*"; + + ------------------------------------------------------------- + function "*" (a : ufixed_t; b : sfixed_t) return sfixed_t is + + begin + return to_sfixed(a) * b; + + end "*"; + + ------------------------------------------------------------- + function "*" (a : sfixed_t; b : ufixed_t) return sfixed_t is + + begin + return b * a; + + end "*"; + + ------------------------------------------------------------- + function "+" (a : ufixed_t; b : ufixed_t) return ufixed_t is + variable result : ufixed_t (uproto(a,'+',b)'high downto uproto(a,'+',b)'low); + + begin + result := ufixed_t(unsigned(reshape(a, result)) + unsigned(reshape(b, result))); + return result; + + end "+"; + + ------------------------------------------------------------- + function "+" (a : sfixed_t; b : sfixed_t) return sfixed_t is + variable result : sfixed_t (sproto(a,'+',b)'high downto sproto(a,'+',b)'low); + + begin + result := to_sfixed(signed(reshape(a,result)) + signed(reshape(b,result)), result); +-- result := to_sfixed(signed(a) + signed(b), result); + return result; + + end "+"; + + ------------------------------------------------------------- + function "+" (a : ufixed_t; b : sfixed_t) return sfixed_t is + + begin + return to_sfixed(a) + b; + + end "+"; + + ------------------------------------------------------------- + function "+" (a : sfixed_t; b : ufixed_t) return sfixed_t is + + begin + return b + a; + + end "+"; + + ------------------------------------------------------------- + function "+" (a : ufixed_t; b : unsigned) return ufixed_t is + + begin + + return ufixed_t(unsigned(a) + b); + + end "+"; + + ------------------------------------------------------------- + function "+" (a : sfixed_t; b : signed) return sfixed_t is + + begin + + return sfixed_t(signed(a) + b); + + end "+"; + + ------------------------------------------------------------- + function "+" (a : ufixed_t; b : integer) return ufixed_t is + + begin + + return ufixed_t(unsigned(a) + to_unsigned(b, a'length)); + + end "+"; + + ------------------------------------------------------------- + function "+" (a : sfixed_t; b : integer) return sfixed_t is + + begin + + return sfixed_t(signed(a) + to_signed(b, a'length)); + + end "+"; + + ------------------------------------------------------------- + function "+" (a : ufixed_t; b : std_logic) return ufixed_t is + variable result : ufixed_t (a'high downto a'low); + variable buns : unsigned(a'length-1 downto 0); + + begin + buns := (a'length-1 downto 1 => '0') & b; + result := ufixed_t(to_unsigned(a) + buns); + return result; + + end "+"; + + ------------------------------------------------------------- + function "+" (a : sfixed_t; b : std_logic) return sfixed_t is + variable result : sfixed_t (a'high downto a'low); + variable bs : signed(a'length-1 downto 0); + + begin + bs := (a'length-1 downto 1 => '0') & b; + result := sfixed_t(to_signed(a) + bs); + return result; + + end "+"; + + ------------------------------------------------------------- + function "-" (a : ufixed_t; b : ufixed_t) return ufixed_t is + variable result : ufixed_t (uproto(a,'-',b)'high downto uproto(a,'-',b)'low); + begin + result := to_ufixed(to_sfixed(a) - to_sfixed(b)); + return result; + + end "-"; + + ------------------------------------------------------------- + function "-" (a : sfixed_t; b : sfixed_t) return sfixed_t is + variable result : sfixed_t (sproto(a,'-',b)'high downto sproto(a,'-',b)'low); + + begin + result := to_sfixed(signed(reshape(a,result)) - signed(reshape(b,result)), result); + return result; + + end "-"; + + ------------------------------------------------------------- + function "-" (a : ufixed_t; b : sfixed_t) return sfixed_t is + begin + return to_sfixed(a) - b; + + end "-"; + + ------------------------------------------------------------- + function "-" (a : sfixed_t; b : ufixed_t) return sfixed_t is + + begin + return a - to_sfixed(b); + + end "-"; + + ------------------------------------------------------------- + function "-" (a : ufixed_t; b : unsigned) return ufixed_t is + + begin + return ufixed_t(unsigned(a) - b); + + end "-"; + + ------------------------------------------------------------- + function "-" (a : sfixed_t; b : signed) return sfixed_t is + + begin + return sfixed_t(signed(a) - b); + + end "-"; + + ------------------------------------------------------------- + function "-" (a : ufixed_t; b : integer) return ufixed_t is + + begin + + return ufixed_t(unsigned(a) - to_unsigned(b, a'length)); + + end "-"; + + ------------------------------------------------------------- + function "-" (a : sfixed_t; b : integer) return sfixed_t is + + begin + + return sfixed_t(signed(a) - to_signed(b, a'length)); + + end "-"; + + ------------------------------------------------------------- + function "-" (a : ufixed_t; b : std_logic) return ufixed_t is + variable result : ufixed_t (a'high downto a'low); + variable buns : unsigned(a'length-1 downto 0); + + begin + buns := (a'length-1 downto 1 => '0') & b; + result := ufixed_t(unsigned(a) - buns); + return result; + + end "-"; + + ------------------------------------------------------------- + function "-" (a : sfixed_t; b : std_logic) return sfixed_t is + variable result : sfixed_t (a'high downto a'low); + variable bs : signed(a'length-1 downto 0); + + begin + bs := (a'length-1 downto 1 => '0') & b; + result := sfixed_t(signed(a) - bs); + return result; + + end "-"; + + ------------------------------------------------------------- + -- Unary Operators + ------------------------------------------------------------- + function "abs" (src : sfixed_t) return sfixed_t is + begin + return to_sfixed(abs(signed(src)), src); + + end "abs"; + + ------------------------------------------------------------- + function "-" (src : ufixed_t) return sfixed_t is + begin + return -to_sfixed(src); + + end "-"; + + ------------------------------------------------------------- + function "-" (src : sfixed_t) return sfixed_t is + begin + return to_sfixed(-signed(src), src); + + end "-"; + + ------------------------------------------------------------- + -- Binary Equality + ------------------------------------------------------------- + function "=" (a : ufixed_t; b : ufixed_t) return boolean is + variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low)); + begin + ta := (others => '0'); + tb := (others => '0'); + ta := to_ufixed(a, ta); + tb := to_ufixed(b, tb); + return to_unsigned(ta) = to_unsigned(tb); + + end "="; + + ------------------------------------------------------------- + function "=" (a : sfixed_t; b : sfixed_t) return boolean is + variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low)); + begin + ta := (others => '0'); + tb := (others => '0'); + ta := to_sfixed(a, ta); + tb := to_sfixed(b, tb); + return to_signed(ta) = to_signed(tb); + + end "="; + + ------------------------------------------------------------- + function "=" (a : ufixed_t; b : sfixed_t) return boolean is + begin + return to_sfixed(a) = b; + end "="; + + ------------------------------------------------------------- + function "=" (a : sfixed_t; b : ufixed_t) return boolean is + begin + return b = a; + end "="; + + ------------------------------------------------------------- + -- Binary Inequality + ------------------------------------------------------------- + function "/=" (a : ufixed_t; b : ufixed_t) return boolean is + begin + return not (a = b); + + end "/="; + + ------------------------------------------------------------- + function "/=" (a : sfixed_t; b : sfixed_t) return boolean is + begin + return not (a = b); + + end "/="; + + ------------------------------------------------------------- + function "/=" (a : ufixed_t; b : sfixed_t) return boolean is + begin + return not (a = b); + end "/="; + + ------------------------------------------------------------- + function "/=" (a : sfixed_t; b : ufixed_t) return boolean is + begin + return not (a = b); + end "/="; + + ------------------------------------------------------------- + -- Binary less than + ------------------------------------------------------------- + function "<" (a : ufixed_t; b : ufixed_t) return boolean is + variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low)); + begin + ta := (others => '0'); + tb := (others => '0'); + ta := to_ufixed(a, ta); + tb := to_ufixed(b, tb); + return to_unsigned(ta) < to_unsigned(tb); + + end "<"; + + ------------------------------------------------------------- + function "<" (a : sfixed_t; b : sfixed_t) return boolean is + variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low)); + begin + ta := (others => '0'); + tb := (others => '0'); + ta := to_sfixed(a, ta); + tb := to_sfixed(b, tb); + return to_signed(ta) < to_signed(tb); + + end "<"; + + ------------------------------------------------------------- + function "<" (a : ufixed_t; b : sfixed_t) return boolean is + begin + return to_sfixed(a) < b; + + end "<"; + + ------------------------------------------------------------- + function "<" (a : sfixed_t; b : ufixed_t) return boolean is + begin + return a < to_sfixed(b); + + end "<"; + + ------------------------------------------------------------- + -- Binary greater than + ------------------------------------------------------------- + function ">" (a : ufixed_t; b : ufixed_t) return boolean is + variable ta, tb: ufixed_t(max(a'high, b'high) downto min(a'low, b'low)); + begin + ta := (others => '0'); + tb := (others => '0'); + ta := to_ufixed(a, ta); + tb := to_ufixed(b, tb); + return to_unsigned(ta) > to_unsigned(tb); + + end ">"; + + ------------------------------------------------------------- + function ">" (a : sfixed_t; b : sfixed_t) return boolean is + variable ta, tb: sfixed_t(max(a'high, b'high) downto min(a'low, b'low)); + begin + ta := (others => '0'); + tb := (others => '0'); + ta := to_sfixed(a, ta); + tb := to_sfixed(b, tb); + return to_signed(ta) > to_signed(tb); + + end ">"; + + ------------------------------------------------------------- + function ">" (a : ufixed_t; b : sfixed_t) return boolean is + begin + return to_sfixed(a) > b; + end ">"; + + ------------------------------------------------------------- + function ">" (a : sfixed_t; b : ufixed_t) return boolean is + begin + return a > to_sfixed(b); + end ">"; + + ------------------------------------------------------------- + -- Binary less equal than + ------------------------------------------------------------- + function "<=" (a : ufixed_t; b : ufixed_t) return boolean is + begin + return not (a > b); + end "<="; + + function "<=" (a : sfixed_t; b : sfixed_t) return boolean is + begin + return not (a > b); + end "<="; + + function "<=" (a : ufixed_t; b : sfixed_t) return boolean is + begin + return not (a > b); + end "<="; + + function "<=" (a : sfixed_t; b : ufixed_t) return boolean is + begin + return not (a > b); + end "<="; + + ------------------------------------------------------------- + -- Binary greater or equal than + ------------------------------------------------------------- + function ">=" (a : ufixed_t; b : ufixed_t) return boolean is + begin + return not (a < b); + end ">="; + + function ">=" (a : sfixed_t; b : sfixed_t) return boolean is + begin + return not (a < b); + end ">="; + + function ">=" (a : ufixed_t; b : sfixed_t) return boolean is + begin + return not (a < b); + end ">="; + + function ">=" (a : sfixed_t; b : ufixed_t) return boolean is + begin + return not (a < b); + end ">="; + + ------------------------------------------------------------- + -- Misc. Operators + ------------------------------------------------------------- + function ipart (src : ufixed_t) return ufixed_t is + begin + return src(src'high downto 0); + end ipart; + + function fpart (src : ufixed_t) return ufixed_t is + begin + return src(-1 downto src'low); + end fpart; + + function ipart (src : sfixed_t) return sfixed_t is + begin + return src(src'high-1 downto 0); + end ipart; + + function fpart (src : sfixed_t) return sfixed_t is + begin + return src(-1 downto src'low); + end fpart; + + ------------------------------------------------------------- + -- Print functions + ------------------------------------------------------------- + procedure print_info(src : in ufixed_t; prefix : in string) is + variable L : line; + + begin + write (L, prefix & "'length = ");write (L, src'length); + writeline (output, L); + + write (L, prefix & "'high(left) = "); + write (L, src'high); + write (L, '('); + write (L, src'left); + write (L, ')'); + writeline (output, L); + + write (L, prefix & "'low(right) = "); + write (L, src'low); + write (L, '('); + write (L, src'right); + write (L, ')'); + writeline (output, L); + + write (L, prefix & "'value = B");write (L, to_string(src)); + writeline (output, L); + + write (L, prefix & "'value = ");write (L, to_real(src)); + writeline (output, L); + + -- write (L, prefix & "'cmsb = ");write (L, cmsb(src)); + -- writeline (output, L); + + -- write (L, prefix & "'clsb = ");write (L, clsb(src)); + -- writeline (output, L); + + writeline (output, L); + + end print_info; + + ------------------------------------------------------------- + procedure print_info(src : in sfixed_t; prefix : in string) is + variable L : line; + + begin + write (L, prefix & "'length = ");write (L, src'length); + writeline (output, L); + + write (L, prefix & "'high(left) = "); + write (L, src'high); + write (L, '('); + write (L, src'left); + write (L, ')'); + writeline (output, L); + + write (L, prefix & "'low(right) = "); + write (L, src'low); + write (L, '('); + write (L, src'right); + write (L, ')'); + writeline (output, L); + + write (L, prefix & "'value = B");write (L, to_string(src)); + writeline (output, L); + + write (L, prefix & "'value = ");write (L, to_real(src)); + writeline (output, L); + + -- write (L, prefix & "'cmsb = ");write (L, cmsb(src)); + -- writeline (output, L); + + -- write (L, prefix & "'clsb = ");write (L, clsb(src)); + -- writeline (output, L); + + writeline (output, L); + + end print_info; + + ------------------------------------------------------------- + procedure print_info(src : in string; prefix : in string) is + variable L : line; + + begin + write (L, prefix & "'length = ");write (L, src'length); + writeline (output, L); + + write (L, prefix & "'high(left) = "); + write (L, src'high); + write (L, '('); + write (L, src'left); + write (L, ')'); + writeline (output, L); + + write (L, prefix & "'low(right) = "); + write (L, src'low); + write (L, '('); + write (L, src'right); + write (L, ')'); + writeline (output, L); + + writeline (output, L); + + end print_info; + + ------------------------------------------------------------- + -- Helpers + ------------------------------------------------------------- + -- Count significant bits for integer part + function cmsb(src : ufixed_t) return integer is + variable j, i : integer := src'high; + begin + for i in src'range loop + if src(i) = '1' then + exit; + end if; + j := j - 1; + end loop; + + -- LRM nachlesen: hier is i=src'high re-initialisert + + return j; + + end cmsb; + + ------------------------------------------------------------- + -- Count significant bits for fractional part + function clsb(src : ufixed_t) return integer is + variable j, i : integer := src'low; + begin + for i in src'reverse_range loop + if src(i) = '1' then + exit; + end if; + j := j + 1; + end loop; + + -- LRM nachlesen: hier is i=src'low re-initialisert + + return j; + + end clsb; + + ------------------------------------------------------------- + function MIN (X, Y: INTEGER) return INTEGER is + variable res : integer := X; + begin + if Y < X then + res := Y; + end if; + + return res; + + end MIN; + + ------------------------------------------------------------- + function MAX (X, Y: INTEGER) return INTEGER is + variable res : integer := X; + begin + if Y > X then + res := Y; + end if; + + return res; + + end MAX; + + ------------------------------------------------------------- + function "MOD" (X, Y: in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 on error + + variable XNEGATIVE : BOOLEAN := X < 0.0; + variable YNEGATIVE : BOOLEAN := Y < 0.0; + variable VALUE : REAL; + begin + -- Check validity of input arguments + if (Y = 0.0) then + assert FALSE + report "MOD(X, 0.0) is undefined" + severity ERROR; + return 0.0; + end if; + + -- Compute value + if ( XNEGATIVE ) then + if ( YNEGATIVE ) then + VALUE := X + (FLOOR(ABS(X)/ABS(Y)))*ABS(Y); + else + VALUE := X + (CEIL(ABS(X)/ABS(Y)))*ABS(Y); + end if; + else + if ( YNEGATIVE ) then + VALUE := X - (CEIL(ABS(X)/ABS(Y)))*ABS(Y); + else + VALUE := X - (FLOOR(ABS(X)/ABS(Y)))*ABS(Y); + end if; + end if; + + return VALUE; + + end "MOD"; + + ------------------------------------------------------------- + -- misc. conversion + function ipart(src : real) return real is + begin + return floor(src); + + end ipart; + + ------------------------------------------------------------- + function fpart(src : real) return real is + begin + return src - floor(src); + + end fpart; + + ------------------------------------------------------------- + function or_red (arg : STD_LOGIC_VECTOR) + return STD_LOGIC is + variable Upper, Lower : STD_LOGIC; + variable Half : INTEGER; + variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0); + variable Result : STD_LOGIC; + begin + if (arg'length < 1) then -- In the case of a NULL range + Result := '0'; + else + BUS_int := to_ux01 (arg); + if (BUS_int'length = 1) then + Result := BUS_int (BUS_int'left); + elsif (BUS_int'length = 2) then + Result := BUS_int (BUS_int'right) or BUS_int (BUS_int'left); + else + Half := (BUS_int'length + 1) / 2 + BUS_int'right; + Upper := or_red (BUS_int (BUS_int'left downto Half)); + Lower := or_red (BUS_int (Half - 1 downto BUS_int'right)); + Result := Upper or Lower; + end if; + end if; + return Result; + + end function or_red; + + ------------------------------------------------------------- + function and_red (arg : STD_LOGIC_VECTOR) + return STD_LOGIC is + variable Upper, Lower : STD_LOGIC; + variable Half : INTEGER; + variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0); + variable Result : STD_LOGIC; + begin + if (arg'length < 1) then -- In the case of a NULL range + Result := '1'; + else + BUS_int := to_ux01 (arg); + if (BUS_int'length = 1) then + Result := BUS_int (BUS_int'left); + elsif (BUS_int'length = 2) then + Result := BUS_int (BUS_int'right) and BUS_int (BUS_int'left); + else + Half := (BUS_int'length + 1) / 2 + BUS_int'right; + Upper := and_red (BUS_int (BUS_int'left downto Half)); + Lower := and_red (BUS_int (Half - 1 downto BUS_int'right)); + Result := Upper and Lower; + end if; + end if; + return Result; + + end function and_red; + + ------------------------------------------------------------- + function xor_red (arg : STD_LOGIC_VECTOR) return STD_ULOGIC is + variable Upper, Lower : STD_ULOGIC; + variable Half : INTEGER; + variable BUS_int : STD_LOGIC_VECTOR (arg'length - 1 downto 0); + variable Result : STD_ULOGIC := '0'; -- In the case of a NULL range + begin + if (arg'length >= 1) then + BUS_int := to_ux01 (arg); + if (BUS_int'length = 1) then + Result := BUS_int (BUS_int'left); + elsif (BUS_int'length = 2) then + Result := BUS_int(BUS_int'right) xor BUS_int(BUS_int'left); + else + Half := (BUS_int'length + 1) / 2 + BUS_int'right; + Upper := xor_red (BUS_int (BUS_int'left downto Half)); + Lower := xor_red (BUS_int (Half - 1 downto BUS_int'right)); + Result := Upper xor Lower; + end if; + end if; + return Result; + + end function xor_red; + + ------------------------------------------------------------- + -- Reduction operators, same as numeric_std functions + function and_red(arg : ufixed_t) return STD_ULOGIC is + begin + return and_red (to_slv(arg)); + end function and_red; + + function nand_red(arg : ufixed_t) return STD_ULOGIC is + begin + return not and_red (to_slv(arg)); + end function nand_red; + + function or_red(arg : ufixed_t) return STD_ULOGIC is + begin + return or_red (to_slv(arg)); + end function or_red; + + function nor_red(arg : ufixed_t) return STD_ULOGIC is + begin + return not or_red (to_slv(arg)); + end function nor_red; + + function xor_red(arg : ufixed_t) return STD_ULOGIC is + begin + return xor_red (to_slv(arg)); + end function xor_red; + + function xnor_red(arg : ufixed_t) return STD_ULOGIC is + begin + return not xor_red (to_slv(arg)); + end function xnor_red; + + function and_red(arg : sfixed_t) return STD_ULOGIC is + begin + return and_red (to_slv(arg)); + end function and_red; + + function nand_red(arg : sfixed_t) return STD_ULOGIC is + begin + return not and_red (to_slv(arg)); + end function nand_red; + + function or_red(arg : sfixed_t) return STD_ULOGIC is + begin + return or_red (to_slv(arg)); + end function or_red; + + function nor_red(arg : sfixed_t) return STD_ULOGIC is + begin + return not or_red (to_slv(arg)); + end function nor_red; + + function xor_red(arg : sfixed_t) return STD_ULOGIC is + begin + return xor_red (to_slv(arg)); + end function xor_red; + + function xnor_red(arg : sfixed_t) return STD_ULOGIC is + begin + return not xor_red (to_slv(arg)); + end function xnor_red; + + ------------------------------------------------------------- + +end; -- package body fixed_ja;