summaryrefslogtreecommitdiff
path: root/libraries/ieee2008/fixed_generic_pkg-body.vhdl
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ieee2008/fixed_generic_pkg-body.vhdl')
-rw-r--r--libraries/ieee2008/fixed_generic_pkg-body.vhdl6365
1 files changed, 6365 insertions, 0 deletions
diff --git a/libraries/ieee2008/fixed_generic_pkg-body.vhdl b/libraries/ieee2008/fixed_generic_pkg-body.vhdl
new file mode 100644
index 0000000..24842a9
--- /dev/null
+++ b/libraries/ieee2008/fixed_generic_pkg-body.vhdl
@@ -0,0 +1,6365 @@
+-- --------------------------------------------------------------------
+--
+-- Copyright © 2008 by IEEE. All rights reserved.
+--
+-- This source file is an essential part of IEEE Std 1076-2008,
+-- IEEE Standard VHDL Language Reference Manual. This source file may not be
+-- copied, sold, or included with software that is sold without written
+-- permission from the IEEE Standards Department. This source file may be
+-- copied for individual use between licensed users. This source file is
+-- provided on an AS IS basis. The IEEE disclaims ANY WARRANTY EXPRESS OR
+-- IMPLIED INCLUDING ANY WARRANTY OF MERCHANTABILITY AND FITNESS FOR USE
+-- FOR A PARTICULAR PURPOSE. The user of the source file shall indemnify
+-- and hold IEEE harmless from any damages or liability arising out of the
+-- use thereof.
+--
+-- Title : Fixed-point package (Generic package body)
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers: Accellera VHDL-TC and IEEE P1076 Working Group
+-- :
+-- Purpose : This packages defines basic binary fixed point arithmetic
+-- : arithmetic functions
+-- :
+-- Note : This package may be modified to include additional data
+-- : required by tools, but it must in no way change the
+-- : external interfaces or simulation behavior of the
+-- : description. It is permissible to add comments and/or
+-- : attributes to the package declarations, but not to change
+-- : or delete any original lines of the package declaration.
+-- : The package body may be changed only in accordance with
+-- : the terms of Clause 16 of this standard.
+-- :
+-- --------------------------------------------------------------------
+-- $Revision: 1220 $
+-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
+-- --------------------------------------------------------------------
+
+library IEEE;
+use IEEE.MATH_REAL.all;
+
+package body fixed_generic_pkg is
+ -- Author David Bishop (dbishop@vhdl.org)
+ -- Other contributers: Jim Lewis, Yannick Grugni, Ryan W. Hilton
+ -- null array constants
+ constant NAUF : UNRESOLVED_ufixed (0 downto 1) := (others => '0');
+ constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0');
+ constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0');
+
+ -- This differed constant will tell you if the package body is synthesizable
+ -- or implemented as real numbers, set to "true" if synthesizable.
+ constant fixedsynth_or_real : BOOLEAN := true;
+
+ -- Special version of "minimum" to do some boundary checking without errors
+ function mins (l, r : INTEGER)
+ return INTEGER is
+ begin -- function mins
+ if (L = INTEGER'low or R = INTEGER'low) then
+ return 0; -- error condition, silent
+ end if;
+ return minimum (L, R);
+ end function mins;
+
+ -- Special version of "minimum" to do some boundary checking with errors
+ function mine (l, r : INTEGER)
+ return INTEGER is
+ begin -- function mine
+ if (L = INTEGER'low or R = INTEGER'low) then
+ report fixed_generic_pkg'instance_name
+ & " Unbounded number passed, was a literal used?"
+ severity error;
+ return 0;
+ end if;
+ return minimum (L, R);
+ end function mine;
+
+ -- The following functions are used only internally. Every function
+ -- calls "cleanvec" either directly or indirectly.
+ -- purpose: Fixes "downto" problem and resolves meta states
+ function cleanvec (
+ arg : UNRESOLVED_sfixed) -- input
+ return UNRESOLVED_sfixed
+ is
+ constant left_index : INTEGER := maximum(arg'left, arg'right);
+ constant right_index : INTEGER := mins(arg'left, arg'right);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin -- function cleanvec
+ assert not (arg'ascending and (arg'low /= INTEGER'low))
+ report fixed_generic_pkg'instance_name
+ & " Vector passed using a ""to"" range, expected is ""downto"""
+ severity error;
+ return arg;
+ end function cleanvec;
+
+ -- purpose: Fixes "downto" problem and resolves meta states
+ function cleanvec (
+ arg : UNRESOLVED_ufixed) -- input
+ return UNRESOLVED_ufixed
+ is
+ constant left_index : INTEGER := maximum(arg'left, arg'right);
+ constant right_index : INTEGER := mins(arg'left, arg'right);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin -- function cleanvec
+ assert not (arg'ascending and (arg'low /= INTEGER'low))
+ report fixed_generic_pkg'instance_name
+ & " Vector passed using a ""to"" range, expected is ""downto"""
+ severity error;
+ return arg;
+ end function cleanvec;
+
+ -- Type convert a "unsigned" into a "ufixed", used internally
+ function to_fixed (
+ arg : UNRESOLVED_UNSIGNED; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ begin -- function to_fixed
+ result := UNRESOLVED_ufixed(arg);
+ return result;
+ end function to_fixed;
+
+ -- Type convert a "signed" into an "sfixed", used internally
+ function to_fixed (
+ arg : UNRESOLVED_SIGNED; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ begin -- function to_fixed
+ result := UNRESOLVED_sfixed(arg);
+ return result;
+ end function to_fixed;
+
+ -- Type convert a "ufixed" into an "unsigned", used internally
+ function to_uns (
+ arg : UNRESOLVED_ufixed) -- fp vector
+ return UNRESOLVED_UNSIGNED
+ is
+ subtype t is UNRESOLVED_UNSIGNED(arg'high - arg'low downto 0);
+ variable slv : t;
+ begin -- function to_uns
+ slv := t(arg);
+ return slv;
+ end function to_uns;
+
+ -- Type convert an "sfixed" into a "signed", used internally
+ function to_s (
+ arg : UNRESOLVED_sfixed) -- fp vector
+ return UNRESOLVED_SIGNED
+ is
+ subtype t is UNRESOLVED_SIGNED(arg'high - arg'low downto 0);
+ variable slv : t;
+ begin -- function to_s
+ slv := t(arg);
+ return slv;
+ end function to_s;
+
+ -- adds 1 to the LSB of the number
+ procedure round_up (arg : in UNRESOLVED_ufixed;
+ result : out UNRESOLVED_ufixed;
+ overflowx : out BOOLEAN) is
+ variable arguns, resuns : UNRESOLVED_UNSIGNED (arg'high-arg'low+1 downto 0)
+ := (others => '0');
+ begin -- round_up
+ arguns (arguns'high-1 downto 0) := to_uns (arg);
+ resuns := arguns + 1;
+ result := to_fixed(resuns(arg'high-arg'low
+ downto 0), arg'high, arg'low);
+ overflowx := (resuns(resuns'high) = '1');
+ end procedure round_up;
+
+ -- adds 1 to the LSB of the number
+ procedure round_up (arg : in UNRESOLVED_sfixed;
+ result : out UNRESOLVED_sfixed;
+ overflowx : out BOOLEAN) is
+ variable args, ress : UNRESOLVED_SIGNED (arg'high-arg'low+1 downto 0);
+ begin -- round_up
+ args (args'high-1 downto 0) := to_s (arg);
+ args(args'high) := arg(arg'high); -- sign extend
+ ress := args + 1;
+ result := to_fixed(ress (ress'high-1
+ downto 0), arg'high, arg'low);
+ overflowx := ((arg(arg'high) /= ress(ress'high-1))
+ and (or (STD_ULOGIC_VECTOR(ress)) /= '0'));
+ end procedure round_up;
+
+ -- Rounding - Performs a "round_nearest" (IEEE 754) which rounds up
+ -- when the remainder is > 0.5. If the remainder IS 0.5 then if the
+ -- bottom bit is a "1" it is rounded, otherwise it remains the same.
+ function round_fixed (arg : UNRESOLVED_ufixed;
+ remainder : UNRESOLVED_ufixed;
+ overflow_style : fixed_overflow_style_type := fixed_overflow_style)
+ return UNRESOLVED_ufixed
+ is
+ variable rounds : BOOLEAN;
+ variable round_overflow : BOOLEAN;
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin
+ rounds := false;
+ if (remainder'length > 1) then
+ if (remainder (remainder'high) = '1') then
+ rounds := (arg(arg'low) = '1')
+ or (or (to_sulv(remainder(remainder'high-1 downto
+ remainder'low))) = '1');
+ end if;
+ else
+ rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
+ end if;
+ if rounds then
+ round_up(arg => arg,
+ result => result,
+ overflowx => round_overflow);
+ else
+ result := arg;
+ end if;
+ if (overflow_style = fixed_saturate) and round_overflow then
+ result := saturate (result'high, result'low);
+ end if;
+ return result;
+ end function round_fixed;
+
+ -- Rounding case statement
+ function round_fixed (arg : UNRESOLVED_sfixed;
+ remainder : UNRESOLVED_sfixed;
+ overflow_style : fixed_overflow_style_type := fixed_overflow_style)
+ return UNRESOLVED_sfixed
+ is
+ variable rounds : BOOLEAN;
+ variable round_overflow : BOOLEAN;
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin
+ rounds := false;
+ if (remainder'length > 1) then
+ if (remainder (remainder'high) = '1') then
+ rounds := (arg(arg'low) = '1')
+ or (or (to_sulv(remainder(remainder'high-1 downto
+ remainder'low))) = '1');
+ end if;
+ else
+ rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
+ end if;
+ if rounds then
+ round_up(arg => arg,
+ result => result,
+ overflowx => round_overflow);
+ else
+ result := arg;
+ end if;
+ if round_overflow then
+ if (overflow_style = fixed_saturate) then
+ if arg(arg'high) = '0' then
+ result := saturate (result'high, result'low);
+ else
+ result := not saturate (result'high, result'low);
+ end if;
+ -- Sign bit not fixed when wrapping
+ end if;
+ end if;
+ return result;
+ end function round_fixed;
+
+ -- converts an sfixed into a ufixed. The output is the same length as the
+ -- input, because abs("1000") = "1000" = 8.
+ function to_ufixed (
+ arg : UNRESOLVED_sfixed)
+ return UNRESOLVED_ufixed
+ is
+ constant left_index : INTEGER := arg'high;
+ constant right_index : INTEGER := mine(arg'low, arg'low);
+ variable xarg : UNRESOLVED_sfixed(left_index+1 downto right_index);
+ variable result : UNRESOLVED_ufixed(left_index downto right_index);
+ begin
+ if arg'length < 1 then
+ return NAUF;
+ end if;
+ xarg := abs(arg);
+ result := UNRESOLVED_ufixed (xarg (left_index downto right_index));
+ return result;
+ end function to_ufixed;
+
+-----------------------------------------------------------------------------
+-- Visible functions
+-----------------------------------------------------------------------------
+
+ -- Conversion functions. These are needed for synthesis where typically
+ -- the only input and output type is a std_logic_vector.
+ function to_sulv (
+ arg : UNRESOLVED_ufixed) -- fixed point vector
+ return STD_ULOGIC_VECTOR
+ is
+ variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
+ begin
+ if arg'length < 1 then
+ return NSLV;
+ end if;
+ result := STD_ULOGIC_VECTOR (arg);
+ return result;
+ end function to_sulv;
+
+ function to_sulv (
+ arg : UNRESOLVED_sfixed) -- fixed point vector
+ return STD_ULOGIC_VECTOR
+ is
+ variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
+ begin
+ if arg'length < 1 then
+ return NSLV;
+ end if;
+ result := STD_ULOGIC_VECTOR (arg);
+ return result;
+ end function to_sulv;
+
+ function to_slv (
+ arg : UNRESOLVED_ufixed) -- fixed point vector
+ return STD_LOGIC_VECTOR is
+ begin
+ return to_sulv(arg);
+ end function to_slv;
+
+ function to_slv (
+ arg : UNRESOLVED_sfixed) -- fixed point vector
+ return STD_LOGIC_VECTOR is
+ begin
+ return to_sulv(arg);
+ end function to_slv;
+
+ function to_ufixed (
+ arg : STD_ULOGIC_VECTOR; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return unresolved_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ begin
+ if (arg'length < 1 or right_index > left_index) then
+ return NAUF;
+ end if;
+ if (arg'length /= result'length) then
+ report fixed_generic_pkg'instance_name & "TO_UFIXED(SLV) "
+ & "Vector lengths do not match. Input length is "
+ & INTEGER'image(arg'length) & " and output will be "
+ & INTEGER'image(result'length) & " wide."
+ severity error;
+ return NAUF;
+ else
+ result := to_fixed (arg => UNRESOLVED_UNSIGNED(arg),
+ left_index => left_index,
+ right_index => right_index);
+ return result;
+ end if;
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : STD_ULOGIC_VECTOR; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return unresolved_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ begin
+ if (arg'length < 1 or right_index > left_index) then
+ return NASF;
+ end if;
+ if (arg'length /= result'length) then
+ report fixed_generic_pkg'instance_name & "TO_SFIXED(SLV) "
+ & "Vector lengths do not match. Input length is "
+ & INTEGER'image(arg'length) & " and output will be "
+ & INTEGER'image(result'length) & " wide."
+ severity error;
+ return NASF;
+ else
+ result := to_fixed (arg => UNRESOLVED_SIGNED(arg),
+ left_index => left_index,
+ right_index => right_index);
+ return result;
+ end if;
+ end function to_sfixed;
+
+ -- Two's complement number, Grows the vector by 1 bit.
+ -- because "abs (1000.000) = 01000.000" or abs(-16) = 16.
+ function "abs" (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed
+ is
+ constant left_index : INTEGER := arg'high;
+ constant right_index : INTEGER := mine(arg'low, arg'low);
+ variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
+ variable result : UNRESOLVED_sfixed (left_index+1 downto right_index);
+ begin
+ if (arg'length < 1 or result'length < 1) then
+ return NASF;
+ end if;
+ ressns (arg'length-1 downto 0) := to_s (cleanvec (arg));
+ ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
+ result := to_fixed (abs(ressns), left_index+1, right_index);
+ return result;
+ end function "abs";
+
+ -- also grows the vector by 1 bit.
+ function "-" (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed
+ is
+ constant left_index : INTEGER := arg'high+1;
+ constant right_index : INTEGER := mine(arg'low, arg'low);
+ variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ begin
+ if (arg'length < 1 or result'length < 1) then
+ return NASF;
+ end if;
+ ressns (arg'length-1 downto 0) := to_s (cleanvec(arg));
+ ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
+ result := to_fixed (-ressns, left_index, right_index);
+ return result;
+ end function "-";
+
+ -- Addition
+ function "+" (
+ l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) + ufixed(c downto d) =
+ return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high)+1;
+ constant right_index : INTEGER := mine(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
+ downto 0);
+ begin
+ if (l'length < 1 or r'length < 1 or result'length < 1) then
+ return NAUF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ result_slv := lslv + rslv;
+ result := to_fixed(result_slv, left_index, right_index);
+ return result;
+ end function "+";
+
+ function "+" (
+ l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) + sfixed(c downto d) =
+ return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high)+1;
+ constant right_index : INTEGER := mine(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
+ variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
+ begin
+ if (l'length < 1 or r'length < 1 or result'length < 1) then
+ return NASF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ result_slv := lslv + rslv;
+ result := to_fixed(result_slv, left_index, right_index);
+ return result;
+ end function "+";
+
+ -- Subtraction
+ function "-" (
+ l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) - ufixed(c downto d) =
+ return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high)+1;
+ constant right_index : INTEGER := mine(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
+ downto 0);
+ begin
+ if (l'length < 1 or r'length < 1 or result'length < 1) then
+ return NAUF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ result_slv := lslv - rslv;
+ result := to_fixed(result_slv, left_index, right_index);
+ return result;
+ end function "-";
+
+ function "-" (
+ l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) - sfixed(c downto d) =
+ return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high)+1;
+ constant right_index : INTEGER := mine(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
+ variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
+ begin
+ if (l'length < 1 or r'length < 1 or result'length < 1) then
+ return NASF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ result_slv := lslv - rslv;
+ result := to_fixed(result_slv, left_index, right_index);
+ return result;
+ end function "-";
+
+ function "*" (
+ l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) * ufixed(c downto d) =
+ return UNRESOLVED_ufixed -- ufixed(a+c+1 downto b+d)
+ is
+ variable lslv : UNRESOLVED_UNSIGNED (l'length-1 downto 0);
+ variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
+ variable result_slv : UNRESOLVED_UNSIGNED (r'length+l'length-1 downto 0);
+ variable result : UNRESOLVED_ufixed (l'high + r'high+1 downto
+ mine(l'low, l'low) + mine(r'low, r'low));
+ begin
+ if (l'length < 1 or r'length < 1 or
+ result'length /= result_slv'length) then
+ return NAUF;
+ end if;
+ lslv := to_uns (cleanvec(l));
+ rslv := to_uns (cleanvec(r));
+ result_slv := lslv * rslv;
+ result := to_fixed (result_slv, result'high, result'low);
+ return result;
+ end function "*";
+
+ function "*" (
+ l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) * sfixed(c downto d) =
+ return UNRESOLVED_sfixed -- sfixed(a+c+1 downto b+d)
+ is
+ variable lslv : UNRESOLVED_SIGNED (l'length-1 downto 0);
+ variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
+ variable result_slv : UNRESOLVED_SIGNED (r'length+l'length-1 downto 0);
+ variable result : UNRESOLVED_sfixed (l'high + r'high+1 downto
+ mine(l'low, l'low) + mine(r'low, r'low));
+ begin
+ if (l'length < 1 or r'length < 1 or
+ result'length /= result_slv'length) then
+ return NASF;
+ end if;
+ lslv := to_s (cleanvec(l));
+ rslv := to_s (cleanvec(r));
+ result_slv := lslv * rslv;
+ result := to_fixed (result_slv, result'high, result'low);
+ return result;
+ end function "*";
+
+ function "/" (
+ l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) / ufixed(c downto d) =
+ return UNRESOLVED_ufixed is -- ufixed(a-d downto b-c-1)
+ begin
+ return divide (l, r);
+ end function "/";
+
+ function "/" (
+ l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) / sfixed(c downto d) =
+ return UNRESOLVED_sfixed is -- sfixed(a-d+1 downto b-c)
+ begin
+ return divide (l, r);
+ end function "/";
+
+ -- This version of divide gives the user more control
+ -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
+ function divide (
+ l, r : UNRESOLVED_ufixed;
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (l'high - mine(r'low, r'low) downto
+ mine (l'low, l'low) - r'high -1);
+ variable dresult : UNRESOLVED_ufixed (result'high downto result'low -guard_bits);
+ variable lresize : UNRESOLVED_ufixed (l'high downto l'high - dresult'length+1);
+ variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
+ variable result_slv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1 or
+ mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
+ return NAUF;
+ end if;
+ lresize := resize (arg => l,
+ left_index => lresize'high,
+ right_index => lresize'low,
+ overflow_style => fixed_wrap, -- vector only grows
+ round_style => fixed_truncate);
+ lslv := to_uns (cleanvec (lresize));
+ rslv := to_uns (cleanvec (r));
+ if (rslv = 0) then
+ report fixed_generic_pkg'instance_name
+ & "DIVIDE(ufixed) Division by zero" severity error;
+ result := saturate (result'high, result'low); -- saturate
+ else
+ result_slv := lslv / rslv;
+ dresult := to_fixed (result_slv, dresult'high, dresult'low);
+ result := resize (arg => dresult,
+ left_index => result'high,
+ right_index => result'low,
+ overflow_style => fixed_wrap, -- overflow impossible
+ round_style => round_style);
+ end if;
+ return result;
+ end function divide;
+
+ -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
+ function divide (
+ l, r : UNRESOLVED_sfixed;
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (l'high - mine(r'low, r'low) + 1 downto
+ mine (l'low, l'low) - r'high);
+ variable dresult : UNRESOLVED_sfixed (result'high downto result'low-guard_bits);
+ variable lresize : UNRESOLVED_sfixed (l'high+1 downto l'high+1 -dresult'length+1);
+ variable lslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
+ variable result_slv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1 or
+ mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
+ return NASF;
+ end if;
+ lresize := resize (arg => l,
+ left_index => lresize'high,
+ right_index => lresize'low,
+ overflow_style => fixed_wrap, -- vector only grows
+ round_style => fixed_truncate);
+ lslv := to_s (cleanvec (lresize));
+ rslv := to_s (cleanvec (r));
+ if (rslv = 0) then
+ report fixed_generic_pkg'instance_name
+ & "DIVIDE(sfixed) Division by zero" severity error;
+ result := saturate (result'high, result'low);
+ else
+ result_slv := lslv / rslv;
+ dresult := to_fixed (result_slv, dresult'high, dresult'low);
+ result := resize (arg => dresult,
+ left_index => result'high,
+ right_index => result'low,
+ overflow_style => fixed_wrap, -- overflow impossible
+ round_style => round_style);
+ end if;
+ return result;
+ end function divide;
+
+ -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
+ function reciprocal (
+ arg : UNRESOLVED_ufixed; -- fixed point input
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_ufixed
+ is
+ constant one : UNRESOLVED_ufixed (0 downto 0) := "1";
+ begin
+ return divide (l => one,
+ r => arg,
+ round_style => round_style,
+ guard_bits => guard_bits);
+ end function reciprocal;
+
+ -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
+ function reciprocal (
+ arg : UNRESOLVED_sfixed; -- fixed point input
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_sfixed
+ is
+ constant one : UNRESOLVED_sfixed (1 downto 0) := "01"; -- extra bit.
+ variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high);
+ begin
+ if (arg'length < 1 or resultx'length < 1) then
+ return NASF;
+ else
+ resultx := divide (l => one,
+ r => arg,
+ round_style => round_style,
+ guard_bits => guard_bits);
+ return resultx (resultx'high-1 downto resultx'low); -- remove extra bit
+ end if;
+ end function reciprocal;
+
+ -- ufixed (a downto b) rem ufixed (c downto d)
+ -- = ufixed (min(a,c) downto min(b,d))
+ function "rem" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return remainder (l, r);
+ end function "rem";
+
+ -- remainder
+ -- sfixed (a downto b) rem sfixed (c downto d)
+ -- = sfixed (min(a,c) downto min(b,d))
+ function "rem" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return remainder (l, r);
+ end function "rem";
+
+ -- ufixed (a downto b) rem ufixed (c downto d)
+ -- = ufixed (min(a,c) downto min(b,d))
+ function remainder (
+ l, r : UNRESOLVED_ufixed; -- fixed point input
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
+ mine(l'low, r'low));
+ variable lresize : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
+ mins(r'low, r'low)-guard_bits);
+ variable rresize : UNRESOLVED_ufixed (r'high downto r'low-guard_bits);
+ variable dresult : UNRESOLVED_ufixed (rresize'range);
+ variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ variable rslv : UNRESOLVED_UNSIGNED (rresize'length-1 downto 0);
+ variable result_slv : UNRESOLVED_UNSIGNED (rslv'range);
+ begin
+ if (l'length < 1 or r'length < 1 or
+ mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
+ return NAUF;
+ end if;
+ lresize := resize (arg => l,
+ left_index => lresize'high,
+ right_index => lresize'low,
+ overflow_style => fixed_wrap, -- vector only grows
+ round_style => fixed_truncate);
+ lslv := to_uns (lresize);
+ rresize := resize (arg => r,
+ left_index => rresize'high,
+ right_index => rresize'low,
+ overflow_style => fixed_wrap, -- vector only grows
+ round_style => fixed_truncate);
+ rslv := to_uns (rresize);
+ if (rslv = 0) then
+ report fixed_generic_pkg'instance_name
+ & "remainder(ufixed) Division by zero" severity error;
+ result := saturate (result'high, result'low); -- saturate
+ else
+ if (r'low <= l'high) then
+ result_slv := lslv rem rslv;
+ dresult := to_fixed (result_slv, dresult'high, dresult'low);
+ result := resize (arg => dresult,
+ left_index => result'high,
+ right_index => result'low,
+ overflow_style => fixed_wrap, -- can't overflow
+ round_style => round_style);
+ end if;
+ if l'low < r'low then
+ result(mins(r'low-1, l'high) downto l'low) :=
+ cleanvec(l(mins(r'low-1, l'high) downto l'low));
+ end if;
+ end if;
+ return result;
+ end function remainder;
+
+ -- remainder
+ -- sfixed (a downto b) rem sfixed (c downto d)
+ -- = sfixed (min(a,c) downto min(b,d))
+ function remainder (
+ l, r : UNRESOLVED_sfixed; -- fixed point input
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_sfixed
+ is
+ variable l_abs : UNRESOLVED_ufixed (l'range);
+ variable r_abs : UNRESOLVED_ufixed (r'range);
+ variable result : UNRESOLVED_sfixed (minimum(r'high, l'high) downto
+ mine(r'low, l'low));
+ variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
+ mins(r'low, l'low));
+ begin
+ if (l'length < 1 or r'length < 1 or
+ mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
+ return NASF;
+ end if;
+ l_abs := to_ufixed (l);
+ r_abs := to_ufixed (r);
+ result := UNRESOLVED_sfixed (remainder (
+ l => l_abs,
+ r => r_abs,
+ round_style => round_style));
+ neg_result := -result;
+ if l(l'high) = '1' then
+ result := neg_result(result'range);
+ end if;
+ return result;
+ end function remainder;
+
+ -- modulo
+ -- ufixed (a downto b) mod ufixed (c downto d)
+ -- = ufixed (min(a,c) downto min(b, d))
+ function "mod" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return modulo (l, r);
+ end function "mod";
+
+ -- sfixed (a downto b) mod sfixed (c downto d)
+ -- = sfixed (c downto min(b, d))
+ function "mod" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return modulo(l, r);
+ end function "mod";
+
+ -- modulo
+ -- ufixed (a downto b) mod ufixed (c downto d)
+ -- = ufixed (min(a,c) downto min(b, d))
+ function modulo (
+ l, r : UNRESOLVED_ufixed; -- fixed point input
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_ufixed is
+ begin
+ return remainder(l => l,
+ r => r,
+ round_style => round_style,
+ guard_bits => guard_bits);
+ end function modulo;
+
+ -- sfixed (a downto b) mod sfixed (c downto d)
+ -- = sfixed (c downto min(b, d))
+ function modulo (
+ l, r : UNRESOLVED_sfixed; -- fixed point input
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits)
+ return UNRESOLVED_sfixed
+ is
+ variable l_abs : UNRESOLVED_ufixed (l'range);
+ variable r_abs : UNRESOLVED_ufixed (r'range);
+ variable result : UNRESOLVED_sfixed (r'high downto
+ mine(r'low, l'low));
+ variable dresult : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
+ mins(r'low, l'low));
+ variable dresult_not_zero : BOOLEAN;
+ begin
+ if (l'length < 1 or r'length < 1 or
+ mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
+ return NASF;
+ end if;
+ l_abs := to_ufixed (l);
+ r_abs := to_ufixed (r);
+ dresult := "0" & UNRESOLVED_sfixed(remainder (l => l_abs,
+ r => r_abs,
+ round_style => round_style));
+ if (to_s(dresult) = 0) then
+ dresult_not_zero := false;
+ else
+ dresult_not_zero := true;
+ end if;
+ if to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '0'
+ and dresult_not_zero then
+ result := resize (arg => r - dresult,
+ left_index => result'high,
+ right_index => result'low,
+ overflow_style => overflow_style,
+ round_style => round_style);
+ elsif to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '1' then
+ result := resize (arg => -dresult,
+ left_index => result'high,
+ right_index => result'low,
+ overflow_style => overflow_style,
+ round_style => round_style);
+ elsif to_x01(l(l'high)) = '0' and to_x01(r(r'high)) = '1'
+ and dresult_not_zero then
+ result := resize (arg => dresult + r,
+ left_index => result'high,
+ right_index => result'low,
+ overflow_style => overflow_style,
+ round_style => round_style);
+ else
+ result := resize (arg => dresult,
+ left_index => result'high,
+ right_index => result'low,
+ overflow_style => overflow_style,
+ round_style => round_style);
+ end if;
+ return result;
+ end function modulo;
+
+ -- Procedure for those who need an "accumulator" function
+ procedure add_carry (
+ L, R : in UNRESOLVED_ufixed;
+ c_in : in STD_ULOGIC;
+ result : out UNRESOLVED_ufixed;
+ c_out : out STD_ULOGIC) is
+ constant left_index : INTEGER := maximum(l'high, r'high)+1;
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
+ downto 0);
+ variable cx : UNRESOLVED_UNSIGNED (0 downto 0); -- Carry in
+ begin
+ if (l'length < 1 or r'length < 1) then
+ result := NAUF;
+ c_out := '0';
+ else
+ cx (0) := c_in;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ result_slv := lslv + rslv + cx;
+ c_out := result_slv(left_index);
+ result := to_fixed(result_slv (left_index-right_index-1 downto 0),
+ left_index-1, right_index);
+ end if;
+ end procedure add_carry;
+
+ procedure add_carry (
+ L, R : in UNRESOLVED_sfixed;
+ c_in : in STD_ULOGIC;
+ result : out UNRESOLVED_sfixed;
+ c_out : out STD_ULOGIC) is
+ constant left_index : INTEGER := maximum(l'high, r'high)+1;
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : UNRESOLVED_SIGNED (left_index-right_index
+ downto 0);
+ variable cx : UNRESOLVED_SIGNED (1 downto 0); -- Carry in
+ begin
+ if (l'length < 1 or r'length < 1) then
+ result := NASF;
+ c_out := '0';
+ else
+ cx (1) := '0';
+ cx (0) := c_in;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ result_slv := lslv + rslv + cx;
+ c_out := result_slv(left_index);
+ result := to_fixed(result_slv (left_index-right_index-1 downto 0),
+ left_index-1, right_index);
+ end if;
+ end procedure add_carry;
+
+ -- Scales the result by a power of 2. Width of input = width of output with
+ -- the decimal point moved.
+ function scalb (y : UNRESOLVED_ufixed; N : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (y'high+N downto y'low+N);
+ begin
+ if y'length < 1 then
+ return NAUF;
+ else
+ result := y;
+ return result;
+ end if;
+ end function scalb;
+
+ function scalb (y : UNRESOLVED_ufixed; N : UNRESOLVED_SIGNED)
+ return UNRESOLVED_ufixed is
+ begin
+ return scalb (y => y,
+ N => to_integer(N));
+ end function scalb;
+
+ function scalb (y : UNRESOLVED_sfixed; N : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (y'high+N downto y'low+N);
+ begin
+ if y'length < 1 then
+ return NASF;
+ else
+ result := y;
+ return result;
+ end if;
+ end function scalb;
+
+ function scalb (y : UNRESOLVED_sfixed; N : UNRESOLVED_SIGNED)
+ return UNRESOLVED_sfixed is
+ begin
+ return scalb (y => y,
+ N => to_integer(N));
+ end function scalb;
+
+ function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN is
+ begin
+ if to_X01(arg(arg'high)) = '1' then
+ return true;
+ else
+ return false;
+ end if;
+ end function Is_Negative;
+
+ function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
+ return INTEGER is
+ begin
+ for_loop : for i in arg'reverse_range loop
+ if arg(i) ?= y then
+ return i;
+ end if;
+ end loop;
+ return arg'high+1; -- return out of bounds 'high
+ end function find_rightmost;
+
+ function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
+ return INTEGER is
+ begin
+ for_loop : for i in arg'range loop
+ if arg(i) ?= y then
+ return i;
+ end if;
+ end loop;
+ return arg'low-1; -- return out of bounds 'low
+ end function find_leftmost;
+
+ function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
+ return INTEGER is
+ begin
+ for_loop : for i in arg'reverse_range loop
+ if arg(i) ?= y then
+ return i;
+ end if;
+ end loop;
+ return arg'high+1; -- return out of bounds 'high
+ end function find_rightmost;
+
+ function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
+ return INTEGER is
+ begin
+ for_loop : for i in arg'range loop
+ if arg(i) ?= y then
+ return i;
+ end if;
+ end loop;
+ return arg'low-1; -- return out of bounds 'low
+ end function find_leftmost;
+
+ function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable argslv : UNRESOLVED_UNSIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin
+ argslv := to_uns (arg);
+ argslv := argslv sll COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "sll";
+
+ function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable argslv : UNRESOLVED_UNSIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin
+ argslv := to_uns (arg);
+ argslv := argslv srl COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "srl";
+
+ function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable argslv : UNRESOLVED_UNSIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin
+ argslv := to_uns (arg);
+ argslv := argslv rol COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "rol";
+
+ function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable argslv : UNRESOLVED_UNSIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin
+ argslv := to_uns (arg);
+ argslv := argslv ror COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "ror";
+
+ function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable argslv : UNRESOLVED_UNSIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin
+ argslv := to_uns (arg);
+ -- Arithmetic shift on an unsigned is a logical shift
+ argslv := argslv sll COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "sla";
+
+ function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable argslv : UNRESOLVED_UNSIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin
+ argslv := to_uns (arg);
+ -- Arithmetic shift on an unsigned is a logical shift
+ argslv := argslv srl COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "sra";
+
+ function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable argslv : UNRESOLVED_SIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin
+ argslv := to_s (arg);
+ argslv := argslv sll COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "sll";
+
+ function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable argslv : UNRESOLVED_SIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin
+ argslv := to_s (arg);
+ argslv := argslv srl COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "srl";
+
+ function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable argslv : UNRESOLVED_SIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin
+ argslv := to_s (arg);
+ argslv := argslv rol COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "rol";
+
+ function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable argslv : UNRESOLVED_SIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin
+ argslv := to_s (arg);
+ argslv := argslv ror COUNT;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "ror";
+
+ function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable argslv : UNRESOLVED_SIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin
+ argslv := to_s (arg);
+ if COUNT > 0 then
+ -- Arithmetic shift left on a 2's complement number is a logic shift
+ argslv := argslv sll COUNT;
+ else
+ argslv := argslv sra -COUNT;
+ end if;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "sla";
+
+ function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable argslv : UNRESOLVED_SIGNED (arg'length-1 downto 0);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin
+ argslv := to_s (arg);
+ if COUNT > 0 then
+ argslv := argslv sra COUNT;
+ else
+ -- Arithmetic shift left on a 2's complement number is a logic shift
+ argslv := argslv sll -COUNT;
+ end if;
+ result := to_fixed (argslv, result'high, result'low);
+ return result;
+ end function "sra";
+
+ -- Because some people want the older functions.
+ function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ if (ARG'length < 1) then
+ return NAUF;
+ end if;
+ return ARG sla COUNT;
+ end function SHIFT_LEFT;
+
+ function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ if (ARG'length < 1) then
+ return NAUF;
+ end if;
+ return ARG sra COUNT;
+ end function SHIFT_RIGHT;
+
+ function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
+ return UNRESOLVED_sfixed is
+ begin
+ if (ARG'length < 1) then
+ return NASF;
+ end if;
+ return ARG sla COUNT;
+ end function SHIFT_LEFT;
+
+ function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
+ return UNRESOLVED_sfixed is
+ begin
+ if (ARG'length < 1) then
+ return NASF;
+ end if;
+ return ARG sra COUNT;
+ end function SHIFT_RIGHT;
+
+ ----------------------------------------------------------------------------
+ -- logical functions
+ ----------------------------------------------------------------------------
+ function "not" (L : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ RESULT := not to_sulv(L);
+ return to_ufixed(RESULT, L'high, L'low);
+ end function "not";
+
+ function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) and to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """and"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_ufixed(RESULT, L'high, L'low);
+ end function "and";
+
+ function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) or to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """or"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_ufixed(RESULT, L'high, L'low);
+ end function "or";
+
+ function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) nand to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """nand"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_ufixed(RESULT, L'high, L'low);
+ end function "nand";
+
+ function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) nor to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """nor"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_ufixed(RESULT, L'high, L'low);
+ end function "nor";
+
+ function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) xor to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """xor"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_ufixed(RESULT, L'high, L'low);
+ end function "xor";
+
+ function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) xnor to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """xnor"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_ufixed(RESULT, L'high, L'low);
+ end function "xnor";
+
+ function "not" (L : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ RESULT := not to_sulv(L);
+ return to_sfixed(RESULT, L'high, L'low);
+ end function "not";
+
+ function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) and to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """and"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_sfixed(RESULT, L'high, L'low);
+ end function "and";
+
+ function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) or to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """or"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_sfixed(RESULT, L'high, L'low);
+ end function "or";
+
+ function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) nand to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """nand"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_sfixed(RESULT, L'high, L'low);
+ end function "nand";
+
+ function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) nor to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """nor"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_sfixed(RESULT, L'high, L'low);
+ end function "nor";
+
+ function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) xor to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """xor"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_sfixed(RESULT, L'high, L'low);
+ end function "xor";
+
+ function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ RESULT := to_sulv(L) xnor to_sulv(R);
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """xnor"": Range error L'RANGE /= R'RANGE"
+ severity warning;
+ RESULT := (others => 'X');
+ end if;
+ return to_sfixed(RESULT, L'high, L'low);
+ end function "xnor";
+
+ -- Vector and std_ulogic functions, same as functions in numeric_std
+ function "and" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L and R(i);
+ end loop;
+ return result;
+ end function "and";
+
+ function "and" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) and R;
+ end loop;
+ return result;
+ end function "and";
+
+ function "or" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L or R(i);
+ end loop;
+ return result;
+ end function "or";
+
+ function "or" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) or R;
+ end loop;
+ return result;
+ end function "or";
+
+ function "nand" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L nand R(i);
+ end loop;
+ return result;
+ end function "nand";
+
+ function "nand" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) nand R;
+ end loop;
+ return result;
+ end function "nand";
+
+ function "nor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L nor R(i);
+ end loop;
+ return result;
+ end function "nor";
+
+ function "nor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) nor R;
+ end loop;
+ return result;
+ end function "nor";
+
+ function "xor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L xor R(i);
+ end loop;
+ return result;
+ end function "xor";
+
+ function "xor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) xor R;
+ end loop;
+ return result;
+ end function "xor";
+
+ function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L xnor R(i);
+ end loop;
+ return result;
+ end function "xnor";
+
+ function "xnor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) xnor R;
+ end loop;
+ return result;
+ end function "xnor";
+
+ function "and" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L and R(i);
+ end loop;
+ return result;
+ end function "and";
+
+ function "and" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) and R;
+ end loop;
+ return result;
+ end function "and";
+
+ function "or" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L or R(i);
+ end loop;
+ return result;
+ end function "or";
+
+ function "or" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) or R;
+ end loop;
+ return result;
+ end function "or";
+
+ function "nand" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L nand R(i);
+ end loop;
+ return result;
+ end function "nand";
+
+ function "nand" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) nand R;
+ end loop;
+ return result;
+ end function "nand";
+
+ function "nor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L nor R(i);
+ end loop;
+ return result;
+ end function "nor";
+
+ function "nor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) nor R;
+ end loop;
+ return result;
+ end function "nor";
+
+ function "xor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L xor R(i);
+ end loop;
+ return result;
+ end function "xor";
+
+ function "xor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) xor R;
+ end loop;
+ return result;
+ end function "xor";
+
+ function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (R'range);
+ begin
+ for i in result'range loop
+ result(i) := L xnor R(i);
+ end loop;
+ return result;
+ end function "xnor";
+
+ function "xnor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (L'range);
+ begin
+ for i in result'range loop
+ result(i) := L(i) xnor R;
+ end loop;
+ return result;
+ end function "xnor";
+
+ -- Reduction operators
+ function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return and to_sulv(l);
+ end function "and";
+
+ function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return nand to_sulv(l);
+ end function "nand";
+
+ function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return or to_sulv(l);
+ end function "or";
+
+ function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return nor to_sulv(l);
+ end function "nor";
+
+ function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return xor to_sulv(l);
+ end function "xor";
+
+ function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return xnor to_sulv(l);
+ end function "xnor";
+
+ function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return and to_sulv(l);
+ end function "and";
+
+ function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return nand to_sulv(l);
+ end function "nand";
+
+ function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return or to_sulv(l);
+ end function "or";
+
+ function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return nor to_sulv(l);
+ end function "nor";
+
+ function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return xor to_sulv(l);
+ end function "xor";
+
+ function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return xnor to_sulv(l);
+ end function "xnor";
+ -- End reduction operators
+
+ function "?=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv ?= rslv;
+ end if;
+ end function "?=";
+
+ function "?/=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?/=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?/="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv ?/= rslv;
+ end if;
+ end function "?/=";
+
+ function "?>" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?>
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?>"": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv ?> rslv;
+ end if;
+ end function "?>";
+
+ function "?>=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?>=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?>="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv ?>= rslv;
+ end if;
+ end function "?>=";
+
+ function "?<" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?<
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?<"": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv ?< rslv;
+ end if;
+ end function "?<";
+
+ function "?<=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?<=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?<="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv ?<= rslv;
+ end if;
+ end function "?<=";
+
+ function "?=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin -- ?=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv ?= rslv;
+ end if;
+ end function "?=";
+
+ function "?/=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin -- ?/=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?/="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv ?/= rslv;
+ end if;
+ end function "?/=";
+
+ function "?>" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin -- ?>
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?>"": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv ?> rslv;
+ end if;
+ end function "?>";
+
+ function "?>=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin -- ?>=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?>="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv ?>= rslv;
+ end if;
+ end function "?>=";
+
+ function "?<" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin -- ?<
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?<"": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv ?< rslv;
+ end if;
+ end function "?<";
+
+ function "?<=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin -- ?<=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """?<="": null detected, returning X"
+ severity warning;
+ return 'X';
+ else
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv ?<= rslv;
+ end if;
+ end function "?<=";
+
+ -- Match function, similar to "std_match" from numeric_std
+ function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ return std_match(to_sulv(L), to_sulv(R));
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ end function std_match;
+
+ function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is
+ begin
+ if (L'high = R'high and L'low = R'low) then
+ return std_match(to_sulv(L), to_sulv(R));
+ else
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ end function std_match;
+
+ -- compare functions
+ function "=" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """="": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv = rslv;
+ end function "=";
+
+ function "=" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """="": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv = rslv;
+ end function "=";
+
+ function "/=" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """/="": null argument detected, returning TRUE"
+ severity warning;
+ return true;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """/="": metavalue detected, returning TRUE"
+ severity warning;
+ return true;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv /= rslv;
+ end function "/=";
+
+ function "/=" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """/="": null argument detected, returning TRUE"
+ severity warning;
+ return true;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """/="": metavalue detected, returning TRUE"
+ severity warning;
+ return true;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv /= rslv;
+ end function "/=";
+
+ function ">" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>"": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv > rslv;
+ end function ">";
+
+ function ">" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>"": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv > rslv;
+ end function ">";
+
+ function "<" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<"": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv < rslv;
+ end function "<";
+
+ function "<" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<"": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv < rslv;
+ end function "<";
+
+ function ">=" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>="": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv >= rslv;
+ end function ">=";
+
+ function ">=" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """>="": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv >= rslv;
+ end function ">=";
+
+ function "<=" (
+ l, r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<="": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_uns (lresize);
+ rslv := to_uns (rresize);
+ return lslv <= rslv;
+ end function "<=";
+
+ function "<=" (
+ l, r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN
+ is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & """<="": metavalue detected, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ lslv := to_s (lresize);
+ rslv := to_s (rresize);
+ return lslv <= rslv;
+ end function "<=";
+
+ -- overloads of the default maximum and minimum functions
+ function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ return NAUF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ return to_fixed(maximum(to_uns(lresize), to_uns(rresize)),
+ left_index, right_index);
+ end function maximum;
+
+ function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ return NASF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ return to_fixed(maximum(to_s(lresize), to_s(rresize)),
+ left_index, right_index);
+ end function maximum;
+
+ function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ return NAUF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ return to_fixed(minimum(to_uns(lresize), to_uns(rresize)),
+ left_index, right_index);
+ end function minimum;
+
+ function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
+ constant left_index : INTEGER := maximum(l'high, r'high);
+ constant right_index : INTEGER := mins(l'low, r'low);
+ variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ return NASF;
+ end if;
+ lresize := resize (l, left_index, right_index);
+ rresize := resize (r, left_index, right_index);
+ return to_fixed(minimum(to_s(lresize), to_s(rresize)),
+ left_index, right_index);
+ end function minimum;
+
+ function to_ufixed (
+ arg : NATURAL; -- integer
+ constant left_index : INTEGER; -- left index (high index)
+ constant right_index : INTEGER := 0; -- right index
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_ufixed
+ is
+ constant fw : INTEGER := mins (right_index, right_index); -- catch literals
+ variable result : UNRESOLVED_ufixed (left_index downto fw);
+ variable sresult : UNRESOLVED_ufixed (left_index downto 0) :=
+ (others => '0'); -- integer portion
+ variable argx : NATURAL; -- internal version of arg
+ begin
+ if (result'length < 1) then
+ return NAUF;
+ end if;
+ if arg /= 0 then
+ argx := arg;
+ for I in 0 to sresult'left loop
+ if (argx mod 2) = 0 then
+ sresult(I) := '0';
+ else
+ sresult(I) := '1';
+ end if;
+ argx := argx/2;
+ end loop;
+ if argx /= 0 then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_UFIXED(NATURAL): vector truncated"
+ severity warning;
+ if overflow_style = fixed_saturate then
+ return saturate (left_index, right_index);
+ end if;
+ end if;
+ result := resize (arg => sresult,
+ left_index => left_index,
+ right_index => right_index,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ else
+ result := (others => '0');
+ end if;
+ return result;
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : INTEGER; -- integer
+ constant left_index : INTEGER; -- left index (high index)
+ constant right_index : INTEGER := 0; -- right index
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_sfixed
+ is
+ constant fw : INTEGER := mins (right_index, right_index); -- catch literals
+ variable result : UNRESOLVED_sfixed (left_index downto fw);
+ variable sresult : UNRESOLVED_sfixed (left_index downto 0) :=
+ (others => '0'); -- integer portion
+ variable argx : INTEGER; -- internal version of arg
+ variable sign : STD_ULOGIC; -- sign of input
+ begin
+ if (result'length < 1) then -- null range
+ return NASF;
+ end if;
+ if arg /= 0 then
+ if (arg < 0) then
+ sign := '1';
+ argx := -(arg + 1);
+ else
+ sign := '0';
+ argx := arg;
+ end if;
+ for I in 0 to sresult'left loop
+ if (argx mod 2) = 0 then
+ sresult(I) := sign;
+ else
+ sresult(I) := not sign;
+ end if;
+ argx := argx/2;
+ end loop;
+ if argx /= 0 or left_index < 0 or sign /= sresult(sresult'left) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_SFIXED(INTEGER): vector truncated"
+ severity warning;
+ if overflow_style = fixed_saturate then -- saturate
+ if arg < 0 then
+ result := not saturate (result'high, result'low); -- underflow
+ else
+ result := saturate (result'high, result'low); -- overflow
+ end if;
+ return result;
+ end if;
+ end if;
+ result := resize (arg => sresult,
+ left_index => left_index,
+ right_index => right_index,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ else
+ result := (others => '0');
+ end if;
+ return result;
+ end function to_sfixed;
+
+ function to_ufixed (
+ arg : REAL; -- real
+ constant left_index : INTEGER; -- left index (high index)
+ constant right_index : INTEGER; -- right index
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
+ return UNRESOLVED_ufixed
+ is
+ constant fw : INTEGER := mins (right_index, right_index); -- catch literals
+ variable result : UNRESOLVED_ufixed (left_index downto fw) :=
+ (others => '0');
+ variable Xresult : UNRESOLVED_ufixed (left_index downto
+ fw-guard_bits) :=
+ (others => '0');
+ variable presult : REAL;
+ begin
+ -- If negative or null range, return.
+ if (left_index < fw) then
+ return NAUF;
+ end if;
+ if (arg < 0.0) then
+ report fixed_generic_pkg'instance_name
+ & "TO_UFIXED: Negative argument passed "
+ & REAL'image(arg) severity error;
+ return result;
+ end if;
+ presult := arg;
+ if presult >= (2.0**(left_index+1)) then
+ assert NO_WARNING report fixed_generic_pkg'instance_name
+ & "TO_UFIXED(REAL): vector truncated"
+ severity warning;
+ if overflow_style = fixed_wrap then
+ presult := presult mod (2.0**(left_index+1)); -- wrap
+ else
+ return saturate (result'high, result'low);
+ end if;
+ end if;
+ for i in Xresult'range loop
+ if presult >= 2.0**i then
+ Xresult(i) := '1';
+ presult := presult - 2.0**i;
+ else
+ Xresult(i) := '0';
+ end if;
+ end loop;
+ if guard_bits > 0 and round_style = fixed_round then
+ result := round_fixed (arg => Xresult (left_index
+ downto right_index),
+ remainder => Xresult (right_index-1 downto
+ right_index-guard_bits),
+ overflow_style => overflow_style);
+ else
+ result := Xresult (result'range);
+ end if;
+ return result;
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : REAL; -- real
+ constant left_index : INTEGER; -- left index (high index)
+ constant right_index : INTEGER; -- right index
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
+ return UNRESOLVED_sfixed
+ is
+ constant fw : INTEGER := mins (right_index, right_index); -- catch literals
+ variable result : UNRESOLVED_sfixed (left_index downto fw) :=
+ (others => '0');
+ variable Xresult : UNRESOLVED_sfixed (left_index+1 downto fw-guard_bits) :=
+ (others => '0');
+ variable presult : REAL;
+ begin
+ if (left_index < fw) then -- null range
+ return NASF;
+ end if;
+ if (arg >= (2.0**left_index) or arg < -(2.0**left_index)) then
+ assert NO_WARNING report fixed_generic_pkg'instance_name
+ & "TO_SFIXED(REAL): vector truncated"
+ severity warning;
+ if overflow_style = fixed_saturate then
+ if arg < 0.0 then -- saturate
+ result := not saturate (result'high, result'low); -- underflow
+ else
+ result := saturate (result'high, result'low); -- overflow
+ end if;
+ return result;
+ else
+ presult := abs(arg) mod (2.0**(left_index+1)); -- wrap
+ end if;
+ else
+ presult := abs(arg);
+ end if;
+ for i in Xresult'range loop
+ if presult >= 2.0**i then
+ Xresult(i) := '1';
+ presult := presult - 2.0**i;
+ else
+ Xresult(i) := '0';
+ end if;
+ end loop;
+ if arg < 0.0 then
+ Xresult := to_fixed(-to_s(Xresult), Xresult'high, Xresult'low);
+ end if;
+ if guard_bits > 0 and round_style = fixed_round then
+ result := round_fixed (arg => Xresult (left_index
+ downto right_index),
+ remainder => Xresult (right_index-1 downto
+ right_index-guard_bits),
+ overflow_style => overflow_style);
+ else
+ result := Xresult (result'range);
+ end if;
+ return result;
+ end function to_sfixed;
+
+ function to_ufixed (
+ arg : UNRESOLVED_UNSIGNED; -- unsigned
+ constant left_index : INTEGER; -- left index (high index)
+ constant right_index : INTEGER := 0; -- right index
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_ufixed
+ is
+ constant ARG_LEFT : INTEGER := ARG'length-1;
+ alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is ARG;
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ begin
+ if arg'length < 1 or (left_index < right_index) then
+ return NAUF;
+ end if;
+ result := resize (arg => UNRESOLVED_ufixed (XARG),
+ left_index => left_index,
+ right_index => right_index,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end function to_ufixed;
+
+ -- converted version
+ function to_ufixed (
+ arg : UNRESOLVED_UNSIGNED) -- unsigned
+ return UNRESOLVED_ufixed
+ is
+ constant ARG_LEFT : INTEGER := ARG'length-1;
+ alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is ARG;
+ begin
+ if arg'length < 1 then
+ return NAUF;
+ end if;
+ return UNRESOLVED_ufixed(xarg);
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : UNRESOLVED_SIGNED; -- signed
+ constant left_index : INTEGER; -- left index (high index)
+ constant right_index : INTEGER := 0; -- right index
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_sfixed
+ is
+ constant ARG_LEFT : INTEGER := ARG'length-1;
+ alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is ARG;
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ begin
+ if arg'length < 1 or (left_index < right_index) then
+ return NASF;
+ end if;
+ result := resize (arg => UNRESOLVED_sfixed (XARG),
+ left_index => left_index,
+ right_index => right_index,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end function to_sfixed;
+
+ -- converted version
+ function to_sfixed (
+ arg : UNRESOLVED_SIGNED) -- signed
+ return UNRESOLVED_sfixed
+ is
+ constant ARG_LEFT : INTEGER := ARG'length-1;
+ alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is ARG;
+ begin
+ if arg'length < 1 then
+ return NASF;
+ end if;
+ return UNRESOLVED_sfixed(xarg);
+ end function to_sfixed;
+
+ function to_sfixed (arg : UNRESOLVED_ufixed) return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (arg'high+1 downto arg'low);
+ begin
+ if arg'length < 1 then
+ return NASF;
+ end if;
+ result (arg'high downto arg'low) := UNRESOLVED_sfixed(cleanvec(arg));
+ result (arg'high+1) := '0';
+ return result;
+ end function to_sfixed;
+
+ -- Because of the fairly complicated sizing rules in the fixed point
+ -- packages these functions are provided to compute the result ranges
+ -- Example:
+ -- signal uf1 : ufixed (3 downto -3);
+ -- signal uf2 : ufixed (4 downto -2);
+ -- signal uf1multuf2 : ufixed (ufixed_high (3, -3, '*', 4, -2) downto
+ -- ufixed_low (3, -3, '*', 4, -2));
+ -- uf1multuf2 <= uf1 * uf2;
+ -- Valid characters: '+', '-', '*', '/', 'r' or 'R' (rem), 'm' or 'M' (mod),
+ -- '1' (reciprocal), 'A', 'a' (abs), 'N', 'n' (-sfixed)
+ function ufixed_high (left_index, right_index : INTEGER;
+ operation : CHARACTER := 'X';
+ left_index2, right_index2 : INTEGER := 0)
+ return INTEGER is
+ begin
+ case operation is
+ when '+'| '-' => return maximum (left_index, left_index2) + 1;
+ when '*' => return left_index + left_index2 + 1;
+ when '/' => return left_index - right_index2;
+ when '1' => return -right_index; -- reciprocal
+ when 'R'|'r' => return mins (left_index, left_index2); -- "rem"
+ when 'M'|'m' => return mins (left_index, left_index2); -- "mod"
+ when others => return left_index; -- For abs and default
+ end case;
+ end function ufixed_high;
+
+ function ufixed_low (left_index, right_index : INTEGER;
+ operation : CHARACTER := 'X';
+ left_index2, right_index2 : INTEGER := 0)
+ return INTEGER is
+ begin
+ case operation is
+ when '+'| '-' => return mins (right_index, right_index2);
+ when '*' => return right_index + right_index2;
+ when '/' => return right_index - left_index2 - 1;
+ when '1' => return -left_index - 1; -- reciprocal
+ when 'R'|'r' => return mins (right_index, right_index2); -- "rem"
+ when 'M'|'m' => return mins (right_index, right_index2); -- "mod"
+ when others => return right_index; -- for abs and default
+ end case;
+ end function ufixed_low;
+
+ function sfixed_high (left_index, right_index : INTEGER;
+ operation : CHARACTER := 'X';
+ left_index2, right_index2 : INTEGER := 0)
+ return INTEGER is
+ begin
+ case operation is
+ when '+'| '-' => return maximum (left_index, left_index2) + 1;
+ when '*' => return left_index + left_index2 + 1;
+ when '/' => return left_index - right_index2 + 1;
+ when '1' => return -right_index + 1; -- reciprocal
+ when 'R'|'r' => return mins (left_index, left_index2); -- "rem"
+ when 'M'|'m' => return left_index2; -- "mod"
+ when 'A'|'a' => return left_index + 1; -- "abs"
+ when 'N'|'n' => return left_index + 1; -- -sfixed
+ when others => return left_index;
+ end case;
+ end function sfixed_high;
+
+ function sfixed_low (left_index, right_index : INTEGER;
+ operation : CHARACTER := 'X';
+ left_index2, right_index2 : INTEGER := 0)
+ return INTEGER is
+ begin
+ case operation is
+ when '+'| '-' => return mins (right_index, right_index2);
+ when '*' => return right_index + right_index2;
+ when '/' => return right_index - left_index2;
+ when '1' => return -left_index; -- reciprocal
+ when 'R'|'r' => return mins (right_index, right_index2); -- "rem"
+ when 'M'|'m' => return mins (right_index, right_index2); -- "mod"
+ when others => return right_index; -- default for abs, neg and default
+ end case;
+ end function sfixed_low;
+
+ -- Same as above, but using the "size_res" input only for their ranges:
+ -- signal uf1multuf2 : ufixed (ufixed_high (uf1, '*', uf2) downto
+ -- ufixed_low (uf1, '*', uf2));
+ -- uf1multuf2 <= uf1 * uf2;
+ function ufixed_high (size_res : UNRESOLVED_ufixed;
+ operation : CHARACTER := 'X';
+ size_res2 : UNRESOLVED_ufixed)
+ return INTEGER is
+ begin
+ return ufixed_high (left_index => size_res'high,
+ right_index => size_res'low,
+ operation => operation,
+ left_index2 => size_res2'high,
+ right_index2 => size_res2'low);
+ end function ufixed_high;
+
+ function ufixed_low (size_res : UNRESOLVED_ufixed;
+ operation : CHARACTER := 'X';
+ size_res2 : UNRESOLVED_ufixed)
+ return INTEGER is
+ begin
+ return ufixed_low (left_index => size_res'high,
+ right_index => size_res'low,
+ operation => operation,
+ left_index2 => size_res2'high,
+ right_index2 => size_res2'low);
+ end function ufixed_low;
+
+ function sfixed_high (size_res : UNRESOLVED_sfixed;
+ operation : CHARACTER := 'X';
+ size_res2 : UNRESOLVED_sfixed)
+ return INTEGER is
+ begin
+ return sfixed_high (left_index => size_res'high,
+ right_index => size_res'low,
+ operation => operation,
+ left_index2 => size_res2'high,
+ right_index2 => size_res2'low);
+ end function sfixed_high;
+
+ function sfixed_low (size_res : UNRESOLVED_sfixed;
+ operation : CHARACTER := 'X';
+ size_res2 : UNRESOLVED_sfixed)
+ return INTEGER is
+ begin
+ return sfixed_low (left_index => size_res'high,
+ right_index => size_res'low,
+ operation => operation,
+ left_index2 => size_res2'high,
+ right_index2 => size_res2'low);
+ end function sfixed_low;
+
+ -- purpose: returns a saturated number
+ function saturate (
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ constant sat : UNRESOLVED_ufixed (left_index downto right_index) :=
+ (others => '1');
+ begin
+ return sat;
+ end function saturate;
+
+ -- purpose: returns a saturated number
+ function saturate (
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable sat : UNRESOLVED_sfixed (left_index downto right_index) :=
+ (others => '1');
+ begin
+ -- saturate positive, to saturate negative, just do "not saturate()"
+ sat (left_index) := '0';
+ return sat;
+ end function saturate;
+
+ function saturate (
+ size_res : UNRESOLVED_ufixed) -- only the size of this is used
+ return UNRESOLVED_ufixed is
+ begin
+ return saturate (size_res'high, size_res'low);
+ end function saturate;
+
+ function saturate (
+ size_res : UNRESOLVED_sfixed) -- only the size of this is used
+ return UNRESOLVED_sfixed is
+ begin
+ return saturate (size_res'high, size_res'low);
+ end function saturate;
+
+ -- As a concession to those who use a graphical DSP environment,
+ -- these functions take parameters in those tools format and create
+ -- fixed point numbers. These functions are designed to convert from
+ -- a std_logic_vector to the VHDL fixed point format using the conventions
+ -- of these packages. In a pure VHDL environment you should use the
+ -- "to_ufixed" and "to_sfixed" routines.
+ -- Unsigned fixed point
+ function to_UFix (
+ arg : STD_ULOGIC_VECTOR;
+ width : NATURAL; -- width of vector
+ fraction : NATURAL) -- width of fraction
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (width-fraction-1 downto -fraction);
+ begin
+ if (arg'length /= result'length) then
+ report fixed_generic_pkg'instance_name
+ & "TO_UFIX (STD_ULOGIC_VECTOR) "
+ & "Vector lengths do not match. Input length is "
+ & INTEGER'image(arg'length) & " and output will be "
+ & INTEGER'image(result'length) & " wide."
+ severity error;
+ return NAUF;
+ else
+ result := to_ufixed (arg, result'high, result'low);
+ return result;
+ end if;
+ end function to_UFix;
+
+ -- signed fixed point
+ function to_SFix (
+ arg : STD_ULOGIC_VECTOR;
+ width : NATURAL; -- width of vector
+ fraction : NATURAL) -- width of fraction
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (width-fraction-1 downto -fraction);
+ begin
+ if (arg'length /= result'length) then
+ report fixed_generic_pkg'instance_name
+ & "TO_SFIX (STD_ULOGIC_VECTOR) "
+ & "Vector lengths do not match. Input length is "
+ & INTEGER'image(arg'length) & " and output will be "
+ & INTEGER'image(result'length) & " wide."
+ severity error;
+ return NASF;
+ else
+ result := to_sfixed (arg, result'high, result'low);
+ return result;
+ end if;
+ end function to_SFix;
+
+ -- finding the bounds of a number. These functions can be used like this:
+ -- signal xxx : ufixed (7 downto -3);
+ -- -- Which is the same as "ufixed (UFix_high (11,3) downto UFix_low(11,3))"
+ -- signal yyy : ufixed (UFix_high (11, 3, "+", 11, 3)
+ -- downto UFix_low(11, 3, "+", 11, 3));
+ -- Where "11" is the width of xxx (xxx'length),
+ -- and 3 is the lower bound (abs (xxx'low))
+ -- In a pure VHDL environment use "ufixed_high" and "ufixed_low"
+ function ufix_high (
+ width, fraction : NATURAL;
+ operation : CHARACTER := 'X';
+ width2, fraction2 : NATURAL := 0)
+ return INTEGER is
+ begin
+ return ufixed_high (left_index => width - 1 - fraction,
+ right_index => -fraction,
+ operation => operation,
+ left_index2 => width2 - 1 - fraction2,
+ right_index2 => -fraction2);
+ end function ufix_high;
+
+ function ufix_low (
+ width, fraction : NATURAL;
+ operation : CHARACTER := 'X';
+ width2, fraction2 : NATURAL := 0)
+ return INTEGER is
+ begin
+ return ufixed_low (left_index => width - 1 - fraction,
+ right_index => -fraction,
+ operation => operation,
+ left_index2 => width2 - 1 - fraction2,
+ right_index2 => -fraction2);
+ end function ufix_low;
+
+ function sfix_high (
+ width, fraction : NATURAL;
+ operation : CHARACTER := 'X';
+ width2, fraction2 : NATURAL := 0)
+ return INTEGER is
+ begin
+ return sfixed_high (left_index => width - fraction,
+ right_index => -fraction,
+ operation => operation,
+ left_index2 => width2 - fraction2,
+ right_index2 => -fraction2);
+ end function sfix_high;
+
+ function sfix_low (
+ width, fraction : NATURAL;
+ operation : CHARACTER := 'X';
+ width2, fraction2 : NATURAL := 0)
+ return INTEGER is
+ begin
+ return sfixed_low (left_index => width - fraction,
+ right_index => -fraction,
+ operation => operation,
+ left_index2 => width2 - fraction2,
+ right_index2 => -fraction2);
+ end function sfix_low;
+
+ function to_unsigned (
+ arg : UNRESOLVED_ufixed; -- ufixed point input
+ constant size : NATURAL; -- length of output
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_UNSIGNED is
+ begin
+ return to_uns(resize (arg => arg,
+ left_index => size-1,
+ right_index => 0,
+ round_style => round_style,
+ overflow_style => overflow_style));
+ end function to_unsigned;
+
+ function to_unsigned (
+ arg : UNRESOLVED_ufixed; -- ufixed point input
+ size_res : UNRESOLVED_UNSIGNED; -- length of output
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_UNSIGNED is
+ begin
+ return to_unsigned (arg => arg,
+ size => size_res'length,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ end function to_unsigned;
+
+ function to_signed (
+ arg : UNRESOLVED_sfixed; -- sfixed point input
+ constant size : NATURAL; -- length of output
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_SIGNED is
+ begin
+ return to_s(resize (arg => arg,
+ left_index => size-1,
+ right_index => 0,
+ round_style => round_style,
+ overflow_style => overflow_style));
+ end function to_signed;
+
+ function to_signed (
+ arg : UNRESOLVED_sfixed; -- sfixed point input
+ size_res : UNRESOLVED_SIGNED; -- used for length of output
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_SIGNED is
+ begin
+ return to_signed (arg => arg,
+ size => size_res'length,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ end function to_signed;
+
+ function to_real (
+ arg : UNRESOLVED_ufixed) -- ufixed point input
+ return REAL
+ is
+ constant left_index : INTEGER := arg'high;
+ constant right_index : INTEGER := arg'low;
+ variable result : REAL; -- result
+ variable arg_int : UNRESOLVED_ufixed (left_index downto right_index);
+ begin
+ if (arg'length < 1) then
+ return 0.0;
+ end if;
+ arg_int := to_x01(cleanvec(arg));
+ if (Is_X(arg_int)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_REAL (ufixed): metavalue detected, returning 0.0"
+ severity warning;
+ return 0.0;
+ end if;
+ result := 0.0;
+ for i in arg_int'range loop
+ if (arg_int(i) = '1') then
+ result := result + (2.0**i);
+ end if;
+ end loop;
+ return result;
+ end function to_real;
+
+ function to_real (
+ arg : UNRESOLVED_sfixed) -- ufixed point input
+ return REAL
+ is
+ constant left_index : INTEGER := arg'high;
+ constant right_index : INTEGER := arg'low;
+ variable result : REAL; -- result
+ variable arg_int : UNRESOLVED_sfixed (left_index downto right_index);
+ -- unsigned version of argument
+ variable arg_uns : UNRESOLVED_ufixed (left_index downto right_index);
+ -- absolute of argument
+ begin
+ if (arg'length < 1) then
+ return 0.0;
+ end if;
+ arg_int := to_x01(cleanvec(arg));
+ if (Is_X(arg_int)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_REAL (sfixed): metavalue detected, returning 0.0"
+ severity warning;
+ return 0.0;
+ end if;
+ arg_uns := to_ufixed (arg_int);
+ result := to_real (arg_uns);
+ if (arg_int(arg_int'high) = '1') then
+ result := -result;
+ end if;
+ return result;
+ end function to_real;
+
+ function to_integer (
+ arg : UNRESOLVED_ufixed; -- fixed point input
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return NATURAL
+ is
+ constant left_index : INTEGER := arg'high;
+ variable arg_uns : UNRESOLVED_UNSIGNED (left_index+1 downto 0)
+ := (others => '0');
+ begin
+ if (arg'length < 1) then
+ return 0;
+ end if;
+ if (Is_X (arg)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_INTEGER (ufixed): metavalue detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ if (left_index < -1) then
+ return 0;
+ end if;
+ arg_uns := to_uns(resize (arg => arg,
+ left_index => arg_uns'high,
+ right_index => 0,
+ round_style => round_style,
+ overflow_style => overflow_style));
+ return to_integer (arg_uns);
+ end function to_integer;
+
+ function to_integer (
+ arg : UNRESOLVED_sfixed; -- fixed point input
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return INTEGER
+ is
+ constant left_index : INTEGER := arg'high;
+ constant right_index : INTEGER := arg'low;
+ variable arg_s : UNRESOLVED_SIGNED (left_index+1 downto 0);
+ begin
+ if (arg'length < 1) then
+ return 0;
+ end if;
+ if (Is_X (arg)) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_INTEGER (sfixed): metavalue detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ if (left_index < -1) then
+ return 0;
+ end if;
+ arg_s := to_s(resize (arg => arg,
+ left_index => arg_s'high,
+ right_index => 0,
+ round_style => round_style,
+ overflow_style => overflow_style));
+ return to_integer (arg_s);
+ end function to_integer;
+
+ function to_01 (
+ s : UNRESOLVED_ufixed; -- ufixed point input
+ constant XMAP : STD_ULOGIC := '0') -- Map x to
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (s'range); -- result
+ begin
+ if (s'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_01(ufixed): null detected, returning NULL"
+ severity warning;
+ return NAUF;
+ end if;
+ return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low);
+ end function to_01;
+
+ function to_01 (
+ s : UNRESOLVED_sfixed; -- sfixed point input
+ constant XMAP : STD_ULOGIC := '0') -- Map x to
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (s'range);
+ begin
+ if (s'length < 1) then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "TO_01(sfixed): null detected, returning NULL"
+ severity warning;
+ return NASF;
+ end if;
+ return to_fixed (to_01(to_s(s), XMAP), s'high, s'low);
+ end function to_01;
+
+ function Is_X (
+ arg : UNRESOLVED_ufixed)
+ return BOOLEAN
+ is
+ variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv
+ begin
+ argslv := to_sulv(arg);
+ return Is_X (argslv);
+ end function Is_X;
+
+ function Is_X (
+ arg : UNRESOLVED_sfixed)
+ return BOOLEAN
+ is
+ variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv
+ begin
+ argslv := to_sulv(arg);
+ return Is_X (argslv);
+ end function Is_X;
+
+ function To_X01 (
+ arg : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed is
+ begin
+ return to_ufixed (To_X01(to_sulv(arg)), arg'high, arg'low);
+ end function To_X01;
+
+ function to_X01 (
+ arg : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return to_sfixed (To_X01(to_sulv(arg)), arg'high, arg'low);
+ end function To_X01;
+
+ function To_X01Z (
+ arg : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed is
+ begin
+ return to_ufixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
+ end function To_X01Z;
+
+ function to_X01Z (
+ arg : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return to_sfixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
+ end function To_X01Z;
+
+ function To_UX01 (
+ arg : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed is
+ begin
+ return to_ufixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
+ end function To_UX01;
+
+ function to_UX01 (
+ arg : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return to_sfixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
+ end function To_UX01;
+
+ function resize (
+ arg : UNRESOLVED_ufixed; -- input
+ constant left_index : INTEGER; -- integer portion
+ constant right_index : INTEGER; -- size of fraction
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_ufixed
+ is
+ constant arghigh : INTEGER := maximum (arg'high, arg'low);
+ constant arglow : INTEGER := mine (arg'high, arg'low);
+ variable invec : UNRESOLVED_ufixed (arghigh downto arglow);
+ variable result : UNRESOLVED_ufixed(left_index downto right_index) :=
+ (others => '0');
+ variable needs_rounding : BOOLEAN := false;
+ begin -- resize
+ if (arg'length < 1) or (result'length < 1) then
+ return NAUF;
+ elsif (invec'length < 1) then
+ return result; -- string literal value
+ else
+ invec := cleanvec(arg);
+ if (right_index > arghigh) then -- return top zeros
+ needs_rounding := (round_style = fixed_round) and
+ (right_index = arghigh+1);
+ elsif (left_index < arglow) then -- return overflow
+ if (overflow_style = fixed_saturate) and
+ (or(to_sulv(invec)) = '1') then
+ result := saturate (result'high, result'low); -- saturate
+ end if;
+ elsif (arghigh > left_index) then
+ -- wrap or saturate?
+ if (overflow_style = fixed_saturate and
+ or (to_sulv(invec(arghigh downto left_index+1))) = '1')
+ then
+ result := saturate (result'high, result'low); -- saturate
+ else
+ if (arglow >= right_index) then
+ result (left_index downto arglow) :=
+ invec(left_index downto arglow);
+ else
+ result (left_index downto right_index) :=
+ invec (left_index downto right_index);
+ needs_rounding := (round_style = fixed_round); -- round
+ end if;
+ end if;
+ else -- arghigh <= integer width
+ if (arglow >= right_index) then
+ result (arghigh downto arglow) := invec;
+ else
+ result (arghigh downto right_index) :=
+ invec (arghigh downto right_index);
+ needs_rounding := (round_style = fixed_round); -- round
+ end if;
+ end if;
+ -- Round result
+ if needs_rounding then
+ result := round_fixed (arg => result,
+ remainder => invec (right_index-1
+ downto arglow),
+ overflow_style => overflow_style);
+ end if;
+ return result;
+ end if;
+ end function resize;
+
+ function resize (
+ arg : UNRESOLVED_sfixed; -- input
+ constant left_index : INTEGER; -- integer portion
+ constant right_index : INTEGER; -- size of fraction
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_sfixed
+ is
+ constant arghigh : INTEGER := maximum (arg'high, arg'low);
+ constant arglow : INTEGER := mine (arg'high, arg'low);
+ variable invec : UNRESOLVED_sfixed (arghigh downto arglow);
+ variable result : UNRESOLVED_sfixed(left_index downto right_index) :=
+ (others => '0');
+ variable reduced : STD_ULOGIC;
+ variable needs_rounding : BOOLEAN := false; -- rounding
+ begin -- resize
+ if (arg'length < 1) or (result'length < 1) then
+ return NASF;
+ elsif (invec'length < 1) then
+ return result; -- string literal value
+ else
+ invec := cleanvec(arg);
+ if (right_index > arghigh) then -- return top zeros
+ if (arg'low /= INTEGER'low) then -- check for a literal
+ result := (others => arg(arghigh)); -- sign extend
+ end if;
+ needs_rounding := (round_style = fixed_round) and
+ (right_index = arghigh+1);
+ elsif (left_index < arglow) then -- return overflow
+ if (overflow_style = fixed_saturate) then
+ reduced := or (to_sulv(invec));
+ if (reduced = '1') then
+ if (invec(arghigh) = '0') then
+ -- saturate POSITIVE
+ result := saturate (result'high, result'low);
+ else
+ -- saturate negative
+ result := not saturate (result'high, result'low);
+ end if;
+ -- else return 0 (input was 0)
+ end if;
+ -- else return 0 (wrap)
+ end if;
+ elsif (arghigh > left_index) then
+ if (invec(arghigh) = '0') then
+ reduced := or (to_sulv(invec(arghigh-1 downto
+ left_index)));
+ if overflow_style = fixed_saturate and reduced = '1' then
+ -- saturate positive
+ result := saturate (result'high, result'low);
+ else
+ if (right_index > arglow) then
+ result := invec (left_index downto right_index);
+ needs_rounding := (round_style = fixed_round);
+ else
+ result (left_index downto arglow) :=
+ invec (left_index downto arglow);
+ end if;
+ end if;
+ else
+ reduced := and (to_sulv(invec(arghigh-1 downto
+ left_index)));
+ if overflow_style = fixed_saturate and reduced = '0' then
+ result := not saturate (result'high, result'low);
+ else
+ if (right_index > arglow) then
+ result := invec (left_index downto right_index);
+ needs_rounding := (round_style = fixed_round);
+ else
+ result (left_index downto arglow) :=
+ invec (left_index downto arglow);
+ end if;
+ end if;
+ end if;
+ else -- arghigh <= integer width
+ if (arglow >= right_index) then
+ result (arghigh downto arglow) := invec;
+ else
+ result (arghigh downto right_index) :=
+ invec (arghigh downto right_index);
+ needs_rounding := (round_style = fixed_round); -- round
+ end if;
+ if (left_index > arghigh) then -- sign extend
+ result(left_index downto arghigh+1) := (others => invec(arghigh));
+ end if;
+ end if;
+ -- Round result
+ if (needs_rounding) then
+ result := round_fixed (arg => result,
+ remainder => invec (right_index-1
+ downto arglow),
+ overflow_style => overflow_style);
+ end if;
+ return result;
+ end if;
+ end function resize;
+
+ -- size_res functions
+ -- These functions compute the size from a passed variable named "size_res"
+ -- The only part of this variable used it it's size, it is never passed
+ -- to a lower level routine.
+ function to_ufixed (
+ arg : STD_ULOGIC_VECTOR; -- shifted vector
+ size_res : UNRESOLVED_ufixed) -- for size only
+ return UNRESOLVED_ufixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_ufixed (size_res'left downto fw);
+ begin
+ if (result'length < 1 or arg'length < 1) then
+ return NAUF;
+ else
+ result := to_ufixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low);
+ return result;
+ end if;
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : STD_ULOGIC_VECTOR; -- shifted vector
+ size_res : UNRESOLVED_sfixed) -- for size only
+ return UNRESOLVED_sfixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_sfixed (size_res'left downto fw);
+ begin
+ if (result'length < 1 or arg'length < 1) then
+ return NASF;
+ else
+ result := to_sfixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low);
+ return result;
+ end if;
+ end function to_sfixed;
+
+ function to_ufixed (
+ arg : NATURAL; -- integer
+ size_res : UNRESOLVED_ufixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_ufixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_ufixed (size_res'left downto fw);
+ begin
+ if (result'length < 1) then
+ return NAUF;
+ else
+ result := to_ufixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : INTEGER; -- integer
+ size_res : UNRESOLVED_sfixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_sfixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_sfixed (size_res'left downto fw);
+ begin
+ if (result'length < 1) then
+ return NASF;
+ else
+ result := to_sfixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function to_sfixed;
+
+ function to_ufixed (
+ arg : REAL; -- real
+ size_res : UNRESOLVED_ufixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
+ return UNRESOLVED_ufixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_ufixed (size_res'left downto fw);
+ begin
+ if (result'length < 1) then
+ return NAUF;
+ else
+ result := to_ufixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ guard_bits => guard_bits,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : REAL; -- real
+ size_res : UNRESOLVED_sfixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style;
+ constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
+ return UNRESOLVED_sfixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_sfixed (size_res'left downto fw);
+ begin
+ if (result'length < 1) then
+ return NASF;
+ else
+ result := to_sfixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ guard_bits => guard_bits,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function to_sfixed;
+
+ function to_ufixed (
+ arg : UNRESOLVED_UNSIGNED; -- unsigned
+ size_res : UNRESOLVED_ufixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_ufixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_ufixed (size_res'left downto fw);
+ begin
+ if (result'length < 1 or arg'length < 1) then
+ return NAUF;
+ else
+ result := to_ufixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : UNRESOLVED_SIGNED; -- signed
+ size_res : UNRESOLVED_sfixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_sfixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_sfixed (size_res'left downto fw);
+ begin
+ if (result'length < 1 or arg'length < 1) then
+ return NASF;
+ else
+ result := to_sfixed (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function to_sfixed;
+
+ function resize (
+ arg : UNRESOLVED_ufixed; -- input
+ size_res : UNRESOLVED_ufixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_ufixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_ufixed (size_res'high downto fw);
+ begin
+ if (result'length < 1 or arg'length < 1) then
+ return NAUF;
+ else
+ result := resize (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function resize;
+
+ function resize (
+ arg : UNRESOLVED_sfixed; -- input
+ size_res : UNRESOLVED_sfixed; -- for size only
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return UNRESOLVED_sfixed
+ is
+ constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
+ variable result : UNRESOLVED_sfixed (size_res'high downto fw);
+ begin
+ if (result'length < 1 or arg'length < 1) then
+ return NASF;
+ else
+ result := resize (arg => arg,
+ left_index => size_res'high,
+ right_index => size_res'low,
+ round_style => round_style,
+ overflow_style => overflow_style);
+ return result;
+ end if;
+ end function resize;
+
+ -- Overloaded math functions for real
+ function "+" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l + to_ufixed (r, l'high, l'low));
+ end function "+";
+
+ function "+" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, r'low) + r);
+ end function "+";
+
+ function "+" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l + to_sfixed (r, l'high, l'low));
+ end function "+";
+
+ function "+" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, r'low) + r);
+ end function "+";
+
+ function "-" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l - to_ufixed (r, l'high, l'low));
+ end function "-";
+
+ function "-" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, r'low) - r);
+ end function "-";
+
+ function "-" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l - to_sfixed (r, l'high, l'low));
+ end function "-";
+
+ function "-" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, r'low) - r);
+ end function "-";
+
+ function "*" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l * to_ufixed (r, l'high, l'low));
+ end function "*";
+
+ function "*" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, r'low) * r);
+ end function "*";
+
+ function "*" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l * to_sfixed (r, l'high, l'low));
+ end function "*";
+
+ function "*" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, r'low) * r);
+ end function "*";
+
+ function "/" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l / to_ufixed (r, l'high, l'low));
+ end function "/";
+
+ function "/" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, r'low) / r);
+ end function "/";
+
+ function "/" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l / to_sfixed (r, l'high, l'low));
+ end function "/";
+
+ function "/" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, r'low) / r);
+ end function "/";
+
+ function "rem" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l rem to_ufixed (r, l'high, l'low));
+ end function "rem";
+
+ function "rem" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, r'low) rem r);
+ end function "rem";
+
+ function "rem" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l rem to_sfixed (r, l'high, l'low));
+ end function "rem";
+
+ function "rem" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, r'low) rem r);
+ end function "rem";
+
+ function "mod" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l mod to_ufixed (r, l'high, l'low));
+ end function "mod";
+
+ function "mod" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, r'low) mod r);
+ end function "mod";
+
+ function "mod" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l mod to_sfixed (r, l'high, l'low));
+ end function "mod";
+
+ function "mod" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, r'low) mod r);
+ end function "mod";
+
+ -- Overloaded math functions for integers
+ function "+" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l + to_ufixed (r, l'high, 0));
+ end function "+";
+
+ function "+" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, 0) + r);
+ end function "+";
+
+ function "+" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l + to_sfixed (r, l'high, 0));
+ end function "+";
+
+ function "+" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, 0) + r);
+ end function "+";
+
+ -- Overloaded functions
+ function "-" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l - to_ufixed (r, l'high, 0));
+ end function "-";
+
+ function "-" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, 0) - r);
+ end function "-";
+
+ function "-" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l - to_sfixed (r, l'high, 0));
+ end function "-";
+
+ function "-" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, 0) - r);
+ end function "-";
+
+ -- Overloaded functions
+ function "*" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l * to_ufixed (r, l'high, 0));
+ end function "*";
+
+ function "*" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, 0) * r);
+ end function "*";
+
+ function "*" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l * to_sfixed (r, l'high, 0));
+ end function "*";
+
+ function "*" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, 0) * r);
+ end function "*";
+
+ -- Overloaded functions
+ function "/" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l / to_ufixed (r, l'high, 0));
+ end function "/";
+
+ function "/" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, 0) / r);
+ end function "/";
+
+ function "/" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l / to_sfixed (r, l'high, 0));
+ end function "/";
+
+ function "/" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, 0) / r);
+ end function "/";
+
+ function "rem" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l rem to_ufixed (r, l'high, 0));
+ end function "rem";
+
+ function "rem" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, 0) rem r);
+ end function "rem";
+
+ function "rem" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l rem to_sfixed (r, l'high, 0));
+ end function "rem";
+
+ function "rem" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, 0) rem r);
+ end function "rem";
+
+ function "mod" (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return (l mod to_ufixed (r, l'high, 0));
+ end function "mod";
+
+ function "mod" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return (to_ufixed (l, r'high, 0) mod r);
+ end function "mod";
+
+ function "mod" (
+ l : UNRESOLVED_sfixed; -- fixed point input
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return (l mod to_sfixed (r, l'high, 0));
+ end function "mod";
+
+ function "mod" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ begin
+ return (to_sfixed (l, r'high, 0) mod r);
+ end function "mod";
+
+ -- overloaded ufixed compare functions with integer
+ function "=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (l = to_ufixed (r, l'high, l'low));
+ end function "=";
+
+ function "/=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (l /= to_ufixed (r, l'high, l'low));
+ end function "/=";
+
+ function ">=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (l >= to_ufixed (r, l'high, l'low));
+ end function ">=";
+
+ function "<=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (l <= to_ufixed (r, l'high, l'low));
+ end function "<=";
+
+ function ">" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (l > to_ufixed (r, l'high, l'low));
+ end function ">";
+
+ function "<" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (l < to_ufixed (r, l'high, l'low));
+ end function "<";
+
+ function "?=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (l ?= to_ufixed (r, l'high, l'low));
+ end function "?=";
+
+ function "?/=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (l ?/= to_ufixed (r, l'high, l'low));
+ end function "?/=";
+
+ function "?>=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (l ?>= to_ufixed (r, l'high, l'low));
+ end function "?>=";
+
+ function "?<=" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (l ?<= to_ufixed (r, l'high, l'low));
+ end function "?<=";
+
+ function "?>" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (l ?> to_ufixed (r, l'high, l'low));
+ end function "?>";
+
+ function "?<" (
+ l : UNRESOLVED_ufixed;
+ r : NATURAL) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (l ?< to_ufixed (r, l'high, l'low));
+ end function "?<";
+
+ function maximum (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return maximum (l, to_ufixed (r, l'high, l'low));
+ end function maximum;
+
+ function minimum (
+ l : UNRESOLVED_ufixed; -- fixed point input
+ r : NATURAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return minimum (l, to_ufixed (r, l'high, l'low));
+ end function minimum;
+
+ -- NATURAL to ufixed
+ function "=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) = r);
+ end function "=";
+
+ function "/=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) /= r);
+ end function "/=";
+
+ function ">=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) >= r);
+ end function ">=";
+
+ function "<=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) <= r);
+ end function "<=";
+
+ function ">" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) > r);
+ end function ">";
+
+ function "<" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) < r);
+ end function "<";
+
+ function "?=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?= r);
+ end function "?=";
+
+ function "?/=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?/= r);
+ end function "?/=";
+
+ function "?>=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?>= r);
+ end function "?>=";
+
+ function "?<=" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?<= r);
+ end function "?<=";
+
+ function "?>" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?> r);
+ end function "?>";
+
+ function "?<" (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?< r);
+ end function "?<";
+
+ function maximum (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return maximum (to_ufixed (l, r'high, r'low), r);
+ end function maximum;
+
+ function minimum (
+ l : NATURAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return minimum (to_ufixed (l, r'high, r'low), r);
+ end function minimum;
+
+ -- overloaded ufixed compare functions with real
+ function "=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l = to_ufixed (r, l'high, l'low));
+ end function "=";
+
+ function "/=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l /= to_ufixed (r, l'high, l'low));
+ end function "/=";
+
+ function ">=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l >= to_ufixed (r, l'high, l'low));
+ end function ">=";
+
+ function "<=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l <= to_ufixed (r, l'high, l'low));
+ end function "<=";
+
+ function ">" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l > to_ufixed (r, l'high, l'low));
+ end function ">";
+
+ function "<" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l < to_ufixed (r, l'high, l'low));
+ end function "<";
+
+ function "?=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?= to_ufixed (r, l'high, l'low));
+ end function "?=";
+
+ function "?/=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?/= to_ufixed (r, l'high, l'low));
+ end function "?/=";
+
+ function "?>=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?>= to_ufixed (r, l'high, l'low));
+ end function "?>=";
+
+ function "?<=" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?<= to_ufixed (r, l'high, l'low));
+ end function "?<=";
+
+ function "?>" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?> to_ufixed (r, l'high, l'low));
+ end function "?>";
+
+ function "?<" (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?< to_ufixed (r, l'high, l'low));
+ end function "?<";
+
+ function maximum (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return maximum (l, to_ufixed (r, l'high, l'low));
+ end function maximum;
+
+ function minimum (
+ l : UNRESOLVED_ufixed;
+ r : REAL)
+ return UNRESOLVED_ufixed is
+ begin
+ return minimum (l, to_ufixed (r, l'high, l'low));
+ end function minimum;
+
+ -- real and ufixed
+ function "=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) = r);
+ end function "=";
+
+ function "/=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) /= r);
+ end function "/=";
+
+ function ">=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) >= r);
+ end function ">=";
+
+ function "<=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) <= r);
+ end function "<=";
+
+ function ">" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) > r);
+ end function ">";
+
+ function "<" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_ufixed (l, r'high, r'low) < r);
+ end function "<";
+
+ function "?=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?= r);
+ end function "?=";
+
+ function "?/=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?/= r);
+ end function "?/=";
+
+ function "?>=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?>= r);
+ end function "?>=";
+
+ function "?<=" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?<= r);
+ end function "?<=";
+
+ function "?>" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?> r);
+ end function "?>";
+
+ function "?<" (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_ufixed (l, r'high, r'low) ?< r);
+ end function "?<";
+
+ function maximum (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return maximum (to_ufixed (l, r'high, r'low), r);
+ end function maximum;
+
+ function minimum (
+ l : REAL;
+ r : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ begin
+ return minimum (to_ufixed (l, r'high, r'low), r);
+ end function minimum;
+
+ -- overloaded sfixed compare functions with integer
+ function "=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return BOOLEAN is
+ begin
+ return (l = to_sfixed (r, l'high, l'low));
+ end function "=";
+
+ function "/=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return BOOLEAN is
+ begin
+ return (l /= to_sfixed (r, l'high, l'low));
+ end function "/=";
+
+ function ">=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return BOOLEAN is
+ begin
+ return (l >= to_sfixed (r, l'high, l'low));
+ end function ">=";
+
+ function "<=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return BOOLEAN is
+ begin
+ return (l <= to_sfixed (r, l'high, l'low));
+ end function "<=";
+
+ function ">" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return BOOLEAN is
+ begin
+ return (l > to_sfixed (r, l'high, l'low));
+ end function ">";
+
+ function "<" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return BOOLEAN is
+ begin
+ return (l < to_sfixed (r, l'high, l'low));
+ end function "<";
+
+ function "?=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return STD_ULOGIC is
+ begin
+ return (l ?= to_sfixed (r, l'high, l'low));
+ end function "?=";
+
+ function "?/=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return STD_ULOGIC is
+ begin
+ return (l ?/= to_sfixed (r, l'high, l'low));
+ end function "?/=";
+
+ function "?>=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return STD_ULOGIC is
+ begin
+ return (l ?>= to_sfixed (r, l'high, l'low));
+ end function "?>=";
+
+ function "?<=" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return STD_ULOGIC is
+ begin
+ return (l ?<= to_sfixed (r, l'high, l'low));
+ end function "?<=";
+
+ function "?>" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return STD_ULOGIC is
+ begin
+ return (l ?> to_sfixed (r, l'high, l'low));
+ end function "?>";
+
+ function "?<" (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return STD_ULOGIC is
+ begin
+ return (l ?< to_sfixed (r, l'high, l'low));
+ end function "?<";
+
+ function maximum (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return maximum (l, to_sfixed (r, l'high, l'low));
+ end function maximum;
+
+ function minimum (
+ l : UNRESOLVED_sfixed;
+ r : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return minimum (l, to_sfixed (r, l'high, l'low));
+ end function minimum;
+
+ -- integer and sfixed
+ function "=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) = r);
+ end function "=";
+
+ function "/=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) /= r);
+ end function "/=";
+
+ function ">=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) >= r);
+ end function ">=";
+
+ function "<=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) <= r);
+ end function "<=";
+
+ function ">" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) > r);
+ end function ">";
+
+ function "<" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) < r);
+ end function "<";
+
+ function "?=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?= r);
+ end function "?=";
+
+ function "?/=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?/= r);
+ end function "?/=";
+
+ function "?>=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?>= r);
+ end function "?>=";
+
+ function "?<=" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?<= r);
+ end function "?<=";
+
+ function "?>" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?> r);
+ end function "?>";
+
+ function "?<" (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?< r);
+ end function "?<";
+
+ function maximum (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return maximum (to_sfixed (l, r'high, r'low), r);
+ end function maximum;
+
+ function minimum (
+ l : INTEGER;
+ r : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return minimum (to_sfixed (l, r'high, r'low), r);
+ end function minimum;
+
+ -- overloaded sfixed compare functions with real
+ function "=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l = to_sfixed (r, l'high, l'low));
+ end function "=";
+
+ function "/=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l /= to_sfixed (r, l'high, l'low));
+ end function "/=";
+
+ function ">=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l >= to_sfixed (r, l'high, l'low));
+ end function ">=";
+
+ function "<=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l <= to_sfixed (r, l'high, l'low));
+ end function "<=";
+
+ function ">" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l > to_sfixed (r, l'high, l'low));
+ end function ">";
+
+ function "<" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return BOOLEAN is
+ begin
+ return (l < to_sfixed (r, l'high, l'low));
+ end function "<";
+
+ function "?=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?= to_sfixed (r, l'high, l'low));
+ end function "?=";
+
+ function "?/=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?/= to_sfixed (r, l'high, l'low));
+ end function "?/=";
+
+ function "?>=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?>= to_sfixed (r, l'high, l'low));
+ end function "?>=";
+
+ function "?<=" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?<= to_sfixed (r, l'high, l'low));
+ end function "?<=";
+
+ function "?>" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?> to_sfixed (r, l'high, l'low));
+ end function "?>";
+
+ function "?<" (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return STD_ULOGIC is
+ begin
+ return (l ?< to_sfixed (r, l'high, l'low));
+ end function "?<";
+
+ function maximum (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return maximum (l, to_sfixed (r, l'high, l'low));
+ end function maximum;
+
+ function minimum (
+ l : UNRESOLVED_sfixed;
+ r : REAL)
+ return UNRESOLVED_sfixed is
+ begin
+ return minimum (l, to_sfixed (r, l'high, l'low));
+ end function minimum;
+
+ -- REAL and sfixed
+ function "=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) = r);
+ end function "=";
+
+ function "/=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) /= r);
+ end function "/=";
+
+ function ">=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) >= r);
+ end function ">=";
+
+ function "<=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) <= r);
+ end function "<=";
+
+ function ">" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) > r);
+ end function ">";
+
+ function "<" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return BOOLEAN is
+ begin
+ return (to_sfixed (l, r'high, r'low) < r);
+ end function "<";
+
+ function "?=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?= r);
+ end function "?=";
+
+ function "?/=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?/= r);
+ end function "?/=";
+
+ function "?>=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?>= r);
+ end function "?>=";
+
+ function "?<=" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?<= r);
+ end function "?<=";
+
+ function "?>" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?> r);
+ end function "?>";
+
+ function "?<" (
+ l : REAL;
+ r : UNRESOLVED_sfixed) -- fixed point input
+ return STD_ULOGIC is
+ begin
+ return (to_sfixed (l, r'high, r'low) ?< r);
+ end function "?<";
+
+ function maximum (
+ l : REAL;
+ r : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return maximum (to_sfixed (l, r'high, r'low), r);
+ end function maximum;
+
+ function minimum (
+ l : REAL;
+ r : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return minimum (to_sfixed (l, r'high, r'low), r);
+ end function minimum;
+
+ -- copied from std_logic_textio
+ type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
+ type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
+ type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
+ type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
+
+ constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
+ constant char_to_MVL9 : MVL9_indexed_by_char :=
+ ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
+ 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
+ constant char_to_MVL9plus : MVL9plus_indexed_by_char :=
+ ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
+ 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error);
+ constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
+ constant NUS : STRING(2 to 1) := (others => ' ');
+
+ -- purpose: Skips white space
+ procedure skip_whitespace (
+ L : inout LINE) is
+ variable readOk : BOOLEAN;
+ variable c : CHARACTER;
+ begin
+ while L /= null and L.all'length /= 0 loop
+ if (L.all(1) = ' ' or L.all(1) = NBSP or L.all(1) = HT) then
+ read (l, c, readOk);
+ else
+ exit;
+ end if;
+ end loop;
+ end procedure skip_whitespace;
+
+ -- purpose: writes fixed point into a line
+ procedure write (
+ L : inout LINE; -- input line
+ VALUE : in UNRESOLVED_ufixed; -- fixed point input
+ JUSTIFIED : in SIDE := right;
+ FIELD : in WIDTH := 0) is
+ variable s : STRING(1 to value'length +1) := (others => ' ');
+ variable sindx : INTEGER;
+ begin -- function write Example: 0011.1100
+ sindx := 1;
+ for i in value'high downto value'low loop
+ if i = -1 then
+ s(sindx) := '.';
+ sindx := sindx + 1;
+ end if;
+ s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
+ sindx := sindx + 1;
+ end loop;
+ write(l, s, justified, field);
+ end procedure write;
+
+ -- purpose: writes fixed point into a line
+ procedure write (
+ L : inout LINE; -- input line
+ VALUE : in UNRESOLVED_sfixed; -- fixed point input
+ JUSTIFIED : in SIDE := right;
+ FIELD : in WIDTH := 0) is
+ variable s : STRING(1 to value'length +1);
+ variable sindx : INTEGER;
+ begin -- function write Example: 0011.1100
+ sindx := 1;
+ for i in value'high downto value'low loop
+ if i = -1 then
+ s(sindx) := '.';
+ sindx := sindx + 1;
+ end if;
+ s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
+ sindx := sindx + 1;
+ end loop;
+ write(l, s, justified, field);
+ end procedure write;
+
+ procedure READ(L : inout LINE;
+ VALUE : out UNRESOLVED_ufixed) is
+ -- Possible data: 00000.0000000
+ -- 000000000000
+ variable c : CHARACTER;
+ variable readOk : BOOLEAN;
+ variable i : INTEGER; -- index variable
+ variable mv : ufixed (VALUE'range);
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ variable founddot : BOOLEAN := false; -- found a "."
+ begin -- READ
+ VALUE := (VALUE'range => 'U');
+ Skip_whitespace (L);
+ if VALUE'length > 0 then -- non Null input string
+ read (l, c, readOk);
+ i := value'high;
+ while i >= VALUE'low loop
+ if readOk = false then -- Bail out if there was a bad read
+ report fixed_generic_pkg'instance_name & "READ(ufixed) "
+ & "End of string encountered"
+ severity error;
+ return;
+ elsif c = '_' then
+ if i = value'high then
+ report fixed_generic_pkg'instance_name & "READ(ufixed) "
+ & "String begins with an ""_""" severity error;
+ return;
+ elsif lastu then
+ report fixed_generic_pkg'instance_name & "READ(ufixed) "
+ & "Two underscores detected in input string ""__"""
+ severity error;
+ return;
+ else
+ lastu := true;
+ end if;
+ elsif c = '.' then -- binary point
+ if founddot then
+ report fixed_generic_pkg'instance_name & "READ(ufixed) "
+ & "Two binary points found in input string" severity error;
+ return;
+ elsif i /= -1 then -- Seperator in the wrong spot
+ report fixed_generic_pkg'instance_name & "READ(ufixed) "
+ & "Decimal point does not match number format "
+ severity error;
+ return;
+ end if;
+ founddot := true;
+ lastu := false;
+ elsif c = ' ' or c = NBSP or c = HT then -- reading done.
+ report fixed_generic_pkg'instance_name & "READ(ufixed) "
+ & "Short read, Space encounted in input string"
+ severity error;
+ return;
+ elsif char_to_MVL9plus(c) = error then
+ report fixed_generic_pkg'instance_name & "READ(ufixed) "
+ & "Character '" &
+ c & "' read, expected STD_ULOGIC literal."
+ severity error;
+ return;
+ else
+ mv(i) := char_to_MVL9(c);
+ i := i - 1;
+ if i < mv'low then
+ VALUE := mv;
+ return;
+ end if;
+ lastu := false;
+ end if;
+ read(L, c, readOk);
+ end loop;
+ end if;
+ end procedure READ;
+
+ procedure READ(L : inout LINE;
+ VALUE : out UNRESOLVED_ufixed;
+ GOOD : out BOOLEAN) is
+ -- Possible data: 00000.0000000
+ -- 000000000000
+ variable c : CHARACTER;
+ variable readOk : BOOLEAN;
+ variable mv : ufixed (VALUE'range);
+ variable i : INTEGER; -- index variable
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ variable founddot : BOOLEAN := false; -- found a "."
+ begin -- READ
+ VALUE := (VALUE'range => 'U');
+ Skip_whitespace (L);
+ if VALUE'length > 0 then
+ read (l, c, readOk);
+ i := value'high;
+ GOOD := false;
+ while i >= VALUE'low loop
+ if not readOk then -- Bail out if there was a bad read
+ return;
+ elsif c = '_' then
+ if i = value'high then -- Begins with an "_"
+ return;
+ elsif lastu then -- "__" detected
+ return;
+ else
+ lastu := true;
+ end if;
+ elsif c = '.' then -- binary point
+ if founddot then
+ return;
+ elsif i /= -1 then -- Seperator in the wrong spot
+ return;
+ end if;
+ founddot := true;
+ lastu := false;
+ elsif (char_to_MVL9plus(c) = error) then -- Illegal character/short read
+ return;
+ else
+ mv(i) := char_to_MVL9(c);
+ i := i - 1;
+ if i < mv'low then -- reading done
+ GOOD := true;
+ VALUE := mv;
+ return;
+ end if;
+ lastu := false;
+ end if;
+ read(L, c, readOk);
+ end loop;
+ else
+ GOOD := true; -- read into a null array
+ end if;
+ end procedure READ;
+
+ procedure READ(L : inout LINE;
+ VALUE : out UNRESOLVED_sfixed) is
+ variable c : CHARACTER;
+ variable readOk : BOOLEAN;
+ variable i : INTEGER; -- index variable
+ variable mv : sfixed (VALUE'range);
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ variable founddot : BOOLEAN := false; -- found a "."
+ begin -- READ
+ VALUE := (VALUE'range => 'U');
+ Skip_whitespace (L);
+ if VALUE'length > 0 then -- non Null input string
+ read (l, c, readOk);
+ i := value'high;
+ while i >= VALUE'low loop
+ if readOk = false then -- Bail out if there was a bad read
+ report fixed_generic_pkg'instance_name & "READ(sfixed) "
+ & "End of string encountered"
+ severity error;
+ return;
+ elsif c = '_' then
+ if i = value'high then
+ report fixed_generic_pkg'instance_name & "READ(sfixed) "
+ & "String begins with an ""_""" severity error;
+ return;
+ elsif lastu then
+ report fixed_generic_pkg'instance_name & "READ(sfixed) "
+ & "Two underscores detected in input string ""__"""
+ severity error;
+ return;
+ else
+ lastu := true;
+ end if;
+ elsif c = '.' then -- binary point
+ if founddot then
+ report fixed_generic_pkg'instance_name & "READ(sfixed) "
+ & "Two binary points found in input string" severity error;
+ return;
+ elsif i /= -1 then -- Seperator in the wrong spot
+ report fixed_generic_pkg'instance_name & "READ(sfixed) "
+ & "Decimal point does not match number format "
+ severity error;
+ return;
+ end if;
+ founddot := true;
+ lastu := false;
+ elsif c = ' ' or c = NBSP or c = HT then -- reading done.
+ report fixed_generic_pkg'instance_name & "READ(sfixed) "
+ & "Short read, Space encounted in input string"
+ severity error;
+ return;
+ elsif char_to_MVL9plus(c) = error then
+ report fixed_generic_pkg'instance_name & "READ(sfixed) "
+ & "Character '" &
+ c & "' read, expected STD_ULOGIC literal."
+ severity error;
+ return;
+ else
+ mv(i) := char_to_MVL9(c);
+ i := i - 1;
+ if i < mv'low then
+ VALUE := mv;
+ return;
+ end if;
+ lastu := false;
+ end if;
+ read(L, c, readOk);
+ end loop;
+ end if;
+ end procedure READ;
+
+ procedure READ(L : inout LINE;
+ VALUE : out UNRESOLVED_sfixed;
+ GOOD : out BOOLEAN) is
+ variable value_ufixed : UNRESOLVED_ufixed (VALUE'range);
+ begin -- READ
+ READ (L => L, VALUE => value_ufixed, GOOD => GOOD);
+ VALUE := UNRESOLVED_sfixed (value_ufixed);
+ end procedure READ;
+
+ -- octal read and write
+ procedure owrite (
+ L : inout LINE; -- input line
+ VALUE : in UNRESOLVED_ufixed; -- fixed point input
+ JUSTIFIED : in SIDE := right;
+ FIELD : in WIDTH := 0) is
+ begin -- Example 03.30
+ write (L => L,
+ VALUE => to_ostring (VALUE),
+ JUSTIFIED => JUSTIFIED,
+ FIELD => FIELD);
+ end procedure owrite;
+
+ procedure owrite (
+ L : inout LINE; -- input line
+ VALUE : in UNRESOLVED_sfixed; -- fixed point input
+ JUSTIFIED : in SIDE := right;
+ FIELD : in WIDTH := 0) is
+ begin -- Example 03.30
+ write (L => L,
+ VALUE => to_ostring (VALUE),
+ JUSTIFIED => JUSTIFIED,
+ FIELD => FIELD);
+ end procedure owrite;
+
+ -- Note that for Octal and Hex read, you can not start with a ".",
+ -- the read is for numbers formatted "A.BC". These routines go to
+ -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
+ procedure Char2TriBits (C : CHARACTER;
+ RESULT : out STD_ULOGIC_VECTOR(2 downto 0);
+ GOOD : out BOOLEAN;
+ ISSUE_ERROR : in BOOLEAN) is
+ begin
+ case c is
+ when '0' => result := o"0"; good := true;
+ when '1' => result := o"1"; good := true;
+ when '2' => result := o"2"; good := true;
+ when '3' => result := o"3"; good := true;
+ when '4' => result := o"4"; good := true;
+ when '5' => result := o"5"; good := true;
+ when '6' => result := o"6"; good := true;
+ when '7' => result := o"7"; good := true;
+ when 'Z' => result := "ZZZ"; good := true;
+ when 'X' => result := "XXX"; good := true;
+ when others =>
+ assert not ISSUE_ERROR
+ report fixed_generic_pkg'instance_name
+ & "OREAD Error: Read a '" & c &
+ "', expected an Octal character (0-7)."
+ severity error;
+ result := "UUU";
+ good := false;
+ end case;
+ end procedure Char2TriBits;
+
+ -- purpose: Routines common to the OREAD routines
+ procedure OREAD_common (
+ L : inout LINE;
+ slv : out STD_ULOGIC_VECTOR;
+ igood : out BOOLEAN;
+ idex : out INTEGER;
+ constant bpoint : in INTEGER; -- binary point
+ constant message : in BOOLEAN;
+ constant smath : in BOOLEAN) is
+
+ -- purpose: error message routine
+ procedure errmes (
+ constant mess : in STRING) is -- error message
+ begin
+ if message then
+ if smath then
+ report fixed_generic_pkg'instance_name
+ & "OREAD(sfixed) "
+ & mess
+ severity error;
+ else
+ report fixed_generic_pkg'instance_name
+ & "OREAD(ufixed) "
+ & mess
+ severity error;
+ end if;
+ end if;
+ end procedure errmes;
+ variable xgood : BOOLEAN;
+ variable nybble : STD_ULOGIC_VECTOR (2 downto 0); -- 3 bits
+ variable c : CHARACTER;
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ variable founddot : BOOLEAN := false; -- found a dot.
+ begin
+ Skip_whitespace (L);
+ if slv'length > 0 then
+ i := slv'high;
+ read (l, c, xgood);
+ while i > 0 loop
+ if xgood = false then
+ errmes ("Error: end of string encountered");
+ exit;
+ elsif c = '_' then
+ if i = slv'length then
+ errmes ("Error: String begins with an ""_""");
+ xgood := false;
+ exit;
+ elsif lastu then
+ errmes ("Error: Two underscores detected in input string ""__""");
+ xgood := false;
+ exit;
+ else
+ lastu := true;
+ end if;
+ elsif (c = '.') then
+ if (i + 1 /= bpoint) then
+ errmes ("encountered ""."" at wrong index");
+ xgood := false;
+ exit;
+ elsif i = slv'length then
+ errmes ("encounted a ""."" at the beginning of the line");
+ xgood := false;
+ exit;
+ elsif founddot then
+ errmes ("Two ""."" encounted in input string");
+ xgood := false;
+ exit;
+ end if;
+ founddot := true;
+ lastu := false;
+ else
+ Char2triBits(c, nybble, xgood, message);
+ if not xgood then
+ exit;
+ end if;
+ slv (i downto i-2) := nybble;
+ i := i - 3;
+ lastu := false;
+ end if;
+ if i > 0 then
+ read (L, c, xgood);
+ end if;
+ end loop;
+ idex := i;
+ igood := xgood;
+ else
+ igood := true; -- read into a null array
+ idex := -1;
+ end if;
+ end procedure OREAD_common;
+
+ -- Note that for Octal and Hex read, you can not start with a ".",
+ -- the read is for numbers formatted "A.BC". These routines go to
+ -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
+ procedure OREAD (L : inout LINE;
+ VALUE : out UNRESOLVED_ufixed) is
+ constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ OREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => true,
+ smath => false);
+ if igood then -- We did not get another error
+ if not ((i = -1) and -- We read everything, and high bits 0
+ (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
+ report fixed_generic_pkg'instance_name
+ & "OREAD(ufixed): Vector truncated."
+ severity error;
+ else
+ if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "OREAD(ufixed): Vector truncated"
+ severity warning;
+ end if;
+ valuex := to_ufixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ end if;
+ end if;
+ end procedure OREAD;
+
+ procedure OREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_ufixed;
+ GOOD : out BOOLEAN) is
+ constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ OREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => false,
+ smath => false);
+ if (igood and -- We did not get another error
+ (i = -1) and -- We read everything, and high bits 0
+ (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
+ valuex := to_ufixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ good := true;
+ else
+ good := false;
+ end if;
+ end procedure OREAD;
+
+ procedure OREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_sfixed) is
+ constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ OREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => true,
+ smath => true);
+ if igood then -- We did not get another error
+ if not ((i = -1) and -- We read everything
+ ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
+ or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
+ report fixed_generic_pkg'instance_name
+ & "OREAD(sfixed): Vector truncated."
+ severity error;
+ else
+ if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "OREAD(sfixed): Vector truncated"
+ severity warning;
+ end if;
+ valuex := to_sfixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ end if;
+ end if;
+ end procedure OREAD;
+
+ procedure OREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_sfixed;
+ GOOD : out BOOLEAN) is
+ constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ OREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => false,
+ smath => true);
+ if (igood -- We did not get another error
+ and (i = -1) -- We read everything
+ and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
+ or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
+ valuex := to_sfixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ good := true;
+ else
+ good := false;
+ end if;
+ end procedure OREAD;
+
+ -- hex read and write
+ procedure hwrite (
+ L : inout LINE; -- input line
+ VALUE : in UNRESOLVED_ufixed; -- fixed point input
+ JUSTIFIED : in SIDE := right;
+ FIELD : in WIDTH := 0) is
+ begin -- Example 03.30
+ write (L => L,
+ VALUE => to_hstring (VALUE),
+ JUSTIFIED => JUSTIFIED,
+ FIELD => FIELD);
+ end procedure hwrite;
+
+ -- purpose: writes fixed point into a line
+ procedure hwrite (
+ L : inout LINE; -- input line
+ VALUE : in UNRESOLVED_sfixed; -- fixed point input
+ JUSTIFIED : in SIDE := right;
+ FIELD : in WIDTH := 0) is
+ begin -- Example 03.30
+ write (L => L,
+ VALUE => to_hstring (VALUE),
+ JUSTIFIED => JUSTIFIED,
+ FIELD => FIELD);
+ end procedure hwrite;
+
+ -- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
+ -- Modified from the original to be more forgiving.
+
+ procedure Char2QuadBits (C : CHARACTER;
+ RESULT : out STD_ULOGIC_VECTOR(3 downto 0);
+ GOOD : out BOOLEAN;
+ ISSUE_ERROR : in BOOLEAN) is
+ begin
+ case c is
+ when '0' => result := x"0"; good := true;
+ when '1' => result := x"1"; good := true;
+ when '2' => result := x"2"; good := true;
+ when '3' => result := x"3"; good := true;
+ when '4' => result := x"4"; good := true;
+ when '5' => result := x"5"; good := true;
+ when '6' => result := x"6"; good := true;
+ when '7' => result := x"7"; good := true;
+ when '8' => result := x"8"; good := true;
+ when '9' => result := x"9"; good := true;
+ when 'A' | 'a' => result := x"A"; good := true;
+ when 'B' | 'b' => result := x"B"; good := true;
+ when 'C' | 'c' => result := x"C"; good := true;
+ when 'D' | 'd' => result := x"D"; good := true;
+ when 'E' | 'e' => result := x"E"; good := true;
+ when 'F' | 'f' => result := x"F"; good := true;
+ when 'Z' => result := "ZZZZ"; good := true;
+ when 'X' => result := "XXXX"; good := true;
+ when others =>
+ assert not ISSUE_ERROR
+ report fixed_generic_pkg'instance_name
+ & "HREAD Error: Read a '" & c &
+ "', expected a Hex character (0-F)."
+ severity error;
+ result := "UUUU";
+ good := false;
+ end case;
+ end procedure Char2QuadBits;
+
+ -- purpose: Routines common to the HREAD routines
+ procedure HREAD_common (
+ L : inout LINE;
+ slv : out STD_ULOGIC_VECTOR;
+ igood : out BOOLEAN;
+ idex : out INTEGER;
+ constant bpoint : in INTEGER; -- binary point
+ constant message : in BOOLEAN;
+ constant smath : in BOOLEAN) is
+
+ -- purpose: error message routine
+ procedure errmes (
+ constant mess : in STRING) is -- error message
+ begin
+ if message then
+ if smath then
+ report fixed_generic_pkg'instance_name
+ & "HREAD(sfixed) "
+ & mess
+ severity error;
+ else
+ report fixed_generic_pkg'instance_name
+ & "HREAD(ufixed) "
+ & mess
+ severity error;
+ end if;
+ end if;
+ end procedure errmes;
+ variable xgood : BOOLEAN;
+ variable nybble : STD_ULOGIC_VECTOR (3 downto 0); -- 4 bits
+ variable c : CHARACTER;
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ variable founddot : BOOLEAN := false; -- found a dot.
+ begin
+ Skip_whitespace (L);
+ if slv'length > 0 then
+ i := slv'high;
+ read (l, c, xgood);
+ while i > 0 loop
+ if xgood = false then
+ errmes ("Error: end of string encountered");
+ exit;
+ elsif c = '_' then
+ if i = slv'length then
+ errmes ("Error: String begins with an ""_""");
+ xgood := false;
+ exit;
+ elsif lastu then
+ errmes ("Error: Two underscores detected in input string ""__""");
+ xgood := false;
+ exit;
+ else
+ lastu := true;
+ end if;
+ elsif (c = '.') then
+ if (i + 1 /= bpoint) then
+ errmes ("encountered ""."" at wrong index");
+ xgood := false;
+ exit;
+ elsif i = slv'length then
+ errmes ("encounted a ""."" at the beginning of the line");
+ xgood := false;
+ exit;
+ elsif founddot then
+ errmes ("Two ""."" encounted in input string");
+ xgood := false;
+ exit;
+ end if;
+ founddot := true;
+ lastu := false;
+ else
+ Char2QuadBits(c, nybble, xgood, message);
+ if not xgood then
+ exit;
+ end if;
+ slv (i downto i-3) := nybble;
+ i := i - 4;
+ lastu := false;
+ end if;
+ if i > 0 then
+ read (L, c, xgood);
+ end if;
+ end loop;
+ idex := i;
+ igood := xgood;
+ else
+ idex := -1;
+ igood := true; -- read null string
+ end if;
+ end procedure HREAD_common;
+
+ procedure HREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_ufixed) is
+ constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ HREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => false,
+ smath => false);
+ if igood then
+ if not ((i = -1) and -- We read everything, and high bits 0
+ (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
+ report fixed_generic_pkg'instance_name
+ & "HREAD(ufixed): Vector truncated."
+ severity error;
+ else
+ if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "HREAD(ufixed): Vector truncated"
+ severity warning;
+ end if;
+ valuex := to_ufixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ end if;
+ end if;
+ end procedure HREAD;
+
+ procedure HREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_ufixed;
+ GOOD : out BOOLEAN) is
+ constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ HREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => false,
+ smath => false);
+ if (igood and -- We did not get another error
+ (i = -1) and -- We read everything, and high bits 0
+ (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
+ valuex := to_ufixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ good := true;
+ else
+ good := false;
+ end if;
+ end procedure HREAD;
+
+ procedure HREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_sfixed) is
+ constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ HREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => true,
+ smath => true);
+ if igood then -- We did not get another error
+ if not ((i = -1) -- We read everything
+ and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
+ or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
+ report fixed_generic_pkg'instance_name
+ & "HREAD(sfixed): Vector truncated."
+ severity error;
+ else
+ if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report fixed_generic_pkg'instance_name
+ & "HREAD(sfixed): Vector truncated"
+ severity warning;
+ end if;
+ valuex := to_sfixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ end if;
+ end if;
+ end procedure HREAD;
+
+ procedure HREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_sfixed;
+ GOOD : out BOOLEAN) is
+ constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ HREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => false,
+ smath => true);
+ if (igood and -- We did not get another error
+ (i = -1) and -- We read everything
+ ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
+ or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
+ valuex := to_sfixed (slv, hbv, lbv);
+ VALUE := valuex (VALUE'range);
+ good := true;
+ else
+ good := false;
+ end if;
+ end procedure HREAD;
+
+ -- To_string functions. Useful in "report" statements.
+ -- Example: report "result was " & to_string(result);
+ function to_string (value : UNRESOLVED_ufixed) return STRING is
+ variable s : STRING(1 to value'length +1) := (others => ' ');
+ variable subval : UNRESOLVED_ufixed (value'high downto -1);
+ variable sindx : INTEGER;
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value'high < 0 then
+ if value(value'high) = 'Z' then
+ return to_string (resize (sfixed(value), 0, value'low));
+ else
+ return to_string (resize (value, 0, value'low));
+ end if;
+ elsif value'low >= 0 then
+ if Is_X (value(value'low)) then
+ subval := (others => value(value'low));
+ subval (value'range) := value;
+ return to_string(subval);
+ else
+ return to_string (resize (value, value'high, -1));
+ end if;
+ else
+ sindx := 1;
+ for i in value'high downto value'low loop
+ if i = -1 then
+ s(sindx) := '.';
+ sindx := sindx + 1;
+ end if;
+ s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
+ sindx := sindx + 1;
+ end loop;
+ return s;
+ end if;
+ end if;
+ end function to_string;
+
+ function to_string (value : UNRESOLVED_sfixed) return STRING is
+ variable s : STRING(1 to value'length + 1) := (others => ' ');
+ variable subval : UNRESOLVED_sfixed (value'high downto -1);
+ variable sindx : INTEGER;
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value'high < 0 then
+ return to_string (resize (value, 0, value'low));
+ elsif value'low >= 0 then
+ if Is_X (value(value'low)) then
+ subval := (others => value(value'low));
+ subval (value'range) := value;
+ return to_string(subval);
+ else
+ return to_string (resize (value, value'high, -1));
+ end if;
+ else
+ sindx := 1;
+ for i in value'high downto value'low loop
+ if i = -1 then
+ s(sindx) := '.';
+ sindx := sindx + 1;
+ end if;
+ s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
+ sindx := sindx + 1;
+ end loop;
+ return s;
+ end if;
+ end if;
+ end function to_string;
+
+ function to_ostring (value : UNRESOLVED_ufixed) return STRING is
+ constant lne : INTEGER := (-VALUE'low+2)/3;
+ variable subval : UNRESOLVED_ufixed (value'high downto -3);
+ variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + VALUE'low) -1);
+ variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value'high < 0 then
+ if value(value'high) = 'Z' then
+ return to_ostring (resize (sfixed(value), 2, value'low));
+ else
+ return to_ostring (resize (value, 2, value'low));
+ end if;
+ elsif value'low >= 0 then
+ if Is_X (value(value'low)) then
+ subval := (others => value(value'low));
+ subval (value'range) := value;
+ return to_ostring(subval);
+ else
+ return to_ostring (resize (value, value'high, -3));
+ end if;
+ else
+ slv := to_sulv (value);
+ if Is_X (value (value'low)) then
+ lpad := (others => value (value'low));
+ else
+ lpad := (others => '0');
+ end if;
+ return to_ostring(slv(slv'high downto slv'high-VALUE'high))
+ & "."
+ & to_ostring(slv(slv'high-VALUE'high-1 downto 0) & lpad);
+ end if;
+ end if;
+ end function to_ostring;
+
+ function to_hstring (value : UNRESOLVED_ufixed) return STRING is
+ constant lne : INTEGER := (-VALUE'low+3)/4;
+ variable subval : UNRESOLVED_ufixed (value'high downto -4);
+ variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + VALUE'low) -1);
+ variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value'high < 0 then
+ if value(value'high) = 'Z' then
+ return to_hstring (resize (sfixed(value), 3, value'low));
+ else
+ return to_hstring (resize (value, 3, value'low));
+ end if;
+ elsif value'low >= 0 then
+ if Is_X (value(value'low)) then
+ subval := (others => value(value'low));
+ subval (value'range) := value;
+ return to_hstring(subval);
+ else
+ return to_hstring (resize (value, value'high, -4));
+ end if;
+ else
+ slv := to_sulv (value);
+ if Is_X (value (value'low)) then
+ lpad := (others => value(value'low));
+ else
+ lpad := (others => '0');
+ end if;
+ return to_hstring(slv(slv'high downto slv'high-VALUE'high))
+ & "."
+ & to_hstring(slv(slv'high-VALUE'high-1 downto 0)&lpad);
+ end if;
+ end if;
+ end function to_hstring;
+
+ function to_ostring (value : UNRESOLVED_sfixed) return STRING is
+ constant ne : INTEGER := ((value'high+1)+2)/3;
+ variable pad : STD_ULOGIC_VECTOR(0 to (ne*3 - (value'high+1)) - 1);
+ constant lne : INTEGER := (-VALUE'low+2)/3;
+ variable subval : UNRESOLVED_sfixed (value'high downto -3);
+ variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + VALUE'low) -1);
+ variable slv : STD_ULOGIC_VECTOR (VALUE'high - VALUE'low downto 0);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value'high < 0 then
+ return to_ostring (resize (value, 2, value'low));
+ elsif value'low >= 0 then
+ if Is_X (value(value'low)) then
+ subval := (others => value(value'low));
+ subval (value'range) := value;
+ return to_ostring(subval);
+ else
+ return to_ostring (resize (value, value'high, -3));
+ end if;
+ else
+ pad := (others => value(value'high));
+ slv := to_sulv (value);
+ if Is_X (value (value'low)) then
+ lpad := (others => value(value'low));
+ else
+ lpad := (others => '0');
+ end if;
+ return to_ostring(pad & slv(slv'high downto slv'high-VALUE'high))
+ & "."
+ & to_ostring(slv(slv'high-VALUE'high-1 downto 0) & lpad);
+ end if;
+ end if;
+ end function to_ostring;
+
+ function to_hstring (value : UNRESOLVED_sfixed) return STRING is
+ constant ne : INTEGER := ((value'high+1)+3)/4;
+ variable pad : STD_ULOGIC_VECTOR(0 to (ne*4 - (value'high+1)) - 1);
+ constant lne : INTEGER := (-VALUE'low+3)/4;
+ variable subval : UNRESOLVED_sfixed (value'high downto -4);
+ variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + VALUE'low) -1);
+ variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value'high < 0 then
+ return to_hstring (resize (value, 3, value'low));
+ elsif value'low >= 0 then
+ if Is_X (value(value'low)) then
+ subval := (others => value(value'low));
+ subval (value'range) := value;
+ return to_hstring(subval);
+ else
+ return to_hstring (resize (value, value'high, -4));
+ end if;
+ else
+ slv := to_sulv (value);
+ pad := (others => value(value'high));
+ if Is_X (value (value'low)) then
+ lpad := (others => value(value'low));
+ else
+ lpad := (others => '0');
+ end if;
+ return to_hstring(pad & slv(slv'high downto slv'high-VALUE'high))
+ & "."
+ & to_hstring(slv(slv'high-VALUE'high-1 downto 0) & lpad);
+ end if;
+ end if;
+ end function to_hstring;
+
+ -- From string functions allow you to convert a string into a fixed
+ -- point number. Example:
+ -- signal uf1 : ufixed (3 downto -3);
+ -- uf1 <= from_string ("0110.100", uf1'high, uf1'low); -- 6.5
+ -- The "." is optional in this syntax, however it exist and is
+ -- in the wrong location an error is produced. Overflow will
+ -- result in saturation.
+ function from_string (
+ bstring : STRING; -- binary string
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ variable L : LINE;
+ variable good : BOOLEAN;
+ begin
+ L := new STRING'(bstring);
+ read (L, result, good);
+ deallocate (L);
+ assert (good)
+ report fixed_generic_pkg'instance_name
+ & "from_string: Bad string "& bstring severity error;
+ return result;
+ end function from_string;
+
+ -- Octal and hex conversions work as follows:
+ -- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped)
+ -- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped)
+ function from_ostring (
+ ostring : STRING; -- Octal string
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ variable L : LINE;
+ variable good : BOOLEAN;
+ begin
+ L := new STRING'(ostring);
+ oread (L, result, good);
+ deallocate (L);
+ assert (good)
+ report fixed_generic_pkg'instance_name
+ & "from_ostring: Bad string "& ostring severity error;
+ return result;
+ end function from_ostring;
+
+ function from_hstring (
+ hstring : STRING; -- hex string
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_ufixed
+ is
+ variable result : UNRESOLVED_ufixed (left_index downto right_index);
+ variable L : LINE;
+ variable good : BOOLEAN;
+ begin
+ L := new STRING'(hstring);
+ hread (L, result, good);
+ deallocate (L);
+ assert (good)
+ report fixed_generic_pkg'instance_name
+ & "from_hstring: Bad string "& hstring severity error;
+ return result;
+ end function from_hstring;
+
+ function from_string (
+ bstring : STRING; -- binary string
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ variable L : LINE;
+ variable good : BOOLEAN;
+ begin
+ L := new STRING'(bstring);
+ read (L, result, good);
+ deallocate (L);
+ assert (good)
+ report fixed_generic_pkg'instance_name
+ & "from_string: Bad string "& bstring severity error;
+ return result;
+ end function from_string;
+
+ function from_ostring (
+ ostring : STRING; -- Octal string
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ variable L : LINE;
+ variable good : BOOLEAN;
+ begin
+ L := new STRING'(ostring);
+ oread (L, result, good);
+ deallocate (L);
+ assert (good)
+ report fixed_generic_pkg'instance_name
+ & "from_ostring: Bad string "& ostring severity error;
+ return result;
+ end function from_ostring;
+
+ function from_hstring (
+ hstring : STRING; -- hex string
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_sfixed
+ is
+ variable result : UNRESOLVED_sfixed (left_index downto right_index);
+ variable L : LINE;
+ variable good : BOOLEAN;
+ begin
+ L := new STRING'(hstring);
+ hread (L, result, good);
+ deallocate (L);
+ assert (good)
+ report fixed_generic_pkg'instance_name
+ & "from_hstring: Bad string "& hstring severity error;
+ return result;
+ end function from_hstring;
+
+ -- Same as above, "size_res" is used for it's range only.
+ function from_string (
+ bstring : STRING; -- binary string
+ size_res : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed is
+ begin
+ return from_string (bstring, size_res'high, size_res'low);
+ end function from_string;
+
+ function from_ostring (
+ ostring : STRING; -- Octal string
+ size_res : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed is
+ begin
+ return from_ostring (ostring, size_res'high, size_res'low);
+ end function from_ostring;
+
+ function from_hstring (
+ hstring : STRING; -- hex string
+ size_res : UNRESOLVED_ufixed)
+ return UNRESOLVED_ufixed is
+ begin
+ return from_hstring(hstring, size_res'high, size_res'low);
+ end function from_hstring;
+
+ function from_string (
+ bstring : STRING; -- binary string
+ size_res : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return from_string (bstring, size_res'high, size_res'low);
+ end function from_string;
+
+ function from_ostring (
+ ostring : STRING; -- Octal string
+ size_res : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return from_ostring (ostring, size_res'high, size_res'low);
+ end function from_ostring;
+
+ function from_hstring (
+ hstring : STRING; -- hex string
+ size_res : UNRESOLVED_sfixed)
+ return UNRESOLVED_sfixed is
+ begin
+ return from_hstring (hstring, size_res'high, size_res'low);
+ end function from_hstring;
+
+ -- Direct conversion functions. Example:
+ -- signal uf1 : ufixed (3 downto -3);
+ -- uf1 <= from_string ("0110.100"); -- 6.5
+ -- In this case the "." is not optional, and the size of
+ -- the output must match exactly.
+ -- purpose: Calculate the string boundaries
+ procedure calculate_string_boundry (
+ arg : in STRING; -- input string
+ left_index : out INTEGER; -- left
+ right_index : out INTEGER) is -- right
+ -- examples "10001.111" would return +4, -3
+ -- "07X.44" would return +2, -2 (then the octal routine would multiply)
+ -- "A_B_._C" would return +1, -1 (then the hex routine would multiply)
+ alias xarg : STRING (arg'length downto 1) is arg; -- make it downto range
+ variable l, r : INTEGER; -- internal indexes
+ variable founddot : BOOLEAN := false;
+ begin
+ if arg'length > 0 then
+ l := xarg'high - 1;
+ r := 0;
+ for i in xarg'range loop
+ if xarg(i) = '_' then
+ if r = 0 then
+ l := l - 1;
+ else
+ r := r + 1;
+ end if;
+ elsif xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT then
+ report fixed_generic_pkg'instance_name
+ & "Found a space in the input STRING " & xarg
+ severity error;
+ elsif xarg(i) = '.' then
+ if founddot then
+ report fixed_generic_pkg'instance_name
+ & "Found two binary points in input string " & xarg
+ severity error;
+ else
+ l := l - i;
+ r := -i + 1;
+ founddot := true;
+ end if;
+ end if;
+ end loop;
+ left_index := l;
+ right_index := r;
+ else
+ left_index := 0;
+ right_index := 0;
+ end if;
+ end procedure calculate_string_boundry;
+
+ -- Direct conversion functions. Example:
+ -- signal uf1 : ufixed (3 downto -3);
+ -- uf1 <= from_string ("0110.100"); -- 6.5
+ -- In this case the "." is not optional, and the size of
+ -- the output must match exactly.
+ function from_string (
+ bstring : STRING) -- binary string
+ return UNRESOLVED_ufixed
+ is
+ variable left_index, right_index : INTEGER;
+ begin
+ calculate_string_boundry (bstring, left_index, right_index);
+ return from_string (bstring, left_index, right_index);
+ end function from_string;
+
+ -- Direct octal and hex conversion functions. In this case
+ -- the string lengths must match. Example:
+ -- signal sf1 := sfixed (5 downto -3);
+ -- sf1 <= from_ostring ("71.4") -- -6.5
+ function from_ostring (
+ ostring : STRING) -- Octal string
+ return UNRESOLVED_ufixed
+ is
+ variable left_index, right_index : INTEGER;
+ begin
+ calculate_string_boundry (ostring, left_index, right_index);
+ return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
+ end function from_ostring;
+
+ function from_hstring (
+ hstring : STRING) -- hex string
+ return UNRESOLVED_ufixed
+ is
+ variable left_index, right_index : INTEGER;
+ begin
+ calculate_string_boundry (hstring, left_index, right_index);
+ return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
+ end function from_hstring;
+
+ function from_string (
+ bstring : STRING) -- binary string
+ return UNRESOLVED_sfixed
+ is
+ variable left_index, right_index : INTEGER;
+ begin
+ calculate_string_boundry (bstring, left_index, right_index);
+ return from_string (bstring, left_index, right_index);
+ end function from_string;
+
+ function from_ostring (
+ ostring : STRING) -- Octal string
+ return UNRESOLVED_sfixed
+ is
+ variable left_index, right_index : INTEGER;
+ begin
+ calculate_string_boundry (ostring, left_index, right_index);
+ return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
+ end function from_ostring;
+
+ function from_hstring (
+ hstring : STRING) -- hex string
+ return UNRESOLVED_sfixed
+ is
+ variable left_index, right_index : INTEGER;
+ begin
+ calculate_string_boundry (hstring, left_index, right_index);
+ return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
+ end function from_hstring;
+
+end package body fixed_generic_pkg;