diff options
author | Tristan Gingold <tgingold@free.fr> | 2014-01-04 11:25:55 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2014-01-04 11:25:55 +0100 |
commit | 8c778be42999972dcda1aac95999e0eb1a5e3e9c (patch) | |
tree | c69189bc93c0bd562d6e6814aafb1dfc1fab2f32 /libraries | |
parent | 071b3291e88f05bc06d91fe4ebe88582292d3f0d (diff) | |
download | ghdl-8c778be42999972dcda1aac95999e0eb1a5e3e9c.tar.gz ghdl-8c778be42999972dcda1aac95999e0eb1a5e3e9c.tar.bz2 ghdl-8c778be42999972dcda1aac95999e0eb1a5e3e9c.zip |
Add ieee 2008 packages.
Diffstat (limited to 'libraries')
23 files changed, 34663 insertions, 0 deletions
diff --git a/libraries/ieee2008/README.ieee b/libraries/ieee2008/README.ieee new file mode 100644 index 000000000..ee524913b --- /dev/null +++ b/libraries/ieee2008/README.ieee @@ -0,0 +1,30 @@ +http://standards.ieee.org/news/2013/ieee_1076_vhdl.html + +MODIFICATION TO IEEE 1076™ LICENSING TERMS ALLOWS FOR OPEN USE OF VHDL STANDARD’S SUPPLEMENTAL MATERIAL + +IEEE 1076 working group assists with creation of additional packages for developers to cultivate new hardware-designer tools to expand VHDL systems + +Shuang Yu, Senior Manager, Solutions Marketing ++1 732 981 3424; shuang.yu@ieee.org + +PISCATAWAY, N.J., USA, 16 July 2013 - IEEE, the world's largest professional organization advancing technology for humanity, today announced a licensing term modification to the supplemental materials for IEEE 1076™ “Standard VHDL Language Reference Manual.” The licensing change allows the standard’s supplemental materials or “packages” to be made available to the public without prior authorization from the IEEE Standards Association (IEEE-SA). The supplemental packages provide developers with the necessary machine-readable code to build hardware-designer tools that help create systems using Very High Speed Integrated Circuits (VHSIC) Hardware Description Language (VHDL), which is then used to design electronic systems at the component and board levels. + +By allowing free use of the standard’s VHDL packages each time a new VHDL design is implemented, the new license terms are intended to save developers the time required to request authorization for their legal use in real-world applications. Under the previous terms, users of the IEEE 1076 standard’s packages were required to request permission from the IEEE-SA. The various packages include the definition of standard types, subtypes, natures and constants for hardware modeling. + +“This licensing change is very important to vendors and users of VHDL,” said Stan Krolikoski, chair of the IEEE Computer Society's Design Automation Standards Committee (DASC), which supported the modification to the license for the supplemental materials. “We worked closely with the IEEE 1076 VHDL Analysis and Standardization Working Group to allow anyone to use these files, within the guidelines of the IEEE 1076-2008 standard, of course. The previous header to the standard’s supplemental packages instructed users to request permission from the IEEE-SA for all uses, which is no longer required.” + +The collaboration between the DASC and the IEEE 1076 Working Group to modify the licensing of the supplemental materials to IEEE 1076 was conducted in the spirit of the OpenStand paradigm for global, open standards. Globally adopted design automation standards, such as IEEE 1076, have paved the way for a giant leap forward in industry's ability to define complex electronic solutions and are examples of standards developed under the market-driven OpenStand principles. + +For more information about the IEEE 1076 VHDL Analysis and Standardization Working Group, please visit the Working Group web page. + +Download IEEE 1076’s supplemental materials at the working group web page. IEEE 1076 is available for purchase at the IEEE Standards Store. + +To learn more about IEEE-SA, visit us on Facebook, follow us on Twitter, connect with us on LinkedIn, or on the Standards Insight Blog. + +About the IEEE Standards Association +The IEEE Standards Association, a globally recognized standards-setting body within IEEE, develops consensus standards through an open process that engages industry and brings together a broad stakeholder community. IEEE standards set specifications and best practices based on current scientific and technological knowledge. The IEEE-SA has a portfolio of over 900 active standards and more than 500 standards under development. For more information visit the IEEE-SA Web site. + +About IEEE +IEEE, a large, global technical professional organization, is dedicated to advancing technology for the benefit of humanity. Through its highly cited publications, conferences, technology standards, and professional and educational activities, IEEE is the trusted voice on a wide variety of areas ranging from aerospace systems, computers and telecommunications to biomedical engineering, electric power and consumer electronics. Learn more at the IEEE Web site. external link + +- See more at: http://standards.ieee.org/news/2013/ieee_1076_vhdl.html#sthash.UFLcTc7E.dpuf diff --git a/libraries/ieee2008/fixed_float_types.vhdl b/libraries/ieee2008/fixed_float_types.vhdl new file mode 100644 index 000000000..cbadcdf34 --- /dev/null +++ b/libraries/ieee2008/fixed_float_types.vhdl @@ -0,0 +1,58 @@ +-- -------------------------------------------------------------------- +-- +-- 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 and Floating Point types package +-- +-- Library : This package shall be compiled into a library +-- symbolically named IEEE. +-- +-- Developers: Accellera VHDL-TC and IEEE P1076 Working Group +-- +-- Purpose : Definitions for use in fixed point and floating point +-- arithmetic packages +-- +-- 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) $ +-- -------------------------------------------------------------------- + +package fixed_float_types is + + -- Types used for generics of fixed_generic_pkg + + type fixed_round_style_type is (fixed_round, fixed_truncate); + + type fixed_overflow_style_type is (fixed_saturate, fixed_wrap); + + -- Type used for generics of float_generic_pkg + + -- These are the same as the C FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, + -- and FE_TOWARDZERO floating point rounding macros. + + type round_type is (round_nearest, -- Default, nearest LSB '0' + round_inf, -- Round toward positive infinity + round_neginf, -- Round toward negative infinity + round_zero); -- Round toward zero (truncate) + +end package fixed_float_types; diff --git a/libraries/ieee2008/fixed_generic_pkg-body.vhdl b/libraries/ieee2008/fixed_generic_pkg-body.vhdl new file mode 100644 index 000000000..24842a964 --- /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; diff --git a/libraries/ieee2008/fixed_generic_pkg.vhdl b/libraries/ieee2008/fixed_generic_pkg.vhdl new file mode 100644 index 000000000..2486cbe1c --- /dev/null +++ b/libraries/ieee2008/fixed_generic_pkg.vhdl @@ -0,0 +1,1436 @@ +-- -------------------------------------------------------------------- +-- +-- 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 declaration) +-- : +-- 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 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) $ +-- -------------------------------------------------------------------- + +use STD.TEXTIO.all; +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use IEEE.fixed_float_types.all; + +package fixed_generic_pkg is + generic ( + -- Rounding routine to use in fixed point, fixed_round or fixed_truncate + fixed_round_style : fixed_round_style_type := fixed_round; + -- Overflow routine to use in fixed point, fixed_saturate or fixed_wrap + fixed_overflow_style : fixed_overflow_style_type := fixed_saturate; + -- Extra bits used in divide routines + fixed_guard_bits : NATURAL := 3; + -- If TRUE, then turn off warnings on "X" propagation + no_warning : BOOLEAN := false + ); + + -- Author David Bishop (dbishop@vhdl.org) + constant CopyRightNotice : STRING := + "Copyright 2008 by IEEE. All rights reserved."; + + -- base Unsigned fixed point type, downto direction assumed + type UNRESOLVED_ufixed is array (INTEGER range <>) of STD_ULOGIC; + -- base Signed fixed point type, downto direction assumed + type UNRESOLVED_sfixed is array (INTEGER range <>) of STD_ULOGIC; + + alias U_ufixed is UNRESOLVED_ufixed; + alias U_sfixed is UNRESOLVED_sfixed; + + subtype ufixed is (resolved) UNRESOLVED_ufixed; + subtype sfixed is (resolved) UNRESOLVED_sfixed; + + --=========================================================================== + -- Arithmetic Operators: + --=========================================================================== + + -- Absolute value, 2's complement + -- abs sfixed(a downto b) = sfixed(a+1 downto b) + function "abs" (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- Negation, 2's complement + -- - sfixed(a downto b) = sfixed(a+1 downto b) + function "-" (arg : UNRESOLVED_sfixed)return UNRESOLVED_sfixed; + + -- Addition + -- ufixed(a downto b) + ufixed(c downto d) + -- = ufixed(maximum(a,c)+1 downto minimum(b,d)) + function "+" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- sfixed(a downto b) + sfixed(c downto d) + -- = sfixed(maximum(a,c)+1 downto minimum(b,d)) + function "+" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- Subtraction + -- ufixed(a downto b) - ufixed(c downto d) + -- = ufixed(maximum(a,c)+1 downto minimum(b,d)) + function "-" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- sfixed(a downto b) - sfixed(c downto d) + -- = sfixed(maximum(a,c)+1 downto minimum(b,d)) + function "-" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- Multiplication + -- ufixed(a downto b) * ufixed(c downto d) = ufixed(a+c+1 downto b+d) + function "*" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- sfixed(a downto b) * sfixed(c downto d) = sfixed(a+c+1 downto b+d) + function "*" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- Division + -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1) + function "/" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c) + function "/" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- Remainder + -- ufixed (a downto b) rem ufixed (c downto d) + -- = ufixed (minimum(a,c) downto minimum(b,d)) + function "rem" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- sfixed (a downto b) rem sfixed (c downto d) + -- = sfixed (minimum(a,c) downto minimum(b,d)) + function "rem" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- Modulo + -- ufixed (a downto b) mod ufixed (c downto d) + -- = ufixed (minimum(a,c) downto minimum(b, d)) + function "mod" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- sfixed (a downto b) mod sfixed (c downto d) + -- = sfixed (c downto minimum(b, d)) + function "mod" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + ---------------------------------------------------------------------------- + -- In these routines the "real" or "natural" (integer) + -- are converted into a fixed point number and then the operation is + -- performed. It is assumed that the array will be large enough. + -- If the input is "real" then the real number is converted into a fixed of + -- the same size as the fixed point input. If the number is an "integer" + -- then it is converted into fixed with the range (l'high downto 0). + ---------------------------------------------------------------------------- + + -- ufixed(a downto b) + ufixed(a downto b) = ufixed(a+1 downto b) + function "+" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + + -- ufixed(c downto d) + ufixed(c downto d) = ufixed(c+1 downto d) + function "+" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed(a downto b) + ufixed(a downto 0) = ufixed(a+1 downto minimum(0,b)) + function "+" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed; + + -- ufixed(a downto 0) + ufixed(c downto d) = ufixed(c+1 downto minimum(0,d)) + function "+" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed(a downto b) - ufixed(a downto b) = ufixed(a+1 downto b) + function "-" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + + -- ufixed(c downto d) - ufixed(c downto d) = ufixed(c+1 downto d) + function "-" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed(a downto b) - ufixed(a downto 0) = ufixed(a+1 downto minimum(0,b)) + function "-" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed; + + -- ufixed(a downto 0) + ufixed(c downto d) = ufixed(c+1 downto minimum(0,d)) + function "-" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed(a downto b) * ufixed(a downto b) = ufixed(2a+1 downto 2b) + function "*" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + + -- ufixed(c downto d) * ufixed(c downto d) = ufixed(2c+1 downto 2d) + function "*" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed (a downto b) * ufixed (a downto 0) = ufixed (2a+1 downto b) + function "*" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed; + + -- ufixed (a downto b) * ufixed (a downto 0) = ufixed (2a+1 downto b) + function "*" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed(a downto b) / ufixed(a downto b) = ufixed(a-b downto b-a-1) + function "/" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + + -- ufixed(a downto b) / ufixed(a downto b) = ufixed(a-b downto b-a-1) + function "/" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed(a downto b) / ufixed(a downto 0) = ufixed(a downto b-a-1) + function "/" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed; + + -- ufixed(c downto 0) / ufixed(c downto d) = ufixed(c-d downto -c-1) + function "/" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed (a downto b) rem ufixed (a downto b) = ufixed (a downto b) + function "rem" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + + -- ufixed (c downto d) rem ufixed (c downto d) = ufixed (c downto d) + function "rem" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed (a downto b) rem ufixed (a downto 0) = ufixed (a downto minimum(b,0)) + function "rem" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed; + + -- ufixed (c downto 0) rem ufixed (c downto d) = ufixed (c downto minimum(d,0)) + function "rem" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed (a downto b) mod ufixed (a downto b) = ufixed (a downto b) + function "mod" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + + -- ufixed (c downto d) mod ufixed (c downto d) = ufixed (c downto d) + function "mod" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- ufixed (a downto b) mod ufixed (a downto 0) = ufixed (a downto minimum(b,0)) + function "mod" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed; + + -- ufixed (c downto 0) mod ufixed (c downto d) = ufixed (c downto minimum(d,0)) + function "mod" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + + -- sfixed(a downto b) + sfixed(a downto b) = sfixed(a+1 downto b) + function "+" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + + -- sfixed(c downto d) + sfixed(c downto d) = sfixed(c+1 downto d) + function "+" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed(a downto b) + sfixed(a downto 0) = sfixed(a+1 downto minimum(0,b)) + function "+" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed; + + -- sfixed(c downto 0) + sfixed(c downto d) = sfixed(c+1 downto minimum(0,d)) + function "+" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed(a downto b) - sfixed(a downto b) = sfixed(a+1 downto b) + function "-" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + + -- sfixed(c downto d) - sfixed(c downto d) = sfixed(c+1 downto d) + function "-" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed(a downto b) - sfixed(a downto 0) = sfixed(a+1 downto minimum(0,b)) + function "-" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed; + + -- sfixed(c downto 0) - sfixed(c downto d) = sfixed(c+1 downto minimum(0,d)) + function "-" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed(a downto b) * sfixed(a downto b) = sfixed(2a+1 downto 2b) + function "*" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + + -- sfixed(c downto d) * sfixed(c downto d) = sfixed(2c+1 downto 2d) + function "*" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed(a downto b) * sfixed(a downto 0) = sfixed(2a+1 downto b) + function "*" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed; + + -- sfixed(c downto 0) * sfixed(c downto d) = sfixed(2c+1 downto d) + function "*" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed(a downto b) / sfixed(a downto b) = sfixed(a-b+1 downto b-a) + function "/" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + + -- sfixed(c downto d) / sfixed(c downto d) = sfixed(c-d+1 downto d-c) + function "/" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed(a downto b) / sfixed(a downto 0) = sfixed(a+1 downto b-a) + function "/" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed; + + -- sfixed(c downto 0) / sfixed(c downto d) = sfixed(c-d+1 downto -c) + function "/" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed (a downto b) rem sfixed (a downto b) = sfixed (a downto b) + function "rem" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + + -- sfixed (c downto d) rem sfixed (c downto d) = sfixed (c downto d) + function "rem" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed (a downto b) rem sfixed (a downto 0) = sfixed (a downto minimum(b,0)) + function "rem" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed; + + -- sfixed (c downto 0) rem sfixed (c downto d) = sfixed (c downto minimum(d,0)) + function "rem" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed (a downto b) mod sfixed (a downto b) = sfixed (a downto b) + function "mod" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + + -- sfixed (c downto d) mod sfixed (c downto d) = sfixed (c downto d) + function "mod" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- sfixed (a downto b) mod sfixed (a downto 0) = sfixed (a downto minimum(b,0)) + function "mod" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed; + + -- sfixed (c downto 0) mod sfixed (c downto d) = sfixed (c downto minimum(d,0)) + function "mod" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- 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; + + -- This version of divide gives the user more control + -- 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; + + -- These functions return 1/X + -- 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; + + -- 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; + + -- REM function + -- ufixed (a downto b) rem ufixed (c downto d) + -- = ufixed (minimum(a,c) downto minimum(b,d)) + function remainder ( + l, r : UNRESOLVED_ufixed; + constant round_style : fixed_round_style_type := fixed_round_style; + constant guard_bits : NATURAL := fixed_guard_bits) + return UNRESOLVED_ufixed; + + -- sfixed (a downto b) rem sfixed (c downto d) + -- = sfixed (minimum(a,c) downto minimum(b,d)) + function remainder ( + l, r : UNRESOLVED_sfixed; + constant round_style : fixed_round_style_type := fixed_round_style; + constant guard_bits : NATURAL := fixed_guard_bits) + return UNRESOLVED_sfixed; + + -- mod function + -- ufixed (a downto b) mod ufixed (c downto d) + -- = ufixed (minimum(a,c) downto minimum(b, d)) + function modulo ( + l, r : UNRESOLVED_ufixed; + constant round_style : fixed_round_style_type := fixed_round_style; + constant guard_bits : NATURAL := fixed_guard_bits) + return UNRESOLVED_ufixed; + + -- sfixed (a downto b) mod sfixed (c downto d) + -- = sfixed (c downto minimum(b, d)) + function modulo ( + l, r : UNRESOLVED_sfixed; + 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; + + -- Procedure for those who need an "accumulator" function. + -- add_carry (ufixed(a downto b), ufixed (c downto d)) + -- = ufixed (maximum(a,c) downto minimum(b,d)) + procedure add_carry ( + L, R : in UNRESOLVED_ufixed; + c_in : in STD_ULOGIC; + result : out UNRESOLVED_ufixed; + c_out : out STD_ULOGIC); + + -- add_carry (sfixed(a downto b), sfixed (c downto d)) + -- = sfixed (maximum(a,c) downto minimum(b,d)) + procedure add_carry ( + L, R : in UNRESOLVED_sfixed; + c_in : in STD_ULOGIC; + result : out UNRESOLVED_sfixed; + c_out : out STD_ULOGIC); + + -- Scales the result by a power of 2. Width of input = width of output with + -- the binary point moved. + function scalb (y : UNRESOLVED_ufixed; N : INTEGER) return UNRESOLVED_ufixed; + function scalb (y : UNRESOLVED_ufixed; N : UNRESOLVED_SIGNED) return UNRESOLVED_ufixed; + function scalb (y : UNRESOLVED_sfixed; N : INTEGER) return UNRESOLVED_sfixed; + function scalb (y : UNRESOLVED_sfixed; N : UNRESOLVED_SIGNED) return UNRESOLVED_sfixed; + + function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN; + + --=========================================================================== + -- Comparison Operators + --=========================================================================== + + function ">" (l, r : UNRESOLVED_ufixed) return BOOLEAN; + function ">" (l, r : UNRESOLVED_sfixed) return BOOLEAN; + function "<" (l, r : UNRESOLVED_ufixed) return BOOLEAN; + function "<" (l, r : UNRESOLVED_sfixed) return BOOLEAN; + function "<=" (l, r : UNRESOLVED_ufixed) return BOOLEAN; + function "<=" (l, r : UNRESOLVED_sfixed) return BOOLEAN; + function ">=" (l, r : UNRESOLVED_ufixed) return BOOLEAN; + function ">=" (l, r : UNRESOLVED_sfixed) return BOOLEAN; + function "=" (l, r : UNRESOLVED_ufixed) return BOOLEAN; + function "=" (l, r : UNRESOLVED_sfixed) return BOOLEAN; + function "/=" (l, r : UNRESOLVED_ufixed) return BOOLEAN; + function "/=" (l, r : UNRESOLVED_sfixed) return BOOLEAN; + + function "?=" (l, r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?/=" (l, r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?>" (l, r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?>=" (l, r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?<" (l, r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?<=" (l, r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?=" (l, r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?/=" (l, r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?>" (l, r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?>=" (l, r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?<" (l, r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?<=" (l, r : UNRESOLVED_sfixed) return STD_ULOGIC; + + function std_match (l, r : UNRESOLVED_ufixed) return BOOLEAN; + function std_match (l, r : UNRESOLVED_sfixed) return BOOLEAN; + + -- Overloads the default "maximum" and "minimum" function + + function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + ---------------------------------------------------------------------------- + -- In these compare functions a natural is converted into a + -- fixed point number of the bounds "maximum(l'high,0) downto 0" + ---------------------------------------------------------------------------- + + function "=" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN; + function "/=" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN; + function ">=" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN; + function "<=" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN; + function ">" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN; + function "<" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN; + + function "=" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function "/=" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function ">=" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function "<=" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function ">" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function "<" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN; + + function "?=" (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC; + function "?/=" (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC; + function "?>=" (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC; + function "?<=" (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC; + function "?>" (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC; + function "?<" (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC; + + function "?=" (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?/=" (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?>=" (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?<=" (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?>" (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?<" (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + + function maximum (l : UNRESOLVED_ufixed; r : NATURAL) + return UNRESOLVED_ufixed; + function minimum (l : UNRESOLVED_ufixed; r : NATURAL) + return UNRESOLVED_ufixed; + function maximum (l : NATURAL; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + function minimum (l : NATURAL; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + ---------------------------------------------------------------------------- + -- In these compare functions a real is converted into a + -- fixed point number of the bounds "l'high+1 downto l'low" + ---------------------------------------------------------------------------- + + function "=" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN; + function "/=" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN; + function ">=" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN; + function "<=" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN; + function ">" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN; + function "<" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN; + + function "=" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function "/=" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function ">=" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function "<=" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function ">" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN; + function "<" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN; + + function "?=" (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC; + function "?/=" (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC; + function "?>=" (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC; + function "?<=" (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC; + function "?>" (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC; + function "?<" (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC; + + function "?=" (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?/=" (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?>=" (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?<=" (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?>" (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + function "?<" (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC; + + function maximum (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + function maximum (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function minimum (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed; + function minimum (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + ---------------------------------------------------------------------------- + -- In these compare functions an integer is converted into a + -- fixed point number of the bounds "maximum(l'high,1) downto 0" + ---------------------------------------------------------------------------- + + function "=" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN; + function "/=" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN; + function ">=" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN; + function "<=" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN; + function ">" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN; + function "<" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN; + + function "=" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN; + function "/=" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN; + function ">=" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN; + function "<=" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN; + function ">" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN; + function "<" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN; + + function "?=" (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC; + function "?/=" (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC; + function "?>=" (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC; + function "?<=" (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC; + function "?>" (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC; + function "?<" (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC; + + function "?=" (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?/=" (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?>=" (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?<=" (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?>" (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?<" (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC; + + function maximum (l : UNRESOLVED_sfixed; r : INTEGER) + return UNRESOLVED_sfixed; + function maximum (l : INTEGER; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + function minimum (l : UNRESOLVED_sfixed; r : INTEGER) + return UNRESOLVED_sfixed; + function minimum (l : INTEGER; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + ---------------------------------------------------------------------------- + -- In these compare functions a real is converted into a + -- fixed point number of the bounds "l'high+1 downto l'low" + ---------------------------------------------------------------------------- + + function "=" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN; + function "/=" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN; + function ">=" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN; + function "<=" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN; + function ">" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN; + function "<" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN; + + function "=" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN; + function "/=" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN; + function ">=" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN; + function "<=" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN; + function ">" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN; + function "<" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN; + + function "?=" (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC; + function "?/=" (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC; + function "?>=" (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC; + function "?<=" (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC; + function "?>" (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC; + function "?<" (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC; + + function "?=" (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?/=" (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?>=" (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?<=" (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?>" (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC; + function "?<" (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC; + + function maximum (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + function maximum (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function minimum (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed; + function minimum (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + --=========================================================================== + -- Shift and Rotate Functions. + -- Note that sra and sla are not the same as the BIT_VECTOR version + --=========================================================================== + + function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) + return UNRESOLVED_ufixed; + function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) + return UNRESOLVED_ufixed; + function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) + return UNRESOLVED_ufixed; + function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) + return UNRESOLVED_ufixed; + function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) + return UNRESOLVED_ufixed; + function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER) + return UNRESOLVED_ufixed; + function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) + return UNRESOLVED_sfixed; + function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) + return UNRESOLVED_sfixed; + function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) + return UNRESOLVED_sfixed; + function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) + return UNRESOLVED_sfixed; + function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) + return UNRESOLVED_sfixed; + function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER) + return UNRESOLVED_sfixed; + function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL) + return UNRESOLVED_ufixed; + function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL) + return UNRESOLVED_ufixed; + function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL) + return UNRESOLVED_sfixed; + function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL) + return UNRESOLVED_sfixed; + + ---------------------------------------------------------------------------- + -- logical functions + ---------------------------------------------------------------------------- + + function "not" (l : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function "and" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function "or" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function "nand" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function "nor" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function "xor" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function "xnor" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function "not" (l : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function "and" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function "or" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function "nand" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function "nor" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function "xor" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function "xnor" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- Vector and std_ulogic functions, same as functions in numeric_std + function "and" (l : STD_ULOGIC; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + function "and" (l : UNRESOLVED_ufixed; r : STD_ULOGIC) + return UNRESOLVED_ufixed; + function "or" (l : STD_ULOGIC; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + function "or" (l : UNRESOLVED_ufixed; r : STD_ULOGIC) + return UNRESOLVED_ufixed; + function "nand" (l : STD_ULOGIC; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + function "nand" (l : UNRESOLVED_ufixed; r : STD_ULOGIC) + return UNRESOLVED_ufixed; + function "nor" (l : STD_ULOGIC; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + function "nor" (l : UNRESOLVED_ufixed; r : STD_ULOGIC) + return UNRESOLVED_ufixed; + function "xor" (l : STD_ULOGIC; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + function "xor" (l : UNRESOLVED_ufixed; r : STD_ULOGIC) + return UNRESOLVED_ufixed; + function "xnor" (l : STD_ULOGIC; r : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + function "xnor" (l : UNRESOLVED_ufixed; r : STD_ULOGIC) + return UNRESOLVED_ufixed; + function "and" (l : STD_ULOGIC; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + function "and" (l : UNRESOLVED_sfixed; r : STD_ULOGIC) + return UNRESOLVED_sfixed; + function "or" (l : STD_ULOGIC; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + function "or" (l : UNRESOLVED_sfixed; r : STD_ULOGIC) + return UNRESOLVED_sfixed; + function "nand" (l : STD_ULOGIC; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + function "nand" (l : UNRESOLVED_sfixed; r : STD_ULOGIC) + return UNRESOLVED_sfixed; + function "nor" (l : STD_ULOGIC; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + function "nor" (l : UNRESOLVED_sfixed; r : STD_ULOGIC) + return UNRESOLVED_sfixed; + function "xor" (l : STD_ULOGIC; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + function "xor" (l : UNRESOLVED_sfixed; r : STD_ULOGIC) + return UNRESOLVED_sfixed; + function "xnor" (l : STD_ULOGIC; r : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + function "xnor" (l : UNRESOLVED_sfixed; r : STD_ULOGIC) + return UNRESOLVED_sfixed; + + -- Reduction operators, same as numeric_std functions + function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC; + function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC; + function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC; + function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC; + function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC; + function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC; + function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC; + function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC; + function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC; + function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC; + function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC; + function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC; + + -- returns arg'low-1 if not found + function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC) + return INTEGER; + function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC) + return INTEGER; + + -- returns arg'high+1 if not found + function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC) + return INTEGER; + function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC) + return INTEGER; + + --=========================================================================== + -- RESIZE Functions + --=========================================================================== + -- resizes the number (larger or smaller) + -- The returned result will be ufixed (left_index downto right_index) + -- If "round_style" is fixed_round, then the result will be rounded. + -- If the MSB of the remainder is a "1" AND the LSB of the unrounded result + -- is a '1' or the lower bits of the remainder include a '1' then the result + -- will be increased by the smallest representable number for that type. + -- "overflow_style" can be fixed_saturate or fixed_wrap. + -- In saturate mode, if the number overflows then the largest possible + -- representable number is returned. If wrap mode, then the upper bits + -- of the number are truncated. + + 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; + + -- "size_res" functions create the size of the output from the indices + -- of the "size_res" input. The actual value of "size_res" is not used. + 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; + + -- Note that in "wrap" mode the sign bit is not replicated. Thus the + -- resize of a negative number can have a positive result in wrap mode. + 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; + + 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; + + --=========================================================================== + -- Conversion Functions + --=========================================================================== + + -- integer (natural) to unsigned fixed point. + -- arguments are the upper and lower bounds of the number, thus + -- ufixed (7 downto -3) <= to_ufixed (int, 7, -3); + 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; + + 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; + + -- real to unsigned fixed point + 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) + return UNRESOLVED_ufixed; + + 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) + return UNRESOLVED_ufixed; + + -- unsigned to unsigned fixed point + 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; + + 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; + + -- Performs a conversion. ufixed (arg'range) is returned + function to_ufixed ( + arg : UNRESOLVED_UNSIGNED) -- unsigned + return UNRESOLVED_ufixed; + + -- unsigned fixed point to unsigned + function to_unsigned ( + arg : UNRESOLVED_ufixed; -- fixed 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; + + -- unsigned fixed point to unsigned + function to_unsigned ( + arg : UNRESOLVED_ufixed; -- fixed point input + size_res : UNRESOLVED_UNSIGNED; -- 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_UNSIGNED; + + -- unsigned fixed point to real + function to_real ( + arg : UNRESOLVED_ufixed) -- fixed point input + return REAL; + + -- unsigned fixed point to integer + 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; + + -- Integer to UNRESOLVED_sfixed + 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; + + 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; + + -- Real to sfixed + 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) + return UNRESOLVED_sfixed; + + 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) + return UNRESOLVED_sfixed; + + -- signed to sfixed + 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; + + 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; + + -- signed to sfixed (output assumed to be size of signed input) + function to_sfixed ( + arg : UNRESOLVED_SIGNED) -- signed + return UNRESOLVED_sfixed; + + -- Conversion from ufixed to sfixed + function to_sfixed ( + arg : UNRESOLVED_ufixed) + return UNRESOLVED_sfixed; + + -- signed fixed point to signed + function to_signed ( + arg : UNRESOLVED_sfixed; -- fixed 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; + + -- signed fixed point to signed + function to_signed ( + arg : UNRESOLVED_sfixed; -- fixed 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; + + -- signed fixed point to real + function to_real ( + arg : UNRESOLVED_sfixed) -- fixed point input + return REAL; + + -- signed fixed point 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; + + -- 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' or 'A' (abs), 'n' or 'N' (unary -) + function ufixed_high (left_index, right_index : INTEGER; + operation : CHARACTER := 'X'; + left_index2, right_index2 : INTEGER := 0) + return INTEGER; + + function ufixed_low (left_index, right_index : INTEGER; + operation : CHARACTER := 'X'; + left_index2, right_index2 : INTEGER := 0) + return INTEGER; + + function sfixed_high (left_index, right_index : INTEGER; + operation : CHARACTER := 'X'; + left_index2, right_index2 : INTEGER := 0) + return INTEGER; + + function sfixed_low (left_index, right_index : INTEGER; + operation : CHARACTER := 'X'; + left_index2, right_index2 : INTEGER := 0) + return INTEGER; + + -- 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; + + function ufixed_low (size_res : UNRESOLVED_ufixed; + operation : CHARACTER := 'X'; + size_res2 : UNRESOLVED_ufixed) + return INTEGER; + + function sfixed_high (size_res : UNRESOLVED_sfixed; + operation : CHARACTER := 'X'; + size_res2 : UNRESOLVED_sfixed) + return INTEGER; + + function sfixed_low (size_res : UNRESOLVED_sfixed; + operation : CHARACTER := 'X'; + size_res2 : UNRESOLVED_sfixed) + return INTEGER; + + -- purpose: returns a saturated number + function saturate ( + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_ufixed; + + -- purpose: returns a saturated number + function saturate ( + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_sfixed; + + function saturate ( + size_res : UNRESOLVED_ufixed) -- only the size of this is used + return UNRESOLVED_ufixed; + + function saturate ( + size_res : UNRESOLVED_sfixed) -- only the size of this is used + return UNRESOLVED_sfixed; + + --=========================================================================== + -- Translation Functions + --=========================================================================== + + -- maps meta-logical values + function to_01 ( + s : UNRESOLVED_ufixed; -- fixed point input + constant XMAP : STD_ULOGIC := '0') -- Map x to + return UNRESOLVED_ufixed; + + -- maps meta-logical values + function to_01 ( + s : UNRESOLVED_sfixed; -- fixed point input + constant XMAP : STD_ULOGIC := '0') -- Map x to + return UNRESOLVED_sfixed; + + function Is_X (arg : UNRESOLVED_ufixed) return BOOLEAN; + function Is_X (arg : UNRESOLVED_sfixed) return BOOLEAN; + function to_X01 (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function to_X01 (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function to_X01Z (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function to_X01Z (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + function to_UX01 (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed; + function to_UX01 (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed; + + -- straight vector conversion routines, needed for synthesis. + -- These functions are here so that a std_logic_vector can be + -- converted to and from sfixed and ufixed. Note that you can + -- not convert these vectors because of their negative index. + + function to_slv ( + arg : UNRESOLVED_ufixed) -- fixed point vector + return STD_LOGIC_VECTOR; + alias to_StdLogicVector is to_slv [UNRESOLVED_ufixed + return STD_LOGIC_VECTOR]; + alias to_Std_Logic_Vector is to_slv [UNRESOLVED_ufixed + return STD_LOGIC_VECTOR]; + + function to_slv ( + arg : UNRESOLVED_sfixed) -- fixed point vector + return STD_LOGIC_VECTOR; + alias to_StdLogicVector is to_slv [UNRESOLVED_sfixed + return STD_LOGIC_VECTOR]; + alias to_Std_Logic_Vector is to_slv [UNRESOLVED_sfixed + return STD_LOGIC_VECTOR]; + + function to_sulv ( + arg : UNRESOLVED_ufixed) -- fixed point vector + return STD_ULOGIC_VECTOR; + alias to_StdULogicVector is to_sulv [UNRESOLVED_ufixed + return STD_ULOGIC_VECTOR]; + alias to_Std_ULogic_Vector is to_sulv [UNRESOLVED_ufixed + return STD_ULOGIC_VECTOR]; + + function to_sulv ( + arg : UNRESOLVED_sfixed) -- fixed point vector + return STD_ULOGIC_VECTOR; + alias to_StdULogicVector is to_sulv [UNRESOLVED_sfixed + return STD_ULOGIC_VECTOR]; + alias to_Std_ULogic_Vector is to_sulv [UNRESOLVED_sfixed + return STD_ULOGIC_VECTOR]; + + function to_ufixed ( + arg : STD_ULOGIC_VECTOR; -- shifted vector + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_ufixed; + + function to_ufixed ( + arg : STD_ULOGIC_VECTOR; -- shifted vector + size_res : UNRESOLVED_ufixed) -- for size only + return UNRESOLVED_ufixed; + + function to_sfixed ( + arg : STD_ULOGIC_VECTOR; -- shifted vector + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_sfixed; + + function to_sfixed ( + arg : STD_ULOGIC_VECTOR; -- shifted vector + size_res : UNRESOLVED_sfixed) -- for size only + return UNRESOLVED_sfixed; + + -- 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; + + -- signed fixed point + function to_SFix ( + arg : STD_ULOGIC_VECTOR; + width : NATURAL; -- width of vector + fraction : NATURAL) -- width of fraction + return UNRESOLVED_sfixed; + + -- 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; + + function UFix_low (width, fraction : NATURAL; + operation : CHARACTER := 'X'; + width2, fraction2 : NATURAL := 0) + return INTEGER; + + -- Same as above but for signed fixed point. Note that the width + -- of a signed fixed point number ignores the sign bit, thus + -- width = sxxx'length-1 + + function SFix_high (width, fraction : NATURAL; + operation : CHARACTER := 'X'; + width2, fraction2 : NATURAL := 0) + return INTEGER; + + function SFix_low (width, fraction : NATURAL; + operation : CHARACTER := 'X'; + width2, fraction2 : NATURAL := 0) + return INTEGER; + + --=========================================================================== + -- string and textio Functions + --=========================================================================== + + -- 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); + + -- 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); + + procedure READ(L : inout LINE; + VALUE : out UNRESOLVED_ufixed); + + procedure READ(L : inout LINE; + VALUE : out UNRESOLVED_ufixed; + GOOD : out BOOLEAN); + + procedure READ(L : inout LINE; + VALUE : out UNRESOLVED_sfixed); + + procedure READ(L : inout LINE; + VALUE : out UNRESOLVED_sfixed; + GOOD : out BOOLEAN); + + alias bwrite is WRITE [LINE, UNRESOLVED_ufixed, SIDE, width]; + alias bwrite is WRITE [LINE, UNRESOLVED_sfixed, SIDE, width]; + alias bread is READ [LINE, UNRESOLVED_ufixed]; + alias bread is READ [LINE, UNRESOLVED_ufixed, BOOLEAN]; + alias bread is READ [LINE, UNRESOLVED_sfixed]; + alias bread is READ [LINE, UNRESOLVED_sfixed, BOOLEAN]; + alias BINARY_WRITE is WRITE [LINE, UNRESOLVED_ufixed, SIDE, width]; + alias BINARY_WRITE is WRITE [LINE, UNRESOLVED_sfixed, SIDE, width]; + alias BINARY_READ is READ [LINE, UNRESOLVED_ufixed, BOOLEAN]; + alias BINARY_READ is READ [LINE, UNRESOLVED_ufixed]; + alias BINARY_READ is READ [LINE, UNRESOLVED_sfixed, BOOLEAN]; + alias BINARY_READ is READ [LINE, UNRESOLVED_sfixed]; + + -- 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); + + procedure OWRITE ( + L : inout LINE; -- input line + VALUE : in UNRESOLVED_sfixed; -- fixed point input + JUSTIFIED : in SIDE := right; + FIELD : in WIDTH := 0); + + procedure OREAD(L : inout LINE; + VALUE : out UNRESOLVED_ufixed); + + procedure OREAD(L : inout LINE; + VALUE : out UNRESOLVED_ufixed; + GOOD : out BOOLEAN); + + procedure OREAD(L : inout LINE; + VALUE : out UNRESOLVED_sfixed); + + procedure OREAD(L : inout LINE; + VALUE : out UNRESOLVED_sfixed; + GOOD : out BOOLEAN); + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_ufixed, BOOLEAN]; + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_ufixed]; + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_sfixed, BOOLEAN]; + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_sfixed]; + alias OCTAL_WRITE is OWRITE [LINE, UNRESOLVED_ufixed, SIDE, WIDTH]; + alias OCTAL_WRITE is OWRITE [LINE, UNRESOLVED_sfixed, SIDE, WIDTH]; + + -- 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); + + -- 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); + + procedure HREAD(L : inout LINE; + VALUE : out UNRESOLVED_ufixed); + + procedure HREAD(L : inout LINE; + VALUE : out UNRESOLVED_ufixed; + GOOD : out BOOLEAN); + + procedure HREAD(L : inout LINE; + VALUE : out UNRESOLVED_sfixed); + + procedure HREAD(L : inout LINE; + VALUE : out UNRESOLVED_sfixed; + GOOD : out BOOLEAN); + alias HEX_READ is HREAD [LINE, UNRESOLVED_ufixed, BOOLEAN]; + alias HEX_READ is HREAD [LINE, UNRESOLVED_sfixed, BOOLEAN]; + alias HEX_READ is HREAD [LINE, UNRESOLVED_ufixed]; + alias HEX_READ is HREAD [LINE, UNRESOLVED_sfixed]; + alias HEX_WRITE is HWRITE [LINE, UNRESOLVED_ufixed, SIDE, WIDTH]; + alias HEX_WRITE is HWRITE [LINE, UNRESOLVED_sfixed, SIDE, WIDTH]; + + -- returns a string, useful for: + -- assert (x = y) report "error found " & to_string(x) severity error; + function to_string (value : UNRESOLVED_ufixed) return STRING; + + alias to_bstring is to_string [UNRESOLVED_ufixed return STRING]; + alias TO_BINARY_STRING is TO_STRING [UNRESOLVED_ufixed return STRING]; + + function to_ostring (value : UNRESOLVED_ufixed) return STRING; + alias TO_OCTAL_STRING is TO_OSTRING [UNRESOLVED_ufixed return STRING]; + + function to_hstring (value : UNRESOLVED_ufixed) return STRING; + alias TO_HEX_STRING is TO_HSTRING [UNRESOLVED_ufixed return STRING]; + + function to_string (value : UNRESOLVED_sfixed) return STRING; + alias to_bstring is to_string [UNRESOLVED_sfixed return STRING]; + alias TO_BINARY_STRING is TO_STRING [UNRESOLVED_sfixed return STRING]; + + function to_ostring (value : UNRESOLVED_sfixed) return STRING; + alias TO_OCTAL_STRING is TO_OSTRING [UNRESOLVED_sfixed return STRING]; + + function to_hstring (value : UNRESOLVED_sfixed) return STRING; + alias TO_HEX_STRING is TO_HSTRING [UNRESOLVED_sfixed return STRING]; + + -- 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; + alias from_bstring is from_string [STRING, INTEGER, INTEGER + return UNRESOLVED_ufixed]; + alias from_binary_string is from_string [STRING, INTEGER, INTEGER + return UNRESOLVED_ufixed]; + + -- 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; + alias from_octal_string is from_ostring [STRING, INTEGER, INTEGER + return UNRESOLVED_ufixed]; + + function from_hstring ( + hstring : STRING; -- hex string + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_ufixed; + alias from_hex_string is from_hstring [STRING, INTEGER, INTEGER + return UNRESOLVED_ufixed]; + + function from_string ( + bstring : STRING; -- binary string + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_sfixed; + alias from_bstring is from_string [STRING, INTEGER, INTEGER + return UNRESOLVED_sfixed]; + alias from_binary_string is from_string [STRING, INTEGER, INTEGER + return UNRESOLVED_sfixed]; + + function from_ostring ( + ostring : STRING; -- Octal string + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_sfixed; + alias from_octal_string is from_ostring [STRING, INTEGER, INTEGER + return UNRESOLVED_sfixed]; + + function from_hstring ( + hstring : STRING; -- hex string + constant left_index : INTEGER; + constant right_index : INTEGER) + return UNRESOLVED_sfixed; + alias from_hex_string is from_hstring [STRING, INTEGER, INTEGER + return UNRESOLVED_sfixed]; + + -- 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; + alias from_bstring is from_string [STRING, UNRESOLVED_ufixed + return UNRESOLVED_ufixed]; + alias from_binary_string is from_string [STRING, UNRESOLVED_ufixed + return UNRESOLVED_ufixed]; + + function from_ostring ( + ostring : STRING; -- Octal string + size_res : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + alias from_octal_string is from_ostring [STRING, UNRESOLVED_ufixed + return UNRESOLVED_ufixed]; + + function from_hstring ( + hstring : STRING; -- hex string + size_res : UNRESOLVED_ufixed) + return UNRESOLVED_ufixed; + alias from_hex_string is from_hstring [STRING, UNRESOLVED_ufixed + return UNRESOLVED_ufixed]; + + function from_string ( + bstring : STRING; -- binary string + size_res : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + alias from_bstring is from_string [STRING, UNRESOLVED_sfixed + return UNRESOLVED_sfixed]; + alias from_binary_string is from_string [STRING, UNRESOLVED_sfixed + return UNRESOLVED_sfixed]; + + function from_ostring ( + ostring : STRING; -- Octal string + size_res : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + alias from_octal_string is from_ostring [STRING, UNRESOLVED_sfixed + return UNRESOLVED_sfixed]; + + function from_hstring ( + hstring : STRING; -- hex string + size_res : UNRESOLVED_sfixed) + return UNRESOLVED_sfixed; + alias from_hex_string is from_hstring [STRING, UNRESOLVED_sfixed + return UNRESOLVED_sfixed]; + + -- 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; + alias from_bstring is from_string [STRING return UNRESOLVED_ufixed]; + alias from_binary_string is from_string [STRING return UNRESOLVED_ufixed]; + + -- 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; + alias from_octal_string is from_ostring [STRING return UNRESOLVED_ufixed]; + + function from_hstring ( + hstring : STRING) -- hex string + return UNRESOLVED_ufixed; + alias from_hex_string is from_hstring [STRING return UNRESOLVED_ufixed]; + + function from_string ( + bstring : STRING) -- binary string + return UNRESOLVED_sfixed; + alias from_bstring is from_string [STRING return UNRESOLVED_sfixed]; + alias from_binary_string is from_string [STRING return UNRESOLVED_sfixed]; + + function from_ostring ( + ostring : STRING) -- Octal string + return UNRESOLVED_sfixed; + alias from_octal_string is from_ostring [STRING return UNRESOLVED_sfixed]; + + function from_hstring ( + hstring : STRING) -- hex string + return UNRESOLVED_sfixed; + alias from_hex_string is from_hstring [STRING return UNRESOLVED_sfixed]; + +end package fixed_generic_pkg; diff --git a/libraries/ieee2008/fixed_pkg.vhdl b/libraries/ieee2008/fixed_pkg.vhdl new file mode 100644 index 000000000..a77cd280f --- /dev/null +++ b/libraries/ieee2008/fixed_pkg.vhdl @@ -0,0 +1,48 @@ +-- -------------------------------------------------------------------- +-- +-- 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 (Instantiated package declaration) +-- : +-- 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 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; + +package fixed_pkg is new IEEE.fixed_generic_pkg + generic map ( + fixed_round_style => IEEE.fixed_float_types.fixed_round, + fixed_overflow_style => IEEE.fixed_float_types.fixed_saturate, + fixed_guard_bits => 3, + no_warning => false + ); diff --git a/libraries/ieee2008/float_generic_pkg-body.vhdl b/libraries/ieee2008/float_generic_pkg-body.vhdl new file mode 100644 index 000000000..635454675 --- /dev/null +++ b/libraries/ieee2008/float_generic_pkg-body.vhdl @@ -0,0 +1,5712 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Floating-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 floating point +-- : 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) $ +-- -------------------------------------------------------------------- + +package body float_generic_pkg is + + -- Author David Bishop (dbishop@vhdl.org) + ----------------------------------------------------------------------------- + -- type declarations + ----------------------------------------------------------------------------- + + -- This deferred constant will tell you if the package body is synthesizable + -- or implemented as real numbers, set to "true" if synthesizable. + constant fphdlsynth_or_real : BOOLEAN := true; -- deferred constant + + -- types of boundary conditions + type boundary_type is (normal, infinity, zero, denormal); + + -- null range array constant + constant NAFP : UNRESOLVED_float (0 downto 1) := (others => '0'); + constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0'); + + -- Special version of "minimum" to do some boundary checking + function mine (L, R : INTEGER) + return INTEGER is + begin -- function minimum + if (L = INTEGER'low or R = INTEGER'low) then + report float_generic_pkg'instance_name + & " Unbounded number passed, was a literal used?" + severity error; + return 0; + end if; + return minimum (L, R); + end function mine; + + -- Generates the base number for the exponent normalization offset. + function gen_expon_base ( + constant exponent_width : NATURAL) + return SIGNED + is + variable result : SIGNED (exponent_width-1 downto 0); + begin + result := (others => '1'); + result (exponent_width-1) := '0'; + return result; + end function gen_expon_base; + + -- Integer version of the "log2" command (contributed by Peter Ashenden) + function log2 (A : NATURAL) return NATURAL is + variable quotient : NATURAL; + variable result : NATURAL := 0; + begin + quotient := A / 2; + while quotient > 0 loop + quotient := quotient / 2; + result := result + 1; + end loop; + return result; + end function log2; + + -- Function similar to the ILOGB function in MATH_REAL + function log2 (A : REAL) return INTEGER is + variable Y : REAL; + variable N : INTEGER := 0; + begin + if (A = 1.0 or A = 0.0) then + return 0; + end if; + Y := A; + if(A > 1.0) then + while Y >= 2.0 loop + Y := Y / 2.0; + N := N + 1; + end loop; + return N; + end if; + -- O < Y < 1 + while Y < 1.0 loop + Y := Y * 2.0; + N := N - 1; + end loop; + return N; + end function log2; + + -- purpose: Test the boundary conditions of a Real number + procedure test_boundary ( + arg : in REAL; -- Input, converted to real + constant fraction_width : in NATURAL; -- length of FP output fraction + constant exponent_width : in NATURAL; -- length of FP exponent + constant denormalize : in BOOLEAN := true; -- Use IEEE extended FP + variable btype : out boundary_type; + variable log2i : out INTEGER + ) is + constant expon_base : SIGNED (exponent_width-1 downto 0) := + gen_expon_base(exponent_width); -- exponent offset + constant exp_min : SIGNED (12 downto 0) := + -(resize(expon_base, 13)) + 1; -- Minimum normal exponent + constant exp_ext_min : SIGNED (12 downto 0) := + exp_min - fraction_width; -- Minimum for denormal exponent + variable log2arg : INTEGER; -- log2 of argument + begin -- function test_boundary + -- Check to see if the exponent is big enough + -- Note that the argument is always an absolute value at this point. + log2arg := log2(arg); + if arg = 0.0 then + btype := zero; + elsif exponent_width > 11 then -- Exponent for Real is 11 (64 bit) + btype := normal; + else + if log2arg < to_integer(exp_min) then + if denormalize then + if log2arg < to_integer(exp_ext_min) then + btype := zero; + else + btype := denormal; + end if; + else + if log2arg < to_integer(exp_min)-1 then + btype := zero; + else + btype := normal; -- Can still represent this number + end if; + end if; + elsif exponent_width < 11 then + if log2arg > to_integer(expon_base)+1 then + btype := infinity; + else + btype := normal; + end if; + else + btype := normal; + end if; + end if; + log2i := log2arg; + end procedure test_boundary; + + -- purpose: Rounds depending on the state of the "round_style" + -- Logic taken from + -- "What Every Computer Scientist Should Know About Floating Point Arithmetic" + -- by David Goldberg (1991) + function check_round ( + fract_in : STD_ULOGIC; -- input fraction + sign : STD_ULOGIC; -- sign bit + remainder : UNSIGNED; -- remainder to round from + sticky : STD_ULOGIC := '0'; -- Sticky bit + constant round_style : round_type) -- rounding type + return BOOLEAN + is + variable result : BOOLEAN; + variable or_reduced : STD_ULOGIC; + begin -- function check_round + result := false; + if (remainder'length > 0) then -- if remainder in a null array + or_reduced := or (remainder & sticky); + rounding_case : case round_style is + when round_nearest => -- Round Nearest, default mode + if remainder(remainder'high) = '1' then -- round + if (remainder'length > 1) then + if ((or (remainder(remainder'high-1 + downto remainder'low)) = '1' + or sticky = '1') + or fract_in = '1') then + -- Make the bottom bit zero if possible if we are at 1/2 + result := true; + end if; + else + result := (fract_in = '1' or sticky = '1'); + end if; + end if; + when round_inf => -- round up if positive, else truncate. + if or_reduced = '1' and sign = '0' then + result := true; + end if; + when round_neginf => -- round down if negative, else truncate. + if or_reduced = '1' and sign = '1' then + result := true; + end if; + when round_zero => -- round toward 0 Truncate + null; + end case rounding_case; + end if; + return result; + end function check_round; + + -- purpose: Rounds depending on the state of the "round_style" + -- unsigned version + procedure fp_round ( + fract_in : in UNSIGNED; -- input fraction + expon_in : in SIGNED; -- input exponent + fract_out : out UNSIGNED; -- output fraction + expon_out : out SIGNED) is -- output exponent + begin -- procedure fp_round + if and (fract_in) = '1' then -- Fraction is all "1" + expon_out := expon_in + 1; + fract_out := to_unsigned(0, fract_out'high+1); + else + expon_out := expon_in; + fract_out := fract_in + 1; + end if; + end procedure fp_round; + + -- This version of break_number doesn't call "classfp" + procedure break_number ( -- internal version + arg : in UNRESOLVED_float; + fptyp : in valid_fpstate; + denormalize : in BOOLEAN := true; + fract : out UNSIGNED; + expon : out SIGNED) is + constant fraction_width : NATURAL := -arg'low; -- length of FP output fraction + constant exponent_width : NATURAL := arg'high; -- length of FP output exponent + constant expon_base : SIGNED (exponent_width-1 downto 0) := + gen_expon_base(exponent_width); -- exponent offset + variable exp : SIGNED (expon'range); + begin + fract (fraction_width-1 downto 0) := + UNSIGNED (to_slv(arg(-1 downto -fraction_width))); + breakcase : case fptyp is + when pos_zero | neg_zero => + fract (fraction_width) := '0'; + exp := -expon_base; + when pos_denormal | neg_denormal => + if denormalize then + exp := -expon_base; + fract (fraction_width) := '0'; + else + exp := -expon_base - 1; + fract (fraction_width) := '1'; + end if; + when pos_normal | neg_normal | pos_inf | neg_inf => + fract (fraction_width) := '1'; + exp := SIGNED(arg(exponent_width-1 downto 0)); + exp (exponent_width-1) := not exp(exponent_width-1); + when others => + assert NO_WARNING + report FLOAT_GENERIC_PKG'instance_name + & "BREAK_NUMBER: " & + "Meta state detected in fp_break_number process" + severity warning; + -- complete the case, if a NAN goes in, a NAN comes out. + exp := (others => '1'); + fract (fraction_width) := '1'; + end case breakcase; + expon := exp; + end procedure break_number; + + -- purpose: floating point to UNSIGNED + -- Used by to_integer, to_unsigned, and to_signed functions + procedure float_to_unsigned ( + arg : in UNRESOLVED_float; -- floating point input + variable sign : out STD_ULOGIC; -- sign of output + variable frac : out UNSIGNED; -- unsigned biased output + constant denormalize : in BOOLEAN; -- turn on denormalization + constant bias : in NATURAL; -- bias for fixed point + constant round_style : in round_type) is -- rounding method + constant fraction_width : INTEGER := -mine(arg'low, arg'low); -- length of FP output fraction + constant exponent_width : INTEGER := arg'high; -- length of FP output exponent + variable fract : UNSIGNED (frac'range); -- internal version of frac + variable isign : STD_ULOGIC; -- internal version of sign + variable exp : INTEGER; -- Exponent + variable expon : SIGNED (exponent_width-1 downto 0); -- Vectorized exp + -- Base to divide fraction by + variable frac_shift : UNSIGNED (frac'high+3 downto 0); -- Fraction shifted + variable shift : INTEGER; + variable remainder : UNSIGNED (2 downto 0); + variable round : STD_ULOGIC; -- round BIT + begin + isign := to_x01(arg(arg'high)); + -- exponent /= '0', normal floating point + expon := to_01(SIGNED(arg (exponent_width-1 downto 0)), 'X'); + expon(exponent_width-1) := not expon(exponent_width-1); + exp := to_integer (expon); + -- Figure out the fraction + fract := (others => '0'); -- fill with zero + fract (fract'high) := '1'; -- Add the "1.0". + shift := (fract'high-1) - exp; + if fraction_width > fract'high then -- Can only use size-2 bits + fract (fract'high-1 downto 0) := UNSIGNED (to_slv (arg(-1 downto + -fract'high))); + else -- can use all bits + fract (fract'high-1 downto fract'high-fraction_width) := + UNSIGNED (to_slv (arg(-1 downto -fraction_width))); + end if; + frac_shift := fract & "000"; + if shift < 0 then -- Overflow + fract := (others => '1'); + else + frac_shift := shift_right (frac_shift, shift); + fract := frac_shift (frac_shift'high downto 3); + remainder := frac_shift (2 downto 0); + -- round (round_zero will bypass this and truncate) + case round_style is + when round_nearest => + round := remainder(2) and + (fract (0) or (or (remainder (1 downto 0)))); + when round_inf => + round := remainder(2) and not isign; + when round_neginf => + round := remainder(2) and isign; + when others => + round := '0'; + end case; + if round = '1' then + fract := fract + 1; + end if; + end if; + frac := fract; + sign := isign; + end procedure float_to_unsigned; + + -- purpose: returns a part of a vector, this function is here because + -- or (fractr (to_integer(shiftx) downto 0)); + -- can't be synthesized in some synthesis tools. + function smallfract ( + arg : UNSIGNED; + shift : NATURAL) + return STD_ULOGIC + is + variable orx : STD_ULOGIC; + begin + orx := arg(shift); + for i in arg'range loop + if i < shift then + orx := arg(i) or orx; + end if; + end loop; + return orx; + end function smallfract; + --------------------------------------------------------------------------- + -- Visible functions + --------------------------------------------------------------------------- + + -- purpose: converts the negative index to a positive one + -- negative indices are illegal in 1164 and 1076.3 + function to_sulv ( + arg : UNRESOLVED_float) -- fp vector + return STD_ULOGIC_VECTOR + is + variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0); + begin -- function to_std_ulogic_vector + if arg'length < 1 then + return NSLV; + end if; + result := STD_ULOGIC_VECTOR (arg); + return result; + end function to_sulv; + + -- Converts an fp into an SULV + function to_slv (arg : UNRESOLVED_float) return STD_LOGIC_VECTOR is + begin + return to_sulv (arg); + end function to_slv; + + -- purpose: normalizes a floating point number + -- This version assumes an "unsigned" input with + function normalize ( + fract : UNRESOLVED_UNSIGNED; -- fraction, unnormalized + expon : UNRESOLVED_SIGNED; -- exponent, normalized by -1 + sign : STD_ULOGIC; -- sign BIT + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + constant exponent_width : NATURAL := float_exponent_width; -- size of output exponent + constant fraction_width : NATURAL := float_fraction_width; -- size of output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float + is + variable sfract : UNSIGNED (fract'high downto 0); -- shifted fraction + variable rfract : UNSIGNED (fraction_width-1 downto 0); -- fraction + variable exp : SIGNED (exponent_width+1 downto 0); -- exponent + variable rexp : SIGNED (exponent_width+1 downto 0); -- result exponent + variable rexpon : UNSIGNED (exponent_width-1 downto 0); -- exponent + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); -- result + variable shiftr : INTEGER; -- shift amount + variable stickyx : STD_ULOGIC; -- version of sticky + constant expon_base : SIGNED (exponent_width-1 downto 0) := + gen_expon_base(exponent_width); -- exponent offset + variable round, zerores, infres : BOOLEAN; + begin -- function normalize + zerores := false; + infres := false; + round := false; + shiftr := find_leftmost (to_01(fract), '1') -- Find the first "1" + - fraction_width - nguard; -- subtract the length we want + exp := resize (expon, exp'length) + shiftr; + if (or (fract) = '0') then -- Zero + zerores := true; + elsif ((exp <= -resize(expon_base, exp'length)-1) and denormalize) + or ((exp < -resize(expon_base, exp'length)-1) and not denormalize) then + if (exp >= -resize(expon_base, exp'length)-fraction_width-1) + and denormalize then + exp := -resize(expon_base, exp'length)-1; + shiftr := -to_integer (expon + expon_base); -- new shift + else -- return zero + zerores := true; + end if; + elsif (exp > expon_base-1) then -- infinity + infres := true; + end if; + if zerores then + result := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif infres then + result := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + sfract := fract srl shiftr; -- shift + if shiftr > 0 then +-- stickyx := sticky or (or (fract (shiftr-1 downto 0))); + stickyx := sticky or smallfract (fract, shiftr-1); + else + stickyx := sticky; + end if; + if nguard > 0 then + round := check_round ( + fract_in => sfract (nguard), + sign => sign, + remainder => sfract(nguard-1 downto 0), + sticky => stickyx, + round_style => round_style); + end if; + if round then + fp_round(fract_in => sfract (fraction_width-1+nguard downto nguard), + expon_in => exp(rexp'range), + fract_out => rfract, + expon_out => rexp); + else + rfract := sfract (fraction_width-1+nguard downto nguard); + rexp := exp(rexp'range); + end if; + -- result + rexpon := UNSIGNED (rexp(exponent_width-1 downto 0)); + rexpon (exponent_width-1) := not rexpon(exponent_width-1); + result (rexpon'range) := UNRESOLVED_float(rexpon); + result (-1 downto -fraction_width) := UNRESOLVED_float(rfract); + end if; + result (exponent_width) := sign; -- sign BIT + return result; + end function normalize; + + -- purpose: normalizes a floating point number + -- This version assumes a "ufixed" input + function normalize ( + fract : UNRESOLVED_ufixed; -- unsigned fixed point + expon : UNRESOLVED_SIGNED; -- exponent, normalized by -1 + sign : STD_ULOGIC; -- sign bit + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + constant exponent_width : NATURAL := float_exponent_width; -- size of output exponent + constant fraction_width : NATURAL := float_fraction_width; -- size of output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable arguns : UNSIGNED (fract'high + fraction_width + nguard + downto 0) := (others => '0'); + begin -- function normalize + arguns (arguns'high downto maximum (arguns'high-fract'length+1, 0)) := + UNSIGNED (to_slv (fract)); + result := normalize (fract => arguns, + expon => expon, + sign => sign, + sticky => sticky, + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => nguard); + return result; + end function normalize; + + -- purpose: normalizes a floating point number + -- This version assumes a "ufixed" input with a "size_res" input + function normalize ( + fract : UNRESOLVED_ufixed; -- unsigned fixed point + expon : UNRESOLVED_SIGNED; -- exponent, normalized by -1 + sign : STD_ULOGIC; -- sign bit + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + size_res : UNRESOLVED_float; -- used for sizing only + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -size_res'low; + constant exponent_width : NATURAL := size_res'high; + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable arguns : UNSIGNED (fract'high + fraction_width + nguard + downto 0) := (others => '0'); + begin -- function normalize + arguns (arguns'high downto maximum (arguns'high-fract'length+1, 0)) := + UNSIGNED (to_slv (fract)); + result := normalize (fract => arguns, + expon => expon, + sign => sign, + sticky => sticky, + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => nguard); + return result; + end function normalize; + + -- Regular "normalize" function with a "size_res" input. + function normalize ( + fract : UNRESOLVED_UNSIGNED; -- unsigned + expon : UNRESOLVED_SIGNED; -- exponent - 1, normalized + sign : STD_ULOGIC; -- sign bit + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + size_res : UNRESOLVED_float; -- used for sizing only + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float is + begin + return normalize (fract => fract, + expon => expon, + sign => sign, + sticky => sticky, + fraction_width => -size_res'low, + exponent_width => size_res'high, + round_style => round_style, + denormalize => denormalize, + nguard => nguard); + end function normalize; + + -- Returns the class which X falls into + function Classfp ( + x : UNRESOLVED_float; -- floating point input + check_error : BOOLEAN := float_check_error) -- check for errors + return valid_fpstate + is + constant fraction_width : INTEGER := -mine(x'low, x'low); -- length of FP output fraction + constant exponent_width : INTEGER := x'high; -- length of FP output exponent + variable arg : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- classfp + if (arg'length < 1 or fraction_width < 3 or exponent_width < 3 + or x'left < x'right) then + report FLOAT_GENERIC_PKG'instance_name + & "CLASSFP: " & + "Floating point number detected with a bad range" + severity error; + return isx; + end if; + -- Check for "X". + arg := to_01 (x, 'X'); + if (arg(0) = 'X') then + return isx; -- If there is an X in the number + -- Special cases, check for illegal number + elsif check_error and + (and (STD_ULOGIC_VECTOR (arg (exponent_width-1 downto 0))) + = '1') then -- Exponent is all "1". + if or (to_slv (arg (-1 downto -fraction_width))) + /= '0' then -- Fraction must be all "0" or this is not a number. + if (arg(-1) = '1') then -- From "W. Khan - IEEE standard + return nan; -- 754 binary FP Signaling nan (Not a number) + else + return quiet_nan; + end if; + -- Check for infinity + elsif arg(exponent_width) = '0' then + return pos_inf; -- Positive infinity + else + return neg_inf; -- Negative infinity + end if; + -- check for "0" + elsif or (STD_LOGIC_VECTOR (arg (exponent_width-1 downto 0))) + = '0' then -- Exponent is all "0" + if or (to_slv (arg (-1 downto -fraction_width))) + = '0' then -- Fraction is all "0" + if arg(exponent_width) = '0' then + return pos_zero; -- Zero + else + return neg_zero; + end if; + else + if arg(exponent_width) = '0' then + return pos_denormal; -- Denormal number (ieee extended fp) + else + return neg_denormal; + end if; + end if; + else + if arg(exponent_width) = '0' then + return pos_normal; -- Normal FP number + else + return neg_normal; + end if; + end if; + end function Classfp; + + procedure break_number ( + arg : in UNRESOLVED_float; + denormalize : in BOOLEAN := float_denormalize; + check_error : in BOOLEAN := float_check_error; + fract : out UNRESOLVED_UNSIGNED; + expon : out UNRESOLVED_SIGNED; + sign : out STD_ULOGIC) is + constant fraction_width : NATURAL := -mine(arg'low, arg'low); -- length of FP output fraction + variable fptyp : valid_fpstate; + begin + fptyp := Classfp (arg, check_error); + sign := to_x01(arg(arg'high)); + break_number ( + arg => arg, + fptyp => fptyp, + denormalize => denormalize, + fract => fract, + expon => expon); + end procedure break_number; + + procedure break_number ( + arg : in UNRESOLVED_float; + denormalize : in BOOLEAN := float_denormalize; + check_error : in BOOLEAN := float_check_error; + fract : out UNRESOLVED_ufixed; -- 1 downto -fraction_width + expon : out UNRESOLVED_SIGNED; -- exponent_width-1 downto 0 + sign : out STD_ULOGIC) is + constant fraction_width : NATURAL := -mine(arg'low, arg'low); -- length of FP output fraction + variable fptyp : valid_fpstate; + variable ufract : UNSIGNED (fraction_width downto 0); -- unsigned fraction + begin + fptyp := Classfp (arg, check_error); + sign := to_x01(arg(arg'high)); + break_number ( + arg => arg, + fptyp => fptyp, + denormalize => denormalize, + fract => ufract, + expon => expon); + fract (0 downto -fraction_width) := ufixed (ufract); + end procedure break_number; + + -- Arithmetic functions + function "abs" ( + arg : UNRESOLVED_float) -- floating point input + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (arg'range); -- result + begin + if (arg'length > 0) then + result := to_01 (arg, 'X'); + result (arg'high) := '0'; -- set the sign bit to positive + return result; + else + return NAFP; + end if; + end function "abs"; + + -- IEEE 754 "negative" function + function "-" ( + arg : UNRESOLVED_float) -- floating point input + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (arg'range); -- result + begin + if (arg'length > 0) then + result := to_01 (arg, 'X'); + result (arg'high) := not result (arg'high); -- invert sign bit + return result; + else + return NAFP; + end if; + end function "-"; + + -- Addition, adds two floating point numbers + function add ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + constant addguard : NATURAL := guard; -- add one guard bit + variable lfptype, rfptype : valid_fpstate; + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + variable fractl, fractr : UNSIGNED (fraction_width+1+addguard downto 0); -- fractions + variable fractc, fracts : UNSIGNED (fractl'range); -- constant and shifted variables + variable urfract, ulfract : UNSIGNED (fraction_width downto 0); + variable ufract : UNSIGNED (fraction_width+1+addguard downto 0); + variable exponl, exponr : SIGNED (exponent_width-1 downto 0); -- exponents + variable rexpon : SIGNED (exponent_width downto 0); -- result exponent + variable shiftx : SIGNED (exponent_width downto 0); -- shift fractions + variable sign : STD_ULOGIC; -- sign of the output + variable leftright : BOOLEAN; -- left or right used + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + variable sticky : STD_ULOGIC; -- Holds precision for rounding + begin -- addition + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + lfptype := isx; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + end if; + if (lfptype = isx or rfptype = isx) then + fpresult := (others => 'X'); + elsif (lfptype = nan or lfptype = quiet_nan or + rfptype = nan or rfptype = quiet_nan) + -- Return quiet NAN, IEEE754-1985-7.1,1 + or (lfptype = pos_inf and rfptype = neg_inf) + or (lfptype = neg_inf and rfptype = pos_inf) then + -- Return quiet NAN, IEEE754-1985-7.1,2 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (lfptype = pos_inf or rfptype = pos_inf) then -- x + inf = inf + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (lfptype = neg_inf or rfptype = neg_inf) then -- x - inf = -inf + fpresult := neg_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (lfptype = neg_zero and rfptype = neg_zero) then -- -0 + -0 = -0 + fpresult := neg_zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + lfptype := classfp (lresize, false); -- errors already checked + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rfptype := classfp (rresize, false); -- errors already checked + break_number ( + arg => lresize, + fptyp => lfptype, + denormalize => denormalize, + fract => ulfract, + expon => exponl); + fractl := (others => '0'); + fractl (fraction_width+addguard downto addguard) := ulfract; + break_number ( + arg => rresize, + fptyp => rfptype, + denormalize => denormalize, + fract => urfract, + expon => exponr); + fractr := (others => '0'); + fractr (fraction_width+addguard downto addguard) := urfract; + shiftx := (exponl(exponent_width-1) & exponl) - exponr; + if shiftx < -fractl'high then + rexpon := exponr(exponent_width-1) & exponr; + fractc := fractr; + fracts := (others => '0'); -- add zero + leftright := false; + sticky := or (fractl); + elsif shiftx < 0 then + shiftx := - shiftx; + fracts := shift_right (fractl, to_integer(shiftx)); + fractc := fractr; + rexpon := exponr(exponent_width-1) & exponr; + leftright := false; +-- sticky := or (fractl (to_integer(shiftx) downto 0)); + sticky := smallfract (fractl, to_integer(shiftx)); + elsif shiftx = 0 then + rexpon := exponl(exponent_width-1) & exponl; + sticky := '0'; + if fractr > fractl then + fractc := fractr; + fracts := fractl; + leftright := false; + else + fractc := fractl; + fracts := fractr; + leftright := true; + end if; + elsif shiftx > fractr'high then + rexpon := exponl(exponent_width-1) & exponl; + fracts := (others => '0'); -- add zero + fractc := fractl; + leftright := true; + sticky := or (fractr); + elsif shiftx > 0 then + fracts := shift_right (fractr, to_integer(shiftx)); + fractc := fractl; + rexpon := exponl(exponent_width-1) & exponl; + leftright := true; +-- sticky := or (fractr (to_integer(shiftx) downto 0)); + sticky := smallfract (fractr, to_integer(shiftx)); + end if; + -- add + fracts (0) := fracts (0) or sticky; -- Or the sticky bit into the LSB + if l(l'high) = r(r'high) then + ufract := fractc + fracts; + sign := l(l'high); + else -- signs are different + ufract := fractc - fracts; -- always positive result + if leftright then -- Figure out which sign to use + sign := l(l'high); + else + sign := r(r'high); + end if; + end if; + if or (ufract) = '0' then + sign := '0'; -- IEEE 854, 6.3, paragraph 2. + end if; + -- normalize + fpresult := normalize (fract => ufract, + expon => rexpon, + sign => sign, + sticky => sticky, + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => addguard); + end if; + return fpresult; + end function add; + + -- Subtraction, Calls "add". + function subtract ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + variable negr : UNRESOLVED_float (r'range); -- negative version of r + begin + negr := -r; -- r := -r + return add (l => l, + r => negr, + round_style => round_style, + guard => guard, + check_error => check_error, + denormalize => denormalize); + end function subtract; + + -- Floating point multiply + function multiply ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + constant multguard : NATURAL := guard; -- guard bits + variable lfptype, rfptype : valid_fpstate; + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + variable fractl, fractr : UNSIGNED (fraction_width downto 0); -- fractions + variable rfract : UNSIGNED ((2*(fraction_width))+1 downto 0); -- result fraction + variable sfract : UNSIGNED (fraction_width+1+multguard downto 0); -- result fraction + variable shifty : INTEGER; -- denormal shift + variable exponl, exponr : SIGNED (exponent_width-1 downto 0); -- exponents + variable rexpon : SIGNED (exponent_width+1 downto 0); -- result exponent + variable fp_sign : STD_ULOGIC; -- sign of result + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + variable sticky : STD_ULOGIC; -- Holds precision for rounding + begin -- multiply + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + lfptype := isx; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + end if; + if (lfptype = isx or rfptype = isx) then + fpresult := (others => 'X'); + elsif ((lfptype = nan or lfptype = quiet_nan or + rfptype = nan or rfptype = quiet_nan)) then + -- Return quiet NAN, IEEE754-1985-7.1,1 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (((lfptype = pos_inf or lfptype = neg_inf) and + (rfptype = pos_zero or rfptype = neg_zero)) or + ((rfptype = pos_inf or rfptype = neg_inf) and + (lfptype = pos_zero or lfptype = neg_zero))) then -- 0 * inf + -- Return quiet NAN, IEEE754-1985-7.1,3 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (lfptype = pos_inf or rfptype = pos_inf + or lfptype = neg_inf or rfptype = neg_inf) then -- x * inf = inf + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + -- figure out the sign + fp_sign := l(l'high) xor r(r'high); -- figure out the sign + fpresult (exponent_width) := fp_sign; + else + fp_sign := l(l'high) xor r(r'high); -- figure out the sign + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + lfptype := classfp (lresize, false); -- errors already checked + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rfptype := classfp (rresize, false); -- errors already checked + break_number ( + arg => lresize, + fptyp => lfptype, + denormalize => denormalize, + fract => fractl, + expon => exponl); + break_number ( + arg => rresize, + fptyp => rfptype, + denormalize => denormalize, + fract => fractr, + expon => exponr); + if (rfptype = pos_denormal or rfptype = neg_denormal) then + shifty := fraction_width - find_leftmost(fractr, '1'); + fractr := shift_left (fractr, shifty); + elsif (lfptype = pos_denormal or lfptype = neg_denormal) then + shifty := fraction_width - find_leftmost(fractl, '1'); + fractl := shift_left (fractl, shifty); + else + shifty := 0; + -- Note that a denormal number * a denormal number is always zero. + end if; + -- multiply + -- add the exponents + rexpon := resize (exponl, rexpon'length) + exponr - shifty + 1; + rfract := fractl * fractr; -- Multiply the fraction + sfract := rfract (rfract'high downto + rfract'high - (fraction_width+1+multguard)); + sticky := or (rfract (rfract'high-(fraction_width+1+multguard) + downto 0)); + -- normalize + fpresult := normalize (fract => sfract, + expon => rexpon, + sign => fp_sign, + sticky => sticky, + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => multguard); + end if; + return fpresult; + end function multiply; + + function short_divide ( + lx, rx : UNSIGNED) + return UNSIGNED + is + -- This is a special divider for the floating point routines. + -- For a true unsigned divider, "stages" needs to = lx'high + constant stages : INTEGER := lx'high - rx'high; -- number of stages + variable partial : UNSIGNED (lx'range); + variable q : UNSIGNED (stages downto 0); + variable partial_argl : SIGNED (rx'high + 2 downto 0); + variable partial_arg : SIGNED (rx'high + 2 downto 0); + begin + partial := lx; + for i in stages downto 0 loop + partial_argl := resize ("0" & SIGNED (partial(lx'high downto i)), + partial_argl'length); + partial_arg := partial_argl - SIGNED ("0" & rx); + if (partial_arg (partial_arg'high) = '1') then -- negative + q(i) := '0'; + else + q(i) := '1'; + partial (lx'high+i-stages downto lx'high+i-stages-rx'high) := + UNSIGNED (partial_arg(rx'range)); + end if; + end loop; + -- to make the output look like that of the unsigned IEEE divide. + return resize (q, lx'length); + end function short_divide; + + -- 1/X function. Needed for algorithm development. + function reciprocal ( + arg : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(arg'low, arg'low); -- length of FP output fraction + constant exponent_width : NATURAL := arg'high; -- length of FP output exponent + constant divguard : NATURAL := guard; -- guard bits + function onedivy ( + arg : UNSIGNED) + return UNSIGNED + is + variable q : UNSIGNED((2*arg'high)+1 downto 0); + variable one : UNSIGNED (q'range); + begin + one := (others => '0'); + one(one'high) := '1'; + q := short_divide (one, arg); -- Unsigned divide + return resize (q, arg'length+1); + end function onedivy; + variable fptype : valid_fpstate; + variable expon : SIGNED (exponent_width-1 downto 0); -- exponents + variable denorm_offset : NATURAL range 0 to 2; + variable fract : UNSIGNED (fraction_width downto 0); + variable fractg : UNSIGNED (fraction_width+divguard downto 0); + variable sfract : UNSIGNED (fraction_width+1+divguard downto 0); -- result fraction + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- reciprocal + fptype := classfp(arg, check_error); + classcase : case fptype is + when isx => + fpresult := (others => 'X'); + when nan | quiet_nan => + -- Return quiet NAN, IEEE754-1985-7.1,1 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + when pos_inf | neg_inf => -- 1/inf, return 0 + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + when neg_zero | pos_zero => -- 1/0 + report FLOAT_GENERIC_PKG'instance_name + & "RECIPROCAL: Floating Point divide by zero" + severity error; + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + when others => + if (fptype = pos_denormal or fptype = neg_denormal) + and ((arg (-1) or arg(-2)) /= '1') then + -- 1/denormal = infinity, with the exception of 2**-expon_base + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + fpresult (exponent_width) := to_x01 (arg (exponent_width)); + else + break_number ( + arg => arg, + fptyp => fptype, + denormalize => denormalize, + fract => fract, + expon => expon); + fractg := (others => '0'); + if (fptype = pos_denormal or fptype = neg_denormal) then + -- The reciprocal of a denormal number is typically zero, + -- except for two special cases which are trapped here. + if (to_x01(arg (-1)) = '1') then + fractg (fractg'high downto divguard+1) := + fract (fract'high-1 downto 0); -- Shift to not denormal + denorm_offset := 1; -- add 1 to exponent compensate + else -- arg(-2) = '1' + fractg (fractg'high downto divguard+2) := + fract (fract'high-2 downto 0); -- Shift to not denormal + denorm_offset := 2; -- add 2 to exponent compensate + end if; + else + fractg (fractg'high downto divguard) := fract; + denorm_offset := 0; + end if; + expon := - expon - 3 + denorm_offset; + sfract := onedivy (fractg); + -- normalize + fpresult := normalize (fract => sfract, + expon => expon, + sign => arg(exponent_width), + sticky => '1', + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => divguard); + end if; + end case classcase; + return fpresult; + end function reciprocal; + + -- floating point division + function divide ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + constant divguard : NATURAL := guard; -- division guard bits + variable lfptype, rfptype : valid_fpstate; + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + variable ulfract, urfract : UNSIGNED (fraction_width downto 0); + variable fractl : UNSIGNED ((2*(fraction_width+divguard)+1) downto 0); -- left + variable fractr : UNSIGNED (fraction_width+divguard downto 0); -- right + variable rfract : UNSIGNED (fractl'range); -- result fraction + variable sfract : UNSIGNED (fraction_width+1+divguard downto 0); -- result fraction + variable exponl, exponr : SIGNED (exponent_width-1 downto 0); -- exponents + variable rexpon : SIGNED (exponent_width+1 downto 0); -- result exponent + variable fp_sign, sticky : STD_ULOGIC; -- sign of result + variable shifty, shiftx : INTEGER; -- denormal number shift + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- divide + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + lfptype := isx; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + end if; + classcase : case rfptype is + when isx => + fpresult := (others => 'X'); + when nan | quiet_nan => + -- Return quiet NAN, IEEE754-1985-7.1,1 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + when pos_inf | neg_inf => + if lfptype = pos_inf or lfptype = neg_inf -- inf / inf + or lfptype = quiet_nan or lfptype = nan then + -- Return quiet NAN, IEEE754-1985-7.1,4 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + else -- x / inf = 0 + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult (fpresult'high) := fp_sign; -- sign + end if; + when pos_zero | neg_zero => + if lfptype = pos_zero or lfptype = neg_zero -- 0 / 0 + or lfptype = quiet_nan or lfptype = nan then + -- Return quiet NAN, IEEE754-1985-7.1,4 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + report float_generic_pkg'instance_name + & "DIVIDE: Floating Point divide by zero" + severity error; + -- Infinity, define in 754-1985-7.2 + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult (fpresult'high) := fp_sign; -- sign + end if; + when others => + classcase2 : case lfptype is + when isx => + fpresult := (others => 'X'); + when nan | quiet_nan => + -- Return quiet NAN, IEEE754-1985-7.1,1 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + when pos_inf | neg_inf => -- inf / x = inf + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult(exponent_width) := fp_sign; + when pos_zero | neg_zero => -- 0 / X = 0 + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult(exponent_width) := fp_sign; + when others => + fp_sign := l(l'high) xor r(r'high); -- sign + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + lfptype := classfp (lresize, false); -- errors already checked + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rfptype := classfp (rresize, false); -- errors already checked + break_number ( + arg => lresize, + fptyp => lfptype, + denormalize => denormalize, + fract => ulfract, + expon => exponl); + -- right side + break_number ( + arg => rresize, + fptyp => rfptype, + denormalize => denormalize, + fract => urfract, + expon => exponr); + -- Compute the exponent + rexpon := resize (exponl, rexpon'length) - exponr - 2; + if (rfptype = pos_denormal or rfptype = neg_denormal) then + -- Do the shifting here not after. That way we have a smaller + -- shifter, and need a smaller divider, because the top + -- bit in the divisor will always be a "1". + shifty := fraction_width - find_leftmost(urfract, '1'); + urfract := shift_left (urfract, shifty); + rexpon := rexpon + shifty; + end if; + fractr := (others => '0'); + fractr (fraction_width+divguard downto divguard) := urfract; + if (lfptype = pos_denormal or lfptype = neg_denormal) then + shiftx := fraction_width - find_leftmost(ulfract, '1'); + ulfract := shift_left (ulfract, shiftx); + rexpon := rexpon - shiftx; + end if; + fractl := (others => '0'); + fractl (fractl'high downto fractl'high-fraction_width) := ulfract; + -- divide + rfract := short_divide (fractl, fractr); -- unsigned divide + sfract := rfract (sfract'range); -- lower bits + sticky := '1'; + -- normalize + fpresult := normalize (fract => sfract, + expon => rexpon, + sign => fp_sign, + sticky => sticky, + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => divguard); + end case classcase2; + end case classcase; + return fpresult; + end function divide; + + -- division by a power of 2 + function dividebyp2 ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lfptype, rfptype : valid_fpstate; + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + variable ulfract, urfract : UNSIGNED (fraction_width downto 0); + variable exponl, exponr : SIGNED(exponent_width-1 downto 0); -- exponents + variable rexpon : SIGNED(exponent_width downto 0); -- result exponent + variable fp_sign : STD_ULOGIC; -- sign of result + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- divisionbyp2 + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + lfptype := isx; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + end if; + classcase : case rfptype is + when isx => + fpresult := (others => 'X'); + when nan | quiet_nan => + -- Return quiet NAN, IEEE754-1985-7.1,1 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + when pos_inf | neg_inf => + if lfptype = pos_inf or lfptype = neg_inf then -- inf / inf + -- Return quiet NAN, IEEE754-1985-7.1,4 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + else -- x / inf = 0 + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult (fpresult'high) := fp_sign; -- sign + end if; + when pos_zero | neg_zero => + if lfptype = pos_zero or lfptype = neg_zero then -- 0 / 0 + -- Return quiet NAN, IEEE754-1985-7.1,4 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + report FLOAT_GENERIC_PKG'instance_name + & "DIVIDEBYP2: Floating Point divide by zero" + severity error; + -- Infinity, define in 754-1985-7.2 + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult (fpresult'high) := fp_sign; -- sign + end if; + when others => + classcase2 : case lfptype is + when isx => + fpresult := (others => 'X'); + when nan | quiet_nan => + -- Return quiet NAN, IEEE754-1985-7.1,1 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + when pos_inf | neg_inf => -- inf / x = inf + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult (exponent_width) := fp_sign; -- sign + when pos_zero | neg_zero => -- 0 / X = 0 + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + fp_sign := l(l'high) xor r(r'high); -- sign + fpresult (exponent_width) := fp_sign; -- sign + when others => + fp_sign := l(l'high) xor r(r'high); -- sign + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + lfptype := classfp (lresize, false); -- errors already checked + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rfptype := classfp (rresize, false); -- errors already checked + break_number ( + arg => lresize, + fptyp => lfptype, + denormalize => denormalize, + fract => ulfract, + expon => exponl); + -- right side + break_number ( + arg => rresize, + fptyp => rfptype, + denormalize => denormalize, + fract => urfract, + expon => exponr); + assert (or (urfract (fraction_width-1 downto 0)) = '0') + report FLOAT_GENERIC_PKG'instance_name + & "DIVIDEBYP2: " + & "Dividebyp2 called with a non power of two divisor" + severity error; + rexpon := (exponl(exponl'high)&exponl) + - (exponr(exponr'high)&exponr) - 1; + -- normalize + fpresult := normalize (fract => ulfract, + expon => rexpon, + sign => fp_sign, + sticky => '1', + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => 0); + end case classcase2; + end case classcase; + return fpresult; + end function dividebyp2; + + -- Multiply accumulate result = l*r + c + function mac ( + l, r, c : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := + -mine (mine(l'low, r'low), c'low); -- length of FP output fraction + constant exponent_width : NATURAL := + maximum (maximum(l'high, r'high), c'high); -- length of FP output exponent + variable lfptype, rfptype, cfptype : valid_fpstate; + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + variable fractl, fractr : UNSIGNED (fraction_width downto 0); -- fractions + variable fractx : UNSIGNED (fraction_width+guard downto 0); + variable fractc, fracts : UNSIGNED (fraction_width+1+guard downto 0); + variable rfract : UNSIGNED ((2*(fraction_width))+1 downto 0); -- result fraction + variable sfract, ufract : UNSIGNED (fraction_width+1+guard downto 0); -- result fraction + variable exponl, exponr, exponc : SIGNED (exponent_width-1 downto 0); -- exponents + variable rexpon, rexpon2 : SIGNED (exponent_width+1 downto 0); -- result exponent + variable shifty : INTEGER; -- denormal shift + variable shiftx : SIGNED (rexpon'range); -- shift fractions + variable fp_sign : STD_ULOGIC; -- sign of result + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + variable cresize : UNRESOLVED_float (exponent_width downto -fraction_width - guard); + variable leftright : BOOLEAN; -- left or right used + variable sticky : STD_ULOGIC; -- Holds precision for rounding + begin -- multiply + if (fraction_width = 0 or l'length < 7 or r'length < 7 or c'length < 7) then + lfptype := isx; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + cfptype := classfp (c, check_error); + end if; + if (lfptype = isx or rfptype = isx or cfptype = isx) then + fpresult := (others => 'X'); + elsif (lfptype = nan or lfptype = quiet_nan or + rfptype = nan or rfptype = quiet_nan or + cfptype = nan or cfptype = quiet_nan) then + -- Return quiet NAN, IEEE754-1985-7.1,1 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (((lfptype = pos_inf or lfptype = neg_inf) and + (rfptype = pos_zero or rfptype = neg_zero)) or + ((rfptype = pos_inf or rfptype = neg_inf) and + (lfptype = pos_zero or lfptype = neg_zero))) then -- 0 * inf + -- Return quiet NAN, IEEE754-1985-7.1,3 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (lfptype = pos_inf or rfptype = pos_inf + or lfptype = neg_inf or rfptype = neg_inf -- x * inf = inf + or cfptype = neg_inf or cfptype = pos_inf) then -- x + inf = inf + fpresult := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + -- figure out the sign + fpresult (exponent_width) := l(l'high) xor r(r'high); + else + fp_sign := l(l'high) xor r(r'high); -- figure out the sign + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + lfptype := classfp (lresize, false); -- errors already checked + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rfptype := classfp (rresize, false); -- errors already checked + cresize := resize (arg => to_x01(c), + exponent_width => exponent_width, + fraction_width => -cresize'low, + denormalize_in => denormalize, + denormalize => denormalize); + cfptype := classfp (cresize, false); -- errors already checked + break_number ( + arg => lresize, + fptyp => lfptype, + denormalize => denormalize, + fract => fractl, + expon => exponl); + break_number ( + arg => rresize, + fptyp => rfptype, + denormalize => denormalize, + fract => fractr, + expon => exponr); + break_number ( + arg => cresize, + fptyp => cfptype, + denormalize => denormalize, + fract => fractx, + expon => exponc); + if (rfptype = pos_denormal or rfptype = neg_denormal) then + shifty := fraction_width - find_leftmost(fractr, '1'); + fractr := shift_left (fractr, shifty); + elsif (lfptype = pos_denormal or lfptype = neg_denormal) then + shifty := fraction_width - find_leftmost(fractl, '1'); + fractl := shift_left (fractl, shifty); + else + shifty := 0; + -- Note that a denormal number * a denormal number is always zero. + end if; + -- multiply + rfract := fractl * fractr; -- Multiply the fraction + -- add the exponents + rexpon := resize (exponl, rexpon'length) + exponr - shifty + 1; + shiftx := rexpon - exponc; + if shiftx < -fractl'high then + rexpon2 := resize (exponc, rexpon2'length); + fractc := "0" & fractx; + fracts := (others => '0'); + sticky := or (rfract); + elsif shiftx < 0 then + shiftx := - shiftx; + fracts := shift_right (rfract (rfract'high downto rfract'high + - fracts'length+1), + to_integer(shiftx)); + fractc := "0" & fractx; + rexpon2 := resize (exponc, rexpon2'length); + leftright := false; + sticky := or (rfract (to_integer(shiftx)+rfract'high + - fracts'length downto 0)); + elsif shiftx = 0 then + rexpon2 := resize (exponc, rexpon2'length); + sticky := or (rfract (rfract'high - fractc'length downto 0)); + if rfract (rfract'high downto rfract'high - fractc'length+1) > fractx + then + fractc := "0" & fractx; + fracts := rfract (rfract'high downto rfract'high + - fracts'length+1); + leftright := false; + else + fractc := rfract (rfract'high downto rfract'high + - fractc'length+1); + fracts := "0" & fractx; + leftright := true; + end if; + elsif shiftx > fractx'high then + rexpon2 := rexpon; + fracts := (others => '0'); + fractc := rfract (rfract'high downto rfract'high - fractc'length+1); + leftright := true; + sticky := or (fractx & rfract (rfract'high - fractc'length + downto 0)); + else -- fractx'high > shiftx > 0 + rexpon2 := rexpon; + fracts := "0" & shift_right (fractx, to_integer (shiftx)); + fractc := rfract (rfract'high downto rfract'high - fractc'length+1); + leftright := true; + sticky := or (fractx (to_integer (shiftx) downto 0) + & rfract (rfract'high - fractc'length downto 0)); + end if; + fracts (0) := fracts (0) or sticky; -- Or the sticky bit into the LSB + if fp_sign = to_X01(c(c'high)) then + ufract := fractc + fracts; + fp_sign := fp_sign; + else -- signs are different + ufract := fractc - fracts; -- always positive result + if leftright then -- Figure out which sign to use + fp_sign := fp_sign; + else + fp_sign := c(c'high); + end if; + end if; + -- normalize + fpresult := normalize (fract => ufract, + expon => rexpon2, + sign => fp_sign, + sticky => sticky, + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => guard); + end if; + return fpresult; + end function mac; + + -- "rem" function + function remainder ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + constant divguard : NATURAL := guard; -- division guard bits + variable lfptype, rfptype : valid_fpstate; + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + variable ulfract, urfract : UNSIGNED (fraction_width downto 0); + variable fractr, fractl : UNSIGNED (fraction_width+divguard downto 0); -- right + variable rfract : UNSIGNED (fractr'range); -- result fraction + variable sfract : UNSIGNED (fraction_width+divguard downto 0); -- result fraction + variable exponl, exponr : SIGNED (exponent_width-1 downto 0); -- exponents + variable rexpon : SIGNED (exponent_width downto 0); -- result exponent + variable fp_sign : STD_ULOGIC; -- sign of result + variable shifty : INTEGER; -- denormal number shift + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- remainder + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + lfptype := isx; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + end if; + if (lfptype = isx or rfptype = isx) then + fpresult := (others => 'X'); + elsif (lfptype = nan or lfptype = quiet_nan) + or (rfptype = nan or rfptype = quiet_nan) + -- Return quiet NAN, IEEE754-1985-7.1,1 + or (lfptype = pos_inf or lfptype = neg_inf) -- inf rem x + -- Return quiet NAN, IEEE754-1985-7.1,5 + or (rfptype = pos_zero or rfptype = neg_zero) then -- x rem 0 + -- Return quiet NAN, IEEE754-1985-7.1,5 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (rfptype = pos_inf or rfptype = neg_inf) then -- x rem inf = 0 + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (abs(l) < abs(r)) then + fpresult := l; + else + fp_sign := to_X01(l(l'high)); -- sign + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + lfptype := classfp (lresize, false); -- errors already checked + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rfptype := classfp (rresize, false); -- errors already checked + fractl := (others => '0'); + break_number ( + arg => lresize, + fptyp => lfptype, + denormalize => denormalize, + fract => ulfract, + expon => exponl); + fractl (fraction_width+divguard downto divguard) := ulfract; + -- right side + fractr := (others => '0'); + break_number ( + arg => rresize, + fptyp => rfptype, + denormalize => denormalize, + fract => urfract, + expon => exponr); + fractr (fraction_width+divguard downto divguard) := urfract; + rexpon := (exponr(exponr'high)&exponr); + shifty := to_integer(exponl - rexpon); + if (shifty > 0) then + fractr := shift_right (fractr, shifty); + rexpon := rexpon + shifty; + end if; + if (fractr /= 0) then + -- rem + rfract := fractl rem fractr; -- unsigned rem + sfract := rfract (sfract'range); -- lower bits + -- normalize + fpresult := normalize (fract => sfract, + expon => rexpon, + sign => fp_sign, + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => divguard); + else + -- If we shift "fractr" so far that it becomes zero, return zero. + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + end if; + end if; + return fpresult; + end function remainder; + + -- "mod" function + function modulo ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := - mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lfptype, rfptype : valid_fpstate; + variable fpresult : UNRESOLVED_float (exponent_width downto -fraction_width); + variable remres : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- remainder + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + lfptype := isx; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + end if; + if (lfptype = isx or rfptype = isx) then + fpresult := (others => 'X'); + elsif (lfptype = nan or lfptype = quiet_nan) + or (rfptype = nan or rfptype = quiet_nan) + -- Return quiet NAN, IEEE754-1985-7.1,1 + or (lfptype = pos_inf or lfptype = neg_inf) -- inf rem x + -- Return quiet NAN, IEEE754-1985-7.1,5 + or (rfptype = pos_zero or rfptype = neg_zero) then -- x rem 0 + -- Return quiet NAN, IEEE754-1985-7.1,5 + fpresult := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (rfptype = pos_inf or rfptype = neg_inf) then -- x rem inf = 0 + fpresult := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + remres := remainder (l => abs(l), + r => abs(r), + round_style => round_style, + guard => guard, + check_error => false, + denormalize => denormalize); + -- MOD is the same as REM, but you do something different with + -- negative values + if (is_negative (l)) then + remres := - remres; + end if; + if (is_negative (l) = is_negative (r) or remres = 0) then + fpresult := remres; + else + fpresult := add (l => remres, + r => r, + round_style => round_style, + guard => guard, + check_error => false, + denormalize => denormalize); + end if; + end if; + return fpresult; + end function modulo; + + -- Square root of a floating point number. Done using Newton's Iteration. + function sqrt ( + arg : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; + constant guard : NATURAL := float_guard_bits; + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_float + is + constant fraction_width : NATURAL := guard-arg'low; -- length of FP output fraction + constant exponent_width : NATURAL := arg'high; -- length of FP output exponent + variable sign : STD_ULOGIC; + variable fpresult : float (arg'range); + variable fptype : valid_fpstate; + variable iexpon : SIGNED(exponent_width-1 downto 0); -- exponents + variable expon : SIGNED(exponent_width downto 0); -- exponents + variable ufact : ufixed (0 downto arg'low); + variable fact : ufixed (2 downto -fraction_width); -- fraction + variable resb : ufixed (fact'high+1 downto fact'low); + begin -- square root + fptype := Classfp (arg, check_error); + classcase : case fptype is + when isx => + fpresult := (others => 'X'); + when nan | quiet_nan | + -- Return quiet NAN, IEEE754-1985-7.1,1 + neg_normal | neg_denormal | neg_inf => -- sqrt (neg) + -- Return quiet NAN, IEEE754-1985-7.1.6 + fpresult := qnanfp (fraction_width => fraction_width-guard, + exponent_width => exponent_width); + when pos_inf => -- Sqrt (inf), return infinity + fpresult := pos_inffp (fraction_width => fraction_width-guard, + exponent_width => exponent_width); + when pos_zero => -- return 0 + fpresult := zerofp (fraction_width => fraction_width-guard, + exponent_width => exponent_width); + when neg_zero => -- IEEE754-1985-6.3 return -0 + fpresult := neg_zerofp (fraction_width => fraction_width-guard, + exponent_width => exponent_width); + when others => + break_number (arg => arg, + denormalize => denormalize, + check_error => false, + fract => ufact, + expon => iexpon, + sign => sign); + expon := resize (iexpon+1, expon'length); -- get exponent + fact := resize (ufact, fact'high, fact'low); + if (expon(0) = '1') then + fact := fact sla 1; -- * 2.0 + end if; + expon := shift_right (expon, 1); -- exponent/2 + -- Newton's iteration - root := (1 + arg) / 2 + resb := (fact + 1) sra 1; + for j in 0 to fraction_width/4 loop + -- root := (root + (arg/root))/2 + resb := resize (arg => (resb + (fact/resb)) sra 1, + left_index => resb'high, + right_index => resb'low, + round_style => fixed_truncate, + overflow_style => fixed_wrap); + end loop; + fpresult := normalize (fract => resb, + expon => expon-1, + sign => '0', + exponent_width => arg'high, + fraction_width => -arg'low, + round_style => round_style, + denormalize => denormalize, + nguard => guard); + end case classcase; + return fpresult; + end function sqrt; + + function Is_Negative (arg : UNRESOLVED_float) return BOOLEAN is + -- Technically -0 should return "false", but I'm leaving that case out. + begin + return (to_x01(arg(arg'high)) = '1'); + end function Is_Negative; + + -- compare functions + -- =, /=, >=, <=, <, > + + function eq ( -- equal = + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN + is + variable lfptype, rfptype : valid_fpstate; + variable is_equal, is_unordered : BOOLEAN; + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- equal + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + return false; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + end if; + if (lfptype = neg_zero or lfptype = pos_zero) and + (rfptype = neg_zero or rfptype = pos_zero) then + is_equal := true; + else + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + is_equal := (to_slv(lresize) = to_slv(rresize)); + end if; + if (check_error) then + is_unordered := Unordered (x => l, + y => r); + else + is_unordered := false; + end if; + return is_equal and not is_unordered; + end function eq; + + function lt ( -- less than < + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lfptype, rfptype : valid_fpstate; + variable expl, expr : UNSIGNED (exponent_width-1 downto 0); + variable fractl, fractr : UNSIGNED (fraction_width-1 downto 0); + variable is_less_than, is_unordered : BOOLEAN; + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + is_less_than := false; + else + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + if to_x01(l(l'high)) = to_x01(r(r'high)) then -- sign bits + expl := UNSIGNED(lresize(exponent_width-1 downto 0)); + expr := UNSIGNED(rresize(exponent_width-1 downto 0)); + if expl = expr then + fractl := UNSIGNED (to_slv(lresize(-1 downto -fraction_width))); + fractr := UNSIGNED (to_slv(rresize(-1 downto -fraction_width))); + if to_x01(l(l'high)) = '0' then -- positive number + is_less_than := (fractl < fractr); + else + is_less_than := (fractl > fractr); -- negative + end if; + else + if to_x01(l(l'high)) = '0' then -- positive number + is_less_than := (expl < expr); + else + is_less_than := (expl > expr); -- negative + end if; + end if; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + if (lfptype = neg_zero and rfptype = pos_zero) then + is_less_than := false; -- -0 < 0 returns false. + else + is_less_than := (to_x01(l(l'high)) > to_x01(r(r'high))); + end if; + end if; + end if; + if check_error then + is_unordered := Unordered (x => l, + y => r); + else + is_unordered := false; + end if; + return is_less_than and not is_unordered; + end function lt; + + function gt ( -- greater than > + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lfptype, rfptype : valid_fpstate; + variable expl, expr : UNSIGNED (exponent_width-1 downto 0); + variable fractl, fractr : UNSIGNED (fraction_width-1 downto 0); + variable is_greater_than : BOOLEAN; + variable is_unordered : BOOLEAN; + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- greater_than + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + is_greater_than := false; + else + lresize := resize (arg => to_x01(l), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + rresize := resize (arg => to_x01(r), + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => denormalize, + denormalize => denormalize); + if to_x01(l(l'high)) = to_x01(r(r'high)) then -- sign bits + expl := UNSIGNED(lresize(exponent_width-1 downto 0)); + expr := UNSIGNED(rresize(exponent_width-1 downto 0)); + if expl = expr then + fractl := UNSIGNED (to_slv(lresize(-1 downto -fraction_width))); + fractr := UNSIGNED (to_slv(rresize(-1 downto -fraction_width))); + if to_x01(l(l'high)) = '0' then -- positive number + is_greater_than := fractl > fractr; + else + is_greater_than := fractl < fractr; -- negative + end if; + else + if to_x01(l(l'high)) = '0' then -- positive number + is_greater_than := expl > expr; + else + is_greater_than := expl < expr; -- negative + end if; + end if; + else + lfptype := classfp (l, check_error); + rfptype := classfp (r, check_error); + if (lfptype = pos_zero and rfptype = neg_zero) then + is_greater_than := false; -- 0 > -0 returns false. + else + is_greater_than := to_x01(l(l'high)) < to_x01(r(r'high)); + end if; + end if; + end if; + if check_error then + is_unordered := Unordered (x => l, + y => r); + else + is_unordered := false; + end if; + return is_greater_than and not is_unordered; + end function gt; + + -- purpose: /= function + function ne ( -- not equal /= + l, r : UNRESOLVED_float; + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN + is + variable is_equal, is_unordered : BOOLEAN; + begin + is_equal := eq (l => l, + r => r, + check_error => false, + denormalize => denormalize); + if check_error then + is_unordered := Unordered (x => l, + y => r); + else + is_unordered := false; + end if; + return not (is_equal and not is_unordered); + end function ne; + + function le ( -- less than or equal to <= + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN + is + variable is_greater_than, is_unordered : BOOLEAN; + begin + is_greater_than := gt (l => l, + r => r, + check_error => false, + denormalize => denormalize); + if check_error then + is_unordered := Unordered (x => l, + y => r); + else + is_unordered := false; + end if; + return not is_greater_than and not is_unordered; + end function le; + + function ge ( -- greater than or equal to >= + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN + is + variable is_less_than, is_unordered : BOOLEAN; + begin + is_less_than := lt (l => l, + r => r, + check_error => false, + denormalize => denormalize); + if check_error then + is_unordered := Unordered (x => l, + y => r); + else + is_unordered := false; + end if; + return not is_less_than and not is_unordered; + end function ge; + + function "?=" (L, R : UNRESOLVED_float) return STD_ULOGIC is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lfptype, rfptype : valid_fpstate; + variable is_equal, is_unordered : STD_ULOGIC; + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- ?= + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + return 'X'; + else + lfptype := classfp (l, float_check_error); + rfptype := classfp (r, float_check_error); + end if; + if (lfptype = neg_zero or lfptype = pos_zero) and + (rfptype = neg_zero or rfptype = pos_zero) then + is_equal := '1'; + else + lresize := resize (arg => l, + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => float_denormalize, + denormalize => float_denormalize); + rresize := resize (arg => r, + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => float_denormalize, + denormalize => float_denormalize); + is_equal := to_sulv(lresize) ?= to_sulv(rresize); + end if; + if (float_check_error) then + if (lfptype = nan or lfptype = quiet_nan or + rfptype = nan or rfptype = quiet_nan) then + is_unordered := '1'; + else + is_unordered := '0'; + end if; + else + is_unordered := '0'; + end if; + return is_equal and not is_unordered; + end function "?="; + + function "?/=" (L, R : UNRESOLVED_float) return STD_ULOGIC is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lfptype, rfptype : valid_fpstate; + variable is_equal, is_unordered : STD_ULOGIC; + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- ?/= + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + return 'X'; + else + lfptype := classfp (l, float_check_error); + rfptype := classfp (r, float_check_error); + end if; + if (lfptype = neg_zero or lfptype = pos_zero) and + (rfptype = neg_zero or rfptype = pos_zero) then + is_equal := '1'; + else + lresize := resize (arg => l, + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => float_denormalize, + denormalize => float_denormalize); + rresize := resize (arg => r, + exponent_width => exponent_width, + fraction_width => fraction_width, + denormalize_in => float_denormalize, + denormalize => float_denormalize); + is_equal := to_sulv(lresize) ?= to_sulv(rresize); + end if; + if (float_check_error) then + if (lfptype = nan or lfptype = quiet_nan or + rfptype = nan or rfptype = quiet_nan) then + is_unordered := '1'; + else + is_unordered := '0'; + end if; + else + is_unordered := '0'; + end if; + return not (is_equal and not is_unordered); + end function "?/="; + + function "?>" (L, R : UNRESOLVED_float) return STD_ULOGIC is + constant fraction_width : NATURAL := -mine(l'low, r'low); + variable founddash : BOOLEAN := false; + begin + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + founddash := true; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + founddash := true; + end if; + end loop; + if founddash then + report float_generic_pkg'instance_name + & " ""?>"": '-' found in compare string" + severity error; + return 'X'; + elsif is_x(l) or is_x(r) then + return 'X'; + elsif l > r then + return '1'; + else + return '0'; + end if; + end if; + end function "?>"; + + function "?>=" (L, R : UNRESOLVED_float) return STD_ULOGIC is + constant fraction_width : NATURAL := -mine(l'low, r'low); + variable founddash : BOOLEAN := false; + begin + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + founddash := true; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + founddash := true; + end if; + end loop; + if founddash then + report float_generic_pkg'instance_name + & " ""?>="": '-' found in compare string" + severity error; + return 'X'; + elsif is_x(l) or is_x(r) then + return 'X'; + elsif l >= r then + return '1'; + else + return '0'; + end if; + end if; + end function "?>="; + + function "?<" (L, R : UNRESOLVED_float) return STD_ULOGIC is + constant fraction_width : NATURAL := -mine(l'low, r'low); + variable founddash : BOOLEAN := false; + begin + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + founddash := true; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + founddash := true; + end if; + end loop; + if founddash then + report float_generic_pkg'instance_name + & " ""?<"": '-' found in compare string" + severity error; + return 'X'; + elsif is_x(l) or is_x(r) then + return 'X'; + elsif l < r then + return '1'; + else + return '0'; + end if; + end if; + end function "?<"; + + function "?<=" (L, R : UNRESOLVED_float) return STD_ULOGIC is + constant fraction_width : NATURAL := -mine(l'low, r'low); + variable founddash : BOOLEAN := false; + begin + if (fraction_width = 0 or l'length < 7 or r'length < 7) then + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + founddash := true; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + founddash := true; + end if; + end loop; + if founddash then + report float_generic_pkg'instance_name + & " ""?<="": '-' found in compare string" + severity error; + return 'X'; + elsif is_x(l) or is_x(r) then + return 'X'; + elsif l <= r then + return '1'; + else + return '0'; + end if; + end if; + end function "?<="; + + function std_match (L, R : UNRESOLVED_float) 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 + report float_generic_pkg'instance_name + & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE" + severity warning; + return false; + end if; + end function std_match; + + function find_rightmost (arg : UNRESOLVED_float; 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_float; 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; + + -- These override the defaults for the compare operators. + function "=" (l, r : UNRESOLVED_float) return BOOLEAN is + begin + return eq(l, r); + end function "="; + + function "/=" (l, r : UNRESOLVED_float) return BOOLEAN is + begin + return ne(l, r); + end function "/="; + + function ">=" (l, r : UNRESOLVED_float) return BOOLEAN is + begin + return ge(l, r); + end function ">="; + + function "<=" (l, r : UNRESOLVED_float) return BOOLEAN is + begin + return le(l, r); + end function "<="; + + function ">" (l, r : UNRESOLVED_float) return BOOLEAN is + begin + return gt(l, r); + end function ">"; + + function "<" (l, r : UNRESOLVED_float) return BOOLEAN is + begin + return lt(l, r); + end function "<"; + + -- purpose: maximum of two numbers (overrides default) + function maximum ( + L, R : UNRESOLVED_float) + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin + if ((L'length < 1) or (R'length < 1)) then return NAFP; + end if; + lresize := resize (l, exponent_width, fraction_width); + rresize := resize (r, exponent_width, fraction_width); + if lresize > rresize then return lresize; + else return rresize; + end if; + end function maximum; + + function minimum ( + L, R : UNRESOLVED_float) + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(l'low, r'low); -- length of FP output fraction + constant exponent_width : NATURAL := maximum(l'high, r'high); -- length of FP output exponent + variable lresize, rresize : UNRESOLVED_float (exponent_width downto -fraction_width); + begin + if ((L'length < 1) or (R'length < 1)) then return NAFP; + end if; + lresize := resize (l, exponent_width, fraction_width); + rresize := resize (r, exponent_width, fraction_width); + if lresize > rresize then return rresize; + else return lresize; + end if; + end function minimum; + + ----------------------------------------------------------------------------- + -- conversion functions + ----------------------------------------------------------------------------- + + -- Converts a floating point number of one format into another format + function resize ( + arg : UNRESOLVED_float; -- Floating point input + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant in_fraction_width : NATURAL := -arg'low; -- length of FP output fraction + constant in_exponent_width : NATURAL := arg'high; -- length of FP output exponent + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + -- result value + variable fptype : valid_fpstate; + variable expon_in : SIGNED (in_exponent_width-1 downto 0); + variable fract_in : UNSIGNED (in_fraction_width downto 0); + variable round : BOOLEAN; + variable expon_out : SIGNED (exponent_width-1 downto 0); -- output fract + variable fract_out : UNSIGNED (fraction_width downto 0); -- output fract + variable passguard : NATURAL; + begin + fptype := classfp(arg, check_error); + if ((fptype = pos_denormal or fptype = neg_denormal) and denormalize_in + and (in_exponent_width < exponent_width + or in_fraction_width < fraction_width)) + or in_exponent_width > exponent_width + or in_fraction_width > fraction_width then + -- size reduction + classcase : case fptype is + when isx => + result := (others => 'X'); + when nan | quiet_nan => + result := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + when pos_inf => + result := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + when neg_inf => + result := neg_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + when pos_zero | neg_zero => + result := zerofp (fraction_width => fraction_width, -- hate -0 + exponent_width => exponent_width); + when others => + break_number ( + arg => arg, + fptyp => fptype, + denormalize => denormalize_in, + fract => fract_in, + expon => expon_in); + if fraction_width > in_fraction_width and denormalize_in then + -- You only get here if you have a denormal input + fract_out := (others => '0'); -- pad with zeros + fract_out (fraction_width downto + fraction_width - in_fraction_width) := fract_in; + result := normalize ( + fract => fract_out, + expon => expon_in, + sign => arg(arg'high), + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => 0); + else + result := normalize ( + fract => fract_in, + expon => expon_in, + sign => arg(arg'high), + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => in_fraction_width - fraction_width); + end if; + end case classcase; + else -- size increase or the same size + if exponent_width > in_exponent_width then + expon_in := SIGNED(arg (in_exponent_width-1 downto 0)); + if fptype = pos_zero or fptype = neg_zero then + result (exponent_width-1 downto 0) := (others => '0'); + elsif expon_in = -1 then -- inf or nan (shorts out check_error) + result (exponent_width-1 downto 0) := (others => '1'); + else + -- invert top BIT + expon_in(expon_in'high) := not expon_in(expon_in'high); + expon_out := resize (expon_in, expon_out'length); -- signed expand + -- Flip it back. + expon_out(expon_out'high) := not expon_out(expon_out'high); + result (exponent_width-1 downto 0) := UNRESOLVED_float(expon_out); + end if; + result (exponent_width) := arg (in_exponent_width); -- sign + else -- exponent_width = in_exponent_width + result (exponent_width downto 0) := arg (in_exponent_width downto 0); + end if; + if fraction_width > in_fraction_width then + result (-1 downto -fraction_width) := (others => '0'); -- zeros + result (-1 downto -in_fraction_width) := + arg (-1 downto -in_fraction_width); + else -- fraction_width = in_fraciton_width + result (-1 downto -fraction_width) := + arg (-1 downto -in_fraction_width); + end if; + end if; + return result; + end function resize; + + function resize ( + arg : UNRESOLVED_float; -- floating point input + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := resize (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low, + round_style => round_style, + check_error => check_error, + denormalize_in => denormalize_in, + denormalize => denormalize); + return result; + end if; + end function resize; + + function to_float32 ( + arg : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float32 is + begin + return resize (arg => arg, + exponent_width => float32'high, + fraction_width => -float32'low, + round_style => round_style, + check_error => check_error, + denormalize_in => denormalize_in, + denormalize => denormalize); + end function to_float32; + + function to_float64 ( + arg : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float64 is + begin + return resize (arg => arg, + exponent_width => float64'high, + fraction_width => -float64'low, + round_style => round_style, + check_error => check_error, + denormalize_in => denormalize_in, + denormalize => denormalize); + end function to_float64; + + function to_float128 ( + arg : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float128 is + begin + return resize (arg => arg, + exponent_width => float128'high, + fraction_width => -float128'low, + round_style => round_style, + check_error => check_error, + denormalize_in => denormalize_in, + denormalize => denormalize); + end function to_float128; + + -- to_float (Real) + -- typically not Synthesizable unless the input is a constant. + function to_float ( + arg : REAL; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable arg_real : REAL; -- Real version of argument + variable validfp : boundary_type; -- Check for valid results + variable exp : INTEGER; -- Integer version of exponent + variable expon : UNSIGNED (exponent_width - 1 downto 0); + -- Unsigned version of exp. + constant expon_base : SIGNED (exponent_width-1 downto 0) := + gen_expon_base(exponent_width); -- exponent offset + variable fract : UNSIGNED (fraction_width-1 downto 0); + variable frac : REAL; -- Real version of fraction + constant roundfrac : REAL := 2.0 ** (-2 - fract'high); -- used for rounding + variable round : BOOLEAN; -- to round or not to round + begin + result := (others => '0'); + arg_real := arg; + if arg_real < 0.0 then + result (exponent_width) := '1'; + arg_real := - arg_real; -- Make it positive. + else + result (exponent_width) := '0'; + end if; + test_boundary (arg => arg_real, + fraction_width => fraction_width, + exponent_width => exponent_width, + denormalize => denormalize, + btype => validfp, + log2i => exp); + if validfp = zero then + return result; -- Result initialized to "0". + elsif validfp = infinity then + result (exponent_width - 1 downto 0) := (others => '1'); -- Exponent all "1" + -- return infinity. + return result; + else + if validfp = denormal then -- Exponent will default to "0". + expon := (others => '0'); + frac := arg_real * (2.0 ** (to_integer(expon_base)-1)); + else -- Number less than 1. "normal" number + expon := UNSIGNED (to_signed (exp-1, exponent_width)); + expon(exponent_width-1) := not expon(exponent_width-1); + frac := (arg_real / 2.0 ** exp) - 1.0; -- Number less than 1. + end if; + for i in 0 to fract'high loop + if frac >= 2.0 ** (-1 - i) then + fract (fract'high - i) := '1'; + frac := frac - 2.0 ** (-1 - i); + else + fract (fract'high - i) := '0'; + end if; + end loop; + round := false; + case round_style is + when round_nearest => + if frac > roundfrac or ((frac = roundfrac) and fract(0) = '1') then + round := true; + end if; + when round_inf => + if frac /= 0.0 and result(exponent_width) = '0' then + round := true; + end if; + when round_neginf => + if frac /= 0.0 and result(exponent_width) = '1' then + round := true; + end if; + when others => + null; -- don't round + end case; + if (round) then + if and(fract) = '1' then -- fraction is all "1" + expon := expon + 1; + fract := (others => '0'); + else + fract := fract + 1; + end if; + end if; + result (exponent_width-1 downto 0) := UNRESOLVED_float(expon); + result (-1 downto -fraction_width) := UNRESOLVED_float(fract); + return result; + end if; + end function to_float; + + -- to_float (Integer) + function to_float ( + arg : INTEGER; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable arg_int : NATURAL; -- Natural version of argument + variable expon : SIGNED (exponent_width-1 downto 0); + variable exptmp : SIGNED (exponent_width-1 downto 0); + -- Unsigned version of exp. + constant expon_base : SIGNED (exponent_width-1 downto 0) := + gen_expon_base(exponent_width); -- exponent offset + variable fract : UNSIGNED (fraction_width-1 downto 0) := (others => '0'); + variable fracttmp : UNSIGNED (fraction_width-1 downto 0); + variable round : BOOLEAN; + variable shift : NATURAL; + variable shiftr : NATURAL; + variable roundfrac : NATURAL; -- used in rounding + begin + if arg < 0 then + result (exponent_width) := '1'; + arg_int := -arg; -- Make it positive. + else + result (exponent_width) := '0'; + arg_int := arg; + end if; + if arg_int = 0 then + result := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + -- If the number is larger than we can represent in this number system + -- we need to return infinity. + shift := log2(arg_int); + if shift > to_integer(expon_base) then + -- worry about infinity + if result (exponent_width) = '0' then + result := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + -- return negative infinity. + result := neg_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + end if; + else -- Normal number (can't be denormal) + -- Compute Exponent + expon := to_signed (shift-1, expon'length); -- positive fraction. + -- Compute Fraction + arg_int := arg_int - 2**shift; -- Subtract off the 1.0 + shiftr := shift; + for I in fract'high downto maximum (fract'high - shift + 1, 0) loop + shiftr := shiftr - 1; + if (arg_int >= 2**shiftr) then + arg_int := arg_int - 2**shiftr; + fract(I) := '1'; + else + fract(I) := '0'; + end if; + end loop; + -- Rounding routine + round := false; + if arg_int > 0 then + roundfrac := 2**(shiftr-1); + case round_style is + when round_nearest => + if arg_int > roundfrac or + ((arg_int = roundfrac) and fract(0) = '1') then + round := true; + end if; + when round_inf => + if arg_int /= 0 and result (exponent_width) = '0' then + round := true; + end if; + when round_neginf => + if arg_int /= 0 and result (exponent_width) = '1' then + round := true; + end if; + when others => + null; + end case; + end if; + if round then + fp_round(fract_in => fract, + expon_in => expon, + fract_out => fracttmp, + expon_out => exptmp); + fract := fracttmp; + expon := exptmp; + end if; + -- Put the number together and return + expon(exponent_width-1) := not expon(exponent_width-1); + result (exponent_width-1 downto 0) := UNRESOLVED_float(expon); + result (-1 downto -fraction_width) := UNRESOLVED_float(fract); + end if; + end if; + return result; + end function to_float; + + -- to_float (unsigned) + function to_float ( + arg : UNSIGNED; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : UNSIGNED(ARG_LEFT downto 0) is ARG; + variable sarg : SIGNED (ARG_LEFT+1 downto 0); -- signed version of arg + begin + if arg'length < 1 then + return NAFP; + end if; + sarg (XARG'range) := SIGNED (XARG); + sarg (sarg'high) := '0'; + result := to_float (arg => sarg, + exponent_width => exponent_width, + fraction_width => fraction_width, + round_style => round_style); + return result; + end function to_float; + + -- to_float (signed) + function to_float ( + arg : SIGNED; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : SIGNED(ARG_LEFT downto 0) is ARG; + variable arg_int : UNSIGNED(xarg'range); -- Real version of argument + variable argb2 : UNSIGNED(xarg'high/2 downto 0); -- log2 of input + variable rexp : SIGNED (exponent_width - 1 downto 0); + variable exp : SIGNED (exponent_width - 1 downto 0); + -- signed version of exp. + variable expon : UNSIGNED (exponent_width - 1 downto 0); + -- Unsigned version of exp. + constant expon_base : SIGNED (exponent_width-1 downto 0) := + gen_expon_base(exponent_width); -- exponent offset + variable round : BOOLEAN; + variable fract : UNSIGNED (fraction_width-1 downto 0); + variable rfract : UNSIGNED (fraction_width-1 downto 0); + variable sign : STD_ULOGIC; -- sign bit + begin + if arg'length < 1 then + return NAFP; + end if; + if Is_X (xarg) then + result := (others => 'X'); + elsif (xarg = 0) then + result := zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + else -- Normal number (can't be denormal) + sign := to_X01(xarg (xarg'high)); + arg_int := UNSIGNED(abs (to_01(xarg))); + -- Compute Exponent + argb2 := to_unsigned(find_leftmost(arg_int, '1'), argb2'length); -- Log2 + if argb2 > UNSIGNED(expon_base) then + result := pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + result (exponent_width) := sign; + else + exp := SIGNED(resize(argb2, exp'length)); + arg_int := shift_left (arg_int, arg_int'high-to_integer(exp)); + if (arg_int'high > fraction_width) then + fract := arg_int (arg_int'high-1 downto (arg_int'high-fraction_width)); + round := check_round ( + fract_in => fract (0), + sign => sign, + remainder => arg_int((arg_int'high-fraction_width-1) + downto 0), + round_style => round_style); + if round then + fp_round(fract_in => fract, + expon_in => exp, + fract_out => rfract, + expon_out => rexp); + else + rfract := fract; + rexp := exp; + end if; + else + rexp := exp; + rfract := (others => '0'); + rfract (fraction_width-1 downto fraction_width-1-(arg_int'high-1)) := + arg_int (arg_int'high-1 downto 0); + end if; + result (exponent_width) := sign; + expon := UNSIGNED (rexp-1); + expon(exponent_width-1) := not expon(exponent_width-1); + result (exponent_width-1 downto 0) := UNRESOLVED_float(expon); + result (-1 downto -fraction_width) := UNRESOLVED_float(rfract); + end if; + end if; + return result; + end function to_float; + + -- std_logic_vector to float + function to_float ( + arg : STD_ULOGIC_VECTOR; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width) -- length of FP output fraction + return UNRESOLVED_float + is + variable fpvar : UNRESOLVED_float (exponent_width downto -fraction_width); + begin + if arg'length < 1 then + return NAFP; + end if; + fpvar := UNRESOLVED_float(arg); + return fpvar; + end function to_float; + + -- purpose: converts a ufixed to a floating point + function to_float ( + arg : UNRESOLVED_ufixed; -- unsigned fixed point input + constant exponent_width : NATURAL := float_exponent_width; -- width of exponent + constant fraction_width : NATURAL := float_fraction_width; -- width of fraction + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- use ieee extensions + return UNRESOLVED_float + is + variable sarg : sfixed (arg'high+1 downto arg'low); -- Signed version of arg + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + begin -- function to_float + if (arg'length < 1) then + return NAFP; + end if; + sarg (arg'range) := sfixed (arg); + sarg (sarg'high) := '0'; + result := to_float (arg => sarg, + exponent_width => exponent_width, + fraction_width => fraction_width, + round_style => round_style, + denormalize => denormalize); + return result; + end function to_float; + + function to_float ( + arg : UNRESOLVED_sfixed; -- signed fixed point + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- rounding option + return UNRESOLVED_float + is + constant integer_width : INTEGER := arg'high; + constant in_fraction_width : INTEGER := arg'low; + variable xresult : sfixed (integer_width downto in_fraction_width); + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable arg_int : UNSIGNED(integer_width - in_fraction_width - 1 + downto 0); -- signed version of argument + variable argx : SIGNED (integer_width - in_fraction_width downto 0); + variable exp, exptmp : SIGNED (exponent_width downto 0); + variable expon : UNSIGNED (exponent_width - 1 downto 0); + -- Unsigned version of exp. + constant expon_base : SIGNED (exponent_width-1 downto 0) := + gen_expon_base(exponent_width); -- exponent offset + variable fract, fracttmp : UNSIGNED (fraction_width-1 downto 0) := + (others => '0'); + variable round : BOOLEAN := false; + begin + if (arg'length < 1) then + return NAFP; + end if; + xresult := to_01(arg, 'X'); + argx := SIGNED(to_slv(xresult)); + if (Is_X (arg)) then + result := (others => 'X'); + elsif (argx = 0) then + result := (others => '0'); + else + result := (others => '0'); -- zero out the result + if argx(argx'left) = '1' then -- toss the sign bit + result (exponent_width) := '1'; -- Negative number + argx := -argx; -- Make it positive. + else + result (exponent_width) := '0'; + end if; + arg_int := UNSIGNED(to_x01(STD_LOGIC_VECTOR (argx(arg_int'range)))); + -- Compute Exponent + exp := to_signed(find_leftmost(arg_int, '1'), exp'length); -- Log2 + if exp + in_fraction_width > expon_base then -- return infinity + result (-1 downto -fraction_width) := (others => '0'); + result (exponent_width -1 downto 0) := (others => '1'); + return result; + elsif (denormalize and + (exp + in_fraction_width <= -resize(expon_base, exp'length))) then + exp := -resize(expon_base, exp'length); + -- shift by a constant + arg_int := shift_left (arg_int, + (arg_int'high + to_integer(expon_base) + + in_fraction_width - 1)); + if (arg_int'high > fraction_width) then + fract := arg_int (arg_int'high-1 downto (arg_int'high-fraction_width)); + round := check_round ( + fract_in => arg_int(arg_int'high-fraction_width), + sign => result(result'high), + remainder => arg_int((arg_int'high-fraction_width-1) + downto 0), + round_style => round_style); + if (round) then + fp_round (fract_in => arg_int (arg_int'high-1 downto + (arg_int'high-fraction_width)), + expon_in => exp, + fract_out => fract, + expon_out => exptmp); + exp := exptmp; + end if; + else + fract (fraction_width-1 downto fraction_width-1-(arg_int'high-1)) := + arg_int (arg_int'high-1 downto 0); + end if; + else + arg_int := shift_left (arg_int, arg_int'high-to_integer(exp)); + exp := exp + in_fraction_width; + if (arg_int'high > fraction_width) then + fract := arg_int (arg_int'high-1 downto (arg_int'high-fraction_width)); + round := check_round ( + fract_in => fract(0), + sign => result(result'high), + remainder => arg_int((arg_int'high-fraction_width-1) + downto 0), + round_style => round_style); + if (round) then + fp_round (fract_in => fract, + expon_in => exp, + fract_out => fracttmp, + expon_out => exptmp); + fract := fracttmp; + exp := exptmp; + end if; + else + fract (fraction_width-1 downto fraction_width-1-(arg_int'high-1)) := + arg_int (arg_int'high-1 downto 0); + end if; + end if; + expon := UNSIGNED (resize(exp-1, exponent_width)); + expon(exponent_width-1) := not expon(exponent_width-1); + result (exponent_width-1 downto 0) := UNRESOLVED_float(expon); + result (-1 downto -fraction_width) := UNRESOLVED_float(fract); + end if; + return result; + end function to_float; + + -- size_res functions + -- Integer to float + function to_float ( + arg : INTEGER; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_float (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low, + round_style => round_style); + return result; + end if; + end function to_float; + + -- real to float + function to_float ( + arg : REAL; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_float (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low, + round_style => round_style, + denormalize => denormalize); + return result; + end if; + end function to_float; + + -- unsigned to float + function to_float ( + arg : UNRESOLVED_UNSIGNED; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_float (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low, + round_style => round_style); + return result; + end if; + end function to_float; + + -- signed to float + function to_float ( + arg : UNRESOLVED_SIGNED; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style) -- rounding + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_float (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low, + round_style => round_style); + return result; + end if; + end function to_float; + + -- std_ulogic_vector to float + function to_float ( + arg : STD_ULOGIC_VECTOR; + size_res : UNRESOLVED_float) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_float (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low); + return result; + end if; + end function to_float; + + -- unsigned fixed point to float + function to_float ( + arg : UNRESOLVED_ufixed; -- unsigned fixed point input + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- use ieee extensions + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_float (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low, + round_style => round_style, + denormalize => denormalize); + return result; + end if; + end function to_float; + + -- signed fixed point to float + function to_float ( + arg : UNRESOLVED_sfixed; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- rounding option + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_float (arg => arg, + exponent_width => size_res'high, + fraction_width => -size_res'low, + round_style => round_style, + denormalize => denormalize); + return result; + end if; + end function to_float; + + -- to_integer (float) + function to_integer ( + arg : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return INTEGER + is + variable validfp : valid_fpstate; -- Valid FP state + variable frac : UNSIGNED (-arg'low downto 0); -- Fraction + variable fract : UNSIGNED (1-arg'low downto 0); -- Fraction + variable expon : SIGNED (arg'high-1 downto 0); + variable isign : STD_ULOGIC; -- internal version of sign + variable round : STD_ULOGIC; -- is rounding needed? + variable result : INTEGER; + variable base : INTEGER; -- Integer exponent + begin + validfp := classfp (arg, check_error); + classcase : case validfp is + when isx | nan | quiet_nan | pos_zero | neg_zero | pos_denormal | neg_denormal => + result := 0; -- return 0 + when pos_inf => + result := INTEGER'high; + when neg_inf => + result := INTEGER'low; + when others => + break_number ( + arg => arg, + fptyp => validfp, + denormalize => false, + fract => frac, + expon => expon); + fract (fract'high) := '0'; -- Add extra bit for 0.6 case + fract (fract'high-1 downto 0) := frac; + isign := to_x01 (arg (arg'high)); + base := to_integer (expon) + 1; + if base < -1 then + result := 0; + elsif base >= frac'high then + result := to_integer (fract) * 2**(base - frac'high); + else -- We need to round + if base = -1 then -- trap for 0.6 case. + result := 0; + else + result := to_integer (fract (frac'high downto frac'high-base)); + end if; + -- rounding routine + case round_style is + when round_nearest => + if frac'high - base > 1 then + round := fract (frac'high - base - 1) and + (fract (frac'high - base) + or (or (fract (frac'high - base - 2 downto 0)))); + else + round := fract (frac'high - base - 1) and + fract (frac'high - base); + end if; + when round_inf => + round := fract(frac'high - base - 1) and not isign; + when round_neginf => + round := fract(frac'high - base - 1) and isign; + when others => + round := '0'; + end case; + if round = '1' then + result := result + 1; + end if; + end if; + if isign = '1' then + result := - result; + end if; + end case classcase; + return result; + end function to_integer; + + -- to_unsigned (float) + function to_unsigned ( + arg : UNRESOLVED_float; -- floating point input + constant size : NATURAL; -- length of output + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_UNSIGNED + is + variable validfp : valid_fpstate; -- Valid FP state + variable frac : UNRESOLVED_UNSIGNED (size-1 downto 0); -- Fraction + variable sign : STD_ULOGIC; -- not used + begin + validfp := classfp (arg, check_error); + classcase : case validfp is + when isx | nan | quiet_nan => + frac := (others => 'X'); + when pos_zero | neg_inf | neg_zero | neg_normal | pos_denormal | neg_denormal => + frac := (others => '0'); -- return 0 + when pos_inf => + frac := (others => '1'); + when others => + float_to_unsigned ( + arg => arg, + frac => frac, + sign => sign, + denormalize => false, + bias => 0, + round_style => round_style); + end case classcase; + return (frac); + end function to_unsigned; + + -- to_signed (float) + function to_signed ( + arg : UNRESOLVED_float; -- floating point input + constant size : NATURAL; -- length of output + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_SIGNED + is + variable sign : STD_ULOGIC; -- true if negative + variable validfp : valid_fpstate; -- Valid FP state + variable frac : UNRESOLVED_UNSIGNED (size-1 downto 0); -- Fraction + variable result : UNRESOLVED_SIGNED (size-1 downto 0); + begin + validfp := classfp (arg, check_error); + classcase : case validfp is + when isx | nan | quiet_nan => + result := (others => 'X'); + when pos_zero | neg_zero | pos_denormal | neg_denormal => + result := (others => '0'); -- return 0 + when pos_inf => + result := (others => '1'); + result (result'high) := '0'; + when neg_inf => + result := (others => '0'); + result (result'high) := '1'; + when others => + float_to_unsigned ( + arg => arg, + sign => sign, + frac => frac, + denormalize => false, + bias => 0, + round_style => round_style); + result (size-1) := '0'; + result (size-2 downto 0) := UNRESOLVED_SIGNED(frac (size-2 downto 0)); + if sign = '1' then + -- Because the most negative signed number is 1 less than the most + -- positive signed number, we need this code. + if frac(frac'high) = '1' then -- return most negative number + result := (others => '0'); + result (result'high) := '1'; + else + result := -result; + end if; + else + if frac(frac'high) = '1' then -- return most positive number + result := (others => '1'); + result (result'high) := '0'; + end if; + end if; + end case classcase; + return result; + end function to_signed; + + -- purpose: Converts a float to ufixed + function to_ufixed ( + arg : UNRESOLVED_float; -- fp input + constant left_index : INTEGER; -- integer part + constant right_index : INTEGER; -- fraction part + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_ufixed + is + constant fraction_width : INTEGER := -mine(arg'low, arg'low); -- length of FP output fraction + constant exponent_width : INTEGER := arg'high; -- length of FP output exponent + constant size : INTEGER := left_index - right_index + 4; -- unsigned size + variable expon_base : INTEGER; -- exponent offset + variable validfp : valid_fpstate; -- Valid FP state + variable exp : INTEGER; -- Exponent + variable expon : UNSIGNED (exponent_width-1 downto 0); -- Vectorized exponent + -- Base to divide fraction by + variable frac : UNSIGNED (size-1 downto 0) := (others => '0'); -- Fraction + variable frac_shift : UNSIGNED (size-1 downto 0); -- Fraction shifted + variable shift : INTEGER; + variable result_big : UNRESOLVED_ufixed (left_index downto right_index-3); + variable result : UNRESOLVED_ufixed (left_index downto right_index); -- result + begin -- function to_ufixed + validfp := classfp (arg, check_error); + classcase : case validfp is + when isx | nan | quiet_nan => + frac := (others => 'X'); + when pos_zero | neg_inf | neg_zero | neg_normal | neg_denormal => + frac := (others => '0'); -- return 0 + when pos_inf => + frac := (others => '1'); -- always saturate + when others => + expon_base := 2**(exponent_width-1) -1; -- exponent offset + -- Figure out the fraction + if (validfp = pos_denormal) and denormalize then + exp := -expon_base +1; + frac (frac'high) := '0'; -- Remove the "1.0". + else + -- exponent /= '0', normal floating point + expon := UNSIGNED(arg (exponent_width-1 downto 0)); + expon(exponent_width-1) := not expon(exponent_width-1); + exp := to_integer (SIGNED(expon)) +1; + frac (frac'high) := '1'; -- Add the "1.0". + end if; + shift := (frac'high - 3 + right_index) - exp; + if fraction_width > frac'high then -- Can only use size-2 bits + frac (frac'high-1 downto 0) := UNSIGNED (to_slv (arg(-1 downto + -frac'high))); + else -- can use all bits + frac (frac'high-1 downto frac'high-fraction_width) := + UNSIGNED (to_slv (arg(-1 downto -fraction_width))); + end if; + frac_shift := frac srl shift; + if shift < 0 then -- Overflow + frac := (others => '1'); + else + frac := frac_shift; + end if; + end case classcase; + result_big := to_ufixed ( + arg => STD_ULOGIC_VECTOR(frac), + left_index => left_index, + right_index => (right_index-3)); + result := resize (arg => result_big, + left_index => left_index, + right_index => right_index, + round_style => round_style, + overflow_style => overflow_style); + return result; + end function to_ufixed; + + -- purpose: Converts a float to sfixed + function to_sfixed ( + arg : UNRESOLVED_float; -- fp input + constant left_index : INTEGER; -- integer part + constant right_index : INTEGER; -- fraction part + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_sfixed + is + constant fraction_width : INTEGER := -mine(arg'low, arg'low); -- length of FP output fraction + constant exponent_width : INTEGER := arg'high; -- length of FP output exponent + constant size : INTEGER := left_index - right_index + 4; -- unsigned size + variable expon_base : INTEGER; -- exponent offset + variable validfp : valid_fpstate; -- Valid FP state + variable exp : INTEGER; -- Exponent + variable sign : BOOLEAN; -- true if negative + variable expon : UNSIGNED (exponent_width-1 downto 0); -- Vectorized exponent + -- Base to divide fraction by + variable frac : UNSIGNED (size-2 downto 0) := (others => '0'); -- Fraction + variable frac_shift : UNSIGNED (size-2 downto 0); -- Fraction shifted + variable shift : INTEGER; + variable rsigned : SIGNED (size-1 downto 0); -- signed version of result + variable result_big : UNRESOLVED_sfixed (left_index downto right_index-3); + variable result : UNRESOLVED_sfixed (left_index downto right_index) + := (others => '0'); -- result + begin -- function to_sfixed + validfp := classfp (arg, check_error); + classcase : case validfp is + when isx | nan | quiet_nan => + result := (others => 'X'); + when pos_zero | neg_zero => + result := (others => '0'); -- return 0 + when neg_inf => + result (left_index) := '1'; -- return smallest negative number + when pos_inf => + result := (others => '1'); -- return largest number + result (left_index) := '0'; + when others => + expon_base := 2**(exponent_width-1) -1; -- exponent offset + if arg(exponent_width) = '0' then + sign := false; + else + sign := true; + end if; + -- Figure out the fraction + if (validfp = pos_denormal or validfp = neg_denormal) + and denormalize then + exp := -expon_base +1; + frac (frac'high) := '0'; -- Add the "1.0". + else + -- exponent /= '0', normal floating point + expon := UNSIGNED(arg (exponent_width-1 downto 0)); + expon(exponent_width-1) := not expon(exponent_width-1); + exp := to_integer (SIGNED(expon)) +1; + frac (frac'high) := '1'; -- Add the "1.0". + end if; + shift := (frac'high - 3 + right_index) - exp; + if fraction_width > frac'high then -- Can only use size-2 bits + frac (frac'high-1 downto 0) := UNSIGNED (to_slv (arg(-1 downto + -frac'high))); + else -- can use all bits + frac (frac'high-1 downto frac'high-fraction_width) := + UNSIGNED (to_slv (arg(-1 downto -fraction_width))); + end if; + frac_shift := frac srl shift; + if shift < 0 then -- Overflow + frac := (others => '1'); + else + frac := frac_shift; + end if; + if not sign then + rsigned := SIGNED("0" & frac); + else + rsigned := -(SIGNED("0" & frac)); + end if; + result_big := to_sfixed ( + arg => STD_LOGIC_VECTOR(rsigned), + left_index => left_index, + right_index => (right_index-3)); + result := resize (arg => result_big, + left_index => left_index, + right_index => right_index, + round_style => round_style, + overflow_style => overflow_style); + end case classcase; + return result; + end function to_sfixed; + + -- size_res versions + -- float to unsigned + function to_unsigned ( + arg : UNRESOLVED_float; -- floating point input + size_res : UNRESOLVED_UNSIGNED; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_UNSIGNED + is + variable result : UNRESOLVED_UNSIGNED (size_res'range); + begin + if (SIZE_RES'length = 0) then + return result; + else + result := to_unsigned ( + arg => arg, + size => size_res'length, + round_style => round_style, + check_error => check_error); + return result; + end if; + end function to_unsigned; + + -- float to signed + function to_signed ( + arg : UNRESOLVED_float; -- floating point input + size_res : UNRESOLVED_SIGNED; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_SIGNED + is + variable result : UNRESOLVED_SIGNED (size_res'range); + begin + if (SIZE_RES'length = 0) then + return result; + else + result := to_signed ( + arg => arg, + size => size_res'length, + round_style => round_style, + check_error => check_error); + return result; + end if; + end function to_signed; + + -- purpose: Converts a float to unsigned fixed point + function to_ufixed ( + arg : UNRESOLVED_float; -- fp input + size_res : UNRESOLVED_ufixed; + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_ufixed + is + variable result : UNRESOLVED_ufixed (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_ufixed ( + arg => arg, + left_index => size_res'high, + right_index => size_res'low, + overflow_style => overflow_style, + round_style => round_style, + check_error => check_error, + denormalize => denormalize); + return result; + end if; + end function to_ufixed; + + -- float to signed fixed point + function to_sfixed ( + arg : UNRESOLVED_float; -- fp input + size_res : UNRESOLVED_sfixed; + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_sfixed + is + variable result : UNRESOLVED_sfixed (size_res'left downto size_res'right); + begin + if (result'length < 1) then + return result; + else + result := to_sfixed ( + arg => arg, + left_index => size_res'high, + right_index => size_res'low, + overflow_style => overflow_style, + round_style => round_style, + check_error => check_error, + denormalize => denormalize); + return result; + end if; + end function to_sfixed; + + -- to_real (float) + -- typically not Synthesizable unless the input is a constant. + function to_real ( + arg : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return REAL + is + constant fraction_width : INTEGER := -mine(arg'low, arg'low); -- length of FP output fraction + constant exponent_width : INTEGER := arg'high; -- length of FP output exponent + variable sign : REAL; -- Sign, + or - 1 + variable exp : INTEGER; -- Exponent + variable expon_base : INTEGER; -- exponent offset + variable frac : REAL := 0.0; -- Fraction + variable validfp : valid_fpstate; -- Valid FP state + variable expon : UNSIGNED (exponent_width - 1 downto 0) + := (others => '1'); -- Vectorized exponent + begin + validfp := classfp (arg, check_error); + classcase : case validfp is + when isx | pos_zero | neg_zero | nan | quiet_nan => + return 0.0; + when neg_inf => + return REAL'low; -- Negative infinity. + when pos_inf => + return REAL'high; -- Positive infinity + when others => + expon_base := 2**(exponent_width-1) -1; + if to_X01(arg(exponent_width)) = '0' then + sign := 1.0; + else + sign := -1.0; + end if; + -- Figure out the fraction + for i in 0 to fraction_width-1 loop + if to_X01(arg (-1 - i)) = '1' then + frac := frac + (2.0 **(-1 - i)); + end if; + end loop; -- i + if validfp = pos_normal or validfp = neg_normal or not denormalize then + -- exponent /= '0', normal floating point + expon := UNSIGNED(arg (exponent_width-1 downto 0)); + expon(exponent_width-1) := not expon(exponent_width-1); + exp := to_integer (SIGNED(expon)) +1; + sign := sign * (2.0 ** exp) * (1.0 + frac); + else -- exponent = '0', IEEE extended floating point + exp := 1 - expon_base; + sign := sign * (2.0 ** exp) * frac; + end if; + return sign; + end case classcase; + end function to_real; + + -- For Verilog compatability + function realtobits (arg : REAL) return STD_ULOGIC_VECTOR is + variable result : float64; -- 64 bit floating point + begin + result := to_float (arg => arg, + exponent_width => float64'high, + fraction_width => -float64'low); + return to_sulv (result); + end function realtobits; + + function bitstoreal (arg : STD_ULOGIC_VECTOR) return REAL is + variable arg64 : float64; -- arg converted to float + begin + arg64 := to_float (arg => arg, + exponent_width => float64'high, + fraction_width => -float64'low); + return to_real (arg64); + end function bitstoreal; + + -- purpose: Removes meta-logical values from FP string + function to_01 ( + arg : UNRESOLVED_float; -- floating point input + XMAP : STD_LOGIC := '0') + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (arg'range); + begin -- function to_01 + if (arg'length < 1) then + assert NO_WARNING + report FLOAT_GENERIC_PKG'instance_name + & "TO_01: null detected, returning NULL" + severity warning; + return NAFP; + end if; + result := UNRESOLVED_float (STD_LOGIC_VECTOR(to_01(UNSIGNED(to_slv(arg)), XMAP))); + return result; + end function to_01; + + function Is_X + (arg : UNRESOLVED_float) + return BOOLEAN is + begin + return Is_X (to_slv(arg)); + end function Is_X; + + function to_X01 (arg : UNRESOLVED_float) return UNRESOLVED_float is + variable result : UNRESOLVED_float (arg'range); + begin + if (arg'length < 1) then + assert NO_WARNING + report FLOAT_GENERIC_PKG'instance_name + & "TO_X01: null detected, returning NULL" + severity warning; + return NAFP; + else + result := UNRESOLVED_float (to_X01(to_slv(arg))); + return result; + end if; + end function to_X01; + + function to_X01Z (arg : UNRESOLVED_float) return UNRESOLVED_float is + variable result : UNRESOLVED_float (arg'range); + begin + if (arg'length < 1) then + assert NO_WARNING + report FLOAT_GENERIC_PKG'instance_name + & "TO_X01Z: null detected, returning NULL" + severity warning; + return NAFP; + else + result := UNRESOLVED_float (to_X01Z(to_slv(arg))); + return result; + end if; + end function to_X01Z; + + function to_UX01 (arg : UNRESOLVED_float) return UNRESOLVED_float is + variable result : UNRESOLVED_float (arg'range); + begin + if (arg'length < 1) then + assert NO_WARNING + report FLOAT_GENERIC_PKG'instance_name + & "TO_UX01: null detected, returning NULL" + severity warning; + return NAFP; + else + result := UNRESOLVED_float (to_UX01(to_slv(arg))); + return result; + end if; + end function to_UX01; + + -- These allows the base math functions to use the default values + -- of their parameters. Thus they do full IEEE floating point. + function "+" (l, r : UNRESOLVED_float) return UNRESOLVED_float is + begin + return add (l, r); + end function "+"; + + function "-" (l, r : UNRESOLVED_float) return UNRESOLVED_float is + begin + return subtract (l, r); + end function "-"; + + function "*" (l, r : UNRESOLVED_float) return UNRESOLVED_float is + begin + return multiply (l, r); + end function "*"; + + function "/" (l, r : UNRESOLVED_float) return UNRESOLVED_float is + begin + return divide (l, r); + end function "/"; + + function "rem" (l, r : UNRESOLVED_float) return UNRESOLVED_float is + begin + return remainder (l, r); + end function "rem"; + + function "mod" (l, r : UNRESOLVED_float) return UNRESOLVED_float is + begin + return modulo (l, r); + end function "mod"; + + -- overloaded versions + function "+" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return add (l, r_float); + end function "+"; + + function "+" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return add (l_float, r); + end function "+"; + + function "+" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return add (l, r_float); + end function "+"; + + function "+" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return add (l_float, r); + end function "+"; + + function "-" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return subtract (l, r_float); + end function "-"; + + function "-" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return subtract (l_float, r); + end function "-"; + + function "-" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return subtract (l, r_float); + end function "-"; + + function "-" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return subtract (l_float, r); + end function "-"; + + function "*" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return multiply (l, r_float); + end function "*"; + + function "*" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return multiply (l_float, r); + end function "*"; + + function "*" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return multiply (l, r_float); + end function "*"; + + function "*" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return multiply (l_float, r); + end function "*"; + + function "/" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return divide (l, r_float); + end function "/"; + + function "/" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return divide (l_float, r); + end function "/"; + + function "/" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return divide (l, r_float); + end function "/"; + + function "/" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return divide (l_float, r); + end function "/"; + + function "rem" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return remainder (l, r_float); + end function "rem"; + + function "rem" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return remainder (l_float, r); + end function "rem"; + + function "rem" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return remainder (l, r_float); + end function "rem"; + + function "rem" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return remainder (l_float, r); + end function "rem"; + + function "mod" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return modulo (l, r_float); + end function "mod"; + + function "mod" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return modulo (l_float, r); + end function "mod"; + + function "mod" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return modulo (l, r_float); + end function "mod"; + + function "mod" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return modulo (l_float, r); + end function "mod"; + + function "=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return eq (l, r_float); + end function "="; + + function "/=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return ne (l, r_float); + end function "/="; + + function ">=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return ge (l, r_float); + end function ">="; + + function "<=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return le (l, r_float); + end function "<="; + + function ">" (l : UNRESOLVED_float; r : REAL) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return gt (l, r_float); + end function ">"; + + function "<" (l : UNRESOLVED_float; r : REAL) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return lt (l, r_float); + end function "<"; + + function "=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return eq (l_float, r); + end function "="; + + function "/=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return ne (l_float, r); + end function "/="; + + function ">=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return ge (l_float, r); + end function ">="; + + function "<=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return le (l_float, r); + end function "<="; + + function ">" (l : REAL; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return gt (l_float, r); + end function ">"; + + function "<" (l : REAL; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return lt (l_float, r); + end function "<"; + + function "=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return eq (l, r_float); + end function "="; + + function "/=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return ne (l, r_float); + end function "/="; + + function ">=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return ge (l, r_float); + end function ">="; + + function "<=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return le (l, r_float); + end function "<="; + + function ">" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return gt (l, r_float); + end function ">"; + + function "<" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return lt (l, r_float); + end function "<"; + + function "=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return eq (l_float, r); + end function "="; + + function "/=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return ne (l_float, r); + end function "/="; + + function ">=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return ge (l_float, r); + end function ">="; + + function "<=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return le (l_float, r); + end function "<="; + + function ">" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return gt (l_float, r); + end function ">"; + + function "<" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float(l, r'high, -r'low); + return lt (l_float, r); + end function "<"; + + -- ?= overloads + function "?=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?= r_float; + end function "?="; + + function "?/=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?/= r_float; + end function "?/="; + + function "?>" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?> r_float; + end function "?>"; + + function "?>=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?>= r_float; + end function "?>="; + + function "?<" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?< r_float; + end function "?<"; + + function "?<=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?<= r_float; + end function "?<="; + + -- real and float + function "?=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?= r; + end function "?="; + + function "?/=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?/= r; + end function "?/="; + + function "?>" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?> r; + end function "?>"; + + function "?>=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?>= r; + end function "?>="; + + function "?<" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?< r; + end function "?<"; + + function "?<=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?<= r; + end function "?<="; + + -- ?= overloads + function "?=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?= r_float; + end function "?="; + + function "?/=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?/= r_float; + end function "?/="; + + function "?>" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?> r_float; + end function "?>"; + + function "?>=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?>= r_float; + end function "?>="; + + function "?<" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?< r_float; + end function "?<"; + + function "?<=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return l ?<= r_float; + end function "?<="; + + -- integer and float + function "?=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?= r; + end function "?="; + + function "?/=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?/= r; + end function "?/="; + + function "?>" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?> r; + end function "?>"; + + function "?>=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?>= r; + end function "?>="; + + function "?<" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?< r; + end function "?<"; + + function "?<=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return l_float ?<= r; + end function "?<="; + + -- minimum and maximum overloads + function minimum (l : UNRESOLVED_float; r : REAL) + return UNRESOLVED_float + is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return minimum (l, r_float); + end function minimum; + + function maximum (l : UNRESOLVED_float; r : REAL) + return UNRESOLVED_float + is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return maximum (l, r_float); + end function maximum; + + function minimum (l : REAL; r : UNRESOLVED_float) + return UNRESOLVED_float + is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return minimum (l_float, r); + end function minimum; + + function maximum (l : REAL; r : UNRESOLVED_float) + return UNRESOLVED_float + is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return maximum (l_float, r); + end function maximum; + + function minimum (l : UNRESOLVED_float; r : INTEGER) + return UNRESOLVED_float + is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return minimum (l, r_float); + end function minimum; + + function maximum (l : UNRESOLVED_float; r : INTEGER) + return UNRESOLVED_float + is + variable r_float : UNRESOLVED_float (l'range); + begin + r_float := to_float (r, l'high, -l'low); + return maximum (l, r_float); + end function maximum; + + function minimum (l : INTEGER; r : UNRESOLVED_float) + return UNRESOLVED_float + is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return minimum (l_float, r); + end function minimum; + + function maximum (l : INTEGER; r : UNRESOLVED_float) + return UNRESOLVED_float + is + variable l_float : UNRESOLVED_float (r'range); + begin + l_float := to_float (l, r'high, -r'low); + return maximum (l_float, r); + end function maximum; + + ---------------------------------------------------------------------------- + -- logical functions + ---------------------------------------------------------------------------- + function "not" (L : UNRESOLVED_float) return UNRESOLVED_float is + variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto + begin + RESULT := not to_sulv(L); + return to_float (RESULT, L'high, -L'low); + end function "not"; + + function "and" (L, R : UNRESOLVED_float) return UNRESOLVED_float 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 float_generic_pkg'instance_name + & """and"": Range error L'RANGE /= R'RANGE" + severity warning; + RESULT := (others => 'X'); + end if; + return to_float (RESULT, L'high, -L'low); + end function "and"; + + function "or" (L, R : UNRESOLVED_float) return UNRESOLVED_float 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 float_generic_pkg'instance_name + & """or"": Range error L'RANGE /= R'RANGE" + severity warning; + RESULT := (others => 'X'); + end if; + return to_float (RESULT, L'high, -L'low); + end function "or"; + + function "nand" (L, R : UNRESOLVED_float) return UNRESOLVED_float 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 float_generic_pkg'instance_name + & """nand"": Range error L'RANGE /= R'RANGE" + severity warning; + RESULT := (others => 'X'); + end if; + return to_float (RESULT, L'high, -L'low); + end function "nand"; + + function "nor" (L, R : UNRESOLVED_float) return UNRESOLVED_float 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 float_generic_pkg'instance_name + & """nor"": Range error L'RANGE /= R'RANGE" + severity warning; + RESULT := (others => 'X'); + end if; + return to_float (RESULT, L'high, -L'low); + end function "nor"; + + function "xor" (L, R : UNRESOLVED_float) return UNRESOLVED_float 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 float_generic_pkg'instance_name + & """xor"": Range error L'RANGE /= R'RANGE" + severity warning; + RESULT := (others => 'X'); + end if; + return to_float (RESULT, L'high, -L'low); + end function "xor"; + + function "xnor" (L, R : UNRESOLVED_float) return UNRESOLVED_float 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 float_generic_pkg'instance_name + & """xnor"": Range error L'RANGE /= R'RANGE" + severity warning; + RESULT := (others => 'X'); + end if; + return to_float (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_float) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (R'range); + begin + result := UNRESOLVED_float (L and to_sulv(R)); + return result; + end function "and"; + + function "and" (L : UNRESOLVED_float; R : STD_ULOGIC) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (L'range); + begin + result := UNRESOLVED_float (to_sulv(L) and R); + return result; + end function "and"; + + function "or" (L : STD_ULOGIC; R : UNRESOLVED_float) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (R'range); + begin + result := UNRESOLVED_float (L or to_sulv(R)); + return result; + end function "or"; + + function "or" (L : UNRESOLVED_float; R : STD_ULOGIC) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (L'range); + begin + result := UNRESOLVED_float (to_sulv(L) or R); + return result; + end function "or"; + + function "nand" (L : STD_ULOGIC; R : UNRESOLVED_float) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (R'range); + begin + result := UNRESOLVED_float (L nand to_sulv(R)); + return result; + end function "nand"; + + function "nand" (L : UNRESOLVED_float; R : STD_ULOGIC) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (L'range); + begin + result := UNRESOLVED_float (to_sulv(L) nand R); + return result; + end function "nand"; + + function "nor" (L : STD_ULOGIC; R : UNRESOLVED_float) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (R'range); + begin + result := UNRESOLVED_float (L nor to_sulv(R)); + return result; + end function "nor"; + + function "nor" (L : UNRESOLVED_float; R : STD_ULOGIC) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (L'range); + begin + result := UNRESOLVED_float (to_sulv(L) nor R); + return result; + end function "nor"; + + function "xor" (L : STD_ULOGIC; R : UNRESOLVED_float) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (R'range); + begin + result := UNRESOLVED_float (L xor to_sulv(R)); + return result; + end function "xor"; + + function "xor" (L : UNRESOLVED_float; R : STD_ULOGIC) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (L'range); + begin + result := UNRESOLVED_float (to_sulv(L) xor R); + return result; + end function "xor"; + + function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_float) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (R'range); + begin + result := UNRESOLVED_float (L xnor to_sulv(R)); + return result; + end function "xnor"; + + function "xnor" (L : UNRESOLVED_float; R : STD_ULOGIC) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (L'range); + begin + result := UNRESOLVED_float (to_sulv(L) xnor R); + return result; + end function "xnor"; + + -- Reduction operators, same as numeric_std functions + + function "and" (l : UNRESOLVED_float) return STD_ULOGIC is + begin + return and to_sulv(l); + end function "and"; + + function "nand" (l : UNRESOLVED_float) return STD_ULOGIC is + begin + return nand to_sulv(l); + end function "nand"; + + function "or" (l : UNRESOLVED_float) return STD_ULOGIC is + begin + return or to_sulv(l); + end function "or"; + + function "nor" (l : UNRESOLVED_float) return STD_ULOGIC is + begin + return nor to_sulv(l); + end function "nor"; + + function "xor" (l : UNRESOLVED_float) return STD_ULOGIC is + begin + return xor to_sulv(l); + end function "xor"; + + function "xnor" (l : UNRESOLVED_float) return STD_ULOGIC is + begin + return xnor to_sulv(l); + end function "xnor"; + + ----------------------------------------------------------------------------- + -- Recommended Functions from the IEEE 754 Appendix + ----------------------------------------------------------------------------- + -- returns x with the sign of y. + function Copysign ( + x, y : UNRESOLVED_float) -- floating point input + return UNRESOLVED_float is + begin + return y(y'high) & x (x'high-1 downto x'low); + end function Copysign; + + -- Returns y * 2**n for integral values of N without computing 2**n + function Scalb ( + y : UNRESOLVED_float; -- floating point input + N : INTEGER; -- exponent to add + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(y'low, y'low); -- length of FP output fraction + constant exponent_width : NATURAL := y'high; -- length of FP output exponent + variable arg, result : UNRESOLVED_float (exponent_width downto -fraction_width); -- internal argument + variable expon : SIGNED (exponent_width-1 downto 0); -- Vectorized exp + variable exp : SIGNED (exponent_width downto 0); + variable ufract : UNSIGNED (fraction_width downto 0); + constant expon_base : SIGNED (exponent_width-1 downto 0) + := gen_expon_base(exponent_width); -- exponent offset + variable fptype : valid_fpstate; + begin + -- This can be done by simply adding N to the exponent. + arg := to_01 (y, 'X'); + fptype := classfp(arg, check_error); + classcase : case fptype is + when isx => + result := (others => 'X'); + when nan | quiet_nan => + -- Return quiet NAN, IEEE754-1985-7.1,1 + result := qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + when others => + break_number ( + arg => arg, + fptyp => fptype, + denormalize => denormalize, + fract => ufract, + expon => expon); + exp := resize (expon, exp'length) + N; + result := normalize ( + fract => ufract, + expon => exp, + sign => to_x01 (arg (arg'high)), + fraction_width => fraction_width, + exponent_width => exponent_width, + round_style => round_style, + denormalize => denormalize, + nguard => 0); + end case classcase; + return result; + end function Scalb; + + -- Returns y * 2**n for integral values of N without computing 2**n + function Scalb ( + y : UNRESOLVED_float; -- floating point input + N : UNRESOLVED_SIGNED; -- exponent to add + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float + is + variable n_int : INTEGER; + begin + n_int := to_integer(N); + return Scalb (y => y, + N => n_int, + round_style => round_style, + check_error => check_error, + denormalize => denormalize); + end function Scalb; + + -- returns the unbiased exponent of x + function Logb ( + x : UNRESOLVED_float) -- floating point input + return INTEGER + is + constant fraction_width : NATURAL := -mine (x'low, x'low); -- length of FP output fraction + constant exponent_width : NATURAL := x'high; -- length of FP output exponent + variable result : INTEGER; -- result + variable arg : UNRESOLVED_float (exponent_width downto -fraction_width); -- internal argument + variable expon : SIGNED (exponent_width - 1 downto 0); + variable fract : UNSIGNED (fraction_width downto 0); + constant expon_base : INTEGER := 2**(exponent_width-1) -1; -- exponent + -- offset +1 + variable fptype : valid_fpstate; + begin + -- Just return the exponent. + arg := to_01 (x, 'X'); + fptype := classfp(arg); + classcase : case fptype is + when isx | nan | quiet_nan => + -- Return quiet NAN, IEEE754-1985-7.1,1 + result := 0; + when pos_denormal | neg_denormal => + fract (fraction_width) := '0'; + fract (fraction_width-1 downto 0) := + UNSIGNED (to_slv(arg(-1 downto -fraction_width))); + result := find_leftmost (fract, '1') -- Find the first "1" + - fraction_width; -- subtract the length we want + result := -expon_base + 1 + result; + when others => + expon := SIGNED(arg (exponent_width - 1 downto 0)); + expon(exponent_width-1) := not expon(exponent_width-1); + expon := expon + 1; + result := to_integer (expon); + end case classcase; + return result; + end function Logb; + + -- returns the unbiased exponent of x + function Logb ( + x : UNRESOLVED_float) -- floating point input + return UNRESOLVED_SIGNED + is + constant exponent_width : NATURAL := x'high; -- length of FP output exponent + variable result : SIGNED (exponent_width - 1 downto 0); -- result + begin + -- Just return the exponent. + result := to_signed (Logb (x), exponent_width); + return result; + end function Logb; + + -- returns the next representable neighbor of x in the direction toward y + function Nextafter ( + x, y : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_float + is + constant fraction_width : NATURAL := -mine(x'low, x'low); -- length of FP output fraction + constant exponent_width : NATURAL := x'high; -- length of FP output exponent + function "=" ( + l, r : UNRESOLVED_float) -- inputs + return BOOLEAN is + begin -- function "=" + return eq (l => l, + r => r, + check_error => false); + end function "="; + function ">" ( + l, r : UNRESOLVED_float) -- inputs + return BOOLEAN is + begin -- function ">" + return gt (l => l, + r => r, + check_error => false); + end function ">"; + variable fract : UNSIGNED (fraction_width-1 downto 0); + variable expon : UNSIGNED (exponent_width-1 downto 0); + variable sign : STD_ULOGIC; + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable validfpx, validfpy : valid_fpstate; -- Valid FP state + begin -- fp_Nextafter + -- If Y > X, add one to the fraction, otherwise subtract. + validfpx := classfp (x, check_error); + validfpy := classfp (y, check_error); + if validfpx = isx or validfpy = isx then + result := (others => 'X'); + return result; + elsif (validfpx = nan or validfpy = nan) then + return nanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif (validfpx = quiet_nan or validfpy = quiet_nan) then + return qnanfp (fraction_width => fraction_width, + exponent_width => exponent_width); + elsif x = y then -- Return X + return x; + else + fract := UNSIGNED (to_slv (x (-1 downto -fraction_width))); -- Fraction + expon := UNSIGNED (x (exponent_width - 1 downto 0)); -- exponent + sign := x(exponent_width); -- sign bit + if (y > x) then + -- Increase the number given + if validfpx = neg_inf then + -- return most negative number + expon := (others => '1'); + expon (0) := '0'; + fract := (others => '1'); + elsif validfpx = pos_zero or validfpx = neg_zero then + -- return smallest denormal number + sign := '0'; + expon := (others => '0'); + fract := (others => '0'); + fract(0) := '1'; + elsif validfpx = pos_normal then + if and (fract) = '1' then -- fraction is all "1". + if and (expon (exponent_width-1 downto 1)) = '1' + and expon (0) = '0' then + -- Exponent is one away from infinity. + assert NO_WARNING + report FLOAT_GENERIC_PKG'instance_name + & "FP_NEXTAFTER: NextAfter overflow" + severity warning; + return pos_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + expon := expon + 1; + fract := (others => '0'); + end if; + else + fract := fract + 1; + end if; + elsif validfpx = pos_denormal then + if and (fract) = '1' then -- fraction is all "1". + -- return smallest possible normal number + expon := (others => '0'); + expon(0) := '1'; + fract := (others => '0'); + else + fract := fract + 1; + end if; + elsif validfpx = neg_normal then + if or (fract) = '0' then -- fraction is all "0". + if or (expon (exponent_width-1 downto 1)) = '0' and + expon (0) = '1' then -- Smallest exponent + -- return the largest negative denormal number + expon := (others => '0'); + fract := (others => '1'); + else + expon := expon - 1; + fract := (others => '1'); + end if; + else + fract := fract - 1; + end if; + elsif validfpx = neg_denormal then + if or (fract(fract'high downto 1)) = '0' + and fract (0) = '1' then -- Smallest possible fraction + return zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + fract := fract - 1; + end if; + end if; + else + -- Decrease the number + if validfpx = pos_inf then + -- return most positive number + expon := (others => '1'); + expon (0) := '0'; + fract := (others => '1'); + elsif validfpx = pos_zero + or classfp (x) = neg_zero then + -- return smallest negative denormal number + sign := '1'; + expon := (others => '0'); + fract := (others => '0'); + fract(0) := '1'; + elsif validfpx = neg_normal then + if and (fract) = '1' then -- fraction is all "1". + if and (expon (exponent_width-1 downto 1)) = '1' + and expon (0) = '0' then + -- Exponent is one away from infinity. + assert NO_WARNING + report FLOAT_GENERIC_PKG'instance_name + & "FP_NEXTAFTER: NextAfter overflow" + severity warning; + return neg_inffp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + expon := expon + 1; -- Fraction overflow + fract := (others => '0'); + end if; + else + fract := fract + 1; + end if; + elsif validfpx = neg_denormal then + if and (fract) = '1' then -- fraction is all "1". + -- return smallest possible normal number + expon := (others => '0'); + expon(0) := '1'; + fract := (others => '0'); + else + fract := fract + 1; + end if; + elsif validfpx = pos_normal then + if or (fract) = '0' then -- fraction is all "0". + if or (expon (exponent_width-1 downto 1)) = '0' and + expon (0) = '1' then -- Smallest exponent + -- return the largest positive denormal number + expon := (others => '0'); + fract := (others => '1'); + else + expon := expon - 1; + fract := (others => '1'); + end if; + else + fract := fract - 1; + end if; + elsif validfpx = pos_denormal then + if or (fract(fract'high downto 1)) = '0' + and fract (0) = '1' then -- Smallest possible fraction + return zerofp (fraction_width => fraction_width, + exponent_width => exponent_width); + else + fract := fract - 1; + end if; + end if; + end if; + result (-1 downto -fraction_width) := UNRESOLVED_float(fract); + result (exponent_width -1 downto 0) := UNRESOLVED_float(expon); + result (exponent_width) := sign; + return result; + end if; + end function Nextafter; + + -- Returns True if X is unordered with Y. + function Unordered ( + x, y : UNRESOLVED_float) -- floating point input + return BOOLEAN + is + variable lfptype, rfptype : valid_fpstate; + begin + lfptype := classfp (x); + rfptype := classfp (y); + if (lfptype = nan or lfptype = quiet_nan or + rfptype = nan or rfptype = quiet_nan or + lfptype = isx or rfptype = isx) then + return true; + else + return false; + end if; + end function Unordered; + + function Finite ( + x : UNRESOLVED_float) + return BOOLEAN + is + variable fp_state : valid_fpstate; -- fp state + begin + fp_state := Classfp (x); + if (fp_state = pos_inf) or (fp_state = neg_inf) then + return true; + else + return false; + end if; + end function Finite; + + function Isnan ( + x : UNRESOLVED_float) + return BOOLEAN + is + variable fp_state : valid_fpstate; -- fp state + begin + fp_state := Classfp (x); + if (fp_state = nan) or (fp_state = quiet_nan) then + return true; + else + return false; + end if; + end function Isnan; + + -- Function to return constants. + function zerofp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float + is + constant result : UNRESOLVED_float (exponent_width downto -fraction_width) := + (others => '0'); -- zero + begin + return result; + end function zerofp; + + function nanfp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width) := + (others => '0'); -- zero + begin + result (exponent_width-1 downto 0) := (others => '1'); + -- Exponent all "1" + result (-1) := '1'; -- MSB of Fraction "1" + -- Note: From W. Khan "IEEE Standard 754 for Binary Floating Point" + -- The difference between a signaling NAN and a quiet NAN is that + -- the MSB of the Fraction is a "1" in a Signaling NAN, and is a + -- "0" in a quiet NAN. + return result; + end function nanfp; + + function qnanfp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width) := + (others => '0'); -- zero + begin + result (exponent_width-1 downto 0) := (others => '1'); + -- Exponent all "1" + result (-fraction_width) := '1'; -- LSB of Fraction "1" + -- (Could have been any bit) + return result; + end function qnanfp; + + function pos_inffp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width) := + (others => '0'); -- zero + begin + result (exponent_width-1 downto 0) := (others => '1'); -- Exponent all "1" + return result; + end function pos_inffp; + + function neg_inffp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width) := + (others => '0'); -- zero + begin + result (exponent_width downto 0) := (others => '1'); -- top bits all "1" + return result; + end function neg_inffp; + + function neg_zerofp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width) := + (others => '0'); -- zero + begin + result (exponent_width) := '1'; + return result; + end function neg_zerofp; + + -- size_res versions + function zerofp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float is + begin + return zerofp ( + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function zerofp; + + function nanfp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float is + begin + return nanfp ( + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function nanfp; + + function qnanfp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float is + begin + return qnanfp ( + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function qnanfp; + + function pos_inffp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float is + begin + return pos_inffp ( + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function pos_inffp; + + function neg_inffp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float is + begin + return neg_inffp ( + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function neg_inffp; + + function neg_zerofp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float is + begin + return neg_zerofp ( + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function neg_zerofp; + + -- Textio functions + -- purpose: writes float into a line (NOTE changed basetype) + 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 NBSP : CHARACTER := CHARACTER'val(160); -- space character + 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); + + -- 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: Checks the punctuation in a line + procedure check_punctuation ( + arg : in STRING; + colon : out BOOLEAN; -- There was a colon in the line + dot : out BOOLEAN; -- There was a dot in the line + good : out BOOLEAN; -- True if enough characters found + chars : in INTEGER) is + -- Examples. Legal inputs are "0000000", "0000.000", "0:000:000" + alias xarg : STRING (1 to arg'length) is arg; -- make it downto range + variable icolon, idot : BOOLEAN; -- internal + variable j : INTEGER := 0; -- charters read + begin + good := false; + icolon := false; + idot := false; + for i in 1 to arg'length loop + if xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT or j = chars then + exit; + elsif xarg(i) = ':' then + icolon := true; + elsif xarg(i) = '.' then + idot := true; + elsif xarg (i) /= '_' then + j := j + 1; + end if; + end loop; + if j = chars then + good := true; -- There are enough charactes to read + end if; + colon := icolon; + if idot and icolon then + dot := false; + else + dot := idot; + end if; + end procedure check_punctuation; + + -- purpose: Searches a line for a ":" and replaces it with a ".". + procedure fix_colon ( + arg : inout STRING; + chars : in integer) is + alias xarg : STRING (1 to arg'length) is arg; -- make it downto range + variable j : INTEGER := 0; -- charters read + begin + for i in 1 to arg'length loop + if xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT or j > chars then + exit; + elsif xarg(i) = ':' then + xarg (i) := '.'; + elsif xarg (i) /= '_' then + j := j + 1; + end if; + end loop; + end procedure fix_colon; + + procedure WRITE ( + L : inout LINE; -- input line + VALUE : in UNRESOLVED_float; -- floating point input + JUSTIFIED : in SIDE := right; + FIELD : in WIDTH := 0) is + variable s : STRING(1 to value'high - value'low +3); + variable sindx : INTEGER; + begin -- function write + s(1) := MVL9_to_char(STD_ULOGIC(VALUE(VALUE'high))); + s(2) := ':'; + sindx := 3; + for i in VALUE'high-1 downto 0 loop + s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i))); + sindx := sindx + 1; + end loop; + s(sindx) := ':'; + sindx := sindx + 1; + for i in -1 downto VALUE'low loop + 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_float) is + -- Possible data: 0:0000:0000000 + -- 000000000000 + variable c : CHARACTER; + variable mv : UNRESOLVED_float (VALUE'range); + variable readOk : BOOLEAN; + variable lastu : BOOLEAN := false; -- last character was an "_" + variable i : INTEGER; -- index variable + begin -- READ + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + READ (l, c, readOk); + if VALUE'length > 0 then + i := value'high; + readloop : loop + if readOk = false then -- Bail out if there was a bad read + report float_generic_pkg'instance_name + & "READ(float): " + & "Error end of file encountered." + severity error; + return; + elsif c = ' ' or c = CR or c = HT then -- reading done. + if (i /= value'low) then + report float_generic_pkg'instance_name + & "READ(float): " + & "Warning: Value truncated." + severity warning; + return; + end if; + elsif c = '_' then + if i = value'high then -- Begins with an "_" + report float_generic_pkg'instance_name + & "READ(float): " + & "String begins with an ""_""" severity error; + return; + elsif lastu then -- "__" detected + report float_generic_pkg'instance_name + & "READ(float): " + & "Two underscores detected in input string ""__""" + severity error; + return; + else + lastu := true; + end if; + elsif c = ':' or c = '.' then -- separator, ignore + if not (i = -1 or i = value'high-1) then + report float_generic_pkg'instance_name + & "READ(float): " + & "Warning: Separator point does not match number format: '" + & c & "' encountered at location " & INTEGER'image(i) & "." + severity warning; + end if; + lastu := false; + elsif (char_to_MVL9plus(c) = error) then + report float_generic_pkg'instance_name + & "READ(float): " + & "Error: Character '" & c & "' read, expected STD_ULOGIC literal." + severity error; + return; + else + mv (i) := char_to_MVL9(c); + i := i - 1; + if i < value'low then + VALUE := mv; + return; + end if; + lastu := false; + end if; + READ (l, c, readOk); + end loop readloop; + end if; + end procedure READ; + + procedure READ (L : inout LINE; VALUE : out UNRESOLVED_float; GOOD : out BOOLEAN) is + -- Possible data: 0:0000:0000000 + -- 000000000000 + variable c : CHARACTER; + variable mv : UNRESOLVED_float (VALUE'range); + variable lastu : BOOLEAN := false; -- last character was an "_" + variable i : INTEGER; -- index variable + variable readOk : BOOLEAN; + begin -- READ + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + READ (l, c, readOk); + if VALUE'length > 0 then + i := value'high; + good := false; + readloop : loop + if readOk = false then -- Bail out if there was a bad read + return; + elsif c = ' ' or c = CR or c = HT then -- reading done + return; + elsif c = '_' then + if i = 0 then -- Begins with an "_" + return; + elsif lastu then -- "__" detected + return; + else + lastu := true; + end if; + elsif c = ':' or c = '.' then -- separator, ignore + -- good := (i = -1 or i = value'high-1); + lastu := false; + elsif (char_to_MVL9plus(c) = error) then + return; + else + mv (i) := char_to_MVL9(c); + i := i - 1; + if i < value'low then + good := true; + VALUE := mv; + return; + end if; + lastu := false; + end if; + READ (l, c, readOk); + end loop readloop; + else + good := true; -- read into a null array + end if; + end procedure READ; + + procedure OWRITE ( + L : inout LINE; -- access type (pointer) + VALUE : in UNRESOLVED_float; -- value to write + JUSTIFIED : in SIDE := right; -- which side to justify text + FIELD : in WIDTH := 0) is -- width of field + begin + WRITE (L => L, + VALUE => to_ostring(VALUE), + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure OWRITE; + + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_float) is + constant ne : INTEGER := ((value'length+2)/3) * 3; -- pad + variable slv : STD_LOGIC_VECTOR (ne-1 downto 0); -- slv + variable slvu : ufixed (VALUE'range); -- Unsigned fixed point + variable c : CHARACTER; + variable ok : BOOLEAN; + variable nybble : STD_LOGIC_VECTOR (2 downto 0); -- 3 bits + variable colon, dot : BOOLEAN; + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then + check_punctuation (arg => L.all, + colon => colon, + dot => dot, + good => ok, + chars => ne/3); + if not ok then + report float_generic_pkg'instance_name & "OREAD: " + & "short string encounted: " & L.all + & " needs to have " & integer'image (ne/3) + & " valid octal characters." + severity error; + return; + elsif dot then + OREAD (L, slvu, ok); -- read it like a UFIXED number + if not ok then + report float_generic_pkg'instance_name & "OREAD: " + & "error encounted reading STRING " & L.all + severity error; + return; + else + VALUE := UNRESOLVED_float (slvu); + end if; + elsif colon then + OREAD (L, nybble, ok); -- read the sign bit + if not ok then + report float_generic_pkg'instance_name & "OREAD: " + & "End of string encountered" + severity error; + return; + elsif nybble (2 downto 1) /= "00" then + report float_generic_pkg'instance_name & "OREAD: " + & "Illegal sign bit STRING encounted " + severity error; + return; + end if; + read (l, c, ok); -- read the colon + fix_colon (L.all, ne/3); -- replaces the colon with a ".". + OREAD (L, slvu (slvu'high-1 downto slvu'low), ok); -- read it like a UFIXED number + if not ok then + report float_generic_pkg'instance_name & "OREAD: " + & "error encounted reading STRING " & L.all + severity error; + return; + else + slvu (slvu'high) := nybble (0); + VALUE := UNRESOLVED_float (slvu); + end if; + else + OREAD (L, slv, ok); + if not ok then + report float_generic_pkg'instance_name & "OREAD: " + & "Error encounted during read" + severity error; + return; + end if; + if (or (slv(ne-1 downto VALUE'high-VALUE'low+1)) = '1') then + report float_generic_pkg'instance_name & "OREAD: " + & "Vector truncated." + severity error; + return; + end if; + VALUE := to_float (slv(VALUE'high-VALUE'low downto 0), + VALUE'high, -VALUE'low); + end if; + end if; + end procedure OREAD; + + procedure OREAD(L : inout LINE; VALUE : out UNRESOLVED_float; GOOD : out BOOLEAN) is + constant ne : INTEGER := ((value'length+2)/3) * 3; -- pad + variable slv : STD_LOGIC_VECTOR (ne-1 downto 0); -- slv + variable slvu : ufixed (VALUE'range); -- Unsigned fixed point + variable c : CHARACTER; + variable ok : BOOLEAN; + variable nybble : STD_LOGIC_VECTOR (2 downto 0); -- 3 bits + variable colon, dot : BOOLEAN; + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + GOOD := false; + Skip_whitespace (L); + if VALUE'length > 0 then + check_punctuation (arg => L.all, + colon => colon, + dot => dot, + good => ok, + chars => ne/3); + if not ok then + return; + elsif dot then + OREAD (L, slvu, ok); -- read it like a UFIXED number + if not ok then + return; + else + VALUE := UNRESOLVED_float (slvu); + end if; + elsif colon then + OREAD (L, nybble, ok); -- read the sign bit + if not ok then + return; + elsif nybble (2 downto 1) /= "00" then + return; + end if; + read (l, c, ok); -- read the colon + fix_colon (L.all, ne/3); -- replaces the colon with a ".". + OREAD (L, slvu (slvu'high-1 downto slvu'low), ok); -- read it like a UFIXED number + if not ok then + return; + else + slvu (slvu'high) := nybble (0); + VALUE := UNRESOLVED_float (slvu); + end if; + else + OREAD (L, slv, ok); + if not ok then + return; + end if; + if (or (slv(ne-1 downto VALUE'high-VALUE'low+1)) = '1') then + return; + end if; + VALUE := to_float (slv(VALUE'high-VALUE'low downto 0), + VALUE'high, -VALUE'low); + end if; + GOOD := true; + end if; + end procedure OREAD; + + procedure HWRITE ( + L : inout LINE; -- access type (pointer) + VALUE : in UNRESOLVED_float; -- value to write + JUSTIFIED : in SIDE := right; -- which side to justify text + FIELD : in WIDTH := 0) is -- width of field + begin + WRITE (L => L, + VALUE => to_hstring(VALUE), + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure HWRITE; + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_float) is + constant ne : INTEGER := ((value'length+3)/4) * 4; -- pad + variable slv : STD_LOGIC_VECTOR (ne-1 downto 0); -- slv + variable slvu : ufixed (VALUE'range); -- Unsigned fixed point + variable c : CHARACTER; + variable ok : BOOLEAN; + variable nybble : STD_LOGIC_VECTOR (3 downto 0); -- 4 bits + variable colon, dot : BOOLEAN; + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then + check_punctuation (arg => L.all, + colon => colon, + dot => dot, + good => ok, + chars => ne/4); + if not ok then + report float_generic_pkg'instance_name & "HREAD: " + & "short string encounted: " & L.all + & " needs to have " & integer'image (ne/4) + & " valid hex characters." + severity error; + return; + elsif dot then + HREAD (L, slvu, ok); -- read it like a UFIXED number + if not ok then + report float_generic_pkg'instance_name & "HREAD: " + & "error encounted reading STRING " & L.all + severity error; + return; + else + VALUE := UNRESOLVED_float (slvu); + end if; + elsif colon then + HREAD (L, nybble, ok); -- read the sign bit + if not ok then + report float_generic_pkg'instance_name & "HREAD: " + & "End of string encountered" + severity error; + return; + elsif nybble (3 downto 1) /= "000" then + report float_generic_pkg'instance_name & "HREAD: " + & "Illegal sign bit STRING encounted " + severity error; + return; + end if; + read (l, c, ok); -- read the colon + fix_colon (L.all, ne/4); -- replaces the colon with a ".". + HREAD (L, slvu (slvu'high-1 downto slvu'low), ok); -- read it like a UFIXED number + if not ok then + report float_generic_pkg'instance_name & "HREAD: " + & "error encounted reading STRING " & L.all + severity error; + return; + else + slvu (slvu'high) := nybble (0); + VALUE := UNRESOLVED_float (slvu); + end if; + else + HREAD (L, slv, ok); + if not ok then + report float_generic_pkg'instance_name & "HREAD: " + & "Error encounted during read" + severity error; + return; + end if; + if (or (slv(ne-1 downto VALUE'high-VALUE'low+1)) = '1') then + report float_generic_pkg'instance_name & "HREAD: " + & "Vector truncated." + severity error; + return; + end if; + VALUE := to_float (slv(VALUE'high-VALUE'low downto 0), + VALUE'high, -VALUE'low); + end if; + end if; + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_float; GOOD : out BOOLEAN) is + constant ne : INTEGER := ((value'length+3)/4) * 4; -- pad + variable slv : STD_LOGIC_VECTOR (ne-1 downto 0); -- slv + variable slvu : ufixed (VALUE'range); -- Unsigned fixed point + variable c : CHARACTER; + variable ok : BOOLEAN; + variable nybble : STD_LOGIC_VECTOR (3 downto 0); -- 4 bits + variable colon, dot : BOOLEAN; + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + GOOD := false; + Skip_whitespace (L); + if VALUE'length > 0 then + check_punctuation (arg => L.all, + colon => colon, + dot => dot, + good => ok, + chars => ne/4); + if not ok then + return; + elsif dot then + HREAD (L, slvu, ok); -- read it like a UFIXED number + if not ok then + return; + else + VALUE := UNRESOLVED_float (slvu); + end if; + elsif colon then + HREAD (L, nybble, ok); -- read the sign bit + if not ok then + return; + elsif nybble (3 downto 1) /= "000" then + return; + end if; + read (l, c, ok); -- read the colon + fix_colon (L.all, ne/4); -- replaces the colon with a ".". + HREAD (L, slvu (slvu'high-1 downto slvu'low), ok); -- read it like a UFIXED number + if not ok then + return; + else + slvu (slvu'high) := nybble (0); + VALUE := UNRESOLVED_float (slvu); + end if; + else + HREAD (L, slv, ok); + if not ok then + return; + end if; + if (or (slv(ne-1 downto VALUE'high-VALUE'low+1)) = '1') then + return; + end if; + VALUE := to_float (slv(VALUE'high-VALUE'low downto 0), + VALUE'high, -VALUE'low); + end if; + GOOD := true; + end if; + end procedure HREAD; + + function to_string (value : UNRESOLVED_float) return STRING is + variable s : STRING(1 to value'high - value'low +3); + variable sindx : INTEGER; + begin -- function write + s(1) := MVL9_to_char(STD_ULOGIC(VALUE(VALUE'high))); + s(2) := ':'; + sindx := 3; + for i in VALUE'high-1 downto 0 loop + s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i))); + sindx := sindx + 1; + end loop; + s(sindx) := ':'; + sindx := sindx + 1; + for i in -1 downto VALUE'low loop + s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i))); + sindx := sindx + 1; + end loop; + return s; + end function to_string; + + function to_hstring (value : UNRESOLVED_float) return STRING is + variable slv : STD_LOGIC_VECTOR (value'length-1 downto 0); + begin + floop : for i in slv'range loop + slv(i) := to_X01Z (value(i + value'low)); + end loop floop; + return to_hstring (slv); + end function to_hstring; + + function to_ostring (value : UNRESOLVED_float) return STRING is + variable slv : STD_LOGIC_VECTOR (value'length-1 downto 0); + begin + floop : for i in slv'range loop + slv(i) := to_X01Z (value(i + value'low)); + end loop floop; + return to_ostring (slv); + end function to_ostring; + + function from_string ( + bstring : STRING; -- binary string + constant exponent_width : NATURAL := float_exponent_width; + constant fraction_width : NATURAL := float_fraction_width) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable L : LINE; + variable good : BOOLEAN; + begin + L := new STRING'(bstring); + READ (L, result, good); + deallocate (L); + assert (good) + report FLOAT_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 exponent_width : NATURAL := float_exponent_width; + constant fraction_width : NATURAL := float_fraction_width) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable L : LINE; + variable good : BOOLEAN; + begin + L := new STRING'(ostring); + OREAD (L, result, good); + deallocate (L); + assert (good) + report FLOAT_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 exponent_width : NATURAL := float_exponent_width; + constant fraction_width : NATURAL := float_fraction_width) + return UNRESOLVED_float + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + variable L : LINE; + variable good : BOOLEAN; + begin + L := new STRING'(hstring); + HREAD (L, result, good); + deallocate (L); + assert (good) + report FLOAT_GENERIC_PKG'instance_name + & "from_hstring: Bad string " & hstring + severity error; + return result; + end function from_hstring; + + function from_string ( + bstring : STRING; -- binary string + size_res : UNRESOLVED_float) -- used for sizing only + return UNRESOLVED_float is + begin + return from_string (bstring => bstring, + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function from_string; + + function from_ostring ( + ostring : STRING; -- Octal string + size_res : UNRESOLVED_float) -- used for sizing only + return UNRESOLVED_float is + begin + return from_ostring (ostring => ostring, + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function from_ostring; + + function from_hstring ( + hstring : STRING; -- hex string + size_res : UNRESOLVED_float) -- used for sizing only + return UNRESOLVED_float is + begin + return from_hstring (hstring => hstring, + exponent_width => size_res'high, + fraction_width => -size_res'low); + end function from_hstring; + +end package body float_generic_pkg; diff --git a/libraries/ieee2008/float_generic_pkg.vhdl b/libraries/ieee2008/float_generic_pkg.vhdl new file mode 100644 index 000000000..c83542965 --- /dev/null +++ b/libraries/ieee2008/float_generic_pkg.vhdl @@ -0,0 +1,997 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Floating-point package (Generic package declaration) +-- : +-- 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 floating point +-- : 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) $ +-- -------------------------------------------------------------------- + +use STD.TEXTIO.all; +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use IEEE.fixed_float_types.all; + +package float_generic_pkg is + generic ( + -- Defaults for sizing routines, when you do a "to_float" this will be + -- the default size. Example float32 would be 8 and 23 (8 downto -23) + float_exponent_width : NATURAL := 8; + float_fraction_width : NATURAL := 23; + -- Rounding algorithm, "round_nearest" is default, other valid values + -- are "round_zero" (truncation), "round_inf" (round up), and + -- "round_neginf" (round down) + float_round_style : round_type := round_nearest; + -- Denormal numbers (very small numbers near zero) true or false + float_denormalize : BOOLEAN := true; + -- Turns on NAN processing (invalid numbers and overflow) true of false + float_check_error : BOOLEAN := true; + -- Guard bits are added to the bottom of every operation for rounding. + -- any natural number (including 0) are valid. + float_guard_bits : NATURAL := 3; + -- If TRUE, then turn off warnings on "X" propagation + no_warning : BOOLEAN := false; + package fixed_pkg is new IEEE.fixed_generic_pkg + generic map (<>) ); + + -- Author David Bishop (dbishop@vhdl.org) + constant CopyRightNotice : STRING := + "Copyright 2008 by IEEE. All rights reserved."; + + use fixed_pkg.all; + + -- Note that this is "INTEGER range <>", thus if you use a literal, then the + -- default range will be (INTEGER'low to INTEGER'low + X) + type UNRESOLVED_float is array (INTEGER range <>) of STD_ULOGIC; -- main type + alias U_float is UNRESOLVED_float; + + subtype float is (resolved) UNRESOLVED_float; + ----------------------------------------------------------------------------- + -- Use the float type to define your own floating point numbers. + -- There must be a negative index or the packages will error out. + -- Minimum supported is "subtype float7 is float (3 downto -3);" + -- "subtype float16 is float (6 downto -9);" is probably the smallest + -- practical one to use. + ----------------------------------------------------------------------------- + + -- IEEE 754 single precision + subtype UNRESOLVED_float32 is UNRESOLVED_float (8 downto -23); + alias U_float32 is UNRESOLVED_float32; + subtype float32 is float (8 downto -23); + ----------------------------------------------------------------------------- + -- IEEE-754 single precision floating point. This is a "float" + -- in C, and a FLOAT in Fortran. The exponent is 8 bits wide, and + -- the fraction is 23 bits wide. This format can hold roughly 7 decimal + -- digits. Infinity is 2**127 = 1.7E38 in this number system. + -- The bit representation is as follows: + -- 1 09876543 21098765432109876543210 + -- 8 76543210 12345678901234567890123 + -- 0 00000000 00000000000000000000000 + -- 8 7 0 -1 -23 + -- +/- exp. fraction + ----------------------------------------------------------------------------- + + -- IEEE 754 double precision + subtype UNRESOLVED_float64 is UNRESOLVED_float (11 downto -52); + alias U_float64 is UNRESOLVED_float64; + subtype float64 is float (11 downto -52); + ----------------------------------------------------------------------------- + -- IEEE-754 double precision floating point. This is a "double float" + -- in C, and a FLOAT*8 in Fortran. The exponent is 11 bits wide, and + -- the fraction is 52 bits wide. This format can hold roughly 15 decimal + -- digits. Infinity is 2**2047 in this number system. + -- The bit representation is as follows: + -- 3 21098765432 1098765432109876543210987654321098765432109876543210 + -- 1 09876543210 1234567890123456789012345678901234567890123456789012 + -- S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + -- 11 10 0 -1 -52 + -- +/- exponent fraction + ----------------------------------------------------------------------------- + + -- IEEE 854 & C extended precision + subtype UNRESOLVED_float128 is UNRESOLVED_float (15 downto -112); + alias U_float128 is UNRESOLVED_float128; + subtype float128 is float (15 downto -112); + ----------------------------------------------------------------------------- + -- The 128 bit floating point number is "long double" in C (on + -- some systems this is a 70 bit floating point number) and FLOAT*32 + -- in Fortran. The exponent is 15 bits wide and the fraction is 112 + -- bits wide. This number can handle approximately 33 decimal digits. + -- Infinity is 2**32,767 in this number system. + ----------------------------------------------------------------------------- + + -- purpose: Checks for a valid floating point number + type valid_fpstate is (nan, -- Signaling NaN (C FP_NAN) + quiet_nan, -- Quiet NaN (C FP_NAN) + neg_inf, -- Negative infinity (C FP_INFINITE) + neg_normal, -- negative normalized nonzero + neg_denormal, -- negative denormalized (FP_SUBNORMAL) + neg_zero, -- -0 (C FP_ZERO) + pos_zero, -- +0 (C FP_ZERO) + pos_denormal, -- Positive denormalized (FP_SUBNORMAL) + pos_normal, -- positive normalized nonzero + pos_inf, -- positive infinity + isx); -- at least one input is unknown + + -- This deferred constant will tell you if the package body is synthesizable + -- or implemented as real numbers. + constant fphdlsynth_or_real : BOOLEAN; -- deferred constant + + -- Returns the class which X falls into + function Classfp ( + x : UNRESOLVED_float; -- floating point input + check_error : BOOLEAN := float_check_error) -- check for errors + return valid_fpstate; + + -- Arithmetic functions, these operators do not require parameters. + function "abs" (arg : UNRESOLVED_float) return UNRESOLVED_float; + function "-" (arg : UNRESOLVED_float) return UNRESOLVED_float; + + -- These allows the base math functions to use the default values + -- of their parameters. Thus they do full IEEE floating point. + + function "+" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "-" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "*" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "/" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "rem" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "mod" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + + -- Basic parameter list + -- round_style - Selects the rounding algorithm to use + -- guard - extra bits added to the end if the operation to add precision + -- check_error - When "false" turns off NAN and overflow checks + -- denormalize - When "false" turns off denormal number processing + + function add ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function subtract ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function multiply ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function divide ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function remainder ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function modulo ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + -- reciprocal + function reciprocal ( + arg : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function dividebyp2 ( + l, r : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + -- Multiply accumulate result = l*r + c + function mac ( + l, r, c : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant guard : NATURAL := float_guard_bits; -- number of guard bits + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + -- Square root (all 754 based implementations need this) + function sqrt ( + arg : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; + constant guard : NATURAL := float_guard_bits; + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_float; + + function Is_Negative (arg : UNRESOLVED_float) return BOOLEAN; + + ----------------------------------------------------------------------------- + -- compare functions + -- =, /=, >=, <=, <, >, maximum, minimum + + function eq ( -- equal = + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN; + + function ne ( -- not equal /= + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN; + + function lt ( -- less than < + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN; + + function gt ( -- greater than > + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN; + + function le ( -- less than or equal to <= + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN; + + function ge ( -- greater than or equal to >= + l, r : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; + constant denormalize : BOOLEAN := float_denormalize) + return BOOLEAN; + + -- Need to overload the default versions of these + function "=" (l, r : UNRESOLVED_float) return BOOLEAN; + function "/=" (l, r : UNRESOLVED_float) return BOOLEAN; + function ">=" (l, r : UNRESOLVED_float) return BOOLEAN; + function "<=" (l, r : UNRESOLVED_float) return BOOLEAN; + function ">" (l, r : UNRESOLVED_float) return BOOLEAN; + function "<" (l, r : UNRESOLVED_float) return BOOLEAN; + + function "?=" (l, r : UNRESOLVED_float) return STD_ULOGIC; + function "?/=" (l, r : UNRESOLVED_float) return STD_ULOGIC; + function "?>" (l, r : UNRESOLVED_float) return STD_ULOGIC; + function "?>=" (l, r : UNRESOLVED_float) return STD_ULOGIC; + function "?<" (l, r : UNRESOLVED_float) return STD_ULOGIC; + function "?<=" (l, r : UNRESOLVED_float) return STD_ULOGIC; + + function std_match (l, r : UNRESOLVED_float) return BOOLEAN; + function find_rightmost (arg : UNRESOLVED_float; y : STD_ULOGIC) + return INTEGER; + function find_leftmost (arg : UNRESOLVED_float; y : STD_ULOGIC) + return INTEGER; + function maximum (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function minimum (l, r : UNRESOLVED_float) return UNRESOLVED_float; + + -- conversion functions + -- Converts one floating point number into another. + + function resize ( + arg : UNRESOLVED_float; -- Floating point input + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function resize ( + arg : UNRESOLVED_float; -- Floating point input + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + function to_float32 ( + arg : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float32; + + function to_float64 ( + arg : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float64; + + function to_float128 ( + arg : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; + constant denormalize_in : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float128; + + -- Converts an fp into an SLV (needed for synthesis) + function to_slv (arg : UNRESOLVED_float) return STD_LOGIC_VECTOR; + alias to_StdLogicVector is to_slv [UNRESOLVED_float return STD_LOGIC_VECTOR]; + alias to_Std_Logic_Vector is to_slv [UNRESOLVED_float return STD_LOGIC_VECTOR]; + + -- Converts an fp into an std_ulogic_vector (sulv) + function to_sulv (arg : UNRESOLVED_float) return STD_ULOGIC_VECTOR; + alias to_StdULogicVector is to_sulv [UNRESOLVED_float return STD_ULOGIC_VECTOR]; + alias to_Std_ULogic_Vector is to_sulv [UNRESOLVED_float return STD_ULOGIC_VECTOR]; + + -- std_ulogic_vector to float + function to_float ( + arg : STD_ULOGIC_VECTOR; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width) -- length of FP output fraction + return UNRESOLVED_float; + + -- Integer to float + function to_float ( + arg : INTEGER; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float; + + -- real to float + function to_float ( + arg : REAL; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + -- unsigned to float + function to_float ( + arg : UNRESOLVED_UNSIGNED; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float; + + -- signed to float + function to_float ( + arg : UNRESOLVED_SIGNED; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float; + + -- unsigned fixed point to float + function to_float ( + arg : UNRESOLVED_ufixed; -- unsigned fixed point input + constant exponent_width : NATURAL := float_exponent_width; -- width of exponent + constant fraction_width : NATURAL := float_fraction_width; -- width of fraction + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- use ieee extensions + return UNRESOLVED_float; + + -- signed fixed point to float + function to_float ( + arg : UNRESOLVED_sfixed; + constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent + constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- rounding option + return UNRESOLVED_float; + + -- size_res functions + -- Integer to float + function to_float ( + arg : INTEGER; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float; + + -- real to float + function to_float ( + arg : REAL; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + -- unsigned to float + function to_float ( + arg : UNRESOLVED_UNSIGNED; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float; + + -- signed to float + function to_float ( + arg : UNRESOLVED_SIGNED; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style) -- rounding option + return UNRESOLVED_float; + + -- sulv to float + function to_float ( + arg : STD_ULOGIC_VECTOR; + size_res : UNRESOLVED_float) + return UNRESOLVED_float; + + -- unsigned fixed point to float + function to_float ( + arg : UNRESOLVED_ufixed; -- unsigned fixed point input + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- use ieee extensions + return UNRESOLVED_float; + + -- signed fixed point to float + function to_float ( + arg : UNRESOLVED_sfixed; + size_res : UNRESOLVED_float; + constant round_style : round_type := float_round_style; -- rounding + constant denormalize : BOOLEAN := float_denormalize) -- rounding option + return UNRESOLVED_float; + + -- float to unsigned + function to_unsigned ( + arg : UNRESOLVED_float; -- floating point input + constant size : NATURAL; -- length of output + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_UNSIGNED; + + -- float to signed + function to_signed ( + arg : UNRESOLVED_float; -- floating point input + constant size : NATURAL; -- length of output + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_SIGNED; + + -- purpose: Converts a float to unsigned fixed point + function to_ufixed ( + arg : UNRESOLVED_float; -- fp input + constant left_index : INTEGER; -- integer part + constant right_index : INTEGER; -- fraction part + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_ufixed; + + -- float to signed fixed point + function to_sfixed ( + arg : UNRESOLVED_float; -- fp input + constant left_index : INTEGER; -- integer part + constant right_index : INTEGER; -- fraction part + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_sfixed; + + -- size_res versions + -- float to unsigned + function to_unsigned ( + arg : UNRESOLVED_float; -- floating point input + size_res : UNRESOLVED_UNSIGNED; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_UNSIGNED; + + -- float to signed + function to_signed ( + arg : UNRESOLVED_float; -- floating point input + size_res : UNRESOLVED_SIGNED; + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return UNRESOLVED_SIGNED; + + -- purpose: Converts a float to unsigned fixed point + function to_ufixed ( + arg : UNRESOLVED_float; -- fp input + size_res : UNRESOLVED_ufixed; + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_ufixed; + + -- float to signed fixed point + function to_sfixed ( + arg : UNRESOLVED_float; -- fp input + size_res : UNRESOLVED_sfixed; + constant overflow_style : fixed_overflow_style_type := fixed_overflow_style; -- saturate + constant round_style : fixed_round_style_type := fixed_round_style; -- rounding + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_sfixed; + + -- float to real + function to_real ( + arg : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return REAL; + + -- float to integer + function to_integer ( + arg : UNRESOLVED_float; -- floating point input + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error) -- check for errors + return INTEGER; + + -- For Verilog compatability + function realtobits (arg : REAL) return STD_ULOGIC_VECTOR; + function bitstoreal (arg : STD_ULOGIC_VECTOR) return REAL; + + -- Maps metalogical values + function to_01 ( + arg : UNRESOLVED_float; -- floating point input + XMAP : STD_LOGIC := '0') + return UNRESOLVED_float; + + function Is_X (arg : UNRESOLVED_float) return BOOLEAN; + function to_X01 (arg : UNRESOLVED_float) return UNRESOLVED_float; + function to_X01Z (arg : UNRESOLVED_float) return UNRESOLVED_float; + function to_UX01 (arg : UNRESOLVED_float) return UNRESOLVED_float; + + -- These two procedures were copied out of the body because they proved + -- very useful for vendor specific algorithm development + -- Break_number converts a floating point number into it's parts + -- Exponent is biased by -1 + + procedure break_number ( + arg : in UNRESOLVED_float; + denormalize : in BOOLEAN := float_denormalize; + check_error : in BOOLEAN := float_check_error; + fract : out UNRESOLVED_UNSIGNED; + expon : out UNRESOLVED_SIGNED; -- NOTE: Add 1 to get the real exponent! + sign : out STD_ULOGIC); + + procedure break_number ( + arg : in UNRESOLVED_float; + denormalize : in BOOLEAN := float_denormalize; + check_error : in BOOLEAN := float_check_error; + fract : out UNRESOLVED_ufixed; -- a number between 1.0 and 2.0 + expon : out UNRESOLVED_SIGNED; -- NOTE: Add 1 to get the real exponent! + sign : out STD_ULOGIC); + + -- Normalize takes a fraction and and exponent and converts them into + -- a floating point number. Does the shifting and the rounding. + -- Exponent is assumed to be biased by -1 + + function normalize ( + fract : UNRESOLVED_UNSIGNED; -- fraction, unnormalized + expon : UNRESOLVED_SIGNED; -- exponent - 1, normalized + sign : STD_ULOGIC; -- sign bit + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + constant exponent_width : NATURAL := float_exponent_width; -- size of output exponent + constant fraction_width : NATURAL := float_fraction_width; -- size of output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float; + + -- Exponent is assumed to be biased by -1 + function normalize ( + fract : UNRESOLVED_ufixed; -- unsigned fixed point + expon : UNRESOLVED_SIGNED; -- exponent - 1, normalized + sign : STD_ULOGIC; -- sign bit + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + constant exponent_width : NATURAL := float_exponent_width; -- size of output exponent + constant fraction_width : NATURAL := float_fraction_width; -- size of output fraction + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float; + + function normalize ( + fract : UNRESOLVED_UNSIGNED; -- unsigned + expon : UNRESOLVED_SIGNED; -- exponent - 1, normalized + sign : STD_ULOGIC; -- sign bit + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + size_res : UNRESOLVED_float; -- used for sizing only + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float; + + -- Exponent is assumed to be biased by -1 + function normalize ( + fract : UNRESOLVED_ufixed; -- unsigned fixed point + expon : UNRESOLVED_SIGNED; -- exponent - 1, normalized + sign : STD_ULOGIC; -- sign bit + sticky : STD_ULOGIC := '0'; -- Sticky bit (rounding) + size_res : UNRESOLVED_float; -- used for sizing only + constant round_style : round_type := float_round_style; -- rounding option + constant denormalize : BOOLEAN := float_denormalize; -- Use IEEE extended FP + constant nguard : NATURAL := float_guard_bits) -- guard bits + return UNRESOLVED_float; + + -- overloaded versions + function "+" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function "+" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function "+" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function "+" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; + function "-" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function "-" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function "-" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function "-" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; + function "*" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function "*" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function "*" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function "*" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; + function "/" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function "/" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function "/" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function "/" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; + function "rem" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function "rem" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function "rem" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function "rem" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; + function "mod" (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function "mod" (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function "mod" (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function "mod" (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; + + -- overloaded compare functions + function "=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN; + function "/=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN; + function ">=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN; + function "<=" (l : UNRESOLVED_float; r : REAL) return BOOLEAN; + function ">" (l : UNRESOLVED_float; r : REAL) return BOOLEAN; + function "<" (l : UNRESOLVED_float; r : REAL) return BOOLEAN; + function "=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN; + function "/=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN; + function ">=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN; + function "<=" (l : REAL; r : UNRESOLVED_float) return BOOLEAN; + function ">" (l : REAL; r : UNRESOLVED_float) return BOOLEAN; + function "<" (l : REAL; r : UNRESOLVED_float) return BOOLEAN; + function "=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN; + function "/=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN; + function ">=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN; + function "<=" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN; + function ">" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN; + function "<" (l : UNRESOLVED_float; r : INTEGER) return BOOLEAN; + function "=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN; + function "/=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN; + function ">=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN; + function "<=" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN; + function ">" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN; + function "<" (l : INTEGER; r : UNRESOLVED_float) return BOOLEAN; + function "?=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC; + function "?/=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC; + function "?>" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC; + function "?>=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC; + function "?<" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC; + function "?<=" (l : UNRESOLVED_float; r : REAL) return STD_ULOGIC; + function "?=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC; + function "?/=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC; + function "?>" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC; + function "?>=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC; + function "?<" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC; + function "?<=" (l : REAL; r : UNRESOLVED_float) return STD_ULOGIC; + function "?=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC; + function "?/=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC; + function "?>" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC; + function "?>=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC; + function "?<" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC; + function "?<=" (l : UNRESOLVED_float; r : INTEGER) return STD_ULOGIC; + function "?=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC; + function "?/=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC; + function "?>" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC; + function "?>=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC; + function "?<" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC; + function "?<=" (l : INTEGER; r : UNRESOLVED_float) return STD_ULOGIC; + -- minimum and maximum overloads + function maximum (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function minimum (l : UNRESOLVED_float; r : REAL) return UNRESOLVED_float; + function maximum (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function minimum (l : REAL; r : UNRESOLVED_float) return UNRESOLVED_float; + function maximum (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function minimum (l : UNRESOLVED_float; r : INTEGER) return UNRESOLVED_float; + function maximum (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; + function minimum (l : INTEGER; r : UNRESOLVED_float) return UNRESOLVED_float; +---------------------------------------------------------------------------- + -- logical functions + ---------------------------------------------------------------------------- + + function "not" (l : UNRESOLVED_float) return UNRESOLVED_float; + function "and" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "or" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "nand" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "nor" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "xor" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + function "xnor" (l, r : UNRESOLVED_float) return UNRESOLVED_float; + -- Vector and std_ulogic functions, same as functions in numeric_std + function "and" (l : STD_ULOGIC; r : UNRESOLVED_float) + return UNRESOLVED_float; + function "and" (l : UNRESOLVED_float; r : STD_ULOGIC) + return UNRESOLVED_float; + function "or" (l : STD_ULOGIC; r : UNRESOLVED_float) + return UNRESOLVED_float; + function "or" (l : UNRESOLVED_float; r : STD_ULOGIC) + return UNRESOLVED_float; + function "nand" (l : STD_ULOGIC; r : UNRESOLVED_float) + return UNRESOLVED_float; + function "nand" (l : UNRESOLVED_float; r : STD_ULOGIC) + return UNRESOLVED_float; + function "nor" (l : STD_ULOGIC; r : UNRESOLVED_float) + return UNRESOLVED_float; + function "nor" (l : UNRESOLVED_float; r : STD_ULOGIC) + return UNRESOLVED_float; + function "xor" (l : STD_ULOGIC; r : UNRESOLVED_float) + return UNRESOLVED_float; + function "xor" (l : UNRESOLVED_float; r : STD_ULOGIC) + return UNRESOLVED_float; + function "xnor" (l : STD_ULOGIC; r : UNRESOLVED_float) + return UNRESOLVED_float; + function "xnor" (l : UNRESOLVED_float; r : STD_ULOGIC) + return UNRESOLVED_float; + -- Reduction operators, same as numeric_std functions + function "and" (l : UNRESOLVED_float) return STD_ULOGIC; + function "nand" (l : UNRESOLVED_float) return STD_ULOGIC; + function "or" (l : UNRESOLVED_float) return STD_ULOGIC; + function "nor" (l : UNRESOLVED_float) return STD_ULOGIC; + function "xor" (l : UNRESOLVED_float) return STD_ULOGIC; + function "xnor" (l : UNRESOLVED_float) return STD_ULOGIC; + + -- Note: "sla", "sra", "sll", "slr", "rol" and "ror" not implemented. + + ----------------------------------------------------------------------------- + -- Recommended Functions from the IEEE 754 Appendix + ----------------------------------------------------------------------------- + + -- returns x with the sign of y. + function Copysign (x, y : UNRESOLVED_float) return UNRESOLVED_float; + + -- Returns y * 2**n for integral values of N without computing 2**n + function Scalb ( + y : UNRESOLVED_float; -- floating point input + N : INTEGER; -- exponent to add + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + -- Returns y * 2**n for integral values of N without computing 2**n + function Scalb ( + y : UNRESOLVED_float; -- floating point input + N : UNRESOLVED_SIGNED; -- exponent to add + constant round_style : round_type := float_round_style; -- rounding option + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) -- Use IEEE extended FP + return UNRESOLVED_float; + + -- returns the unbiased exponent of x + function Logb (x : UNRESOLVED_float) return INTEGER; + function Logb (x : UNRESOLVED_float) return UNRESOLVED_SIGNED; + + -- returns the next representable neighbor of x in the direction toward y + function Nextafter ( + x, y : UNRESOLVED_float; -- floating point input + constant check_error : BOOLEAN := float_check_error; -- check for errors + constant denormalize : BOOLEAN := float_denormalize) + return UNRESOLVED_float; + + -- Returns TRUE if X is unordered with Y. + function Unordered (x, y : UNRESOLVED_float) return BOOLEAN; + function Finite (x : UNRESOLVED_float) return BOOLEAN; + function Isnan (x : UNRESOLVED_float) return BOOLEAN; + + -- Function to return constants. + function zerofp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float; + function nanfp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float; + function qnanfp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float; + function pos_inffp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float; + function neg_inffp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float; + function neg_zerofp ( + constant exponent_width : NATURAL := float_exponent_width; -- exponent + constant fraction_width : NATURAL := float_fraction_width) -- fraction + return UNRESOLVED_float; + -- size_res versions + function zerofp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float; + function nanfp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float; + function qnanfp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float; + function pos_inffp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float; + function neg_inffp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float; + function neg_zerofp ( + size_res : UNRESOLVED_float) -- variable is only use for sizing + return UNRESOLVED_float; + + --=========================================================================== + -- string and textio Functions + --=========================================================================== + + -- writes S:EEEE:FFFFFFFF + procedure WRITE ( + L : inout LINE; -- access type (pointer) + VALUE : in UNRESOLVED_float; -- value to write + JUSTIFIED : in SIDE := right; -- which side to justify text + FIELD : in WIDTH := 0); -- width of field + + -- Reads SEEEEFFFFFFFF, "." and ":" are ignored + procedure READ (L : inout LINE; VALUE : out UNRESOLVED_float); + procedure READ (L : inout LINE; VALUE : out UNRESOLVED_float; + GOOD : out BOOLEAN); + + alias BREAD is READ [LINE, UNRESOLVED_float, BOOLEAN]; + alias BREAD is READ [LINE, UNRESOLVED_float]; + alias BWRITE is WRITE [LINE, UNRESOLVED_float, SIDE, WIDTH]; + alias BINARY_READ is READ [LINE, UNRESOLVED_FLOAT, BOOLEAN]; + alias BINARY_READ is READ [LINE, UNRESOLVED_FLOAT]; + alias BINARY_WRITE is WRITE [LINE, UNRESOLVED_float, SIDE, WIDTH]; + + procedure OWRITE ( + L : inout LINE; -- access type (pointer) + VALUE : in UNRESOLVED_float; -- value to write + JUSTIFIED : in SIDE := right; -- which side to justify text + FIELD : in WIDTH := 0); -- width of field + + -- Octal read with padding, no separators used + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_float); + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_float; + GOOD : out BOOLEAN); + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_FLOAT, BOOLEAN]; + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_FLOAT]; + alias OCTAL_WRITE is OWRITE [LINE, UNRESOLVED_FLOAT, SIDE, WIDTH]; + + -- Hex write with padding, no separators + procedure HWRITE ( + L : inout LINE; -- access type (pointer) + VALUE : in UNRESOLVED_float; -- value to write + JUSTIFIED : in SIDE := right; -- which side to justify text + FIELD : in WIDTH := 0); -- width of field + + -- Hex read with padding, no separators used + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_float); + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_float; + GOOD : out BOOLEAN); + alias HEX_READ is HREAD [LINE, UNRESOLVED_FLOAT, BOOLEAN]; + alias HEX_READ is HREAD [LINE, UNRESOLVED_FLOAT]; + alias HEX_WRITE is HWRITE [LINE, UNRESOLVED_FLOAT, SIDE, WIDTH]; + + -- returns "S:EEEE:FFFFFFFF" + function to_string (value : UNRESOLVED_float) return STRING; + alias TO_BSTRING is TO_STRING [UNRESOLVED_FLOAT return STRING]; + alias TO_BINARY_STRING is TO_STRING [UNRESOLVED_FLOAT return STRING]; + + -- Returns a HEX string, with padding + function to_hstring (value : UNRESOLVED_float) return STRING; + alias TO_HEX_STRING is TO_HSTRING [UNRESOLVED_FLOAT return STRING]; + + -- Returns and octal string, with padding + function to_ostring (value : UNRESOLVED_float) return STRING; + alias TO_OCTAL_STRING is TO_OSTRING [UNRESOLVED_FLOAT return STRING]; + + function from_string ( + bstring : STRING; -- binary string + constant exponent_width : NATURAL := float_exponent_width; + constant fraction_width : NATURAL := float_fraction_width) + return UNRESOLVED_float; + alias from_bstring is from_string [STRING, NATURAL, NATURAL + return UNRESOLVED_float]; + alias from_binary_string is from_string [STRING, NATURAL, NATURAL + return UNRESOLVED_float]; + function from_ostring ( + ostring : STRING; -- Octal string + constant exponent_width : NATURAL := float_exponent_width; + constant fraction_width : NATURAL := float_fraction_width) + return UNRESOLVED_float; + alias from_octal_string is from_ostring [STRING, NATURAL, NATURAL + return UNRESOLVED_float]; + + function from_hstring ( + hstring : STRING; -- hex string + constant exponent_width : NATURAL := float_exponent_width; + constant fraction_width : NATURAL := float_fraction_width) + return UNRESOLVED_float; + alias from_hex_string is from_hstring [STRING, NATURAL, NATURAL + return UNRESOLVED_float]; + + function from_string ( + bstring : STRING; -- binary string + size_res : UNRESOLVED_float) -- used for sizing only + return UNRESOLVED_float; + alias from_bstring is from_string [STRING, UNRESOLVED_float + return UNRESOLVED_float]; + alias from_binary_string is from_string [STRING, UNRESOLVED_float + return UNRESOLVED_float]; + + function from_ostring ( + ostring : STRING; -- Octal string + size_res : UNRESOLVED_float) -- used for sizing only + return UNRESOLVED_float; + alias from_octal_string is from_ostring [STRING, UNRESOLVED_float + return UNRESOLVED_float]; + + function from_hstring ( + hstring : STRING; -- hex string + size_res : UNRESOLVED_float) -- used for sizing only + return UNRESOLVED_float; + alias from_hex_string is from_hstring [STRING, UNRESOLVED_float + return UNRESOLVED_float]; + +end package float_generic_pkg; diff --git a/libraries/ieee2008/float_pkg.vhdl b/libraries/ieee2008/float_pkg.vhdl new file mode 100644 index 000000000..e69697acf --- /dev/null +++ b/libraries/ieee2008/float_pkg.vhdl @@ -0,0 +1,52 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Floating-point package (Instantiated package declaration) +-- : +-- 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 floating point +-- : 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; + +package float_pkg is new IEEE.float_generic_pkg + generic map ( + float_exponent_width => 8, -- float32'high + float_fraction_width => 23, -- -float32'low + float_round_style => IEEE.fixed_float_types.round_nearest, -- round nearest algorithm + float_denormalize => true, -- Use IEEE extended floating + float_check_error => true, -- Turn on NAN and overflow processing + float_guard_bits => 3, -- number of guard bits + no_warning => false, -- show warnings + fixed_pkg => IEEE.fixed_pkg + ); diff --git a/libraries/ieee2008/math_complex-body.vhdl b/libraries/ieee2008/math_complex-body.vhdl new file mode 100644 index 000000000..ecd85e665 --- /dev/null +++ b/libraries/ieee2008/math_complex-body.vhdl @@ -0,0 +1,1600 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Mathematical Packages +-- : (MATH_COMPLEX package body) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC VHDL Mathematical Packages Working Group +-- : +-- Purpose : This package defines a standard for designers to use in +-- : describing VHDL models that make use of common COMPLEX +-- : constants and common COMPLEX mathematical functions and +-- : operators. +-- : +-- Limitation: The values generated by the functions in this package +-- : may vary from platform to platform, and the precision +-- : of results is only guaranteed to be the minimum required +-- : by IEEE Std 1076-2008. +-- : +-- 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) $ +-- -------------------------------------------------------------------- + +use WORK.MATH_REAL.all; + +package body MATH_COMPLEX is + + -- + -- Equality and Inequality Operators for COMPLEX_POLAR + -- + function "=" ( L: in COMPLEX_POLAR; R: in COMPLEX_POLAR ) return BOOLEAN + is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns FALSE on error + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in =(L,R)" + severity ERROR; + return FALSE; + end if; + + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in =(L,R)" + severity ERROR; + return FALSE; + end if; + + -- Get special values + if ( L.MAG = 0.0 and R.MAG = 0.0 ) then + return TRUE; + end if; + + -- Get value for general case + if ( L.MAG = R.MAG and L.ARG = R.ARG ) then + return TRUE; + end if; + + return FALSE; + end function "="; + + + function "/=" ( L: in COMPLEX_POLAR; R: in COMPLEX_POLAR ) return BOOLEAN + is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns FALSE on error + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in /=(L,R)" + severity ERROR; + return FALSE; + end if; + + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in /=(L,R)" + severity ERROR; + return FALSE; + end if; + + -- Get special values + if ( L.MAG = 0.0 and R.MAG = 0.0 ) then + return FALSE; + end if; + + -- Get value for general case + if ( L.MAG = R.MAG and L.ARG = R.ARG ) then + return FALSE; + end if; + + return TRUE; + end function "/="; + + -- + -- Other Functions Start Here + -- + + function CMPLX(X: in REAL; Y: in REAL := 0.0 ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(X, Y); + end function CMPLX; + + + function GET_PRINCIPAL_VALUE(X: in REAL ) return PRINCIPAL_VALUE is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + variable TEMP: REAL; + begin + -- Check if already a principal value + if ( X > -MATH_PI and X <= MATH_PI ) then + return PRINCIPAL_VALUE'(X); + end if; + + -- Get principal value + TEMP := X; + while ( TEMP <= -MATH_PI ) loop + TEMP := TEMP + MATH_2_PI; + end loop; + while (TEMP > MATH_PI ) loop + TEMP := TEMP - MATH_2_PI; + end loop; + + return PRINCIPAL_VALUE'(TEMP); + end function GET_PRINCIPAL_VALUE; + + function COMPLEX_TO_POLAR(Z: in COMPLEX ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + variable TEMP: REAL; + begin + -- Get value for special cases + if ( Z.RE = 0.0 ) then + if ( Z.IM = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + elsif ( Z.IM > 0.0 ) then + return COMPLEX_POLAR'(Z.IM, MATH_PI_OVER_2); + else + return COMPLEX_POLAR'(-Z.IM, -MATH_PI_OVER_2); + end if; + end if; + + if ( Z.IM = 0.0 ) then + if ( Z.RE = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + elsif ( Z.RE > 0.0 ) then + return COMPLEX_POLAR'(Z.RE, 0.0); + else + return COMPLEX_POLAR'(-Z.RE, MATH_PI); + end if; + end if; + + -- Get principal value for general case + TEMP := ARCTAN(Z.IM, Z.RE); + + return COMPLEX_POLAR'(SQRT(Z.RE*Z.RE + Z.IM*Z.IM), + GET_PRINCIPAL_VALUE(TEMP)); + end function COMPLEX_TO_POLAR; + + function POLAR_TO_COMPLEX(Z: in COMPLEX_POLAR ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns MATH_CZERO on error + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in POLAR_TO_COMPLEX(Z)" + severity ERROR; + return MATH_CZERO; + end if; + + -- Get value for general case + return COMPLEX'( Z.MAG*COS(Z.ARG), Z.MAG*SIN(Z.ARG) ); + end function POLAR_TO_COMPLEX; + + + function "ABS"(Z: in COMPLEX ) return POSITIVE_REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) ABS(Z) = SQRT(Z.RE*Z.RE + Z.IM*Z.IM) + + begin + -- Get value for general case + return POSITIVE_REAL'(SQRT(Z.RE*Z.RE + Z.IM*Z.IM)); + end function "ABS"; + + function "ABS"(Z: in COMPLEX_POLAR ) return POSITIVE_REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) ABS(Z) = Z.MAG + -- b) Returns 0.0 on error + + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in ABS(Z)" + severity ERROR; + return 0.0; + end if; + + -- Get value for general case + return Z.MAG; + end function "ABS"; + + + function ARG(Z: in COMPLEX ) return PRINCIPAL_VALUE is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) ARG(Z) = ARCTAN(Z.IM, Z.RE) + + variable ZTEMP : COMPLEX_POLAR; + begin + -- Get value for general case + ZTEMP := COMPLEX_TO_POLAR(Z); + return ZTEMP.ARG; + end function ARG; + + function ARG(Z: in COMPLEX_POLAR ) return PRINCIPAL_VALUE is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) ARG(Z) = Z.ARG + -- b) Returns 0.0 on error + + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in ARG(Z)" + severity ERROR; + return 0.0; + end if; + + -- Get value for general case + return Z.ARG; + end function ARG; + + function "-" (Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns -x -jy for Z = x + jy + begin + -- Get value for general case + return COMPLEX'(-Z.RE, -Z.IM); + end function "-"; + + function "-" (Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns (Z.MAG, Z.ARG + MATH_PI) + -- b) Returns Z on error + variable TEMP: REAL; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in -(Z)" + severity ERROR; + return Z; + end if; + + -- Get principal value for general case + TEMP := REAL'(Z.ARG) + MATH_PI; + + return COMPLEX_POLAR'(Z.MAG, GET_PRINCIPAL_VALUE(TEMP)); + end function "-"; + + function CONJ (Z: in COMPLEX) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns x - jy for Z = x + jy + begin + -- Get value for general case + return COMPLEX'(Z.RE, -Z.IM); + end function CONJ; + + function CONJ (Z: in COMPLEX_POLAR) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX conjugate (Z.MAG, -Z.ARG) + -- b) Returns Z on error + -- + variable TEMP: PRINCIPAL_VALUE; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in CONJ(Z)" + severity ERROR; + return Z; + end if; + + -- Get principal value for general case + if ( Z.ARG = MATH_PI or Z.ARG = 0.0 ) then + TEMP := Z.ARG; + else + TEMP := -Z.ARG; + end if; + + return COMPLEX_POLAR'(Z.MAG, TEMP); + end function CONJ; + + function SQRT(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + variable ZTEMP : COMPLEX_POLAR; + variable ZOUT : COMPLEX; + variable TMAG : REAL; + variable TARG : REAL; + begin + -- Get value for special cases + if ( Z = MATH_CZERO ) then + return MATH_CZERO; + end if; + + -- Get value for general case + ZTEMP := COMPLEX_TO_POLAR(Z); + TMAG := SQRT(ZTEMP.MAG); + TARG := 0.5*ZTEMP.ARG; + + if ( COS(TARG) > 0.0 ) then + ZOUT.RE := TMAG*COS(TARG); + ZOUT.IM := TMAG*SIN(TARG); + return ZOUT; + end if; + + if ( COS(TARG) < 0.0 ) then + ZOUT.RE := TMAG*COS(TARG + MATH_PI); + ZOUT.IM := TMAG*SIN(TARG + MATH_PI); + return ZOUT; + end if; + + if ( SIN(TARG) > 0.0 ) then + ZOUT.RE := 0.0; + ZOUT.IM := TMAG*SIN(TARG); + return ZOUT; + end if; + + ZOUT.RE := 0.0; + ZOUT.IM := TMAG*SIN(TARG + MATH_PI); + return ZOUT; + end function SQRT; + + function SQRT(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns Z on error + + variable ZOUT : COMPLEX_POLAR; + variable TMAG : REAL; + variable TARG : REAL; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in SQRT(Z)" + severity ERROR; + return Z; + end if; + + -- Get value for special cases + if ( Z.MAG = 0.0 and Z.ARG = 0.0 ) then + return Z; + end if; + + -- Get principal value for general case + TMAG := SQRT(Z.MAG); + TARG := 0.5*Z.ARG; + + ZOUT.MAG := POSITIVE_REAL'(TMAG); + + if ( COS(TARG) < 0.0 ) then + TARG := TARG + MATH_PI; + end if; + + if ( (COS(TARG) = 0.0) and (SIN(TARG) < 0.0) ) then + TARG := TARG + MATH_PI; + end if; + + ZOUT.ARG := GET_PRINCIPAL_VALUE(TARG); + return ZOUT; + end function SQRT; + + function EXP(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + + variable TEMP: REAL; + begin + -- Get value for special cases + if ( Z = MATH_CZERO ) then + return MATH_CBASE_1; + end if; + + if ( Z.RE = 0.0 ) then + if ( Z.IM = MATH_PI or Z.IM = -MATH_PI ) then + return COMPLEX'(-1.0, 0.0); + end if; + + if ( Z.IM = MATH_PI_OVER_2 ) then + return MATH_CBASE_J; + end if; + + if ( Z.IM = -MATH_PI_OVER_2 ) then + return COMPLEX'(0.0, -1.0); + end if; + end if; + + -- Get value for general case + TEMP := EXP(Z.RE); + return COMPLEX'(TEMP*COS(Z.IM), TEMP*SIN(Z.IM)); + end function EXP; + + function EXP(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns Z on error + + variable ZTEMP : COMPLEX; + variable temp: REAL; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in EXP(Z)" + severity ERROR; + return Z; + end if; + + -- Get value for special cases + if ( Z.MAG = 0.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(1.0, 0.0); + end if; + + if ( Z.MAG = MATH_PI and (Z.ARG = MATH_PI_OVER_2 or + Z.ARG = -MATH_PI_OVER_2 )) then + return COMPLEX_POLAR'(1.0, MATH_PI); + end if; + + if ( Z.MAG = MATH_PI_OVER_2 ) then + if ( Z.ARG = MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(1.0, MATH_PI_OVER_2); + end if; + + if ( Z.ARG = -MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(1.0, -MATH_PI_OVER_2); + end if; + end if; + + -- Get principal value for general case + ZTEMP := POLAR_TO_COMPLEX(Z); + ZOUT.MAG := POSITIVE_REAL'(EXP(ZTEMP.RE)); + ZOUT.ARG := GET_PRINCIPAL_VALUE(ZTEMP.IM); + + return ZOUT; + end function EXP; + + function LOG(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX'(REAL'LOW, 0.0) on error + + variable ZTEMP : COMPLEX_POLAR; + variable TEMP : REAL; + begin + -- Check validity of input arguments + if ( Z.RE = 0.0 and Z.IM = 0.0 ) then + assert FALSE + report "Z.RE = 0.0 and Z.IM = 0.0 in LOG(Z)" + severity ERROR; + return COMPLEX'(REAL'LOW, 0.0); + end if; + + -- Get value for special cases + if ( Z.IM = 0.0 ) then + if ( Z.RE = -1.0 ) then + return COMPLEX'(0.0, MATH_PI); + end if; + if ( Z.RE = MATH_E ) then + return MATH_CBASE_1; + end if; + if ( Z.RE = 1.0 ) then + return MATH_CZERO; + end if; + end if; + + if ( Z.RE = 0.0 ) then + if (Z.IM = 1.0) then + return COMPLEX'(0.0, MATH_PI_OVER_2); + end if; + if (Z.IM = -1.0) then + return COMPLEX'(0.0, -MATH_PI_OVER_2); + end if; + end if; + + -- Get value for general case + ZTEMP := COMPLEX_TO_POLAR(Z); + TEMP := LOG(ZTEMP.MAG); + return COMPLEX'(TEMP, ZTEMP.ARG); + end function LOG; + + function LOG2(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX'(REAL'LOW, 0.0) on error + + variable ZTEMP : COMPLEX_POLAR; + variable TEMP : REAL; + begin + + -- Check validity of input arguments + if ( Z.RE = 0.0 and Z.IM = 0.0 ) then + assert FALSE + report "Z.RE = 0.0 and Z.IM = 0.0 in LOG2(Z)" + severity ERROR; + return COMPLEX'(REAL'LOW, 0.0); + end if; + + -- Get value for special cases + if ( Z.IM = 0.0 ) then + if ( Z.RE = 2.0 ) then + return MATH_CBASE_1; + end if; + if ( Z.RE = 1.0 ) then + return MATH_CZERO; + end if; + end if; + + -- Get value for general case + ZTEMP := COMPLEX_TO_POLAR(Z); + TEMP := MATH_LOG2_OF_E*LOG(ZTEMP.MAG); + return COMPLEX'(TEMP, MATH_LOG2_OF_E*ZTEMP.ARG); + end function LOG2; + + function LOG10(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX'(REAL'LOW, 0.0) on error + + variable ZTEMP : COMPLEX_POLAR; + variable TEMP : REAL; + begin + -- Check validity of input arguments + if ( Z.RE = 0.0 and Z.IM = 0.0 ) then + assert FALSE + report "Z.RE = 0.0 and Z.IM = 0.0 in LOG10(Z)" + severity ERROR; + return COMPLEX'(REAL'LOW, 0.0); + end if; + + -- Get value for special cases + if ( Z.IM = 0.0 ) then + if ( Z.RE = 10.0 ) then + return MATH_CBASE_1; + end if; + if ( Z.RE = 1.0 ) then + return MATH_CZERO; + end if; + end if; + + -- Get value for general case + ZTEMP := COMPLEX_TO_POLAR(Z); + TEMP := MATH_LOG10_OF_E*LOG(ZTEMP.MAG); + return COMPLEX'(TEMP, MATH_LOG10_OF_E*ZTEMP.ARG); + end function LOG10; + + + function LOG(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(REAL'HIGH, MATH_PI) on error + + variable ZTEMP : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.MAG <= 0.0 ) then + assert FALSE + report "Z.MAG <= 0.0 in LOG(Z)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in LOG(Z)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + -- Compute value for special cases + if (Z.MAG = 1.0 ) then + if ( Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.ARG = MATH_PI ) then + return COMPLEX_POLAR'(MATH_PI, MATH_PI_OVER_2); + end if; + + if ( Z.ARG = MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(MATH_PI_OVER_2, MATH_PI_OVER_2); + end if; + + if ( Z.ARG = -MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(MATH_PI_OVER_2, -MATH_PI_OVER_2); + end if; + end if; + + if ( Z.MAG = MATH_E and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(1.0, 0.0); + end if; + + -- Compute value for general case + ZTEMP.RE := LOG(Z.MAG); + ZTEMP.IM := Z.ARG; + ZOUT := COMPLEX_TO_POLAR(ZTEMP); + return ZOUT; + end function LOG; + + + + function LOG2(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(REAL'HIGH, MATH_PI) on error + + variable ZTEMP : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.MAG <= 0.0 ) then + assert FALSE + report "Z.MAG <= 0.0 in LOG2(Z)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in LOG2(Z)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + -- Compute value for special cases + if (Z.MAG = 1.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = 2.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(1.0, 0.0); + end if; + + -- Compute value for general case + ZTEMP.RE := MATH_LOG2_OF_E*LOG(Z.MAG); + ZTEMP.IM := MATH_LOG2_OF_E*Z.ARG; + ZOUT := COMPLEX_TO_POLAR(ZTEMP); + return ZOUT; + end function LOG2; + + function LOG10(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(REAL'HIGH, MATH_PI) on error + variable ZTEMP : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.MAG <= 0.0 ) then + assert FALSE + report "Z.MAG <= 0.0 in LOG10(Z)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in LOG10(Z)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + -- Compute value for special cases + if (Z.MAG = 1.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = 10.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(1.0, 0.0); + end if; + + -- Compute value for general case + ZTEMP.RE := MATH_LOG10_OF_E*LOG(Z.MAG); + ZTEMP.IM := MATH_LOG10_OF_E*Z.ARG; + ZOUT := COMPLEX_TO_POLAR(ZTEMP); + return ZOUT; + end function LOG10; + + function LOG(Z: in COMPLEX; BASE: in REAL ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX'(REAL'LOW, 0.0) on error + + variable ZTEMP : COMPLEX_POLAR; + variable TEMPRE : REAL; + variable TEMPIM : REAL; + begin + -- Check validity of input arguments + if ( Z.RE = 0.0 and Z.IM = 0.0 ) then + assert FALSE + report "Z.RE = 0.0 and Z.IM = 0.0 in LOG(Z,BASE)" + severity ERROR; + return COMPLEX'(REAL'LOW, 0.0); + end if; + + if ( BASE <= 0.0 or BASE = 1.0 ) then + assert FALSE + report "BASE <= 0.0 or BASE = 1.0 in LOG(Z,BASE)" + severity ERROR; + return COMPLEX'(REAL'LOW, 0.0); + end if; + + -- Get value for special cases + if ( Z.IM = 0.0 ) then + if ( Z.RE = BASE ) then + return MATH_CBASE_1; + end if; + if ( Z.RE = 1.0 ) then + return MATH_CZERO; + end if; + end if; + + -- Get value for general case + ZTEMP := COMPLEX_TO_POLAR(Z); + TEMPRE := LOG(ZTEMP.MAG, BASE); + TEMPIM := ZTEMP.ARG/LOG(BASE); + return COMPLEX'(TEMPRE, TEMPIM); + end function LOG; + + function LOG(Z: in COMPLEX_POLAR; BASE: in REAL ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(REAL'HIGH, MATH_PI) on error + + variable ZTEMP : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.MAG <= 0.0 ) then + assert FALSE + report "Z.MAG <= 0.0 in LOG(Z,BASE)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + if ( BASE <= 0.0 or BASE = 1.0 ) then + assert FALSE + report "BASE <= 0.0 or BASE = 1.0 in LOG(Z,BASE)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in LOG(Z,BASE)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, MATH_PI); + end if; + + -- Compute value for special cases + if (Z.MAG = 1.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = BASE and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(1.0, 0.0); + end if; + + -- Compute value for general case + ZTEMP.RE := LOG(Z.MAG, BASE); + ZTEMP.IM := Z.ARG/LOG(BASE); + ZOUT := COMPLEX_TO_POLAR(ZTEMP); + return ZOUT; + end function LOG; + + + function SIN(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + -- Get value for special cases + if ( Z.IM = 0.0 ) then + if ( Z.RE = 0.0 or Z.RE = MATH_PI) then + return MATH_CZERO; + end if; + end if; + + -- Get value for general case + return COMPLEX'(SIN(Z.RE)*COSH(Z.IM), COS(Z.RE)*SINH(Z.IM)); + end function SIN; + + function SIN(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(0.0, 0.0) on error + + variable Z1, Z2 : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in SIN(Z)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Compute value for special cases + if ( Z.MAG = 0.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = MATH_PI and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Compute value for general case + Z1 := POLAR_TO_COMPLEX(Z); + Z2 := COMPLEX'(SIN(Z1.RE)*COSH(Z1.IM), COS(Z1.RE)*SINH(Z1.IM)); + ZOUT := COMPLEX_TO_POLAR(Z2); + return ZOUT; + end function SIN; + + function COS(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + + + -- Get value for special cases + if ( Z.IM = 0.0 ) then + if ( Z.RE = MATH_PI_OVER_2 or Z.RE = -MATH_PI_OVER_2) then + return MATH_CZERO; + end if; + end if; + + -- Get value for general case + return COMPLEX'(COS(Z.RE)*COSH(Z.IM), -SIN(Z.RE)*SINH(Z.IM)); + end function COS; + + function COS(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(0.0, 0.0) on error + + variable Z1, Z2 : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in COS(Z)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Compute value for special cases + if ( Z.MAG = MATH_PI_OVER_2 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = MATH_PI_OVER_2 and Z.ARG = MATH_PI ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Compute value for general case + Z1 := POLAR_TO_COMPLEX(Z); + Z2 := COMPLEX'(COS(Z1.RE)*COSH(Z1.IM), -SIN(Z1.RE)*SINH(Z1.IM)); + ZOUT := COMPLEX_TO_POLAR(Z2); + return ZOUT; + end function COS; + + function SINH(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + -- Get value for special cases + if ( Z.RE = 0.0 ) then + if ( Z.IM = 0.0 or Z.IM = MATH_PI ) then + return MATH_CZERO; + end if; + + + + if ( Z.IM = MATH_PI_OVER_2 ) then + return MATH_CBASE_J; + end if; + + if ( Z.IM = -MATH_PI_OVER_2 ) then + return -MATH_CBASE_J; + end if; + end if; + + -- Get value for general case + return COMPLEX'(SINH(Z.RE)*COS(Z.IM), COSH(Z.RE)*SIN(Z.IM)); + end function SINH; + + function SINH(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(0.0, 0.0) on error + + variable Z1, Z2 : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in SINH(Z)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Compute value for special cases + if ( Z.MAG = 0.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = MATH_PI and Z.ARG = MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = MATH_PI_OVER_2 and Z.ARG = MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(1.0, MATH_PI_OVER_2); + end if; + + if ( Z.MAG = MATH_PI_OVER_2 and Z.ARG = -MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(1.0, -MATH_PI_OVER_2); + end if; + + -- Compute value for general case + Z1 := POLAR_TO_COMPLEX(Z); + Z2 := COMPLEX'(SINH(Z1.RE)*COS(Z1.IM), COSH(Z1.RE)*SIN(Z1.IM)); + ZOUT := COMPLEX_TO_POLAR(Z2); + return ZOUT; + end function SINH; + + + function COSH(Z: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + -- Get value for special cases + if ( Z.RE = 0.0 ) then + if ( Z.IM = 0.0 ) then + return MATH_CBASE_1; + end if; + + if ( Z.IM = MATH_PI ) then + return -MATH_CBASE_1; + end if; + + if ( Z.IM = MATH_PI_OVER_2 or Z.IM = -MATH_PI_OVER_2 ) then + return MATH_CZERO; + end if; + end if; + + -- Get value for general case + return COMPLEX'(COSH(Z.RE)*COS(Z.IM), SINH(Z.RE)*SIN(Z.IM)); + end function COSH; + + function COSH(Z: in COMPLEX_POLAR ) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR(0.0, 0.0) on error + + variable Z1, Z2 : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( Z.ARG = -MATH_PI ) then + assert FALSE + report "Z.ARG = -MATH_PI in COSH(Z)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Compute value for special cases + if ( Z.MAG = 0.0 and Z.ARG = 0.0 ) then + return COMPLEX_POLAR'(1.0, 0.0); + end if; + + if ( Z.MAG = MATH_PI and Z.ARG = MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(1.0, MATH_PI); + end if; + + if ( Z.MAG = MATH_PI_OVER_2 and Z.ARG = MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( Z.MAG = MATH_PI_OVER_2 and Z.ARG = -MATH_PI_OVER_2 ) then + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Compute value for general case + Z1 := POLAR_TO_COMPLEX(Z); + Z2 := COMPLEX'(COSH(Z1.RE)*COS(Z1.IM), SINH(Z1.RE)*SIN(Z1.IM)); + ZOUT := COMPLEX_TO_POLAR(Z2); + return ZOUT; + end function COSH; + + + -- + -- Arithmetic Operators + -- + function "+" ( L: in COMPLEX; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L.RE + R.RE, L.IM + R.IM); + end function "+"; + + function "+" ( L: in REAL; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L + R.RE, R.IM); + end function "+"; + + function "+" ( L: in COMPLEX; R: in REAL ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L.RE + R, L.IM); + end function "+"; + + function "+" (L: in COMPLEX_POLAR; R: in COMPLEX_POLAR) + return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZL, ZR : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in +(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in +(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZL := POLAR_TO_COMPLEX( L ); + ZR := POLAR_TO_COMPLEX( R ); + ZOUT := COMPLEX_TO_POLAR(COMPLEX'(ZL.RE + ZR.RE, ZL.IM +ZR.IM)); + return ZOUT; + end function "+"; + + function "+" ( L: in REAL; R: in COMPLEX_POLAR) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + variable ZR : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in +(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZR := POLAR_TO_COMPLEX( R ); + ZOUT := COMPLEX_TO_POLAR(COMPLEX'(L + ZR.RE, ZR.IM)); + return ZOUT; + end function "+"; + + function "+" ( L: in COMPLEX_POLAR; R: in REAL) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZL : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in +(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZL := POLAR_TO_COMPLEX( L ); + ZOUT := COMPLEX_TO_POLAR(COMPLEX'(ZL.RE + R, ZL.IM)); + return ZOUT; + end function "+"; + + function "-" ( L: in COMPLEX; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L.RE - R.RE, L.IM - R.IM); + end function "-"; + + function "-" ( L: in REAL; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L - R.RE, -1.0 * R.IM); + end function "-"; + + function "-" ( L: in COMPLEX; R: in REAL ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L.RE - R, L.IM); + end function "-"; + + function "-" ( L: in COMPLEX_POLAR; R: in COMPLEX_POLAR) + return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZL, ZR : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in -(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in -(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + -- Get principal value + ZL := POLAR_TO_COMPLEX( L ); + ZR := POLAR_TO_COMPLEX( R ); + ZOUT := COMPLEX_TO_POLAR(COMPLEX'(ZL.RE - ZR.RE, ZL.IM -ZR.IM)); + return ZOUT; + end function "-"; + + function "-" ( L: in REAL; R: in COMPLEX_POLAR) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZR : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in -(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZR := POLAR_TO_COMPLEX( R ); + ZOUT := COMPLEX_TO_POLAR(COMPLEX'(L - ZR.RE, -1.0*ZR.IM)); + return ZOUT; + end function "-"; + + function "-" ( L: in COMPLEX_POLAR; R: in REAL) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZL : COMPLEX; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in -(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZL := POLAR_TO_COMPLEX( L ); + ZOUT := COMPLEX_TO_POLAR(COMPLEX'(ZL.RE - R, ZL.IM)); + return ZOUT; + end function "-"; + + + function "*" ( L: in COMPLEX; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L.RE * R.RE - L.IM * R.IM, L.RE * R.IM + L.IM * R.RE); + end function "*"; + + + function "*" ( L: in REAL; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L * R.RE, L * R.IM); + end function "*"; + + function "*" ( L: in COMPLEX; R: in REAL ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + return COMPLEX'(L.RE * R, L.IM * R); + end function "*"; + + function "*" ( L: in COMPLEX_POLAR; R: in COMPLEX_POLAR) + return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in *(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in *(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZOUT.MAG := L.MAG * R.MAG; + ZOUT.ARG := GET_PRINCIPAL_VALUE(L.ARG + R.ARG); + + return ZOUT; + end function "*"; + + function "*" ( L: in REAL; R: in COMPLEX_POLAR) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZL : COMPLEX_POLAR; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in *(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZL.MAG := POSITIVE_REAL'(ABS(L)); + if ( L < 0.0 ) then + ZL.ARG := MATH_PI; + else + ZL.ARG := 0.0; + end if; + + ZOUT.MAG := ZL.MAG * R.MAG; + ZOUT.ARG := GET_PRINCIPAL_VALUE(ZL.ARG + R.ARG); + + return ZOUT; + end function "*"; + + function "*" ( L: in COMPLEX_POLAR; R: in REAL) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(0.0, 0.0) on error + -- + variable ZR : COMPLEX_POLAR; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in *(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZR.MAG := POSITIVE_REAL'(ABS(R)); + if ( R < 0.0 ) then + ZR.ARG := MATH_PI; + else + ZR.ARG := 0.0; + end if; + + ZOUT.MAG := L.MAG * ZR.MAG; + ZOUT.ARG := GET_PRINCIPAL_VALUE(L.ARG + ZR.ARG); + + return ZOUT; + end function "*"; + + function "/" ( L: in COMPLEX; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX'(REAL'HIGH, 0.0) on error + -- + variable TEMP : REAL := R.RE*R.RE + R.IM*R.IM; + begin + -- Check validity of input arguments + if (TEMP = 0.0) then + assert FALSE + report "Attempt to divide COMPLEX by (0.0, 0.0)" + severity ERROR; + return COMPLEX'(REAL'HIGH, 0.0); + end if; + + -- Get value + return COMPLEX'( (L.RE * R.RE + L.IM * R.IM) / TEMP, + (L.IM * R.RE - L.RE * R.IM) / TEMP); + end function "/"; + + function "/" ( L: in REAL; R: in COMPLEX ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX'(REAL'HIGH, 0.0) on error + -- + variable TEMP : REAL := R.RE*R.RE + R.IM*R.IM; + begin + -- Check validity of input arguments + if (TEMP = 0.0) then + assert FALSE + report "Attempt to divide COMPLEX by (0.0, 0.0)" + severity ERROR; + return COMPLEX'(REAL'HIGH, 0.0); + end if; + + -- Get value + TEMP := L / TEMP; + return COMPLEX'( TEMP * R.RE, -TEMP * R.IM ); + end function "/"; + + function "/" ( L: in COMPLEX; R: in REAL ) return COMPLEX is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX'(REAL'HIGH, 0.0) on error + begin + -- Check validity of input arguments + if (R = 0.0) then + assert FALSE + report "Attempt to divide COMPLEX by 0.0" + severity ERROR; + return COMPLEX'(REAL'HIGH, 0.0); + end if; + + -- Get value + return COMPLEX'(L.RE / R, L.IM / R); + end function "/"; + + + function "/" ( L: in COMPLEX_POLAR; R: in COMPLEX_POLAR) + return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(REAL'HIGH, 0.0) on error + -- + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if (R.MAG = 0.0) then + assert FALSE + report "Attempt to divide COMPLEX_POLAR by (0.0, 0.0)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, 0.0); + end if; + + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in /(L,R)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, 0.0); + end if; + + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_PI in /(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZOUT.MAG := L.MAG/R.MAG; + ZOUT.ARG := GET_PRINCIPAL_VALUE(L.ARG - R.ARG); + + return ZOUT; + end function "/"; + + function "/" ( L: in COMPLEX_POLAR; R: in REAL) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(REAL'HIGH, 0.0) on error + -- + variable ZR : COMPLEX_POLAR; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if (R = 0.0) then + assert FALSE + report "Attempt to divide COMPLEX_POLAR by 0.0" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, 0.0); + end if; + + if ( L.ARG = -MATH_PI ) then + assert FALSE + report "L.ARG = -MATH_PI in /(L,R)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, 0.0); + end if; + + -- Get principal value + ZR.MAG := POSITIVE_REAL'(ABS(R)); + if R < 0.0 then + ZR.ARG := MATH_PI; + else + ZR.ARG := 0.0; + end if; + + ZOUT.MAG := L.MAG/ZR.MAG; + ZOUT.ARG := GET_PRINCIPAL_VALUE(L.ARG - ZR.ARG); + + return ZOUT; + end function "/"; + + function "/" ( L: in REAL; R: in COMPLEX_POLAR) return COMPLEX_POLAR is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns COMPLEX_POLAR'(REAL'HIGH, 0.0) on error + -- + variable ZL : COMPLEX_POLAR; + variable ZOUT : COMPLEX_POLAR; + begin + -- Check validity of input arguments + if (R.MAG = 0.0) then + assert FALSE + report "Attempt to divide COMPLEX_POLAR by (0.0, 0.0)" + severity ERROR; + return COMPLEX_POLAR'(REAL'HIGH, 0.0); + end if; + + if ( R.ARG = -MATH_PI ) then + assert FALSE + report "R.ARG = -MATH_P in /(L,R)" + severity ERROR; + return COMPLEX_POLAR'(0.0, 0.0); + end if; + + -- Get principal value + ZL.MAG := POSITIVE_REAL'(ABS(L)); + if L < 0.0 then + ZL.ARG := MATH_PI; + else + ZL.ARG := 0.0; + end if; + + ZOUT.MAG := ZL.MAG/R.MAG; + ZOUT.ARG := GET_PRINCIPAL_VALUE(ZL.ARG - R.ARG); + + return ZOUT; + end function "/"; + +end package body MATH_COMPLEX; diff --git a/libraries/ieee2008/math_complex.vhdl b/libraries/ieee2008/math_complex.vhdl new file mode 100644 index 000000000..9d4cdcad3 --- /dev/null +++ b/libraries/ieee2008/math_complex.vhdl @@ -0,0 +1,1080 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Mathematical Packages +-- : (MATH_COMPLEX package declaration) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC VHDL Mathematical Packages Working Group +-- : +-- Purpose : This package defines a standard for designers to use in +-- : describing VHDL models that make use of common COMPLEX +-- : constants and common COMPLEX mathematical functions and +-- : operators. +-- : +-- Limitation: The values generated by the functions in this package +-- : may vary from platform to platform, and the precision +-- : of results is only guaranteed to be the minimum required +-- : by IEEE Std 1076-2008. +-- : +-- 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) $ +-- -------------------------------------------------------------------- + +use WORK.MATH_REAL.all; +package MATH_COMPLEX is + constant CopyRightNotice : STRING + := "Copyright 2008 IEEE. All rights reserved."; + + -- + -- Type Definitions + -- + type COMPLEX is + record + RE : REAL; -- Real part + IM : REAL; -- Imaginary part + end record; + + subtype POSITIVE_REAL is REAL range 0.0 to REAL'high; + + subtype PRINCIPAL_VALUE is REAL range -MATH_PI to MATH_PI; + + type COMPLEX_POLAR is + record + MAG : POSITIVE_REAL; -- Magnitude + ARG : PRINCIPAL_VALUE; -- Angle in radians; -MATH_PI is illegal + end record; + + -- + -- Constant Definitions + -- + constant MATH_CBASE_1 : COMPLEX := COMPLEX'(1.0, 0.0); + constant MATH_CBASE_J : COMPLEX := COMPLEX'(0.0, 1.0); + constant MATH_CZERO : COMPLEX := COMPLEX'(0.0, 0.0); + + + -- + -- Overloaded equality and inequality operators for COMPLEX_POLAR + -- (equality and inequality operators for COMPLEX are predefined) + -- + + function "=" (L : in COMPLEX_POLAR; R : in COMPLEX_POLAR) return BOOLEAN; + -- Purpose: + -- Returns TRUE if L is equal to R and returns FALSE otherwise + -- Special values: + -- COMPLEX_POLAR'(0.0, X) = COMPLEX_POLAR'(0.0, Y) returns TRUE + -- regardless of the value of X and Y. + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Error if R.ARG = -MATH_PI + -- Range: + -- "="(L,R) is either TRUE or FALSE + -- Notes: + -- None + + function "/=" (L : in COMPLEX_POLAR; R : in COMPLEX_POLAR) return BOOLEAN; + -- Purpose: + -- Returns TRUE if L is not equal to R and returns FALSE + -- otherwise + -- Special values: + -- COMPLEX_POLAR'(0.0, X) /= COMPLEX_POLAR'(0.0, Y) returns + -- FALSE regardless of the value of X and Y. + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Error if R.ARG = -MATH_PI + -- Range: + -- "/="(L,R) is either TRUE or FALSE + -- Notes: + -- None + + -- + -- Function Declarations + -- + function CMPLX(X : in REAL; Y : in REAL := 0.0) return COMPLEX; + -- Purpose: + -- Returns COMPLEX number X + iY + -- Special values: + -- None + -- Domain: + -- X in REAL + -- Y in REAL + -- Error conditions: + -- None + -- Range: + -- CMPLX(X,Y) is mathematically unbounded + -- Notes: + -- None + + function GET_PRINCIPAL_VALUE(X : in REAL) return PRINCIPAL_VALUE; + -- Purpose: + -- Returns principal value of angle X; X in radians + -- Special values: + -- None + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- -MATH_PI < GET_PRINCIPAL_VALUE(X) <= MATH_PI + -- Notes: + -- None + + function COMPLEX_TO_POLAR(Z : in COMPLEX) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value COMPLEX_POLAR of Z + -- Special values: + -- COMPLEX_TO_POLAR(MATH_CZERO) = COMPLEX_POLAR'(0.0, 0.0) + -- COMPLEX_TO_POLAR(Z) = COMPLEX_POLAR'(ABS(Z.IM), + -- SIGN(Z.IM)*MATH_PI_OVER_2) if Z.RE = 0.0 + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function POLAR_TO_COMPLEX(Z : in COMPLEX_POLAR) return COMPLEX; + -- Purpose: + -- Returns COMPLEX value of Z + -- Special values: + -- None + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- POLAR_TO_COMPLEX(Z) is mathematically unbounded + -- Notes: + -- None + + function "ABS"(Z : in COMPLEX) return POSITIVE_REAL; + -- Purpose: + -- Returns absolute value (magnitude) of Z + -- Special values: + -- None + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- ABS(Z) is mathematically unbounded + -- Notes: + -- ABS(Z) = SQRT(Z.RE*Z.RE + Z.IM*Z.IM) + + function "ABS"(Z : in COMPLEX_POLAR) return POSITIVE_REAL; + -- Purpose: + -- Returns absolute value (magnitude) of Z + -- Special values: + -- None + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- ABS(Z) >= 0.0 + -- Notes: + -- ABS(Z) = Z.MAG + + function ARG(Z : in COMPLEX) return PRINCIPAL_VALUE; + -- Purpose: + -- Returns argument (angle) in radians of the principal + -- value of Z + -- Special values: + -- ARG(Z) = 0.0 if Z.RE >= 0.0 and Z.IM = 0.0 + -- ARG(Z) = SIGN(Z.IM)*MATH_PI_OVER_2 if Z.RE = 0.0 + -- ARG(Z) = MATH_PI if Z.RE < 0.0 and Z.IM = 0.0 + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- -MATH_PI < ARG(Z) <= MATH_PI + -- Notes: + -- ARG(Z) = ARCTAN(Z.IM, Z.RE) + + function ARG(Z : in COMPLEX_POLAR) return PRINCIPAL_VALUE; + -- Purpose: + -- Returns argument (angle) in radians of the principal + -- value of Z + -- Special values: + -- None + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- -MATH_PI < ARG(Z) <= MATH_PI + -- Notes: + -- ARG(Z) = Z.ARG + + + function "-" (Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns unary minus of Z + -- Special values: + -- None + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- "-"(Z) is mathematically unbounded + -- Notes: + -- Returns -x -jy for Z= x + jy + + function "-" (Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of unary minus of Z + -- Special values: + -- "-"(Z) = COMPLEX_POLAR'(Z.MAG, MATH_PI) if Z.ARG = 0.0 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- Returns COMPLEX_POLAR'(Z.MAG, Z.ARG - SIGN(Z.ARG)*MATH_PI) if + -- Z.ARG /= 0.0 + + function CONJ (Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns complex conjugate of Z + -- Special values: + -- None + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- CONJ(Z) is mathematically unbounded + -- Notes: + -- Returns x -jy for Z= x + jy + + function CONJ (Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of complex conjugate of Z + -- Special values: + -- CONJ(Z) = COMPLEX_POLAR'(Z.MAG, MATH_PI) if Z.ARG = MATH_PI + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- Returns COMPLEX_POLAR'(Z.MAG, -Z.ARG) if Z.ARG /= MATH_PI + + function SQRT(Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns square root of Z with positive real part + -- or, if the real part is zero, the one with nonnegative + -- imaginary part + -- Special values: + -- SQRT(MATH_CZERO) = MATH_CZERO + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- SQRT(Z) is mathematically unbounded + -- Notes: + -- None + + function SQRT(Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns square root of Z with positive real part + -- or, if the real part is zero, the one with nonnegative + -- imaginary part + -- Special values: + -- SQRT(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = 0.0 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function EXP(Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns exponential of Z + -- Special values: + -- EXP(MATH_CZERO) = MATH_CBASE_1 + -- EXP(Z) = -MATH_CBASE_1 if Z.RE = 0.0 and ABS(Z.IM) = MATH_PI + -- EXP(Z) = SIGN(Z.IM)*MATH_CBASE_J if Z.RE = 0.0 and + -- ABS(Z.IM) = MATH_PI_OVER_2 + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- EXP(Z) is mathematically unbounded + -- Notes: + -- None + + + + function EXP(Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of exponential of Z + -- Special values: + -- EXP(Z) = COMPLEX_POLAR'(1.0, 0.0) if Z.MAG =0.0 and + -- Z.ARG = 0.0 + -- EXP(Z) = COMPLEX_POLAR'(1.0, MATH_PI) if Z.MAG = MATH_PI and + -- ABS(Z.ARG) = MATH_PI_OVER_2 + -- EXP(Z) = COMPLEX_POLAR'(1.0, MATH_PI_OVER_2) if + -- Z.MAG = MATH_PI_OVER_2 and + -- Z.ARG = MATH_PI_OVER_2 + -- EXP(Z) = COMPLEX_POLAR'(1.0, -MATH_PI_OVER_2) if + -- Z.MAG = MATH_PI_OVER_2 and + -- Z.ARG = -MATH_PI_OVER_2 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function LOG(Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns natural logarithm of Z + -- Special values: + -- LOG(MATH_CBASE_1) = MATH_CZERO + -- LOG(-MATH_CBASE_1) = COMPLEX'(0.0, MATH_PI) + -- LOG(MATH_CBASE_J) = COMPLEX'(0.0, MATH_PI_OVER_2) + -- LOG(-MATH_CBASE_J) = COMPLEX'(0.0, -MATH_PI_OVER_2) + -- LOG(Z) = MATH_CBASE_1 if Z = COMPLEX'(MATH_E, 0.0) + -- Domain: + -- Z in COMPLEX and ABS(Z) /= 0.0 + -- Error conditions: + -- Error if ABS(Z) = 0.0 + -- Range: + -- LOG(Z) is mathematically unbounded + -- Notes: + -- None + + function LOG2(Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns logarithm base 2 of Z + -- Special values: + -- LOG2(MATH_CBASE_1) = MATH_CZERO + -- LOG2(Z) = MATH_CBASE_1 if Z = COMPLEX'(2.0, 0.0) + -- Domain: + -- Z in COMPLEX and ABS(Z) /= 0.0 + -- Error conditions: + -- Error if ABS(Z) = 0.0 + -- Range: + -- LOG2(Z) is mathematically unbounded + -- Notes: + -- None + + function LOG10(Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns logarithm base 10 of Z + -- Special values: + -- LOG10(MATH_CBASE_1) = MATH_CZERO + -- LOG10(Z) = MATH_CBASE_1 if Z = COMPLEX'(10.0, 0.0) + -- Domain: + -- Z in COMPLEX and ABS(Z) /= 0.0 + -- Error conditions: + -- Error if ABS(Z) = 0.0 + -- Range: + -- LOG10(Z) is mathematically unbounded + -- Notes: + -- None + + function LOG(Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of natural logarithm of Z + -- Special values: + -- LOG(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = 1.0 and + -- Z.ARG = 0.0 + -- LOG(Z) = COMPLEX_POLAR'(MATH_PI, MATH_PI_OVER_2) if + -- Z.MAG = 1.0 and Z.ARG = MATH_PI + -- LOG(Z) = COMPLEX_POLAR'(MATH_PI_OVER_2, MATH_PI_OVER_2) if + -- Z.MAG = 1.0 and Z.ARG = MATH_PI_OVER_2 + -- LOG(Z) = COMPLEX_POLAR'(MATH_PI_OVER_2, -MATH_PI_OVER_2) if + -- Z.MAG = 1.0 and Z.ARG = -MATH_PI_OVER_2 + -- LOG(Z) = COMPLEX_POLAR'(1.0, 0.0) if Z.MAG = MATH_E and + -- Z.ARG = 0.0 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Z.MAG /= 0.0 + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Error if Z.MAG = 0.0 + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function LOG2(Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of logarithm base 2 of Z + -- Special values: + -- LOG2(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = 1.0 and + -- Z.ARG = 0.0 + -- LOG2(Z) = COMPLEX_POLAR'(1.0, 0.0) if Z.MAG = 2.0 and + -- Z.ARG = 0.0 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Z.MAG /= 0.0 + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Error if Z.MAG = 0.0 + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function LOG10(Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of logarithm base 10 of Z + -- Special values: + -- LOG10(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = 1.0 and + -- Z.ARG = 0.0 + -- LOG10(Z) = COMPLEX_POLAR'(1.0, 0.0) if Z.MAG = 10.0 and + -- Z.ARG = 0.0 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Z.MAG /= 0.0 + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Error if Z.MAG = 0.0 + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function LOG(Z : in COMPLEX; BASE : in REAL) return COMPLEX; + -- Purpose: + -- Returns logarithm base BASE of Z + -- Special values: + -- LOG(MATH_CBASE_1, BASE) = MATH_CZERO + -- LOG(Z,BASE) = MATH_CBASE_1 if Z = COMPLEX'(BASE, 0.0) + -- Domain: + -- Z in COMPLEX and ABS(Z) /= 0.0 + -- BASE > 0.0 + -- BASE /= 1.0 + -- Error conditions: + -- Error if ABS(Z) = 0.0 + -- Error if BASE <= 0.0 + -- Error if BASE = 1.0 + -- Range: + -- LOG(Z,BASE) is mathematically unbounded + -- Notes: + -- None + + function LOG(Z : in COMPLEX_POLAR; BASE : in REAL) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of logarithm base BASE of Z + -- Special values: + -- LOG(Z, BASE) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = 1.0 and + -- Z.ARG = 0.0 + -- LOG(Z, BASE) = COMPLEX_POLAR'(1.0, 0.0) if Z.MAG = BASE and + -- Z.ARG = 0.0 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Z.MAG /= 0.0 + -- BASE > 0.0 + -- BASE /= 1.0 + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Error if Z.MAG = 0.0 + -- Error if BASE <= 0.0 + -- Error if BASE = 1.0 + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function SIN (Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns sine of Z + -- Special values: + -- SIN(MATH_CZERO) = MATH_CZERO + -- SIN(Z) = MATH_CZERO if Z = COMPLEX'(MATH_PI, 0.0) + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- ABS(SIN(Z)) <= SQRT(SIN(Z.RE)*SIN(Z.RE) + + -- SINH(Z.IM)*SINH(Z.IM)) + -- Notes: + -- None + + function SIN (Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of sine of Z + -- Special values: + -- SIN(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = 0.0 and + -- Z.ARG = 0.0 + -- SIN(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = MATH_PI and + -- Z.ARG = 0.0 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function COS (Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns cosine of Z + -- Special values: + -- COS(Z) = MATH_CZERO if Z = COMPLEX'(MATH_PI_OVER_2, 0.0) + -- COS(Z) = MATH_CZERO if Z = COMPLEX'(-MATH_PI_OVER_2, 0.0) + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- ABS(COS(Z)) <= SQRT(COS(Z.RE)*COS(Z.RE) + + -- SINH(Z.IM)*SINH(Z.IM)) + -- Notes: + -- None + + + function COS (Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of cosine of Z + -- Special values: + -- COS(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = MATH_PI_OVER_2 + -- and Z.ARG = 0.0 + -- COS(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = MATH_PI_OVER_2 + -- and Z.ARG = MATH_PI + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function SINH (Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns hyperbolic sine of Z + -- Special values: + -- SINH(MATH_CZERO) = MATH_CZERO + -- SINH(Z) = MATH_CZERO if Z.RE = 0.0 and Z.IM = MATH_PI + -- SINH(Z) = MATH_CBASE_J if Z.RE = 0.0 and + -- Z.IM = MATH_PI_OVER_2 + -- SINH(Z) = -MATH_CBASE_J if Z.RE = 0.0 and + -- Z.IM = -MATH_PI_OVER_2 + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- ABS(SINH(Z)) <= SQRT(SINH(Z.RE)*SINH(Z.RE) + + -- SIN(Z.IM)*SIN(Z.IM)) + -- Notes: + -- None + + function SINH (Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of hyperbolic sine of Z + -- Special values: + -- SINH(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = 0.0 and + -- Z.ARG = 0.0 + -- SINH(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = MATH_PI and + -- Z.ARG = MATH_PI_OVER_2 + -- SINH(Z) = COMPLEX_POLAR'(1.0, MATH_PI_OVER_2) if Z.MAG = + -- MATH_PI_OVER_2 and Z.ARG = MATH_PI_OVER_2 + -- SINH(Z) = COMPLEX_POLAR'(1.0, -MATH_PI_OVER_2) if Z.MAG = + -- MATH_PI_OVER_2 and Z.ARG = -MATH_PI_OVER_2 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function COSH (Z : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns hyperbolic cosine of Z + -- Special values: + -- COSH(MATH_CZERO) = MATH_CBASE_1 + -- COSH(Z) = -MATH_CBASE_1 if Z.RE = 0.0 and Z.IM = MATH_PI + -- COSH(Z) = MATH_CZERO if Z.RE = 0.0 and Z.IM = MATH_PI_OVER_2 + -- COSH(Z) = MATH_CZERO if Z.RE = 0.0 and Z.IM = -MATH_PI_OVER_2 + -- Domain: + -- Z in COMPLEX + -- Error conditions: + -- None + -- Range: + -- ABS(COSH(Z)) <= SQRT(SINH(Z.RE)*SINH(Z.RE) + + -- COS(Z.IM)*COS(Z.IM)) + -- Notes: + -- None + + + function COSH (Z : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns principal value of hyperbolic cosine of Z + -- Special values: + -- COSH(Z) = COMPLEX_POLAR'(1.0, 0.0) if Z.MAG = 0.0 and + -- Z.ARG = 0.0 + -- COSH(Z) = COMPLEX_POLAR'(1.0, MATH_PI) if Z.MAG = MATH_PI and + -- Z.ARG = MATH_PI_OVER_2 + -- COSH(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = + -- MATH_PI_OVER_2 and Z.ARG = MATH_PI_OVER_2 + -- COSH(Z) = COMPLEX_POLAR'(0.0, 0.0) if Z.MAG = + -- MATH_PI_OVER_2 and Z.ARG = -MATH_PI_OVER_2 + -- Domain: + -- Z in COMPLEX_POLAR and Z.ARG /= -MATH_PI + -- Error conditions: + -- Error if Z.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + -- + -- Arithmetic Operators + -- + + function "+" (L : in COMPLEX; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic addition of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in COMPLEX + -- Error conditions: + -- None + -- Range: + -- "+"(Z) is mathematically unbounded + -- Notes: + -- None + + function "+" (L : in REAL; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic addition of L and R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX + -- Error conditions: + -- None + -- Range: + -- "+"(Z) is mathematically unbounded + -- Notes: + -- None + + function "+" (L : in COMPLEX; R : in REAL) return COMPLEX; + -- Purpose: + -- Returns arithmetic addition of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in REAL + -- Error conditions: + -- None + -- Range: + -- "+"(Z) is mathematically unbounded + -- Notes: + -- None + + function "+" (L : in COMPLEX_POLAR; R : in COMPLEX_POLAR) + return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic addition of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + + function "+" (L : in REAL; R : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic addition of L and R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "+" (L : in COMPLEX_POLAR; R : in REAL) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic addition of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in REAL + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "-" (L : in COMPLEX; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic subtraction of L minus R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in COMPLEX + -- Error conditions: + -- None + -- Range: + -- "-"(Z) is mathematically unbounded + -- Notes: + -- None + + function "-" (L : in REAL; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic subtraction of L minus R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX + -- Error conditions: + -- None + -- Range: + -- "-"(Z) is mathematically unbounded + -- Notes: + -- None + + function "-" (L : in COMPLEX; R : in REAL) return COMPLEX; + -- Purpose: + -- Returns arithmetic subtraction of L minus R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in REAL + -- Error conditions: + -- None + -- Range: + -- "-"(Z) is mathematically unbounded + -- Notes: + -- None + + function "-" (L : in COMPLEX_POLAR; R : in COMPLEX_POLAR) + return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic subtraction of L minus R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "-" (L : in REAL; R : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic subtraction of L minus R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + + function "-" (L : in COMPLEX_POLAR; R : in REAL) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic subtraction of L minus R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in REAL + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "*" (L : in COMPLEX; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic multiplication of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in COMPLEX + -- Error conditions: + -- None + -- Range: + -- "*"(Z) is mathematically unbounded + -- Notes: + -- None + + function "*" (L : in REAL; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic multiplication of L and R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX + -- Error conditions: + -- None + -- Range: + -- "*"(Z) is mathematically unbounded + -- Notes: + -- None + + function "*" (L : in COMPLEX; R : in REAL) return COMPLEX; + -- Purpose: + -- Returns arithmetic multiplication of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in REAL + -- Error conditions: + -- None + + -- Range: + -- "*"(Z) is mathematically unbounded + -- Notes: + -- None + + function "*" (L : in COMPLEX_POLAR; R : in COMPLEX_POLAR) + return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic multiplication of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "*" (L : in REAL; R : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic multiplication of L and R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- Error conditions: + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "*" (L : in COMPLEX_POLAR; R : in REAL) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic multiplication of L and R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in REAL + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + + function "/" (L : in COMPLEX; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic division of L by R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in COMPLEX and R /= MATH_CZERO + -- Error conditions: + -- Error if R = MATH_CZERO + -- Range: + -- "/"(Z) is mathematically unbounded + -- Notes: + -- None + + function "/" (L : in REAL; R : in COMPLEX) return COMPLEX; + -- Purpose: + -- Returns arithmetic division of L by R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX and R /= MATH_CZERO + -- Error conditions: + -- Error if R = MATH_CZERO + -- Range: + -- "/"(Z) is mathematically unbounded + -- Notes: + -- None + + function "/" (L : in COMPLEX; R : in REAL) return COMPLEX; + -- Purpose: + -- Returns arithmetic division of L by R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX + -- R in REAL and R /= 0.0 + -- Error conditions: + -- Error if R = 0.0 + -- Range: + -- "/"(Z) is mathematically unbounded + -- Notes: + -- None + + function "/" (L : in COMPLEX_POLAR; R : in COMPLEX_POLAR) + return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic division of L by R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- R.MAG > 0.0 + -- Error conditions: + -- Error if R.MAG <= 0.0 + -- Error if L.ARG = -MATH_PI + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "/" (L : in REAL; R : in COMPLEX_POLAR) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic division of L by R + -- Special values: + -- None + -- Domain: + -- L in REAL + -- R in COMPLEX_POLAR and R.ARG /= -MATH_PI + -- R.MAG > 0.0 + -- Error conditions: + -- Error if R.MAG <= 0.0 + -- Error if R.ARG = -MATH_PI + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None + + function "/" (L : in COMPLEX_POLAR; R : in REAL) return COMPLEX_POLAR; + -- Purpose: + -- Returns arithmetic division of L by R + -- Special values: + -- None + -- Domain: + -- L in COMPLEX_POLAR and L.ARG /= -MATH_PI + -- R /= 0.0 + -- Error conditions: + -- Error if L.ARG = -MATH_PI + -- Error if R = 0.0 + -- Range: + -- result.MAG >= 0.0 + -- -MATH_PI < result.ARG <= MATH_PI + -- Notes: + -- None +end package MATH_COMPLEX; diff --git a/libraries/ieee2008/math_real-body.vhdl b/libraries/ieee2008/math_real-body.vhdl new file mode 100644 index 000000000..b2f9373c3 --- /dev/null +++ b/libraries/ieee2008/math_real-body.vhdl @@ -0,0 +1,1931 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Mathematical Packages +-- : (MATH_REAL package body) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC VHDL Mathematical Packages Working Group +-- : +-- Purpose : This package defines a standard for designers to use in +-- : describing VHDL models that make use of common REAL +-- : constants and common REAL elementary mathematical +-- : functions. +-- : +-- Limitation: The values generated by the functions in this package +-- : may vary from platform to platform, and the precision +-- : of results is only guaranteed to be the minimum required +-- : by IEEE Std 1076-2008. +-- : +-- 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) $ +-- -------------------------------------------------------------------- + +package body MATH_REAL is + + -- + -- Local Constants for Use in the Package Body Only + -- + constant MATH_E_P2 : REAL := 7.38905_60989_30650; -- e**2 + constant MATH_E_P10 : REAL := 22026.46579_48067_17; -- e**10 + constant MATH_EIGHT_PI : REAL := 25.13274_12287_18345_90770_115; --8*pi + constant MAX_ITER: INTEGER := 27; -- Maximum precision factor for cordic + constant MAX_COUNT: INTEGER := 150; -- Maximum count for number of tries + constant BASE_EPS: REAL := 0.00001; -- Factor for convergence criteria + constant KC : REAL := 6.0725293500888142e-01; -- Constant for cordic + + -- + -- Local Type Declarations for Cordic Operations + -- + type REAL_VECTOR is array (NATURAL range <>) of REAL; + type NATURAL_VECTOR is array (NATURAL range <>) of NATURAL; + subtype REAL_VECTOR_N is REAL_VECTOR (0 to MAX_ITER); + subtype REAL_ARR_2 is REAL_VECTOR (0 to 1); + subtype REAL_ARR_3 is REAL_VECTOR (0 to 2); + subtype QUADRANT is INTEGER range 0 to 3; + type CORDIC_MODE_TYPE is (ROTATION, VECTORING); + + -- + -- Auxiliary Functions for Cordic Algorithms + -- + function POWER_OF_2_SERIES (D : in NATURAL_VECTOR; INITIAL_VALUE : in REAL; + NUMBER_OF_VALUES : in NATURAL) return REAL_VECTOR is + -- Description: + -- Returns power of two for a vector of values + -- Notes: + -- None + -- + variable V : REAL_VECTOR (0 to NUMBER_OF_VALUES); + variable TEMP : REAL := INITIAL_VALUE; + variable FLAG : BOOLEAN := TRUE; + begin + for I in 0 to NUMBER_OF_VALUES loop + V(I) := TEMP; + for P in D'RANGE loop + if I = D(P) then + FLAG := FALSE; + exit; + end if; + end loop; + if FLAG then + TEMP := TEMP/2.0; + end if; + FLAG := TRUE; + end loop; + return V; + end function POWER_OF_2_SERIES; + + + constant TWO_AT_MINUS : REAL_VECTOR := POWER_OF_2_SERIES( + NATURAL_VECTOR'(100, 90),1.0, + MAX_ITER); + + constant EPSILON : REAL_VECTOR_N := ( + 7.8539816339744827e-01, + 4.6364760900080606e-01, + 2.4497866312686413e-01, + 1.2435499454676144e-01, + 6.2418809995957351e-02, + 3.1239833430268277e-02, + 1.5623728620476830e-02, + 7.8123410601011116e-03, + 3.9062301319669717e-03, + 1.9531225164788189e-03, + 9.7656218955931937e-04, + 4.8828121119489829e-04, + 2.4414062014936175e-04, + 1.2207031189367021e-04, + 6.1035156174208768e-05, + 3.0517578115526093e-05, + 1.5258789061315760e-05, + 7.6293945311019699e-06, + 3.8146972656064960e-06, + 1.9073486328101870e-06, + 9.5367431640596080e-07, + 4.7683715820308876e-07, + 2.3841857910155801e-07, + 1.1920928955078067e-07, + 5.9604644775390553e-08, + 2.9802322387695303e-08, + 1.4901161193847654e-08, + 7.4505805969238281e-09 + ); + + function CORDIC ( X0 : in REAL; + Y0 : in REAL; + Z0 : in REAL; + N : in NATURAL; -- Precision factor + CORDIC_MODE : in CORDIC_MODE_TYPE -- Rotation (Z -> 0) + -- or vectoring (Y -> 0) + ) return REAL_ARR_3 is + -- Description: + -- Compute cordic values + -- Notes: + -- None + variable X : REAL := X0; + variable Y : REAL := Y0; + variable Z : REAL := Z0; + variable X_TEMP : REAL; + begin + if CORDIC_MODE = ROTATION then + for K in 0 to N loop + X_TEMP := X; + if ( Z >= 0.0) then + X := X - Y * TWO_AT_MINUS(K); + Y := Y + X_TEMP * TWO_AT_MINUS(K); + Z := Z - EPSILON(K); + else + X := X + Y * TWO_AT_MINUS(K); + Y := Y - X_TEMP * TWO_AT_MINUS(K); + Z := Z + EPSILON(K); + end if; + end loop; + else + for K in 0 to N loop + X_TEMP := X; + if ( Y < 0.0) then + X := X - Y * TWO_AT_MINUS(K); + Y := Y + X_TEMP * TWO_AT_MINUS(K); + Z := Z - EPSILON(K); + else + X := X + Y * TWO_AT_MINUS(K); + Y := Y - X_TEMP * TWO_AT_MINUS(K); + Z := Z + EPSILON(K); + end if; + end loop; + end if; + return REAL_ARR_3'(X, Y, Z); + end function CORDIC; + + -- + -- Bodies for Global Mathematical Functions Start Here + -- + function SIGN (X: in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- None + begin + if ( X > 0.0 ) then + return 1.0; + elsif ( X < 0.0 ) then + return -1.0; + else + return 0.0; + end if; + end function SIGN; + + function CEIL (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) No conversion to an INTEGER type is expected, so truncate + -- cannot overflow for large arguments + -- b) The domain supported by this function is X <= LARGE + -- c) Returns X if ABS(X) >= LARGE + + constant LARGE: REAL := REAL(INTEGER'HIGH); + variable RD: REAL; + + begin + if ABS(X) >= LARGE then + return X; + end if; + + RD := REAL ( INTEGER(X)); + if RD = X then + return X; + end if; + + if X > 0.0 then + if RD >= X then + return RD; + else + return RD + 1.0; + end if; + elsif X = 0.0 then + return 0.0; + else + if RD <= X then + return RD + 1.0; + else + return RD; + end if; + end if; + end function CEIL; + + function FLOOR (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) No conversion to an INTEGER type is expected, so truncate + -- cannot overflow for large arguments + -- b) The domain supported by this function is ABS(X) <= LARGE + -- c) Returns X if ABS(X) >= LARGE + + constant LARGE: REAL := REAL(INTEGER'HIGH); + variable RD: REAL; + + begin + if ABS( X ) >= LARGE then + return X; + end if; + + RD := REAL ( INTEGER(X)); + if RD = X then + return X; + end if; + + if X > 0.0 then + if RD <= X then + return RD; + else + return RD - 1.0; + end if; + elsif X = 0.0 then + return 0.0; + else + if RD >= X then + return RD - 1.0; + else + return RD; + end if; + end if; + end function FLOOR; + + function ROUND (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 if X = 0.0 + -- b) Returns FLOOR(X + 0.5) if X > 0 + -- c) Returns CEIL(X - 0.5) if X < 0 + + begin + if X > 0.0 then + return FLOOR(X + 0.5); + elsif X < 0.0 then + return CEIL( X - 0.5); + else + return 0.0; + end if; + end function ROUND; + + function TRUNC (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 if X = 0.0 + -- b) Returns FLOOR(X) if X > 0 + -- c) Returns CEIL(X) if X < 0 + + begin + if X > 0.0 then + return FLOOR(X); + elsif X < 0.0 then + return CEIL( X); + else + return 0.0; + end if; + end function TRUNC; + + + + + function "MOD" (X, Y: in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 on error + + variable XNEGATIVE : BOOLEAN := X < 0.0; + variable YNEGATIVE : BOOLEAN := Y < 0.0; + variable VALUE : REAL; + begin + -- Check validity of input arguments + if (Y = 0.0) then + assert FALSE + report "MOD(X, 0.0) is undefined" + severity ERROR; + return 0.0; + end if; + + -- Compute value + if ( XNEGATIVE ) then + if ( YNEGATIVE ) then + VALUE := X + (FLOOR(ABS(X)/ABS(Y)))*ABS(Y); + else + VALUE := X + (CEIL(ABS(X)/ABS(Y)))*ABS(Y); + end if; + else + if ( YNEGATIVE ) then + VALUE := X - (CEIL(ABS(X)/ABS(Y)))*ABS(Y); + else + VALUE := X - (FLOOR(ABS(X)/ABS(Y)))*ABS(Y); + end if; + end if; + + return VALUE; + end function "MOD"; + + + function REALMAX (X, Y : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) REALMAX(X,Y) = X when X = Y + -- + begin + if X >= Y then + return X; + else + return Y; + end if; + end function REALMAX; + + function REALMIN (X, Y : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) REALMIN(X,Y) = X when X = Y + -- + begin + if X <= Y then + return X; + else + return Y; + end if; + end function REALMIN; + + + procedure UNIFORM(variable SEED1,SEED2:inout POSITIVE;variable X:out REAL) + is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 on error + -- + variable Z, K: INTEGER; + variable TSEED1 : INTEGER := INTEGER'(SEED1); + variable TSEED2 : INTEGER := INTEGER'(SEED2); + begin + -- Check validity of arguments + if SEED1 > 2147483562 then + assert FALSE + report "SEED1 > 2147483562 in UNIFORM" + severity ERROR; + X := 0.0; + return; + end if; + + if SEED2 > 2147483398 then + assert FALSE + report "SEED2 > 2147483398 in UNIFORM" + severity ERROR; + X := 0.0; + return; + end if; + + -- Compute new seed values and pseudo-random number + K := TSEED1/53668; + TSEED1 := 40014 * (TSEED1 - K * 53668) - K * 12211; + + if TSEED1 < 0 then + TSEED1 := TSEED1 + 2147483563; + end if; + + K := TSEED2/52774; + TSEED2 := 40692 * (TSEED2 - K * 52774) - K * 3791; + + if TSEED2 < 0 then + TSEED2 := TSEED2 + 2147483399; + end if; + + Z := TSEED1 - TSEED2; + if Z < 1 then + Z := Z + 2147483562; + end if; + + -- Get output values + SEED1 := POSITIVE'(TSEED1); + SEED2 := POSITIVE'(TSEED2); + X := REAL(Z)*4.656613e-10; + end procedure UNIFORM; + + + + function SQRT (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Uses the Newton-Raphson approximation: + -- F(n+1) = 0.5*[F(n) + x/F(n)] + -- b) Returns 0.0 on error + -- + + constant EPS : REAL := BASE_EPS*BASE_EPS; -- Convergence factor + + variable INIVAL: REAL; + variable OLDVAL : REAL ; + variable NEWVAL : REAL ; + variable COUNT : INTEGER := 1; + + begin + -- Check validity of argument + if ( X < 0.0 ) then + assert FALSE + report "X < 0.0 in SQRT(X)" + severity ERROR; + return 0.0; + end if; + + -- Get the square root for special cases + if X = 0.0 then + return 0.0; + else + if ( X = 1.0 ) then + return 1.0; + end if; + end if; + + -- Get the square root for general cases + INIVAL := EXP(LOG(X)*(0.5)); -- Mathematically correct but imprecise + OLDVAL := INIVAL; + NEWVAL := (X/OLDVAL + OLDVAL)*0.5; + + -- Check for relative and absolute error and max count + while ( ( (ABS((NEWVAL -OLDVAL)/NEWVAL) > EPS) OR + (ABS(NEWVAL - OLDVAL) > EPS) ) AND + (COUNT < MAX_COUNT) ) loop + OLDVAL := NEWVAL; + NEWVAL := (X/OLDVAL + OLDVAL)*0.5; + COUNT := COUNT + 1; + end loop; + return NEWVAL; + end function SQRT; + + function CBRT (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Uses the Newton-Raphson approximation: + -- F(n+1) = (1/3)*[2*F(n) + x/F(n)**2]; + -- + constant EPS : REAL := BASE_EPS*BASE_EPS; + + variable INIVAL: REAL; + variable XLOCAL : REAL := X; + variable NEGATIVE : BOOLEAN := X < 0.0; + variable OLDVAL : REAL ; + variable NEWVAL : REAL ; + variable COUNT : INTEGER := 1; + + begin + + -- Compute root for special cases + if X = 0.0 then + return 0.0; + elsif ( X = 1.0 ) then + return 1.0; + else + if X = -1.0 then + return -1.0; + end if; + end if; + + -- Compute root for general cases + if NEGATIVE then + XLOCAL := -X; + end if; + + INIVAL := EXP(LOG(XLOCAL)/(3.0)); -- Mathematically correct but + -- imprecise + OLDVAL := INIVAL; + NEWVAL := (XLOCAL/(OLDVAL*OLDVAL) + 2.0*OLDVAL)/3.0; + + -- Check for relative and absolute errors and max count + while ( ( (ABS((NEWVAL -OLDVAL)/NEWVAL) > EPS ) OR + (ABS(NEWVAL - OLDVAL) > EPS ) ) AND + ( COUNT < MAX_COUNT ) ) loop + OLDVAL := NEWVAL; + NEWVAL :=(XLOCAL/(OLDVAL*OLDVAL) + 2.0*OLDVAL)/3.0; + COUNT := COUNT + 1; + end loop; + + if NEGATIVE then + NEWVAL := -NEWVAL; + end if; + + return NEWVAL; + end function CBRT; + + function "**" (X : in INTEGER; Y : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 on error condition + + begin + -- Check validity of argument + if ( ( X < 0 ) and ( Y /= 0.0 ) ) then + assert FALSE + report "X < 0 and Y /= 0.0 in X**Y" + severity ERROR; + return 0.0; + end if; + + if ( ( X = 0 ) and ( Y <= 0.0 ) ) then + assert FALSE + report "X = 0 and Y <= 0.0 in X**Y" + severity ERROR; + return 0.0; + end if; + + -- Get value for special cases + if ( X = 0 and Y > 0.0 ) then + return 0.0; + end if; + + if ( X = 1 ) then + return 1.0; + end if; + + if ( Y = 0.0 and X /= 0 ) then + return 1.0; + end if; + + if ( Y = 1.0) then + return (REAL(X)); + end if; + + -- Get value for general case + return EXP (Y * LOG (REAL(X))); + end function "**"; + + function "**" (X : in REAL; Y : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 on error condition + + begin + -- Check validity of argument + if ( ( X < 0.0 ) and ( Y /= 0.0 ) ) then + assert FALSE + report "X < 0.0 and Y /= 0.0 in X**Y" + severity ERROR; + return 0.0; + end if; + + if ( ( X = 0.0 ) and ( Y <= 0.0 ) ) then + assert FALSE + report "X = 0.0 and Y <= 0.0 in X**Y" + severity ERROR; + return 0.0; + end if; + + -- Get value for special cases + if ( X = 0.0 and Y > 0.0 ) then + return 0.0; + end if; + + if ( X = 1.0 ) then + return 1.0; + end if; + + if ( Y = 0.0 and X /= 0.0 ) then + return 1.0; + end if; + + if ( Y = 1.0) then + return (X); + end if; + + -- Get value for general case + return EXP (Y * LOG (X)); + end function "**"; + + function EXP (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) This function computes the exponential using the following + -- series: + -- exp(x) = 1 + x + x**2/2! + x**3/3! + ... ; |x| < 1.0 + -- and reduces argument X to take advantage of exp(x+y) = + -- exp(x)*exp(y) + -- + -- b) This implementation limits X to be less than LOG(REAL'HIGH) + -- to avoid overflow. Returns REAL'HIGH when X reaches that + -- limit + -- + constant EPS : REAL := BASE_EPS*BASE_EPS*BASE_EPS;-- Precision criteria + + variable RECIPROCAL: BOOLEAN := X < 0.0;-- Check sign of argument + variable XLOCAL : REAL := ABS(X); -- Use positive value + variable OLDVAL: REAL ; + variable COUNT: INTEGER ; + variable NEWVAL: REAL ; + variable LAST_TERM: REAL ; + variable FACTOR : REAL := 1.0; + + begin + -- Compute value for special cases + if X = 0.0 then + return 1.0; + end if; + + if XLOCAL = 1.0 then + if RECIPROCAL then + return MATH_1_OVER_E; + else + return MATH_E; + end if; + end if; + + if XLOCAL = 2.0 then + if RECIPROCAL then + return 1.0/MATH_E_P2; + else + return MATH_E_P2; + end if; + end if; + + if XLOCAL = 10.0 then + if RECIPROCAL then + return 1.0/MATH_E_P10; + else + return MATH_E_P10; + end if; + end if; + + if XLOCAL > LOG(REAL'HIGH) then + if RECIPROCAL then + return 0.0; + else + assert FALSE + report "X > LOG(REAL'HIGH) in EXP(X)" + severity NOTE; + return REAL'HIGH; + end if; + end if; + + -- Reduce argument to ABS(X) < 1.0 + while XLOCAL > 10.0 loop + XLOCAL := XLOCAL - 10.0; + FACTOR := FACTOR*MATH_E_P10; + end loop; + + while XLOCAL > 1.0 loop + XLOCAL := XLOCAL - 1.0; + FACTOR := FACTOR*MATH_E; + end loop; + + -- Compute value for case 0 < XLOCAL < 1 + OLDVAL := 1.0; + LAST_TERM := XLOCAL; + NEWVAL:= OLDVAL + LAST_TERM; + COUNT := 2; + + -- Check for relative and absolute errors and max count + while ( ( (ABS((NEWVAL - OLDVAL)/NEWVAL) > EPS) OR + (ABS(NEWVAL - OLDVAL) > EPS) ) AND + (COUNT < MAX_COUNT ) ) loop + OLDVAL := NEWVAL; + LAST_TERM := LAST_TERM*(XLOCAL / (REAL(COUNT))); + NEWVAL := OLDVAL + LAST_TERM; + COUNT := COUNT + 1; + end loop; + + -- Compute final value using exp(x+y) = exp(x)*exp(y) + NEWVAL := NEWVAL*FACTOR; + + if RECIPROCAL then + NEWVAL := 1.0/NEWVAL; + end if; + + return NEWVAL; + end function EXP; + + + -- + -- Auxiliary Functions to Compute LOG + -- + function ILOGB(X: in REAL) return INTEGER IS + -- Description: + -- Returns n such that -1 <= ABS(X)/2^n < 2 + -- Notes: + -- None + + variable N: INTEGER := 0; + variable Y: REAL := ABS(X); + + begin + if(Y = 1.0 or Y = 0.0) then + return 0; + end if; + + if( Y > 1.0) then + while Y >= 2.0 loop + Y := Y/2.0; + N := N+1; + end loop; + return N; + end if; + + -- O < Y < 1 + while Y < 1.0 loop + Y := Y*2.0; + N := N -1; + end loop; + return N; + end function ILOGB; + + function LDEXP(X: in REAL; N: in INTEGER) RETURN REAL IS + -- Description: + -- Returns X*2^n + -- Notes: + -- None + begin + return X*(2.0 ** N); + end function LDEXP; + + function LOG (X : in REAL ) return REAL IS + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- + -- Notes: + -- a) Returns REAL'LOW on error + -- + -- Copyright (c) 1992 Regents of the University of California. + -- All rights reserved. + -- + -- Redistribution and use in source and binary forms, with or without + -- modification, are permitted provided that the following conditions + -- are met: + -- 1. Redistributions of source code must retain the above copyright + -- notice, this list of conditions and the following disclaimer. + -- 2. Redistributions in binary form must reproduce the above copyright + -- notice, this list of conditions and the following disclaimer in the + -- documentation and/or other materials provided with the distribution. + -- 3. All advertising materials mentioning features or use of this + -- software must display the following acknowledgement: + -- This product includes software developed by the University of + -- California, Berkeley and its contributors. + -- 4. Neither the name of the University nor the names of its + -- contributors may be used to endorse or promote products derived + -- from this software without specific prior written permission. + -- + -- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' + -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + -- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + -- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + -- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + -- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + -- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + -- USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + -- DAMAGE. + -- + -- NOTE: This VHDL version was generated using the C version of the + -- original function by the IEEE VHDL Mathematical Package + -- Working Group (CS/JT) + + constant N: INTEGER := 128; + + -- Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128. + -- Used for generation of extend precision logarithms. + -- The constant 35184372088832 is 2^45, so the divide is exact. + -- It ensures correct reading of logF_head, even for inaccurate + -- decimal-to-binary conversion routines. (Everybody gets the + -- right answer for INTEGERs less than 2^53.) + -- Values for LOG(F) were generated using error < 10^-57 absolute + -- with the bc -l package. + + type REAL_VECTOR is array (NATURAL range <>) of REAL; + + constant A1:REAL := 0.08333333333333178827; + constant A2:REAL := 0.01250000000377174923; + constant A3:REAL := 0.002232139987919447809; + constant A4:REAL := 0.0004348877777076145742; + + constant LOGF_HEAD: REAL_VECTOR(0 TO N) := ( + 0.0, + 0.007782140442060381246, + 0.015504186535963526694, + 0.023167059281547608406, + 0.030771658666765233647, + 0.038318864302141264488, + 0.045809536031242714670, + 0.053244514518837604555, + 0.060624621816486978786, + 0.067950661908525944454, + 0.075223421237524235039, + 0.082443669210988446138, + 0.089612158689760690322, + 0.096729626458454731618, + 0.103796793681567578460, + 0.110814366340264314203, + 0.117783035656430001836, + 0.124703478501032805070, + 0.131576357788617315236, + 0.138402322859292326029, + 0.145182009844575077295, + 0.151916042025732167530, + 0.158605030176659056451, + 0.165249572895390883786, + 0.171850256926518341060, + 0.178407657472689606947, + 0.184922338493834104156, + 0.191394852999565046047, + 0.197825743329758552135, + 0.204215541428766300668, + 0.210564769107350002741, + 0.216873938300523150246, + 0.223143551314024080056, + 0.229374101064877322642, + 0.235566071312860003672, + 0.241719936886966024758, + 0.247836163904594286577, + 0.253915209980732470285, + 0.259957524436686071567, + 0.265963548496984003577, + 0.271933715484010463114, + 0.277868451003087102435, + 0.283768173130738432519, + 0.289633292582948342896, + 0.295464212893421063199, + 0.301261330578199704177, + 0.307025035294827830512, + 0.312755710004239517729, + 0.318453731118097493890, + 0.324119468654316733591, + 0.329753286372579168528, + 0.335355541920762334484, + 0.340926586970454081892, + 0.346466767346100823488, + 0.351976423156884266063, + 0.357455888922231679316, + 0.362905493689140712376, + 0.368325561158599157352, + 0.373716409793814818840, + 0.379078352934811846353, + 0.384411698910298582632, + 0.389716751140440464951, + 0.394993808240542421117, + 0.400243164127459749579, + 0.405465108107819105498, + 0.410659924985338875558, + 0.415827895143593195825, + 0.420969294644237379543, + 0.426084395310681429691, + 0.431173464818130014464, + 0.436236766774527495726, + 0.441274560805140936281, + 0.446287102628048160113, + 0.451274644139630254358, + 0.456237433481874177232, + 0.461175715122408291790, + 0.466089729924533457960, + 0.470979715219073113985, + 0.475845904869856894947, + 0.480688529345570714212, + 0.485507815781602403149, + 0.490303988045525329653, + 0.495077266798034543171, + 0.499827869556611403822, + 0.504556010751912253908, + 0.509261901790523552335, + 0.513945751101346104405, + 0.518607764208354637958, + 0.523248143765158602036, + 0.527867089620485785417, + 0.532464798869114019908, + 0.537041465897345915436, + 0.541597282432121573947, + 0.546132437597407260909, + 0.550647117952394182793, + 0.555141507540611200965, + 0.559615787935399566777, + 0.564070138285387656651, + 0.568504735352689749561, + 0.572919753562018740922, + 0.577315365035246941260, + 0.581691739635061821900, + 0.586049045003164792433, + 0.590387446602107957005, + 0.594707107746216934174, + 0.599008189645246602594, + 0.603290851438941899687, + 0.607555250224322662688, + 0.611801541106615331955, + 0.616029877215623855590, + 0.620240409751204424537, + 0.624433288012369303032, + 0.628608659422752680256, + 0.632766669570628437213, + 0.636907462236194987781, + 0.641031179420679109171, + 0.645137961373620782978, + 0.649227946625615004450, + 0.653301272011958644725, + 0.657358072709030238911, + 0.661398482245203922502, + 0.665422632544505177065, + 0.669430653942981734871, + 0.673422675212350441142, + 0.677398823590920073911, + 0.681359224807238206267, + 0.685304003098281100392, + 0.689233281238557538017, + 0.693147180560117703862); + + constant LOGF_TAIL: REAL_VECTOR(0 TO N) := ( + 0.0, + -0.00000000000000543229938420049, + 0.00000000000000172745674997061, + -0.00000000000001323017818229233, + -0.00000000000001154527628289872, + -0.00000000000000466529469958300, + 0.00000000000005148849572685810, + -0.00000000000002532168943117445, + -0.00000000000005213620639136504, + -0.00000000000001819506003016881, + 0.00000000000006329065958724544, + 0.00000000000008614512936087814, + -0.00000000000007355770219435028, + 0.00000000000009638067658552277, + 0.00000000000007598636597194141, + 0.00000000000002579999128306990, + -0.00000000000004654729747598444, + -0.00000000000007556920687451336, + 0.00000000000010195735223708472, + -0.00000000000017319034406422306, + -0.00000000000007718001336828098, + 0.00000000000010980754099855238, + -0.00000000000002047235780046195, + -0.00000000000008372091099235912, + 0.00000000000014088127937111135, + 0.00000000000012869017157588257, + 0.00000000000017788850778198106, + 0.00000000000006440856150696891, + 0.00000000000016132822667240822, + -0.00000000000007540916511956188, + -0.00000000000000036507188831790, + 0.00000000000009120937249914984, + 0.00000000000018567570959796010, + -0.00000000000003149265065191483, + -0.00000000000009309459495196889, + 0.00000000000017914338601329117, + -0.00000000000001302979717330866, + 0.00000000000023097385217586939, + 0.00000000000023999540484211737, + 0.00000000000015393776174455408, + -0.00000000000036870428315837678, + 0.00000000000036920375082080089, + -0.00000000000009383417223663699, + 0.00000000000009433398189512690, + 0.00000000000041481318704258568, + -0.00000000000003792316480209314, + 0.00000000000008403156304792424, + -0.00000000000034262934348285429, + 0.00000000000043712191957429145, + -0.00000000000010475750058776541, + -0.00000000000011118671389559323, + 0.00000000000037549577257259853, + 0.00000000000013912841212197565, + 0.00000000000010775743037572640, + 0.00000000000029391859187648000, + -0.00000000000042790509060060774, + 0.00000000000022774076114039555, + 0.00000000000010849569622967912, + -0.00000000000023073801945705758, + 0.00000000000015761203773969435, + 0.00000000000003345710269544082, + -0.00000000000041525158063436123, + 0.00000000000032655698896907146, + -0.00000000000044704265010452446, + 0.00000000000034527647952039772, + -0.00000000000007048962392109746, + 0.00000000000011776978751369214, + -0.00000000000010774341461609578, + 0.00000000000021863343293215910, + 0.00000000000024132639491333131, + 0.00000000000039057462209830700, + -0.00000000000026570679203560751, + 0.00000000000037135141919592021, + -0.00000000000017166921336082431, + -0.00000000000028658285157914353, + -0.00000000000023812542263446809, + 0.00000000000006576659768580062, + -0.00000000000028210143846181267, + 0.00000000000010701931762114254, + 0.00000000000018119346366441110, + 0.00000000000009840465278232627, + -0.00000000000033149150282752542, + -0.00000000000018302857356041668, + -0.00000000000016207400156744949, + 0.00000000000048303314949553201, + -0.00000000000071560553172382115, + 0.00000000000088821239518571855, + -0.00000000000030900580513238244, + -0.00000000000061076551972851496, + 0.00000000000035659969663347830, + 0.00000000000035782396591276383, + -0.00000000000046226087001544578, + 0.00000000000062279762917225156, + 0.00000000000072838947272065741, + 0.00000000000026809646615211673, + -0.00000000000010960825046059278, + 0.00000000000002311949383800537, + -0.00000000000058469058005299247, + -0.00000000000002103748251144494, + -0.00000000000023323182945587408, + -0.00000000000042333694288141916, + -0.00000000000043933937969737844, + 0.00000000000041341647073835565, + 0.00000000000006841763641591466, + 0.00000000000047585534004430641, + 0.00000000000083679678674757695, + -0.00000000000085763734646658640, + 0.00000000000021913281229340092, + -0.00000000000062242842536431148, + -0.00000000000010983594325438430, + 0.00000000000065310431377633651, + -0.00000000000047580199021710769, + -0.00000000000037854251265457040, + 0.00000000000040939233218678664, + 0.00000000000087424383914858291, + 0.00000000000025218188456842882, + -0.00000000000003608131360422557, + -0.00000000000050518555924280902, + 0.00000000000078699403323355317, + -0.00000000000067020876961949060, + 0.00000000000016108575753932458, + 0.00000000000058527188436251509, + -0.00000000000035246757297904791, + -0.00000000000018372084495629058, + 0.00000000000088606689813494916, + 0.00000000000066486268071468700, + 0.00000000000063831615170646519, + 0.00000000000025144230728376072, + -0.00000000000017239444525614834); + + variable M, J:INTEGER; + variable F1, F2, G, Q, U, U2, V: REAL; + variable ZERO: REAL := 0.0;--Made variable so no constant folding occurs + variable ONE: REAL := 1.0; --Made variable so no constant folding occurs + + -- double logb(), ldexp(); + + variable U1:REAL; + + begin + + -- Check validity of argument + if ( X <= 0.0 ) then + assert FALSE + report "X <= 0.0 in LOG(X)" + severity ERROR; + return(REAL'LOW); + end if; + + -- Compute value for special cases + if ( X = 1.0 ) then + return 0.0; + end if; + + if ( X = MATH_E ) then + return 1.0; + end if; + + -- Argument reduction: 1 <= g < 2; x/2^m = g; + -- y = F*(1 + f/F) for |f| <= 2^-8 + + M := ILOGB(X); + G := LDEXP(X, -M); + J := INTEGER(REAL(N)*(G-1.0)); -- C code adds 0.5 for rounding + F1 := (1.0/REAL(N)) * REAL(J) + 1.0; --F1*128 is an INTEGER in [128,512] + F2 := G - F1; + + -- Approximate expansion for log(1+f2/F1) ~= u + q + G := 1.0/(2.0*F1+F2); + U := 2.0*F2*G; + V := U*U; + Q := U*V*(A1 + V*(A2 + V*(A3 + V*A4))); + + -- Case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8, + -- u1 has at most 35 bits, and F1*u1 is exact, as F1 has < 8 bits. + -- It also adds exactly to |m*log2_hi + log_F_head[j] | < 750. + -- + if ( J /= 0 or M /= 0) then + U1 := U + 513.0; + U1 := U1 - 513.0; + + -- Case 2: |1-x| < 1/256. The m- and j- dependent terms are zero + -- u1 = u to 24 bits. + -- + else + U1 := U; + --TRUNC(U1); --In c this is u1 = (double) (float) (u1) + end if; + + U2 := (2.0*(F2 - F1*U1) - U1*F2) * G; + -- u1 + u2 = 2f/(2F+f) to extra precision. + + -- log(x) = log(2^m*F1*(1+f2/F1)) = + -- (m*log2_hi+LOGF_HEAD(j)+u1) + (m*log2_lo+LOGF_TAIL(j)+q); + -- (exact) + (tiny) + + U1 := U1 + REAL(M)*LOGF_HEAD(N) + LOGF_HEAD(J); -- Exact + U2 := (U2 + LOGF_TAIL(J)) + Q; -- Tiny + U2 := U2 + LOGF_TAIL(N)*REAL(M); + return (U1 + U2); + end function LOG; + + + function LOG2 (X: in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns REAL'LOW on error + begin + -- Check validity of arguments + if ( X <= 0.0 ) then + assert FALSE + report "X <= 0.0 in LOG2(X)" + severity ERROR; + return(REAL'LOW); + end if; + + -- Compute value for special cases + if ( X = 1.0 ) then + return 0.0; + end if; + + if ( X = 2.0 ) then + return 1.0; + end if; + + -- Compute value for general case + return ( MATH_LOG2_OF_E*LOG(X) ); + end function LOG2; + + + function LOG10 (X: in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns REAL'LOW on error + begin + -- Check validity of arguments + if ( X <= 0.0 ) then + assert FALSE + report "X <= 0.0 in LOG10(X)" + severity ERROR; + return(REAL'LOW); + end if; + + -- Compute value for special cases + if ( X = 1.0 ) then + return 0.0; + end if; + + if ( X = 10.0 ) then + return 1.0; + end if; + + -- Compute value for general case + return ( MATH_LOG10_OF_E*LOG(X) ); + end function LOG10; + + + function LOG (X: in REAL; BASE: in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns REAL'LOW on error + begin + -- Check validity of arguments + if ( X <= 0.0 ) then + assert FALSE + report "X <= 0.0 in LOG(X, BASE)" + severity ERROR; + return(REAL'LOW); + end if; + + if ( BASE <= 0.0 or BASE = 1.0 ) then + assert FALSE + report "BASE <= 0.0 or BASE = 1.0 in LOG(X, BASE)" + severity ERROR; + return(REAL'LOW); + end if; + + -- Compute value for special cases + if ( X = 1.0 ) then + return 0.0; + end if; + + if ( X = BASE ) then + return 1.0; + end if; + + -- Compute value for general case + return ( LOG(X)/LOG(BASE)); + end function LOG; + + + function SIN (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) SIN(-X) = -SIN(X) + -- b) SIN(X) = X if ABS(X) < EPS + -- c) SIN(X) = X - X**3/3! if EPS < ABS(X) < BASE_EPS + -- d) SIN(MATH_PI_OVER_2 - X) = COS(X) + -- e) COS(X) = 1.0 - 0.5*X**2 if ABS(X) < EPS + -- f) COS(X) = 1.0 - 0.5*X**2 + (X**4)/4! if + -- EPS< ABS(X) <BASE_EPS + + constant EPS : REAL := BASE_EPS*BASE_EPS; -- Convergence criteria + + variable N : INTEGER; + variable NEGATIVE : BOOLEAN := X < 0.0; + variable XLOCAL : REAL := ABS(X) ; + variable VALUE: REAL; + variable TEMP : REAL; + + begin + -- Make XLOCAL < MATH_2_PI + if XLOCAL > MATH_2_PI then + TEMP := FLOOR(XLOCAL/MATH_2_PI); + XLOCAL := XLOCAL - TEMP*MATH_2_PI; + end if; + + if XLOCAL < 0.0 then + -- adjust for rounding error + XLOCAL := 0.0; + end if; + + -- Compute value for special cases + if XLOCAL = 0.0 or XLOCAL = MATH_2_PI or XLOCAL = MATH_PI then + return 0.0; + end if; + + if XLOCAL = MATH_PI_OVER_2 then + if NEGATIVE then + return -1.0; + else + return 1.0; + end if; + end if; + + if XLOCAL = MATH_3_PI_OVER_2 then + if NEGATIVE then + return 1.0; + else + return -1.0; + end if; + end if; + + if XLOCAL < EPS then + if NEGATIVE then + return -XLOCAL; + else + return XLOCAL; + end if; + else + if XLOCAL < BASE_EPS then + TEMP := XLOCAL - (XLOCAL*XLOCAL*XLOCAL)/6.0; + if NEGATIVE then + return -TEMP; + else + return TEMP; + end if; + end if; + end if; + + TEMP := MATH_PI - XLOCAL; + if ABS(TEMP) < EPS then + if NEGATIVE then + return -TEMP; + else + return TEMP; + end if; + else + if ABS(TEMP) < BASE_EPS then + TEMP := TEMP - (TEMP*TEMP*TEMP)/6.0; + if NEGATIVE then + return -TEMP; + else + return TEMP; + end if; + end if; + end if; + + TEMP := MATH_2_PI - XLOCAL; + if ABS(TEMP) < EPS then + if NEGATIVE then + return TEMP; + else + return -TEMP; + end if; + else + if ABS(TEMP) < BASE_EPS then + TEMP := TEMP - (TEMP*TEMP*TEMP)/6.0; + if NEGATIVE then + return TEMP; + else + return -TEMP; + end if; + end if; + end if; + + TEMP := ABS(MATH_PI_OVER_2 - XLOCAL); + if TEMP < EPS then + TEMP := 1.0 - TEMP*TEMP*0.5; + if NEGATIVE then + return -TEMP; + else + return TEMP; + end if; + else + if TEMP < BASE_EPS then + TEMP := 1.0 -TEMP*TEMP*0.5 + TEMP*TEMP*TEMP*TEMP/24.0; + if NEGATIVE then + return -TEMP; + else + return TEMP; + end if; + end if; + end if; + + TEMP := ABS(MATH_3_PI_OVER_2 - XLOCAL); + if TEMP < EPS then + TEMP := 1.0 - TEMP*TEMP*0.5; + if NEGATIVE then + return TEMP; + else + return -TEMP; + end if; + else + if TEMP < BASE_EPS then + TEMP := 1.0 -TEMP*TEMP*0.5 + TEMP*TEMP*TEMP*TEMP/24.0; + if NEGATIVE then + return TEMP; + else + return -TEMP; + end if; + end if; + end if; + + -- Compute value for general cases + if ((XLOCAL < MATH_PI_OVER_2 ) and (XLOCAL > 0.0)) then + VALUE:= CORDIC( KC, 0.0, x, 27, ROTATION)(1); + end if; + + N := INTEGER ( FLOOR(XLOCAL/MATH_PI_OVER_2)); + case QUADRANT( N mod 4) is + when 0 => + VALUE := CORDIC( KC, 0.0, XLOCAL, 27, ROTATION)(1); + when 1 => + VALUE := CORDIC( KC, 0.0, XLOCAL - MATH_PI_OVER_2, 27, + ROTATION)(0); + when 2 => + VALUE := -CORDIC( KC, 0.0, XLOCAL - MATH_PI, 27, ROTATION)(1); + when 3 => + VALUE := -CORDIC( KC, 0.0, XLOCAL - MATH_3_PI_OVER_2, 27, + ROTATION)(0); + end case; + + if NEGATIVE then + return -VALUE; + else + return VALUE; + end if; + end function SIN; + + + function COS (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) COS(-X) = COS(X) + -- b) COS(X) = SIN(MATH_PI_OVER_2 - X) + -- c) COS(MATH_PI + X) = -COS(X) + -- d) COS(X) = 1.0 - X*X/2.0 if ABS(X) < EPS + -- e) COS(X) = 1.0 - 0.5*X**2 + (X**4)/4! if + -- EPS< ABS(X) <BASE_EPS + -- + constant EPS : REAL := BASE_EPS*BASE_EPS; + + variable XLOCAL : REAL := ABS(X); + variable VALUE: REAL; + variable TEMP : REAL; + + begin + -- Make XLOCAL < MATH_2_PI + if XLOCAL > MATH_2_PI then + TEMP := FLOOR(XLOCAL/MATH_2_PI); + XLOCAL := XLOCAL - TEMP*MATH_2_PI; + end if; + + if XLOCAL < 0.0 then + -- adjust for rounding error + XLOCAL := 0.0; + end if; + + -- Compute value for special cases + if XLOCAL = 0.0 or XLOCAL = MATH_2_PI then + return 1.0; + end if; + + if XLOCAL = MATH_PI then + return -1.0; + end if; + + if XLOCAL = MATH_PI_OVER_2 or XLOCAL = MATH_3_PI_OVER_2 then + return 0.0; + end if; + + TEMP := ABS(XLOCAL); + if ( TEMP < EPS) then + return (1.0 - 0.5*TEMP*TEMP); + else + if (TEMP < BASE_EPS) then + return (1.0 -0.5*TEMP*TEMP + TEMP*TEMP*TEMP*TEMP/24.0); + end if; + end if; + + TEMP := ABS(XLOCAL -MATH_2_PI); + if ( TEMP < EPS) then + return (1.0 - 0.5*TEMP*TEMP); + else + if (TEMP < BASE_EPS) then + return (1.0 -0.5*TEMP*TEMP + TEMP*TEMP*TEMP*TEMP/24.0); + end if; + end if; + + TEMP := ABS (XLOCAL - MATH_PI); + if TEMP < EPS then + return (-1.0 + 0.5*TEMP*TEMP); + else + if (TEMP < BASE_EPS) then + return (-1.0 +0.5*TEMP*TEMP - TEMP*TEMP*TEMP*TEMP/24.0); + end if; + end if; + + -- Compute value for general cases + return SIN(MATH_PI_OVER_2 - XLOCAL); + end function COS; + + function TAN (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) TAN(0.0) = 0.0 + -- b) TAN(-X) = -TAN(X) + -- c) Returns REAL'LOW on error if X < 0.0 + -- d) Returns REAL'HIGH on error if X > 0.0 + + variable NEGATIVE : BOOLEAN := X < 0.0; + variable XLOCAL : REAL := ABS(X) ; + variable VALUE: REAL; + variable TEMP : REAL; + + begin + -- Make 0.0 <= XLOCAL <= MATH_2_PI + if XLOCAL > MATH_2_PI then + TEMP := FLOOR(XLOCAL/MATH_2_PI); + XLOCAL := XLOCAL - TEMP*MATH_2_PI; + end if; + + if XLOCAL < 0.0 then + -- adjust for rounding error + XLOCAL := 0.0; + end if; + + -- Check validity of argument + if XLOCAL = MATH_PI_OVER_2 then + assert FALSE + report "X is a multiple of MATH_PI_OVER_2 in TAN(X)" + severity ERROR; + if NEGATIVE then + return(REAL'LOW); + else + return(REAL'HIGH); + end if; + end if; + + if XLOCAL = MATH_3_PI_OVER_2 then + assert FALSE + report "X is a multiple of MATH_3_PI_OVER_2 in TAN(X)" + severity ERROR; + if NEGATIVE then + return(REAL'HIGH); + else + return(REAL'LOW); + end if; + end if; + + -- Compute value for special cases + if XLOCAL = 0.0 or XLOCAL = MATH_PI then + return 0.0; + end if; + + -- Compute value for general cases + VALUE := SIN(XLOCAL)/COS(XLOCAL); + if NEGATIVE then + return -VALUE; + else + return VALUE; + end if; + end function TAN; + + function ARCSIN (X : in REAL ) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) ARCSIN(-X) = -ARCSIN(X) + -- b) Returns X on error + + variable NEGATIVE : BOOLEAN := X < 0.0; + variable XLOCAL : REAL := ABS(X); + variable VALUE : REAL; + + begin + -- Check validity of arguments + if XLOCAL > 1.0 then + assert FALSE + report "ABS(X) > 1.0 in ARCSIN(X)" + severity ERROR; + return X; + end if; + + -- Compute value for special cases + if XLOCAL = 0.0 then + return 0.0; + elsif XLOCAL = 1.0 then + if NEGATIVE then + return -MATH_PI_OVER_2; + else + return MATH_PI_OVER_2; + end if; + end if; + + -- Compute value for general cases + if XLOCAL < 0.9 then + VALUE := ARCTAN(XLOCAL/(SQRT(1.0 - XLOCAL*XLOCAL))); + else + VALUE := MATH_PI_OVER_2 - ARCTAN(SQRT(1.0 - XLOCAL*XLOCAL)/XLOCAL); + end if; + + if NEGATIVE then + VALUE := -VALUE; + end if; + + return VALUE; + end function ARCSIN; + + function ARCCOS (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) ARCCOS(-X) = MATH_PI - ARCCOS(X) + -- b) Returns X on error + + variable NEGATIVE : BOOLEAN := X < 0.0; + variable XLOCAL : REAL := ABS(X); + variable VALUE : REAL; + + begin + -- Check validity of argument + if XLOCAL > 1.0 then + assert FALSE + report "ABS(X) > 1.0 in ARCCOS(X)" + severity ERROR; + return X; + end if; + + -- Compute value for special cases + if X = 1.0 then + return 0.0; + elsif X = 0.0 then + return MATH_PI_OVER_2; + elsif X = -1.0 then + return MATH_PI; + end if; + + -- Compute value for general cases + if XLOCAL > 0.9 then + VALUE := ARCTAN(SQRT(1.0 - XLOCAL*XLOCAL)/XLOCAL); + else + VALUE := MATH_PI_OVER_2 - ARCTAN(XLOCAL/SQRT(1.0 - XLOCAL*XLOCAL)); + end if; + + + if NEGATIVE then + VALUE := MATH_PI - VALUE; + end if; + + return VALUE; + end function ARCCOS; + + + function ARCTAN (Y : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) ARCTAN(-Y) = -ARCTAN(Y) + -- b) ARCTAN(Y) = -ARCTAN(1.0/Y) + MATH_PI_OVER_2 for |Y| > 1.0 + -- c) ARCTAN(Y) = Y for |Y| < EPS + + constant EPS : REAL := BASE_EPS*BASE_EPS*BASE_EPS; + + variable NEGATIVE : BOOLEAN := Y < 0.0; + variable RECIPROCAL : BOOLEAN; + variable YLOCAL : REAL := ABS(Y); + variable VALUE : REAL; + + begin + -- Make argument |Y| <=1.0 + if YLOCAL > 1.0 then + YLOCAL := 1.0/YLOCAL; + RECIPROCAL := TRUE; + else + RECIPROCAL := FALSE; + end if; + + -- Compute value for special cases + if YLOCAL = 0.0 then + if RECIPROCAL then + if NEGATIVE then + return (-MATH_PI_OVER_2); + else + return (MATH_PI_OVER_2); + end if; + else + return 0.0; + end if; + end if; + + if YLOCAL < EPS then + if NEGATIVE then + if RECIPROCAL then + return (-MATH_PI_OVER_2 + YLOCAL); + else + return -YLOCAL; + end if; + else + if RECIPROCAL then + return (MATH_PI_OVER_2 - YLOCAL); + else + return YLOCAL; + end if; + end if; + end if; + + -- Compute value for general cases + VALUE := CORDIC( 1.0, YLOCAL, 0.0, 27, VECTORING )(2); + + if RECIPROCAL then + VALUE := MATH_PI_OVER_2 - VALUE; + end if; + + if NEGATIVE then + VALUE := -VALUE; + end if; + + return VALUE; + end function ARCTAN; + + + function ARCTAN (Y : in REAL; X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns 0.0 on error + + variable YLOCAL : REAL; + variable VALUE : REAL; + begin + + -- Check validity of arguments + if (Y = 0.0 and X = 0.0 ) then + assert FALSE report + "ARCTAN(0.0, 0.0) is undetermined" + severity ERROR; + return 0.0; + end if; + + -- Compute value for special cases + if Y = 0.0 then + if X > 0.0 then + return 0.0; + else + return MATH_PI; + end if; + end if; + + if X = 0.0 then + if Y > 0.0 then + return MATH_PI_OVER_2; + else + return -MATH_PI_OVER_2; + end if; + end if; + + + -- Compute value for general cases + YLOCAL := ABS(Y/X); + + VALUE := ARCTAN(YLOCAL); + + if X < 0.0 then + VALUE := MATH_PI - VALUE; + end if; + + if Y < 0.0 then + VALUE := -VALUE; + end if; + + return VALUE; + end function ARCTAN; + + + function SINH (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns (EXP(X) - EXP(-X))/2.0 + -- b) SINH(-X) = SINH(X) + + variable NEGATIVE : BOOLEAN := X < 0.0; + variable XLOCAL : REAL := ABS(X); + variable TEMP : REAL; + variable VALUE : REAL; + + begin + -- Compute value for special cases + if XLOCAL = 0.0 then + return 0.0; + end if; + + -- Compute value for general cases + TEMP := EXP(XLOCAL); + VALUE := (TEMP - 1.0/TEMP)*0.5; + + if NEGATIVE then + VALUE := -VALUE; + end if; + + return VALUE; + end function SINH; + + function COSH (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns (EXP(X) + EXP(-X))/2.0 + -- b) COSH(-X) = COSH(X) + + variable XLOCAL : REAL := ABS(X); + variable TEMP : REAL; + variable VALUE : REAL; + begin + -- Compute value for special cases + if XLOCAL = 0.0 then + return 1.0; + end if; + + + -- Compute value for general cases + TEMP := EXP(XLOCAL); + VALUE := (TEMP + 1.0/TEMP)*0.5; + + return VALUE; + end function COSH; + + function TANH (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns (EXP(X) - EXP(-X))/(EXP(X) + EXP(-X)) + -- b) TANH(-X) = -TANH(X) + + variable NEGATIVE : BOOLEAN := X < 0.0; + variable XLOCAL : REAL := ABS(X); + variable TEMP : REAL; + variable VALUE : REAL; + + begin + -- Compute value for special cases + if XLOCAL = 0.0 then + return 0.0; + end if; + + -- Compute value for general cases + TEMP := EXP(XLOCAL); + VALUE := (TEMP - 1.0/TEMP)/(TEMP + 1.0/TEMP); + + if NEGATIVE then + return -VALUE; + else + return VALUE; + end if; + end function TANH; + + function ARCSINH (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns LOG( X + SQRT( X*X + 1.0)) + + begin + -- Compute value for special cases + if X = 0.0 then + return 0.0; + end if; + + -- Compute value for general cases + return ( LOG( X + SQRT( X*X + 1.0)) ); + end function ARCSINH; + + + + function ARCCOSH (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns LOG( X + SQRT( X*X - 1.0)); X >= 1.0 + -- b) Returns X on error + + begin + -- Check validity of arguments + if X < 1.0 then + assert FALSE + report "X < 1.0 in ARCCOSH(X)" + severity ERROR; + return X; + end if; + + -- Compute value for special cases + if X = 1.0 then + return 0.0; + end if; + + -- Compute value for general cases + return ( LOG( X + SQRT( X*X - 1.0))); + end function ARCCOSH; + + function ARCTANH (X : in REAL) return REAL is + -- Description: + -- See function declaration in IEEE Std 1076.2-1996 + -- Notes: + -- a) Returns (LOG( (1.0 + X)/(1.0 - X)))/2.0 ; | X | < 1.0 + -- b) Returns X on error + begin + -- Check validity of arguments + if ABS(X) >= 1.0 then + assert FALSE + report "ABS(X) >= 1.0 in ARCTANH(X)" + severity ERROR; + return X; + end if; + + -- Compute value for special cases + if X = 0.0 then + return 0.0; + end if; + + -- Compute value for general cases + return( 0.5*LOG( (1.0+X)/(1.0-X) ) ); + end function ARCTANH; + +end package body MATH_REAL; diff --git a/libraries/ieee2008/math_real.vhdl b/libraries/ieee2008/math_real.vhdl new file mode 100644 index 000000000..f4660a7e1 --- /dev/null +++ b/libraries/ieee2008/math_real.vhdl @@ -0,0 +1,622 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Mathematical Packages +-- : (MATH_REAL package declaration) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC VHDL Mathematical Packages Working Group +-- : +-- Purpose : This package defines a standard for designers to use in +-- : describing VHDL models that make use of common REAL +-- : constants and common REAL elementary mathematical +-- : functions. +-- : +-- Limitation: The values generated by the functions in this package +-- : may vary from platform to platform, and the precision +-- : of results is only guaranteed to be the minimum required +-- : by IEEE Std 1076-2008. +-- : +-- 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) $ +-- -------------------------------------------------------------------- + +package MATH_REAL is + constant CopyRightNotice : STRING + := "Copyright 2008 IEEE. All rights reserved."; + + -- + -- Constant Definitions + -- + constant MATH_E : REAL := 2.71828_18284_59045_23536; + -- Value of e + constant MATH_1_OVER_E : REAL := 0.36787_94411_71442_32160; + -- Value of 1/e + constant MATH_PI : REAL := 3.14159_26535_89793_23846; + -- Value of pi + constant MATH_2_PI : REAL := 6.28318_53071_79586_47693; + -- Value of 2*pi + constant MATH_1_OVER_PI : REAL := 0.31830_98861_83790_67154; + -- Value of 1/pi + constant MATH_PI_OVER_2 : REAL := 1.57079_63267_94896_61923; + -- Value of pi/2 + constant MATH_PI_OVER_3 : REAL := 1.04719_75511_96597_74615; + -- Value of pi/3 + constant MATH_PI_OVER_4 : REAL := 0.78539_81633_97448_30962; + -- Value of pi/4 + constant MATH_3_PI_OVER_2 : REAL := 4.71238_89803_84689_85769; + -- Value 3*pi/2 + constant MATH_LOG_OF_2 : REAL := 0.69314_71805_59945_30942; + -- Natural log of 2 + constant MATH_LOG_OF_10 : REAL := 2.30258_50929_94045_68402; + -- Natural log of 10 + constant MATH_LOG2_OF_E : REAL := 1.44269_50408_88963_4074; + -- Log base 2 of e + constant MATH_LOG10_OF_E : REAL := 0.43429_44819_03251_82765; + -- Log base 10 of e + constant MATH_SQRT_2 : REAL := 1.41421_35623_73095_04880; + -- square root of 2 + constant MATH_1_OVER_SQRT_2 : REAL := 0.70710_67811_86547_52440; + -- square root of 1/2 + constant MATH_SQRT_PI : REAL := 1.77245_38509_05516_02730; + -- square root of pi + constant MATH_DEG_TO_RAD : REAL := 0.01745_32925_19943_29577; + -- Conversion factor from degree to radian + constant MATH_RAD_TO_DEG : REAL := 57.29577_95130_82320_87680; + -- Conversion factor from radian to degree + + -- + -- Function Declarations + -- + function SIGN (X : in REAL) return REAL; + -- Purpose: + -- Returns 1.0 if X > 0.0; 0.0 if X = 0.0; -1.0 if X < 0.0 + -- Special values: + -- None + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- ABS(SIGN(X)) <= 1.0 + -- Notes: + -- None + + function CEIL (X : in REAL) return REAL; + -- Purpose: + -- Returns smallest INTEGER value (as REAL) not less than X + -- Special values: + -- None + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- CEIL(X) is mathematically unbounded + -- Notes: + -- a) Implementations have to support at least the domain + -- ABS(X) < REAL(INTEGER'HIGH) + + function FLOOR (X : in REAL) return REAL; + -- Purpose: + -- Returns largest INTEGER value (as REAL) not greater than X + -- Special values: + -- FLOOR(0.0) = 0.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- FLOOR(X) is mathematically unbounded + -- Notes: + -- a) Implementations have to support at least the domain + -- ABS(X) < REAL(INTEGER'HIGH) + + function ROUND (X : in REAL) return REAL; + -- Purpose: + -- Rounds X to the nearest integer value (as real). If X is + -- halfway between two integers, rounding is away from 0.0 + -- Special values: + -- ROUND(0.0) = 0.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- ROUND(X) is mathematically unbounded + -- Notes: + -- a) Implementations have to support at least the domain + -- ABS(X) < REAL(INTEGER'HIGH) + + function TRUNC (X : in REAL) return REAL; + -- Purpose: + -- Truncates X towards 0.0 and returns truncated value + -- Special values: + -- TRUNC(0.0) = 0.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- TRUNC(X) is mathematically unbounded + -- Notes: + -- a) Implementations have to support at least the domain + -- ABS(X) < REAL(INTEGER'HIGH) + + function "MOD" (X, Y : in REAL) return REAL; + -- Purpose: + -- Returns floating point modulus of X/Y, with the same sign as + -- Y, and absolute value less than the absolute value of Y, and + -- for some INTEGER value N the result satisfies the relation + -- X = Y*N + MOD(X,Y) + -- Special values: + -- None + -- Domain: + -- X in REAL; Y in REAL and Y /= 0.0 + -- Error conditions: + -- Error if Y = 0.0 + -- Range: + -- ABS(MOD(X,Y)) < ABS(Y) + -- Notes: + -- None + + function REALMAX (X, Y : in REAL) return REAL; + -- Purpose: + -- Returns the algebraically larger of X and Y + -- Special values: + -- REALMAX(X,Y) = X when X = Y + -- Domain: + -- X in REAL; Y in REAL + -- Error conditions: + -- None + -- Range: + -- REALMAX(X,Y) is mathematically unbounded + -- Notes: + -- None + + function REALMIN (X, Y : in REAL) return REAL; + -- Purpose: + -- Returns the algebraically smaller of X and Y + -- Special values: + -- REALMIN(X,Y) = X when X = Y + -- Domain: + -- X in REAL; Y in REAL + -- Error conditions: + -- None + -- Range: + -- REALMIN(X,Y) is mathematically unbounded + -- Notes: + -- None + + procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL); + -- Purpose: + -- Returns, in X, a pseudo-random number with uniform + -- distribution in the open interval (0.0, 1.0). + -- Special values: + -- None + -- Domain: + -- 1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398 + -- Error conditions: + -- Error if SEED1 or SEED2 outside of valid domain + -- Range: + -- 0.0 < X < 1.0 + -- Notes: + -- a) The semantics for this function are described by the + -- algorithm published by Pierre L'Ecuyer in "Communications + -- of the ACM," vol. 31, no. 6, June 1988, pp. 742-774. + -- The algorithm is based on the combination of two + -- multiplicative linear congruential generators for 32-bit + -- platforms. + -- + -- b) Before the first call to UNIFORM, the seed values + -- (SEED1, SEED2) have to be initialized to values in the range + -- [1, 2147483562] and [1, 2147483398] respectively. The + -- seed values are modified after each call to UNIFORM. + -- + -- c) This random number generator is portable for 32-bit + -- computers, and it has a period of ~2.30584*(10**18) for each + -- set of seed values. + -- + -- d) For information on spectral tests for the algorithm, refer + -- to the L'Ecuyer article. + + function SQRT (X : in REAL) return REAL; + -- Purpose: + -- Returns square root of X + -- Special values: + -- SQRT(0.0) = 0.0 + -- SQRT(1.0) = 1.0 + -- Domain: + -- X >= 0.0 + -- Error conditions: + -- Error if X < 0.0 + -- Range: + -- SQRT(X) >= 0.0 + -- Notes: + -- a) The upper bound of the reachable range of SQRT is + -- approximately given by: + -- SQRT(X) <= SQRT(REAL'HIGH) + + function CBRT (X : in REAL) return REAL; + -- Purpose: + -- Returns cube root of X + -- Special values: + -- CBRT(0.0) = 0.0 + -- CBRT(1.0) = 1.0 + -- CBRT(-1.0) = -1.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- CBRT(X) is mathematically unbounded + -- Notes: + -- a) The reachable range of CBRT is approximately given by: + -- ABS(CBRT(X)) <= CBRT(REAL'HIGH) + + function "**" (X : in INTEGER; Y : in REAL) return REAL; + -- Purpose: + -- Returns Y power of X ==> X**Y + -- Special values: + -- X**0.0 = 1.0; X /= 0 + -- 0**Y = 0.0; Y > 0.0 + -- X**1.0 = REAL(X); X >= 0 + -- 1**Y = 1.0 + -- Domain: + -- X > 0 + -- X = 0 for Y > 0.0 + -- X < 0 for Y = 0.0 + -- Error conditions: + -- Error if X < 0 and Y /= 0.0 + -- Error if X = 0 and Y <= 0.0 + -- Range: + -- X**Y >= 0.0 + -- Notes: + -- a) The upper bound of the reachable range for "**" is + -- approximately given by: + -- X**Y <= REAL'HIGH + + function "**" (X : in REAL; Y : in REAL) return REAL; + -- Purpose: + -- Returns Y power of X ==> X**Y + -- Special values: + -- X**0.0 = 1.0; X /= 0.0 + -- 0.0**Y = 0.0; Y > 0.0 + -- X**1.0 = X; X >= 0.0 + -- 1.0**Y = 1.0 + -- Domain: + -- X > 0.0 + -- X = 0.0 for Y > 0.0 + -- X < 0.0 for Y = 0.0 + -- Error conditions: + -- Error if X < 0.0 and Y /= 0.0 + -- Error if X = 0.0 and Y <= 0.0 + -- Range: + -- X**Y >= 0.0 + -- Notes: + -- a) The upper bound of the reachable range for "**" is + -- approximately given by: + -- X**Y <= REAL'HIGH + + function EXP (X : in REAL) return REAL; + -- Purpose: + -- Returns e**X; where e = MATH_E + -- Special values: + -- EXP(0.0) = 1.0 + -- EXP(1.0) = MATH_E + -- EXP(-1.0) = MATH_1_OVER_E + -- EXP(X) = 0.0 for X <= -LOG(REAL'HIGH) + -- Domain: + -- X in REAL such that EXP(X) <= REAL'HIGH + -- Error conditions: + -- Error if X > LOG(REAL'HIGH) + -- Range: + -- EXP(X) >= 0.0 + -- Notes: + -- a) The usable domain of EXP is approximately given by: + -- X <= LOG(REAL'HIGH) + + function LOG (X : in REAL) return REAL; + -- Purpose: + -- Returns natural logarithm of X + -- Special values: + -- LOG(1.0) = 0.0 + -- LOG(MATH_E) = 1.0 + -- Domain: + -- X > 0.0 + -- Error conditions: + -- Error if X <= 0.0 + -- Range: + -- LOG(X) is mathematically unbounded + -- Notes: + -- a) The reachable range of LOG is approximately given by: + -- LOG(0+) <= LOG(X) <= LOG(REAL'HIGH) + + function LOG2 (X : in REAL) return REAL; + -- Purpose: + -- Returns logarithm base 2 of X + -- Special values: + -- LOG2(1.0) = 0.0 + -- LOG2(2.0) = 1.0 + -- Domain: + -- X > 0.0 + -- Error conditions: + -- Error if X <= 0.0 + -- Range: + -- LOG2(X) is mathematically unbounded + -- Notes: + -- a) The reachable range of LOG2 is approximately given by: + -- LOG2(0+) <= LOG2(X) <= LOG2(REAL'HIGH) + + function LOG10 (X : in REAL) return REAL; + -- Purpose: + -- Returns logarithm base 10 of X + -- Special values: + -- LOG10(1.0) = 0.0 + -- LOG10(10.0) = 1.0 + -- Domain: + -- X > 0.0 + -- Error conditions: + -- Error if X <= 0.0 + -- Range: + -- LOG10(X) is mathematically unbounded + -- Notes: + -- a) The reachable range of LOG10 is approximately given by: + -- LOG10(0+) <= LOG10(X) <= LOG10(REAL'HIGH) + + function LOG (X : in REAL; BASE : in REAL) return REAL; + -- Purpose: + -- Returns logarithm base BASE of X + -- Special values: + -- LOG(1.0, BASE) = 0.0 + -- LOG(BASE, BASE) = 1.0 + -- Domain: + -- X > 0.0 + -- BASE > 0.0 + -- BASE /= 1.0 + -- Error conditions: + -- Error if X <= 0.0 + -- Error if BASE <= 0.0 + -- Error if BASE = 1.0 + -- Range: + -- LOG(X, BASE) is mathematically unbounded + -- Notes: + -- a) When BASE > 1.0, the reachable range of LOG is + -- approximately given by: + -- LOG(0+, BASE) <= LOG(X, BASE) <= LOG(REAL'HIGH, BASE) + -- b) When 0.0 < BASE < 1.0, the reachable range of LOG is + -- approximately given by: + -- LOG(REAL'HIGH, BASE) <= LOG(X, BASE) <= LOG(0+, BASE) + + function SIN (X : in REAL) return REAL; + -- Purpose: + -- Returns sine of X; X in radians + -- Special values: + -- SIN(X) = 0.0 for X = k*MATH_PI, where k is an INTEGER + -- SIN(X) = 1.0 for X = (4*k+1)*MATH_PI_OVER_2, where k is an + -- INTEGER + -- SIN(X) = -1.0 for X = (4*k+3)*MATH_PI_OVER_2, where k is an + -- INTEGER + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- ABS(SIN(X)) <= 1.0 + -- Notes: + -- a) For larger values of ABS(X), degraded accuracy is allowed. + + function COS (X : in REAL) return REAL; + -- Purpose: + -- Returns cosine of X; X in radians + -- Special values: + -- COS(X) = 0.0 for X = (2*k+1)*MATH_PI_OVER_2, where k is an + -- INTEGER + -- COS(X) = 1.0 for X = (2*k)*MATH_PI, where k is an INTEGER + -- COS(X) = -1.0 for X = (2*k+1)*MATH_PI, where k is an INTEGER + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- ABS(COS(X)) <= 1.0 + -- Notes: + -- a) For larger values of ABS(X), degraded accuracy is allowed. + + function TAN (X : in REAL) return REAL; + -- Purpose: + -- Returns tangent of X; X in radians + -- Special values: + -- TAN(X) = 0.0 for X = k*MATH_PI, where k is an INTEGER + -- Domain: + -- X in REAL and + -- X /= (2*k+1)*MATH_PI_OVER_2, where k is an INTEGER + -- Error conditions: + -- Error if X = ((2*k+1) * MATH_PI_OVER_2), where k is an + -- INTEGER + -- Range: + -- TAN(X) is mathematically unbounded + -- Notes: + -- a) For larger values of ABS(X), degraded accuracy is allowed. + + function ARCSIN (X : in REAL) return REAL; + -- Purpose: + -- Returns inverse sine of X + -- Special values: + -- ARCSIN(0.0) = 0.0 + -- ARCSIN(1.0) = MATH_PI_OVER_2 + -- ARCSIN(-1.0) = -MATH_PI_OVER_2 + -- Domain: + -- ABS(X) <= 1.0 + -- Error conditions: + -- Error if ABS(X) > 1.0 + -- Range: + -- ABS(ARCSIN(X) <= MATH_PI_OVER_2 + -- Notes: + -- None + + function ARCCOS (X : in REAL) return REAL; + -- Purpose: + -- Returns inverse cosine of X + -- Special values: + -- ARCCOS(1.0) = 0.0 + -- ARCCOS(0.0) = MATH_PI_OVER_2 + -- ARCCOS(-1.0) = MATH_PI + -- Domain: + -- ABS(X) <= 1.0 + -- Error conditions: + -- Error if ABS(X) > 1.0 + -- Range: + -- 0.0 <= ARCCOS(X) <= MATH_PI + -- Notes: + -- None + + function ARCTAN (Y : in REAL) return REAL; + -- Purpose: + -- Returns the value of the angle in radians of the point + -- (1.0, Y), which is in rectangular coordinates + -- Special values: + -- ARCTAN(0.0) = 0.0 + -- Domain: + -- Y in REAL + -- Error conditions: + -- None + -- Range: + -- ABS(ARCTAN(Y)) <= MATH_PI_OVER_2 + -- Notes: + -- None + + function ARCTAN (Y : in REAL; X : in REAL) return REAL; + -- Purpose: + -- Returns the principal value of the angle in radians of + -- the point (X, Y), which is in rectangular coordinates + -- Special values: + -- ARCTAN(0.0, X) = 0.0 if X > 0.0 + -- ARCTAN(0.0, X) = MATH_PI if X < 0.0 + -- ARCTAN(Y, 0.0) = MATH_PI_OVER_2 if Y > 0.0 + -- ARCTAN(Y, 0.0) = -MATH_PI_OVER_2 if Y < 0.0 + -- Domain: + -- Y in REAL + -- X in REAL, X /= 0.0 when Y = 0.0 + -- Error conditions: + -- Error if X = 0.0 and Y = 0.0 + -- Range: + -- -MATH_PI < ARCTAN(Y,X) <= MATH_PI + -- Notes: + -- None + + function SINH (X : in REAL) return REAL; + -- Purpose: + -- Returns hyperbolic sine of X + -- Special values: + -- SINH(0.0) = 0.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- SINH(X) is mathematically unbounded + -- Notes: + -- a) The usable domain of SINH is approximately given by: + -- ABS(X) <= LOG(REAL'HIGH) + + + function COSH (X : in REAL) return REAL; + -- Purpose: + -- Returns hyperbolic cosine of X + -- Special values: + -- COSH(0.0) = 1.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- COSH(X) >= 1.0 + -- Notes: + -- a) The usable domain of COSH is approximately given by: + -- ABS(X) <= LOG(REAL'HIGH) + + function TANH (X : in REAL) return REAL; + -- Purpose: + -- Returns hyperbolic tangent of X + -- Special values: + -- TANH(0.0) = 0.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- ABS(TANH(X)) <= 1.0 + -- Notes: + -- None + + function ARCSINH (X : in REAL) return REAL; + -- Purpose: + -- Returns inverse hyperbolic sine of X + -- Special values: + -- ARCSINH(0.0) = 0.0 + -- Domain: + -- X in REAL + -- Error conditions: + -- None + -- Range: + -- ARCSINH(X) is mathematically unbounded + -- Notes: + -- a) The reachable range of ARCSINH is approximately given by: + -- ABS(ARCSINH(X)) <= LOG(REAL'HIGH) + + function ARCCOSH (X : in REAL) return REAL; + -- Purpose: + -- Returns inverse hyperbolic cosine of X + -- Special values: + -- ARCCOSH(1.0) = 0.0 + -- Domain: + -- X >= 1.0 + -- Error conditions: + -- Error if X < 1.0 + -- Range: + -- ARCCOSH(X) >= 0.0 + -- Notes: + -- a) The upper bound of the reachable range of ARCCOSH is + -- approximately given by: ARCCOSH(X) <= LOG(REAL'HIGH) + + function ARCTANH (X : in REAL) return REAL; + -- Purpose: + -- Returns inverse hyperbolic tangent of X + -- Special values: + -- ARCTANH(0.0) = 0.0 + -- Domain: + -- ABS(X) < 1.0 + -- Error conditions: + -- Error if ABS(X) >= 1.0 + -- Range: + -- ARCTANH(X) is mathematically unbounded + -- Notes: + -- a) The reachable range of ARCTANH is approximately given by: + -- ABS(ARCTANH(X)) < LOG(REAL'HIGH) + +end package MATH_REAL; diff --git a/libraries/ieee2008/numeric_bit-body.vhdl b/libraries/ieee2008/numeric_bit-body.vhdl new file mode 100644 index 000000000..f3e17b055 --- /dev/null +++ b/libraries/ieee2008/numeric_bit-body.vhdl @@ -0,0 +1,3042 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Synthesis Packages +-- : (NUMERIC_BIT package body) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC Synthesis Working Group, +-- : Accellera VHDL-TC, and IEEE P1076 Working Group +-- : +-- Purpose : This package defines numeric types and arithmetic functions +-- : for use with synthesis tools. Two numeric types are defined: +-- : -- > UNSIGNED: represents an UNSIGNED number in vector form +-- : -- > SIGNED: represents a SIGNED number in vector form +-- : The base element type is type BIT. +-- : The leftmost bit is treated as the most significant bit. +-- : Signed vectors are represented in two's complement form. +-- : This package contains overloaded arithmetic operators on +-- : the SIGNED and UNSIGNED types. The package also contains +-- : useful type conversions functions, clock detection +-- : functions, and other utility functions. +-- : +-- : If any argument to a function is a null array, a null array +-- : is returned (exceptions, if any, are noted individually). +-- +-- 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) $ +-- -------------------------------------------------------------------- + +package body NUMERIC_BIT is + + -- null range array constants + + constant NAU : UNSIGNED(0 downto 1) := (others => '0'); + constant NAS : SIGNED(0 downto 1) := (others => '0'); + + -- implementation controls + + constant NO_WARNING : BOOLEAN := false; -- default to emit warnings + + -- =========================Local Subprograms ================================= + + function SIGNED_NUM_BITS (ARG : INTEGER) return NATURAL is + variable NBITS : NATURAL; + variable N : NATURAL; + begin + if ARG >= 0 then + N := ARG; + else + N := -(ARG+1); + end if; + NBITS := 1; + while N > 0 loop + NBITS := NBITS+1; + N := N / 2; + end loop; + return NBITS; + end function SIGNED_NUM_BITS; + + function UNSIGNED_NUM_BITS (ARG : NATURAL) return NATURAL is + variable NBITS : NATURAL; + variable N : NATURAL; + begin + N := ARG; + NBITS := 1; + while N > 1 loop + NBITS := NBITS+1; + N := N / 2; + end loop; + return NBITS; + end function UNSIGNED_NUM_BITS; + + ------------------------------------------------------------------------------ + -- this internal function computes the addition of two UNSIGNED + -- with input carry + -- * the two arguments are of the same length + + function ADD_UNSIGNED (L, R : UNSIGNED; C : BIT) return UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNSIGNED(L_LEFT downto 0) is R; + variable RESULT : UNSIGNED(L_LEFT downto 0); + variable CBIT : BIT := C; + begin + for I in 0 to L_LEFT loop + RESULT(I) := CBIT xor XL(I) xor XR(I); + CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I)); + end loop; + return RESULT; + end function ADD_UNSIGNED; + + -- this internal function computes the addition of two SIGNED + -- with input carry + -- * the two arguments are of the same length + + function ADD_SIGNED (L, R : SIGNED; C : BIT) return SIGNED is + constant L_LEFT : INTEGER := L'length-1; + alias XL : SIGNED(L_LEFT downto 0) is L; + alias XR : SIGNED(L_LEFT downto 0) is R; + variable RESULT : SIGNED(L_LEFT downto 0); + variable CBIT : BIT := C; + begin + for I in 0 to L_LEFT loop + RESULT(I) := CBIT xor XL(I) xor XR(I); + CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I)); + end loop; + return RESULT; + end function ADD_SIGNED; + + ------------------------------------------------------------------------------ + + -- this internal procedure computes UNSIGNED division + -- giving the quotient and remainder. + procedure DIVMOD (NUM, XDENOM : UNSIGNED; XQUOT, XREMAIN : out UNSIGNED) is + variable TEMP : UNSIGNED(NUM'length downto 0); + variable QUOT : UNSIGNED(MAXIMUM(NUM'length, XDENOM'length)-1 downto 0); + alias DENOM : UNSIGNED(XDENOM'length-1 downto 0) is XDENOM; + variable TOPBIT : INTEGER; + begin + TEMP := "0"&NUM; + QUOT := (others => '0'); + TOPBIT := -1; + for J in DENOM'range loop + if DENOM(J) = '1' then + TOPBIT := J; + exit; + end if; + end loop; + assert TOPBIT >= 0 report "NUMERIC_BIT.DIVMOD: DIV, MOD, or REM by zero" + severity error; + + for J in NUM'length-(TOPBIT+1) downto 0 loop + if TEMP(TOPBIT+J+1 downto J) >= "0"&DENOM(TOPBIT downto 0) then + TEMP(TOPBIT+J+1 downto J) := (TEMP(TOPBIT+J+1 downto J)) + -("0"&DENOM(TOPBIT downto 0)); + QUOT(J) := '1'; + end if; + assert TEMP(TOPBIT+J+1) = '0' + report "NUMERIC_BIT.DIVMOD: internal error in the division algorithm" + severity error; + end loop; + XQUOT := RESIZE(QUOT, XQUOT'length); + XREMAIN := RESIZE(TEMP, XREMAIN'length); + end procedure DIVMOD; + + -----------------Local Subprograms - shift/rotate ops------------------------- + + function XSLL (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : BIT_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : BIT_VECTOR(ARG_L downto 0) := (others => '0'); + begin + if COUNT <= ARG_L then + RESULT(ARG_L downto COUNT) := XARG(ARG_L-COUNT downto 0); + end if; + return RESULT; + end function XSLL; + + function XSRL (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : BIT_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : BIT_VECTOR(ARG_L downto 0) := (others => '0'); + begin + if COUNT <= ARG_L then + RESULT(ARG_L-COUNT downto 0) := XARG(ARG_L downto COUNT); + end if; + return RESULT; + end function XSRL; + + function XSRA (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : BIT_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : BIT_VECTOR(ARG_L downto 0); + variable XCOUNT : NATURAL := COUNT; + begin + if ((ARG'length <= 1) or (XCOUNT = 0)) then return ARG; + else + if (XCOUNT > ARG_L) then XCOUNT := ARG_L; + end if; + RESULT(ARG_L-XCOUNT downto 0) := XARG(ARG_L downto XCOUNT); + RESULT(ARG_L downto (ARG_L - XCOUNT + 1)) := (others => XARG(ARG_L)); + end if; + return RESULT; + end function XSRA; + + function XROL (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : BIT_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : BIT_VECTOR(ARG_L downto 0) := XARG; + variable COUNTM : INTEGER; + begin + COUNTM := COUNT mod (ARG_L + 1); + if COUNTM /= 0 then + RESULT(ARG_L downto COUNTM) := XARG(ARG_L-COUNTM downto 0); + RESULT(COUNTM-1 downto 0) := XARG(ARG_L downto ARG_L-COUNTM+1); + end if; + return RESULT; + end function XROL; + + function XROR (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : BIT_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : BIT_VECTOR(ARG_L downto 0) := XARG; + variable COUNTM : INTEGER; + begin + COUNTM := COUNT mod (ARG_L + 1); + if COUNTM /= 0 then + RESULT(ARG_L-COUNTM downto 0) := XARG(ARG_L downto COUNTM); + RESULT(ARG_L downto ARG_L-COUNTM+1) := XARG(COUNTM-1 downto 0); + end if; + return RESULT; + end function XROR; + + ---------------- Local Subprograms - Relational Operators -------------------- + + -- + -- General "=" for UNSIGNED vectors, same length + -- + function UNSIGNED_EQUAL (L, R : UNSIGNED) return BOOLEAN is + begin + return BIT_VECTOR(L) = BIT_VECTOR(R); + end function UNSIGNED_EQUAL; + + -- + -- General "=" for SIGNED vectors, same length + -- + function SIGNED_EQUAL (L, R : SIGNED) return BOOLEAN is + begin + return BIT_VECTOR(L) = BIT_VECTOR(R); + end function SIGNED_EQUAL; + + -- + -- General "<" for UNSIGNED vectors, same length + -- + function UNSIGNED_LESS (L, R : UNSIGNED) return BOOLEAN is + begin + return BIT_VECTOR(L) < BIT_VECTOR(R); + end function UNSIGNED_LESS; + + -- + -- General "<" function for SIGNED vectors, same length + -- + function SIGNED_LESS (L, R : SIGNED) return BOOLEAN is + -- Need aliases to assure index direction + variable INTERN_L : SIGNED(0 to L'length-1); + variable INTERN_R : SIGNED(0 to R'length-1); + begin + INTERN_L := L; + INTERN_R := R; + INTERN_L(0) := not INTERN_L(0); + INTERN_R(0) := not INTERN_R(0); + return BIT_VECTOR(INTERN_L) < BIT_VECTOR(INTERN_R); + end function SIGNED_LESS; + + -- + -- General "<=" function for UNSIGNED vectors, same length + -- + function UNSIGNED_LESS_OR_EQUAL (L, R : UNSIGNED) return BOOLEAN is + begin + return BIT_VECTOR(L) <= BIT_VECTOR(R); + end function UNSIGNED_LESS_OR_EQUAL; + + -- + -- General "<=" function for SIGNED vectors, same length + -- + function SIGNED_LESS_OR_EQUAL (L, R : SIGNED) return BOOLEAN is + -- Need aliases to assure index direction + variable INTERN_L : SIGNED(0 to L'length-1); + variable INTERN_R : SIGNED(0 to R'length-1); + begin + INTERN_L := L; + INTERN_R := R; + INTERN_L(0) := not INTERN_L(0); + INTERN_R(0) := not INTERN_R(0); + return BIT_VECTOR(INTERN_L) <= BIT_VECTOR(INTERN_R); + end function SIGNED_LESS_OR_EQUAL; + + -- ====================== Exported Functions ================================== + + -- Id: A.1 + function "abs" (ARG : SIGNED) return SIGNED is + constant ARG_LEFT : INTEGER := ARG'length-1; + variable RESULT : SIGNED(ARG_LEFT downto 0); + begin + if ARG'length < 1 then return NAS; + end if; + RESULT := ARG; + if RESULT(RESULT'left) = '1' then + RESULT := -RESULT; + end if; + return RESULT; + end function "abs"; + + -- Id: A.2 + function "-" (ARG : SIGNED) return SIGNED is + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : SIGNED(ARG_LEFT downto 0) is ARG; + variable RESULT : SIGNED(ARG_LEFT downto 0); + variable CBIT : BIT := '1'; + begin + if ARG'length < 1 then return NAS; + end if; + for I in 0 to RESULT'left loop + RESULT(I) := not(XARG(I)) xor CBIT; + CBIT := CBIT and not(XARG(I)); + end loop; + return RESULT; + end function "-"; + + -- ============================================================================ + + -- Id: A.3 + function "+" (L, R : UNSIGNED) return UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + return ADD_UNSIGNED(RESIZE(L, SIZE), RESIZE(R, SIZE), '0'); + end function "+"; + + -- Id: A.3R + function "+" (L : UNSIGNED; R : BIT) return UNSIGNED is + variable XR : UNSIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L + XR); + end function "+"; + + -- Id: A.3L + function "+" (L : BIT; R : UNSIGNED) return UNSIGNED is + variable XL : UNSIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL + R); + end function "+"; + + -- Id: A.4 + function "+" (L, R : SIGNED) return SIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + return ADD_SIGNED(RESIZE(L, SIZE), RESIZE(R, SIZE), '0'); + end function "+"; + + -- Id: A.4R + function "+" (L : SIGNED; R : BIT) return SIGNED is + variable XR : SIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L + XR); + end function "+"; + + -- Id: A.4L + function "+" (L : BIT; R : SIGNED) return SIGNED is + variable XL : SIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL + R); + end function "+"; + + -- Id: A.5 + function "+" (L : UNSIGNED; R : NATURAL) return UNSIGNED is + begin + return L + TO_UNSIGNED(R, L'length); + end function "+"; + + -- Id: A.6 + function "+" (L : NATURAL; R : UNSIGNED) return UNSIGNED is + begin + return TO_UNSIGNED(L, R'length) + R; + end function "+"; + + -- Id: A.7 + function "+" (L : SIGNED; R : INTEGER) return SIGNED is + begin + return L + TO_SIGNED(R, L'length); + end function "+"; + + -- Id: A.8 + function "+" (L : INTEGER; R : SIGNED) return SIGNED is + begin + return TO_SIGNED(L, R'length) + R; + end function "+"; + + -- ============================================================================ + + -- Id: A.9 + function "-" (L, R : UNSIGNED) return UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + return ADD_UNSIGNED(RESIZE(L, SIZE), + not(RESIZE(R, SIZE)), + '1'); + end function "-"; + + -- Id: A.9R + function "-" (L : UNSIGNED; R : BIT) return UNSIGNED is + variable XR : UNSIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L - XR); + end function "-"; + + -- Id: A.9L + function "-" (L : BIT; R : UNSIGNED) return UNSIGNED is + variable XL : UNSIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL - R); + end function "-"; + + -- Id: A.10 + function "-" (L, R : SIGNED) return SIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + return ADD_SIGNED(RESIZE(L, SIZE), + not(RESIZE(R, SIZE)), + '1'); + end function "-"; + + -- Id: A.10R + function "-" (L : SIGNED; R : BIT) return SIGNED is + variable XR : SIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L - XR); + end function "-"; + + -- Id: A.10L + function "-" (L : BIT; R : SIGNED) return SIGNED is + variable XL : SIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL - R); + end function "-"; + + -- Id: A.11 + function "-" (L : UNSIGNED; R : NATURAL) return UNSIGNED is + begin + return L - TO_UNSIGNED(R, L'length); + end function "-"; + + -- Id: A.12 + function "-" (L : NATURAL; R : UNSIGNED) return UNSIGNED is + begin + return TO_UNSIGNED(L, R'length) - R; + end function "-"; + + -- Id: A.13 + function "-" (L : SIGNED; R : INTEGER) return SIGNED is + begin + return L - TO_SIGNED(R, L'length); + end function "-"; + + -- Id: A.14 + function "-" (L : INTEGER; R : SIGNED) return SIGNED is + begin + return TO_SIGNED(L, R'length) - R; + end function "-"; + + -- ============================================================================ + + -- Id: A.15 + function "*" (L, R : UNSIGNED) return UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNSIGNED(R_LEFT downto 0) is R; + variable RESULT : UNSIGNED((L'length+R'length-1) downto 0) := (others => '0'); + variable ADVAL : UNSIGNED((L'length+R'length-1) downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + ADVAL := RESIZE(XR, RESULT'length); + for I in 0 to L_LEFT loop + if XL(I) = '1' then RESULT := RESULT + ADVAL; + end if; + ADVAL := SHIFT_LEFT(ADVAL, 1); + end loop; + return RESULT; + end function "*"; + + -- Id: A.16 + function "*" (L, R : SIGNED) return SIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + variable XL : SIGNED(L_LEFT downto 0); + variable XR : SIGNED(R_LEFT downto 0); + variable RESULT : SIGNED((L_LEFT+R_LEFT+1) downto 0) := (others => '0'); + variable ADVAL : SIGNED((L_LEFT+R_LEFT+1) downto 0); + begin + if ((L_LEFT < 0) or (R_LEFT < 0)) then return NAS; + end if; + XL := L; + XR := R; + ADVAL := RESIZE(XR, RESULT'length); + for I in 0 to L_LEFT-1 loop + if XL(I) = '1' then RESULT := RESULT + ADVAL; + end if; + ADVAL := SHIFT_LEFT(ADVAL, 1); + end loop; + if XL(L_LEFT) = '1' then + RESULT := RESULT - ADVAL; + end if; + return RESULT; + end function "*"; + + -- Id: A.17 + function "*" (L : UNSIGNED; R : NATURAL) return UNSIGNED is + begin + return L * TO_UNSIGNED(R, L'length); + end function "*"; + + -- Id: A.18 + function "*" (L : NATURAL; R : UNSIGNED) return UNSIGNED is + begin + return TO_UNSIGNED(L, R'length) * R; + end function "*"; + + -- Id: A.19 + function "*" (L : SIGNED; R : INTEGER) return SIGNED is + begin + return L * TO_SIGNED(R, L'length); + end function "*"; + + -- Id: A.20 + function "*" (L : INTEGER; R : SIGNED) return SIGNED is + begin + return TO_SIGNED(L, R'length) * R; + end function "*"; + + -- ============================================================================ + + -- Id: A.21 + function "/" (L, R : UNSIGNED) return UNSIGNED is + variable FQUOT : UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNSIGNED(R'length-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + DIVMOD(L, R, FQUOT, FREMAIN); + return FQUOT; + end function "/"; + + -- Id: A.22 + function "/" (L, R : SIGNED) return SIGNED is + variable FQUOT : UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNSIGNED(R'length-1 downto 0); + variable XNUM : UNSIGNED(L'length-1 downto 0); + variable XDENOM : UNSIGNED(R'length-1 downto 0); + variable QNEG : BOOLEAN := false; + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + if L(L'left) = '1' then + XNUM := UNSIGNED(-L); + QNEG := true; + else + XNUM := UNSIGNED(L); + end if; + if R(R'left) = '1' then + XDENOM := UNSIGNED(-R); + QNEG := not QNEG; + else + XDENOM := UNSIGNED(R); + end if; + DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); + if QNEG then FQUOT := "0"-FQUOT; + end if; + return SIGNED(FQUOT); + end function "/"; + + -- Id: A.23 + function "/" (L : UNSIGNED; R : NATURAL) return UNSIGNED is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, UNSIGNED_NUM_BITS(R)); + variable XR, QUOT : UNSIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAU; + end if; + if (R_LENGTH > L'length) then + QUOT := (others => '0'); + return RESIZE(QUOT, L'length); + end if; + XR := TO_UNSIGNED(R, R_LENGTH); + QUOT := RESIZE((L / XR), QUOT'length); + return RESIZE(QUOT, L'length); + end function "/"; + + -- Id: A.24 + function "/" (L : NATURAL; R : UNSIGNED) return UNSIGNED is + constant L_LENGTH : NATURAL := MAXIMUM(UNSIGNED_NUM_BITS(L), R'length); + variable XL, QUOT : UNSIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAU; + end if; + XL := TO_UNSIGNED(L, L_LENGTH); + QUOT := RESIZE((XL / R), QUOT'length); + if L_LENGTH > R'length + and QUOT(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => '0') + then + assert NO_WARNING report "NUMERIC_BIT.""/"": Quotient Truncated" + severity warning; + end if; + return RESIZE(QUOT, R'length); + end function "/"; + + -- Id: A.25 + function "/" (L : SIGNED; R : INTEGER) return SIGNED is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, SIGNED_NUM_BITS(R)); + variable XR, QUOT : SIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAS; + end if; + if (R_LENGTH > L'length) then + QUOT := (others => '0'); + return RESIZE(QUOT, L'length); + end if; + XR := TO_SIGNED(R, R_LENGTH); + QUOT := RESIZE((L / XR), QUOT'length); + return RESIZE(QUOT, L'length); + end function "/"; + + -- Id: A.26 + function "/" (L : INTEGER; R : SIGNED) return SIGNED is + constant L_LENGTH : NATURAL := MAXIMUM(SIGNED_NUM_BITS(L), R'length); + variable XL, QUOT : SIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAS; + end if; + XL := TO_SIGNED(L, L_LENGTH); + QUOT := RESIZE((XL / R), QUOT'length); + if L_LENGTH > R'length and QUOT(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => QUOT(R'length-1)) + then + assert NO_WARNING report "NUMERIC_BIT.""/"": Quotient Truncated" + severity warning; + end if; + return RESIZE(QUOT, R'length); + end function "/"; + + -- ============================================================================ + + -- Id: A.27 + function "rem" (L, R : UNSIGNED) return UNSIGNED is + variable FQUOT : UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNSIGNED(R'length-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + DIVMOD(L, R, FQUOT, FREMAIN); + return FREMAIN; + end function "rem"; + + -- Id: A.28 + function "rem" (L, R : SIGNED) return SIGNED is + variable FQUOT : UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNSIGNED(R'length-1 downto 0); + variable XNUM : UNSIGNED(L'length-1 downto 0); + variable XDENOM : UNSIGNED(R'length-1 downto 0); + variable RNEG : BOOLEAN := false; + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + if L(L'left) = '1' then + XNUM := UNSIGNED(-L); + RNEG := true; + else + XNUM := UNSIGNED(L); + end if; + if R(R'left) = '1' then + XDENOM := UNSIGNED(-R); + else + XDENOM := UNSIGNED(R); + end if; + DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); + if RNEG then + FREMAIN := "0"-FREMAIN; + end if; + return SIGNED(FREMAIN); + end function "rem"; + + -- Id: A.29 + function "rem" (L : UNSIGNED; R : NATURAL) return UNSIGNED is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, UNSIGNED_NUM_BITS(R)); + variable XR, XREM : UNSIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAU; + end if; + XR := TO_UNSIGNED(R, R_LENGTH); + XREM := RESIZE((L rem XR), XREM'length); + if R_LENGTH > L'length and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => '0') + then + assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "rem"; + + -- Id: A.30 + function "rem" (L : NATURAL; R : UNSIGNED) return UNSIGNED is + constant L_LENGTH : NATURAL := MAXIMUM(UNSIGNED_NUM_BITS(L), R'length); + variable XL, XREM : UNSIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAU; + end if; + XL := TO_UNSIGNED(L, L_LENGTH); + XREM := RESIZE((XL rem R), XREM'length); + if L_LENGTH > R'length and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => '0') + then + assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "rem"; + + -- Id: A.31 + function "rem" (L : SIGNED; R : INTEGER) return SIGNED is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, SIGNED_NUM_BITS(R)); + variable XR, XREM : SIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAS; + end if; + XR := TO_SIGNED(R, R_LENGTH); + XREM := RESIZE((L rem XR), XREM'length); + if R_LENGTH > L'length and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => XREM(L'length-1)) + then + assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "rem"; + + -- Id: A.32 + function "rem" (L : INTEGER; R : SIGNED) return SIGNED is + constant L_LENGTH : NATURAL := MAXIMUM(SIGNED_NUM_BITS(L), R'length); + variable XL, XREM : SIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAS; + end if; + XL := TO_SIGNED(L, L_LENGTH); + XREM := RESIZE((XL rem R), XREM'length); + if L_LENGTH > R'length and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => XREM(R'length-1)) + then + assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "rem"; + + -- ============================================================================ + + -- Id: A.33 + function "mod" (L, R : UNSIGNED) return UNSIGNED is + variable FQUOT : UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNSIGNED(R'length-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + DIVMOD(L, R, FQUOT, FREMAIN); + return FREMAIN; + end function "mod"; + + -- Id: A.34 + function "mod" (L, R : SIGNED) return SIGNED is + variable FQUOT : UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNSIGNED(R'length-1 downto 0); + variable XNUM : UNSIGNED(L'length-1 downto 0); + variable XDENOM : UNSIGNED(R'length-1 downto 0); + variable RNEG : BOOLEAN := false; + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + if L(L'left) = '1' then + XNUM := UNSIGNED(-L); + else + XNUM := UNSIGNED(L); + end if; + if R(R'left) = '1' then + XDENOM := UNSIGNED(-R); + RNEG := true; + else + XDENOM := UNSIGNED(R); + end if; + DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); + if RNEG and L(L'left) = '1' then + FREMAIN := "0"-FREMAIN; + elsif RNEG and FREMAIN /= "0" then + FREMAIN := FREMAIN-XDENOM; + elsif L(L'left) = '1' and FREMAIN /= "0" then + FREMAIN := XDENOM-FREMAIN; + end if; + return SIGNED(FREMAIN); + end function "mod"; + + -- Id: A.35 + function "mod" (L : UNSIGNED; R : NATURAL) return UNSIGNED is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, UNSIGNED_NUM_BITS(R)); + variable XR, XREM : UNSIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAU; + end if; + XR := TO_UNSIGNED(R, R_LENGTH); + XREM := RESIZE((L mod XR), XREM'length); + if R_LENGTH > L'length and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => '0') + then + assert NO_WARNING report "NUMERIC_BIT.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "mod"; + + -- Id: A.36 + function "mod" (L : NATURAL; R : UNSIGNED) return UNSIGNED is + constant L_LENGTH : NATURAL := MAXIMUM(UNSIGNED_NUM_BITS(L), R'length); + variable XL, XREM : UNSIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAU; + end if; + XL := TO_UNSIGNED(L, L_LENGTH); + XREM := RESIZE((XL mod R), XREM'length); + if L_LENGTH > R'length and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => '0') + then + assert NO_WARNING report "NUMERIC_BIT.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "mod"; + + -- Id: A.37 + function "mod" (L : SIGNED; R : INTEGER) return SIGNED is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, SIGNED_NUM_BITS(R)); + variable XR, XREM : SIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAS; + end if; + XR := TO_SIGNED(R, R_LENGTH); + XREM := RESIZE((L mod XR), XREM'length); + if R_LENGTH > L'length and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => XREM(L'length-1)) + then + assert NO_WARNING report "NUMERIC_BIT.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "mod"; + + -- Id: A.38 + function "mod" (L : INTEGER; R : SIGNED) return SIGNED is + constant L_LENGTH : NATURAL := MAXIMUM(SIGNED_NUM_BITS(L), R'length); + variable XL, XREM : SIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAS; + end if; + XL := TO_SIGNED(L, L_LENGTH); + XREM := RESIZE((XL mod R), XREM'length); + if L_LENGTH > R'length and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => XREM(R'length-1)) + then + assert NO_WARNING report "NUMERIC_BIT.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "mod"; + + -- ============================================================================ + -- Id: A.39 + function find_leftmost (ARG : UNSIGNED; Y : BIT) return INTEGER is + begin + for INDEX in ARG'range loop + if ARG(INDEX) = Y then + return INDEX; + end if; + end loop; + return -1; + end function find_leftmost; + + -- Id: A.40 + function find_leftmost (ARG : SIGNED; Y : BIT) return INTEGER is + begin + for INDEX in ARG'range loop + if ARG(INDEX) = Y then + return INDEX; + end if; + end loop; + return -1; + end function find_leftmost; + + -- Id: A.41 + function find_rightmost (ARG : UNSIGNED; Y : BIT) return INTEGER is + begin + for INDEX in ARG'reverse_range loop + if ARG(INDEX) = Y then + return INDEX; + end if; + end loop; + return -1; + end function find_rightmost; + + -- Id: A.42 + function find_rightmost (ARG : SIGNED; Y : BIT) return INTEGER is + begin + for INDEX in ARG'reverse_range loop + if ARG(INDEX) = Y then + return INDEX; + end if; + end loop; + return -1; + end function find_rightmost; + + -- ============================================================================ + + -- Id: C.1 + function ">" (L, R : UNSIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return not UNSIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function ">"; + + -- Id: C.2 + function ">" (L, R : SIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return not SIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function ">"; + + -- Id: C.3 + function ">" (L : NATURAL; R : UNSIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return true; + end if; + return not UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R'length), R); + end function ">"; + + -- Id: C.4 + function ">" (L : INTEGER; R : SIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L > 0; + end if; + return not SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R'length), R); + end function ">"; + + -- Id: C.5 + function ">" (L : UNSIGNED; R : NATURAL) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return false; + end if; + return not UNSIGNED_LESS_OR_EQUAL(L, TO_UNSIGNED(R, L'length)); + end function ">"; + + -- Id: C.6 + function ">" (L : SIGNED; R : INTEGER) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 > R; + end if; + return not SIGNED_LESS_OR_EQUAL(L, TO_SIGNED(R, L'length)); + end function ">"; + + -- ============================================================================ + + -- Id: C.7 + function "<" (L, R : UNSIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return UNSIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function "<"; + + -- Id: C.8 + function "<" (L, R : SIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return SIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function "<"; + + -- Id: C.9 + function "<" (L : NATURAL; R : UNSIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return UNSIGNED_LESS(TO_UNSIGNED(L, R'length), R); + end function "<"; + + -- Id: C.10 + function "<" (L : INTEGER; R : SIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return SIGNED_LESS(TO_SIGNED(L, R'length), R); + end function "<"; + + -- Id: C.11 + function "<" (L : UNSIGNED; R : NATURAL) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return UNSIGNED_LESS(L, TO_UNSIGNED(R, L'length)); + end function "<"; + + -- Id: C.12 + function "<" (L : SIGNED; R : INTEGER) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return SIGNED_LESS(L, TO_SIGNED(R, L'length)); + end function "<"; + + -- ============================================================================ + + -- Id: C.13 + function "<=" (L, R : UNSIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return UNSIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function "<="; + + -- Id: C.14 + function "<=" (L, R : SIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return SIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function "<="; + + -- Id: C.15 + function "<=" (L : NATURAL; R : UNSIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R'length), R); + end function "<="; + + -- Id: C.16 + function "<=" (L : INTEGER; R : SIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R'length), R); + end function "<="; + + -- Id: C.17 + function "<=" (L : UNSIGNED; R : NATURAL) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return UNSIGNED_LESS_OR_EQUAL(L, TO_UNSIGNED(R, L'length)); + end function "<="; + + -- Id: C.18 + function "<=" (L : SIGNED; R : INTEGER) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return SIGNED_LESS_OR_EQUAL(L, TO_SIGNED(R, L'length)); + end function "<="; + + -- ============================================================================ + + -- Id: C.19 + function ">=" (L, R : UNSIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return not UNSIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function ">="; + + -- Id: C.20 + function ">=" (L, R : SIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return not SIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function ">="; + + -- Id: C.21 + function ">=" (L : NATURAL; R : UNSIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return L > 0; + end if; + return not UNSIGNED_LESS(TO_UNSIGNED(L, R'length), R); + end function ">="; + + -- Id: C.22 + function ">=" (L : INTEGER; R : SIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L > 0; + end if; + return not SIGNED_LESS(TO_SIGNED(L, R'length), R); + end function ">="; + + -- Id: C.23 + function ">=" (L : UNSIGNED; R : NATURAL) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return 0 > R; + end if; + return not UNSIGNED_LESS(L, TO_UNSIGNED(R, L'length)); + end function ">="; + + -- Id: C.24 + function ">=" (L : SIGNED; R : INTEGER) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 > R; + end if; + return not SIGNED_LESS(L, TO_SIGNED(R, L'length)); + end function ">="; + + -- ============================================================================ + + -- Id: C.25 + function "=" (L, R : UNSIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return UNSIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function "="; + + -- Id: C.26 + function "=" (L, R : SIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + return SIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)); + end function "="; + + -- Id: C.27 + function "=" (L : NATURAL; R : UNSIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return false; + end if; + return UNSIGNED_EQUAL(TO_UNSIGNED(L, R'length), R); + end function "="; + + -- Id: C.28 + function "=" (L : INTEGER; R : SIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return false; + end if; + return SIGNED_EQUAL(TO_SIGNED(L, R'length), R); + end function "="; + + -- Id: C.29 + function "=" (L : UNSIGNED; R : NATURAL) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return false; + end if; + return UNSIGNED_EQUAL(L, TO_UNSIGNED(R, L'length)); + end function "="; + + -- Id: C.30 + function "=" (L : SIGNED; R : INTEGER) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return false; + end if; + return SIGNED_EQUAL(L, TO_SIGNED(R, L'length)); + end function "="; + + -- ============================================================================ + + -- Id: C.31 + function "/=" (L, R : UNSIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + return not(UNSIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE))); + end function "/="; + + -- Id: C.32 + function "/=" (L, R : SIGNED) return BOOLEAN is + variable SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_BIT.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + return not(SIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE))); + end function "/="; + + -- Id: C.33 + function "/=" (L : NATURAL; R : UNSIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return true; + end if; + return not(UNSIGNED_EQUAL(TO_UNSIGNED(L, R'length), R)); + end function "/="; + + -- Id: C.34 + function "/=" (L : INTEGER; R : SIGNED) return BOOLEAN is + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + if SIGNED_NUM_BITS(L) > R'length then return true; + end if; + return not(SIGNED_EQUAL(TO_SIGNED(L, R'length), R)); + end function "/="; + + -- Id: C.35 + function "/=" (L : UNSIGNED; R : NATURAL) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return true; + end if; + return not(UNSIGNED_EQUAL(L, TO_UNSIGNED(R, L'length))); + end function "/="; + + -- Id: C.36 + function "/=" (L : SIGNED; R : INTEGER) return BOOLEAN is + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + if SIGNED_NUM_BITS(R) > L'length then return true; + end if; + return not(SIGNED_EQUAL(L, TO_SIGNED(R, L'length))); + end function "/="; + + -- ============================================================================ + + -- Id: C.37 + function MINIMUM (L, R : UNSIGNED) return UNSIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + if UNSIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)) then + return RESIZE(L, SIZE); + else + return RESIZE(R, SIZE); + end if; + end function MINIMUM; + + -- Id: C.38 + function MINIMUM (L, R : SIGNED) return SIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + if SIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)) then + return RESIZE(L, SIZE); + else + return RESIZE(R, SIZE); + end if; + end function MINIMUM; + + -- Id: C.39 + function MINIMUM (L : NATURAL; R : UNSIGNED) return UNSIGNED is + begin + return MINIMUM(TO_UNSIGNED(L, R'length), R); + end function MINIMUM; + + -- Id: C.40 + function MINIMUM (L : INTEGER; R : SIGNED) return SIGNED is + begin + return MINIMUM(TO_SIGNED(L, R'length), R); + end function MINIMUM; + + -- Id: C.41 + function MINIMUM (L : UNSIGNED; R : NATURAL) return UNSIGNED is + begin + return MINIMUM(L, TO_UNSIGNED(R, L'length)); + end function MINIMUM; + + -- Id: C.42 + function MINIMUM (L : SIGNED; R : INTEGER) return SIGNED is + begin + return MINIMUM(L, TO_SIGNED(R, L'length)); + end function MINIMUM; + + -- ============================================================================ + + -- Id: C.43 + function MAXIMUM (L, R : UNSIGNED) return UNSIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + if UNSIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)) then + return RESIZE(R, SIZE); + else + return RESIZE(L, SIZE); + end if; + end function MAXIMUM; + + -- Id: C.44 + function MAXIMUM (L, R : SIGNED) return SIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + if SIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE)) then + return RESIZE(R, SIZE); + else + return RESIZE(L, SIZE); + end if; + end function MAXIMUM; + + -- Id: C.45 + function MAXIMUM (L : NATURAL; R : UNSIGNED) return UNSIGNED is + begin + return MAXIMUM(TO_UNSIGNED(L, R'length), R); + end function MAXIMUM; + + -- Id: C.46 + function MAXIMUM (L : INTEGER; R : SIGNED) return SIGNED is + begin + return MAXIMUM(TO_SIGNED(L, R'length), R); + end function MAXIMUM; + + -- Id: C.47 + function MAXIMUM (L : UNSIGNED; R : NATURAL) return UNSIGNED is + begin + return MAXIMUM(L, TO_UNSIGNED(R, L'length)); + end function MAXIMUM; + + -- Id: C.48 + function MAXIMUM (L : SIGNED; R : INTEGER) return SIGNED is + begin + return MAXIMUM(L, TO_SIGNED(R, L'length)); + end function MAXIMUM; + + -- ============================================================================ + + -- Id: C.49 + function "?>" (L, R : UNSIGNED) return BIT is + begin + if L > R then + return '1'; + else + return '0'; + end if; + end function "?>"; + + -- Id: C.50 + function "?>" (L, R : SIGNED) return BIT is + begin + if L > R then + return '1'; + else + return '0'; + end if; + end function "?>"; + + -- Id: C.51 + function "?>" (L : NATURAL; R : UNSIGNED) return BIT is + begin + if L > R then + return '1'; + else + return '0'; + end if; + end function "?>"; + + -- Id: C.52 + function "?>" (L : INTEGER; R : SIGNED) return BIT is + begin + if L > R then + return '1'; + else + return '0'; + end if; + end function "?>"; + + -- Id: C.53 + function "?>" (L : UNSIGNED; R : NATURAL) return BIT is + begin + if L > R then + return '1'; + else + return '0'; + end if; + end function "?>"; + + -- Id: C.54 + function "?>" (L : SIGNED; R : INTEGER) return BIT is + begin + if L > R then + return '1'; + else + return '0'; + end if; + end function "?>"; + + -- ============================================================================ + + -- Id: C.55 + function "?<" (L, R : UNSIGNED) return BIT is + begin + if L < R then + return '1'; + else + return '0'; + end if; + end function "?<"; + + -- Id: C.56 + function "?<" (L, R : SIGNED) return BIT is + begin + if L < R then + return '1'; + else + return '0'; + end if; + end function "?<"; + + -- Id: C.57 + function "?<" (L : NATURAL; R : UNSIGNED) return BIT is + begin + if L < R then + return '1'; + else + return '0'; + end if; + end function "?<"; + + -- Id: C.58 + function "?<" (L : INTEGER; R : SIGNED) return BIT is + begin + if L < R then + return '1'; + else + return '0'; + end if; + end function "?<"; + + -- Id: C.59 + function "?<" (L : UNSIGNED; R : NATURAL) return BIT is + begin + if L < R then + return '1'; + else + return '0'; + end if; + end function "?<"; + + -- Id: C.60 + function "?<" (L : SIGNED; R : INTEGER) return BIT is + begin + if L < R then + return '1'; + else + return '0'; + end if; + end function "?<"; + + -- ============================================================================ + + -- Id: C.61 + function "?<=" (L, R : UNSIGNED) return BIT is + begin + if L <= R then + return '1'; + else + return '0'; + end if; + end function "?<="; + + -- Id: C.62 + function "?<=" (L, R : SIGNED) return BIT is + begin + if L <= R then + return '1'; + else + return '0'; + end if; + end function "?<="; + + -- Id: C.63 + function "?<=" (L : NATURAL; R : UNSIGNED) return BIT is + begin + if L <= R then + return '1'; + else + return '0'; + end if; + end function "?<="; + + -- Id: C.64 + function "?<=" (L : INTEGER; R : SIGNED) return BIT is + begin + if L <= R then + return '1'; + else + return '0'; + end if; + end function "?<="; + + -- Id: C.65 + function "?<=" (L : UNSIGNED; R : NATURAL) return BIT is + begin + if L <= R then + return '1'; + else + return '0'; + end if; + end function "?<="; + + -- Id: C.66 + function "?<=" (L : SIGNED; R : INTEGER) return BIT is + begin + if L <= R then + return '1'; + else + return '0'; + end if; + end function "?<="; + + -- ============================================================================ + + -- Id: C.67 + function "?>=" (L, R : UNSIGNED) return BIT is + begin + if L >= R then + return '1'; + else + return '0'; + end if; + end function "?>="; + + -- Id: C.68 + function "?>=" (L, R : SIGNED) return BIT is + begin + if L >= R then + return '1'; + else + return '0'; + end if; + end function "?>="; + + -- Id: C.69 + function "?>=" (L : NATURAL; R : UNSIGNED) return BIT is + begin + if L >= R then + return '1'; + else + return '0'; + end if; + end function "?>="; + + -- Id: C.70 + function "?>=" (L : INTEGER; R : SIGNED) return BIT is + begin + if L >= R then + return '1'; + else + return '0'; + end if; + end function "?>="; + + -- Id: C.71 + function "?>=" (L : UNSIGNED; R : NATURAL) return BIT is + begin + if L >= R then + return '1'; + else + return '0'; + end if; + end function "?>="; + + -- Id: C.72 + function "?>=" (L : SIGNED; R : INTEGER) return BIT is + begin + if L >= R then + return '1'; + else + return '0'; + end if; + end function "?>="; + + -- ============================================================================ + + -- Id: C.73 + function "?=" (L, R : UNSIGNED) return BIT is + begin + if L = R then + return '1'; + else + return '0'; + end if; + end function "?="; + + -- Id: C.74 + function "?=" (L, R : SIGNED) return BIT is + begin + if L = R then + return '1'; + else + return '0'; + end if; + end function "?="; + + -- Id: C.75 + function "?=" (L : NATURAL; R : UNSIGNED) return BIT is + begin + if L = R then + return '1'; + else + return '0'; + end if; + end function "?="; + + -- Id: C.76 + function "?=" (L : INTEGER; R : SIGNED) return BIT is + begin + if L = R then + return '1'; + else + return '0'; + end if; + end function "?="; + + -- Id: C.77 + function "?=" (L : UNSIGNED; R : NATURAL) return BIT is + begin + if L = R then + return '1'; + else + return '0'; + end if; + end function "?="; + + -- Id: C.78 + function "?=" (L : SIGNED; R : INTEGER) return BIT is + begin + if L = R then + return '1'; + else + return '0'; + end if; + end function "?="; + + -- ============================================================================ + + -- Id: C.79 + function "?/=" (L, R : UNSIGNED) return BIT is + begin + if L /= R then + return '1'; + else + return '0'; + end if; + end function "?/="; + + -- Id: C.80 + function "?/=" (L, R : SIGNED) return BIT is + begin + if L /= R then + return '1'; + else + return '0'; + end if; + end function "?/="; + + -- Id: C.81 + function "?/=" (L : NATURAL; R : UNSIGNED) return BIT is + begin + if L /= R then + return '1'; + else + return '0'; + end if; + end function "?/="; + + -- Id: C.82 + function "?/=" (L : INTEGER; R : SIGNED) return BIT is + begin + if L /= R then + return '1'; + else + return '0'; + end if; + end function "?/="; + + -- Id: C.83 + function "?/=" (L : UNSIGNED; R : NATURAL) return BIT is + begin + if L /= R then + return '1'; + else + return '0'; + end if; + end function "?/="; + + -- Id: C.84 + function "?/=" (L : SIGNED; R : INTEGER) return BIT is + begin + if L /= R then + return '1'; + else + return '0'; + end if; + end function "?/="; + + -- ============================================================================ + + -- Id: S.1 + function SHIFT_LEFT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNSIGNED(XSLL(BIT_VECTOR(ARG), COUNT)); + end function SHIFT_LEFT; + + -- Id: S.2 + function SHIFT_RIGHT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNSIGNED(XSRL(BIT_VECTOR(ARG), COUNT)); + end function SHIFT_RIGHT; + + -- Id: S.3 + function SHIFT_LEFT (ARG : SIGNED; COUNT : NATURAL) return SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return SIGNED(XSLL(BIT_VECTOR(ARG), COUNT)); + end function SHIFT_LEFT; + + -- Id: S.4 + function SHIFT_RIGHT (ARG : SIGNED; COUNT : NATURAL) return SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return SIGNED(XSRA(BIT_VECTOR(ARG), COUNT)); + end function SHIFT_RIGHT; + + -- ============================================================================ + + -- Id: S.5 + function ROTATE_LEFT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNSIGNED(XROL(BIT_VECTOR(ARG), COUNT)); + end function ROTATE_LEFT; + + -- Id: S.6 + function ROTATE_RIGHT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNSIGNED(XROR(BIT_VECTOR(ARG), COUNT)); + end function ROTATE_RIGHT; + + -- Id: S.7 + function ROTATE_LEFT (ARG : SIGNED; COUNT : NATURAL) return SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return SIGNED(XROL(BIT_VECTOR(ARG), COUNT)); + end function ROTATE_LEFT; + + -- Id: S.8 + function ROTATE_RIGHT (ARG : SIGNED; COUNT : NATURAL) return SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return SIGNED(XROR(BIT_VECTOR(ARG), COUNT)); + end function ROTATE_RIGHT; + + -- ============================================================================ + + ------------------------------------------------------------------------------ + -- Note: Function S.9 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.9 + function "sll" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return SHIFT_RIGHT(ARG, -COUNT); + end if; + end function "sll"; + + ------------------------------------------------------------------------------ + -- Note: Function S.10 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.10 + function "sll" (ARG : SIGNED; COUNT : INTEGER) return SIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), -COUNT)); + end if; + end function "sll"; + + ------------------------------------------------------------------------------ + -- Note: Function S.11 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.11 + function "srl" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_RIGHT(ARG, COUNT); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "srl"; + + ------------------------------------------------------------------------------ + -- Note: Function S.12 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.12 + function "srl" (ARG : SIGNED; COUNT : INTEGER) return SIGNED is + begin + if (COUNT >= 0) then + return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT)); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "srl"; + + ------------------------------------------------------------------------------ + -- Note: Function S.13 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.13 + function "rol" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED is + begin + if (COUNT >= 0) then + return ROTATE_LEFT(ARG, COUNT); + else + return ROTATE_RIGHT(ARG, -COUNT); + end if; + end function "rol"; + + ------------------------------------------------------------------------------ + -- Note: Function S.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.14 + function "rol" (ARG : SIGNED; COUNT : INTEGER) return SIGNED is + begin + if (COUNT >= 0) then + return ROTATE_LEFT(ARG, COUNT); + else + return ROTATE_RIGHT(ARG, -COUNT); + end if; + end function "rol"; + + ------------------------------------------------------------------------------ + -- Note: Function S.15 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.15 + function "ror" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED is + begin + if (COUNT >= 0) then + return ROTATE_RIGHT(ARG, COUNT); + else + return ROTATE_LEFT(ARG, -COUNT); + end if; + end function "ror"; + + ------------------------------------------------------------------------------ + -- Note: Function S.16 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.16 + function "ror" (ARG : SIGNED; COUNT : INTEGER) return SIGNED is + begin + if (COUNT >= 0) then + return ROTATE_RIGHT(ARG, COUNT); + else + return ROTATE_LEFT(ARG, -COUNT); + end if; + end function "ror"; + + ------------------------------------------------------------------------------ + -- Note: Function S.17 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.17 + function "sla" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return SHIFT_RIGHT(ARG, -COUNT); + end if; + end function "sla"; + + ------------------------------------------------------------------------------ + -- Note: Function S.18 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.18 + function "sla" (ARG : SIGNED; COUNT : INTEGER) return SIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return SHIFT_RIGHT(ARG, -COUNT); + end if; + end function "sla"; + + ------------------------------------------------------------------------------ + -- Note: Function S.19 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.19 + function "sra" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_RIGHT(ARG, COUNT); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "sra"; + + ------------------------------------------------------------------------------ + -- Note: Function S.20 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.20 + function "sra" (ARG : SIGNED; COUNT : INTEGER) return SIGNED is + begin + if (COUNT >= 0) then + return SHIFT_RIGHT(ARG, COUNT); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "sra"; + + -- ============================================================================ + + -- Id: D.1 + function TO_INTEGER (ARG : UNSIGNED) return NATURAL is + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : UNSIGNED(ARG_LEFT downto 0) is ARG; + variable RESULT : NATURAL := 0; + begin + if (ARG'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.TO_INTEGER: null detected, returning 0" + severity warning; + return 0; + end if; + for I in XARG'range loop + RESULT := RESULT+RESULT; + if XARG(I) = '1' then + RESULT := RESULT + 1; + end if; + end loop; + return RESULT; + end function TO_INTEGER; + + -- Id: D.2 + function TO_INTEGER (ARG : SIGNED) return INTEGER is + begin + if (ARG'length < 1) then + assert NO_WARNING + report "NUMERIC_BIT.TO_INTEGER: null detected, returning 0" + severity warning; + return 0; + end if; + if ARG(ARG'left) = '0' then + return TO_INTEGER(UNSIGNED(ARG)); + else + return (- (TO_INTEGER(UNSIGNED(- (ARG + 1)))) -1); + end if; + end function TO_INTEGER; + + -- Id: D.3 + function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNSIGNED is + variable RESULT : UNSIGNED(SIZE-1 downto 0); + variable I_VAL : NATURAL := ARG; + begin + if (SIZE < 1) then return NAU; + end if; + for I in 0 to RESULT'left loop + if (I_VAL mod 2) = 0 then + RESULT(I) := '0'; + else RESULT(I) := '1'; + end if; + I_VAL := I_VAL/2; + end loop; + if not(I_VAL = 0) then + assert NO_WARNING + report "NUMERIC_BIT.TO_UNSIGNED: vector truncated" + severity warning; + end if; + return RESULT; + end function TO_UNSIGNED; + + -- Id: D.4 + function TO_SIGNED (ARG : INTEGER; + SIZE : NATURAL) return SIGNED is + variable RESULT : SIGNED(SIZE-1 downto 0); + variable B_VAL : BIT := '0'; + variable I_VAL : INTEGER := ARG; + begin + if (SIZE < 1) then return NAS; + end if; + if (ARG < 0) then + B_VAL := '1'; + I_VAL := -(ARG+1); + end if; + for I in 0 to RESULT'left loop + if (I_VAL mod 2) = 0 then + RESULT(I) := B_VAL; + else + RESULT(I) := not B_VAL; + end if; + I_VAL := I_VAL/2; + end loop; + if ((I_VAL /= 0) or (B_VAL /= RESULT(RESULT'left))) then + assert NO_WARNING + report "NUMERIC_BIT.TO_SIGNED: vector truncated" + severity warning; + end if; + return RESULT; + end function TO_SIGNED; + + function TO_UNSIGNED (ARG : NATURAL; SIZE_RES : UNSIGNED) + return UNSIGNED is + begin + return TO_UNSIGNED (ARG => ARG, + SIZE => SIZE_RES'length); + end function TO_UNSIGNED; + + function TO_SIGNED (ARG : INTEGER; SIZE_RES : SIGNED) + return SIGNED is + begin + return TO_SIGNED (ARG => ARG, + SIZE => SIZE_RES'length); + end function TO_SIGNED; + + -- ============================================================================ + + -- Id: R.1 + function RESIZE (ARG : SIGNED; NEW_SIZE : NATURAL) return SIGNED is + alias INVEC : SIGNED(ARG'length-1 downto 0) is ARG; + variable RESULT : SIGNED(NEW_SIZE-1 downto 0) := (others => '0'); + constant BOUND : INTEGER := MINIMUM(ARG'length, RESULT'length)-2; + begin + if (NEW_SIZE < 1) then return NAS; + end if; + if (ARG'length = 0) then return RESULT; + end if; + RESULT := (others => ARG(ARG'left)); + if BOUND >= 0 then + RESULT(BOUND downto 0) := INVEC(BOUND downto 0); + end if; + return RESULT; + end function RESIZE; + + -- Id: R.2 + function RESIZE (ARG : UNSIGNED; NEW_SIZE : NATURAL) return UNSIGNED is + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : UNSIGNED(ARG_LEFT downto 0) is ARG; + variable RESULT : UNSIGNED(NEW_SIZE-1 downto 0) := (others => '0'); + begin + if (NEW_SIZE < 1) then return NAU; + end if; + if XARG'length = 0 then return RESULT; + end if; + if (RESULT'length < ARG'length) then + RESULT(RESULT'left downto 0) := XARG(RESULT'left downto 0); + else + RESULT(RESULT'left downto XARG'left+1) := (others => '0'); + RESULT(XARG'left downto 0) := XARG; + end if; + return RESULT; + end function RESIZE; + + function RESIZE (ARG, SIZE_RES : UNSIGNED) + return UNSIGNED is + begin + return RESIZE (ARG => ARG, + NEW_SIZE => SIZE_RES'length); + end function RESIZE; + + function RESIZE (ARG, SIZE_RES : SIGNED) + return SIGNED is + begin + return RESIZE (ARG => ARG, + NEW_SIZE => SIZE_RES'length); + end function RESIZE; + + -- ============================================================================ + + -- Id: L.1 + function "not" (L : UNSIGNED) return UNSIGNED is + variable RESULT : UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNSIGNED(not(BIT_VECTOR(L))); + return RESULT; + end function "not"; + + -- Id: L.2 + function "and" (L, R : UNSIGNED) return UNSIGNED is + variable RESULT : UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNSIGNED(BIT_VECTOR(L) and BIT_VECTOR(R)); + return RESULT; + end function "and"; + + -- Id: L.3 + function "or" (L, R : UNSIGNED) return UNSIGNED is + variable RESULT : UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNSIGNED(BIT_VECTOR(L) or BIT_VECTOR(R)); + return RESULT; + end function "or"; + + -- Id: L.4 + function "nand" (L, R : UNSIGNED) return UNSIGNED is + variable RESULT : UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNSIGNED(BIT_VECTOR(L) nand BIT_VECTOR(R)); + return RESULT; + end function "nand"; + + -- Id: L.5 + function "nor" (L, R : UNSIGNED) return UNSIGNED is + variable RESULT : UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNSIGNED(BIT_VECTOR(L) nor BIT_VECTOR(R)); + return RESULT; + end function "nor"; + + -- Id: L.6 + function "xor" (L, R : UNSIGNED) return UNSIGNED is + variable RESULT : UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNSIGNED(BIT_VECTOR(L) xor BIT_VECTOR(R)); + return RESULT; + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.7 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.7 + function "xnor" (L, R : UNSIGNED) return UNSIGNED is + variable RESULT : UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNSIGNED(BIT_VECTOR(L) xnor BIT_VECTOR(R)); + return RESULT; + end function "xnor"; + + -- Id: L.8 + function "not" (L : SIGNED) return SIGNED is + variable RESULT : SIGNED(L'length-1 downto 0); + begin + RESULT := SIGNED(not(BIT_VECTOR(L))); + return RESULT; + end function "not"; + + -- Id: L.9 + function "and" (L, R : SIGNED) return SIGNED is + variable RESULT : SIGNED(L'length-1 downto 0); + begin + RESULT := SIGNED(BIT_VECTOR(L) and BIT_VECTOR(R)); + return RESULT; + end function "and"; + + -- Id: L.10 + function "or" (L, R : SIGNED) return SIGNED is + variable RESULT : SIGNED(L'length-1 downto 0); + begin + RESULT := SIGNED(BIT_VECTOR(L) or BIT_VECTOR(R)); + return RESULT; + end function "or"; + + -- Id: L.11 + function "nand" (L, R : SIGNED) return SIGNED is + variable RESULT : SIGNED(L'length-1 downto 0); + begin + RESULT := SIGNED(BIT_VECTOR(L) nand BIT_VECTOR(R)); + return RESULT; + end function "nand"; + + -- Id: L.12 + function "nor" (L, R : SIGNED) return SIGNED is + variable RESULT : SIGNED(L'length-1 downto 0); + begin + RESULT := SIGNED(BIT_VECTOR(L) nor BIT_VECTOR(R)); + return RESULT; + end function "nor"; + + -- Id: L.13 + function "xor" (L, R : SIGNED) return SIGNED is + variable RESULT : SIGNED(L'length-1 downto 0); + begin + RESULT := SIGNED(BIT_VECTOR(L) xor BIT_VECTOR(R)); + return RESULT; + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.14 + function "xnor" (L, R : SIGNED) return SIGNED is + variable RESULT : SIGNED(L'length-1 downto 0); + begin + RESULT := SIGNED(BIT_VECTOR(L) xnor BIT_VECTOR(R)); + return RESULT; + end function "xnor"; + + -- Id: L.15 + function "and" (L : BIT; R : UNSIGNED) return UNSIGNED is + begin + return UNSIGNED (L and BIT_VECTOR(R)); + end function "and"; + + -- Id: L.16 + function "and" (L : UNSIGNED; R : BIT) return UNSIGNED is + begin + return UNSIGNED (BIT_VECTOR(L) and R); + end function "and"; + + -- Id: L.17 + function "or" (L : BIT; R : UNSIGNED) return UNSIGNED is + begin + return UNSIGNED (L or BIT_VECTOR(R)); + end function "or"; + + -- Id: L.18 + function "or" (L : UNSIGNED; R : BIT) return UNSIGNED is + begin + return UNSIGNED (BIT_VECTOR(L) or R); + end function "or"; + + -- Id: L.19 + function "nand" (L : BIT; R : UNSIGNED) return UNSIGNED is + begin + return UNSIGNED (L nand BIT_VECTOR(R)); + end function "nand"; + + -- Id: L.20 + function "nand" (L : UNSIGNED; R : BIT) return UNSIGNED is + begin + return UNSIGNED (BIT_VECTOR(L) nand R); + end function "nand"; + + -- Id: L.21 + function "nor" (L : BIT; R : UNSIGNED) return UNSIGNED is + begin + return UNSIGNED (L nor BIT_VECTOR(R)); + end function "nor"; + + -- Id: L.22 + function "nor" (L : UNSIGNED; R : BIT) return UNSIGNED is + begin + return UNSIGNED (BIT_VECTOR(L) nor R); + end function "nor"; + + -- Id: L.23 + function "xor" (L : BIT; R : UNSIGNED) return UNSIGNED is + begin + return UNSIGNED (L xor BIT_VECTOR(R)); + end function "xor"; + + -- Id: L.24 + function "xor" (L : UNSIGNED; R : BIT) return UNSIGNED is + begin + return UNSIGNED (BIT_VECTOR(L) xor R); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.25 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.25 + function "xnor" (L : BIT; R : UNSIGNED) return UNSIGNED is + begin + return UNSIGNED (L xnor BIT_VECTOR(R)); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.26 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.26 + function "xnor" (L : UNSIGNED; R : BIT) return UNSIGNED is + begin + return UNSIGNED (BIT_VECTOR(L) xnor R); + end function "xnor"; + + -- Id: L.27 + function "and" (L : BIT; R : SIGNED) return SIGNED is + begin + return SIGNED (L and BIT_VECTOR(R)); + end function "and"; + + -- Id: L.28 + function "and" (L : SIGNED; R : BIT) return SIGNED is + begin + return SIGNED (BIT_VECTOR(L) and R); + end function "and"; + + -- Id: L.29 + function "or" (L : BIT; R : SIGNED) return SIGNED is + begin + return SIGNED (L or BIT_VECTOR(R)); + end function "or"; + + -- Id: L.30 + function "or" (L : SIGNED; R : BIT) return SIGNED is + begin + return SIGNED (BIT_VECTOR(L) or R); + end function "or"; + + -- Id: L.31 + function "nand" (L : BIT; R : SIGNED) return SIGNED is + begin + return SIGNED (L nand BIT_VECTOR(R)); + end function "nand"; + + -- Id: L.32 + function "nand" (L : SIGNED; R : BIT) return SIGNED is + begin + return SIGNED (BIT_VECTOR(L) nand R); + end function "nand"; + + -- Id: L.33 + function "nor" (L : BIT; R : SIGNED) return SIGNED is + begin + return SIGNED (L nor BIT_VECTOR(R)); + end function "nor"; + + -- Id: L.34 + function "nor" (L : SIGNED; R : BIT) return SIGNED is + begin + return SIGNED (BIT_VECTOR(L) nor R); + end function "nor"; + + -- Id: L.35 + function "xor" (L : BIT; R : SIGNED) return SIGNED is + begin + return SIGNED (L xor BIT_VECTOR(R)); + end function "xor"; + + -- Id: L.36 + function "xor" (L : SIGNED; R : BIT) return SIGNED is + begin + return SIGNED (BIT_VECTOR(L) xor R); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.37 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.37 + function "xnor" (L : BIT; R : SIGNED) return SIGNED is + begin + return SIGNED (L xnor BIT_VECTOR(R)); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.38 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.38 + function "xnor" (L : SIGNED; R : BIT) return SIGNED is + begin + return SIGNED (BIT_VECTOR(L) xnor R); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.39 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.39 + function "and" (L : SIGNED) return BIT is + begin + return and (BIT_VECTOR (L)); + end function "and"; + + ------------------------------------------------------------------------------ + -- Note: Function L.40 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.40 + function "and" (L : UNSIGNED) return BIT is + begin + return and (BIT_VECTOR (L)); + end function "and"; + + ------------------------------------------------------------------------------ + -- Note: Function L.41 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.41 + function "nand" (L : SIGNED) return BIT is + begin + return nand (BIT_VECTOR (L)); + end function "nand"; + + ------------------------------------------------------------------------------ + -- Note: Function L.42 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.42 + function "nand" (L : UNSIGNED) return BIT is + begin + return nand (BIT_VECTOR (L)); + end function "nand"; + + ------------------------------------------------------------------------------ + -- Note: Function L.43 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.43 + function "or" (L : SIGNED) return BIT is + begin + return or (BIT_VECTOR (L)); + end function "or"; + + ------------------------------------------------------------------------------ + -- Note: Function L.44 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.44 + function "or" (L : UNSIGNED) return BIT is + begin + return or (BIT_VECTOR (L)); + end function "or"; + + ------------------------------------------------------------------------------ + -- Note: Function L.45 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.45 + function "nor" (L : SIGNED) return BIT is + begin + return nor (BIT_VECTOR (L)); + end function "nor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.46 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.46 + function "nor" (L : UNSIGNED) return BIT is + begin + return nor (BIT_VECTOR (L)); + end function "nor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.47 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.47 + function "xor" (L : SIGNED) return BIT is + begin + return xor (BIT_VECTOR (L)); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.48 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.48 + function "xor" (L : UNSIGNED) return BIT is + begin + return xor (BIT_VECTOR (L)); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.49 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.49 + function "xnor" (L : SIGNED) return BIT is + begin + return xnor (BIT_VECTOR (L)); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.50 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.50 + function "xnor" (L : UNSIGNED) return BIT is + begin + return xnor (BIT_VECTOR (L)); + end function "xnor"; + + -- ============================================================================ + -- string conversion and write operations + -- ============================================================================ + function to_ostring (value : UNSIGNED) return STRING is + begin + return to_ostring(BIT_VECTOR (value)); + end function to_ostring; + + function to_ostring (value : SIGNED) return STRING is + constant result_length : INTEGER := (value'length+2)/3; + constant pad : BIT_VECTOR(1 to (result_length*3 - value'length)) + := (others => value (value'left)); -- Extend sign bit + begin + return to_ostring(pad & BIT_VECTOR (value)); + end function to_ostring; + + function to_hstring (value : UNSIGNED) return STRING is + begin + return to_hstring(BIT_VECTOR (value)); + end function to_hstring; + + function to_hstring (value : SIGNED) return STRING is + constant result_length : INTEGER := (value'length+3)/4; + constant pad : BIT_VECTOR(1 to (result_length*4 - value'length)) + := (others => value (value'left)); -- Extend sign bit + begin + return to_hstring(pad & BIT_VECTOR (value)); + end function to_hstring; + + procedure READ(L : inout LINE; VALUE : out UNSIGNED; GOOD : out BOOLEAN) is + variable ivalue : BIT_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := UNSIGNED(ivalue); + end procedure READ; + + procedure READ(L : inout LINE; VALUE : out UNSIGNED) is + variable ivalue : BIT_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue); + VALUE := UNSIGNED (ivalue); + end procedure READ; + + procedure READ(L : inout LINE; VALUE : out SIGNED; GOOD : out BOOLEAN) is + variable ivalue : BIT_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := SIGNED(ivalue); + end procedure READ; + + procedure READ(L : inout LINE; VALUE : out SIGNED) is + variable ivalue : BIT_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue); + VALUE := SIGNED (ivalue); + end procedure READ; + + procedure WRITE (L : inout LINE; VALUE : in UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : BIT_VECTOR(value'range); + begin + ivalue := BIT_VECTOR (VALUE); + WRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure WRITE; + + procedure WRITE (L : inout LINE; VALUE : in SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : BIT_VECTOR(value'range); + begin + ivalue := BIT_VECTOR (VALUE); + WRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure WRITE; + + procedure OREAD (L : inout LINE; VALUE : out UNSIGNED; GOOD : out BOOLEAN) is + variable ivalue : BIT_VECTOR(value'range); + begin + OREAD (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := UNSIGNED(ivalue); + end procedure OREAD; + + procedure OREAD (L : inout LINE; VALUE : out SIGNED; GOOD : out BOOLEAN) is + constant ne : INTEGER := (value'length+2)/3; + constant pad : INTEGER := ne*3 - value'length; + variable ivalue : BIT_VECTOR(0 to ne*3-1); + variable ok : BOOLEAN; + begin + OREAD (L => L, + VALUE => ivalue, -- Read padded STRING + good => ok); + -- Bail out if there was a bad read + if not ok then + good := false; + return; + end if; + if (pad > 0) then + if (ivalue(0) = '0') then -- positive + if ivalue(0) = or (ivalue(0 to pad)) then + VALUE := SIGNED (ivalue (pad to ivalue'high)); + good := true; + else + good := false; + end if; + else -- negative + if ivalue(0) = and (ivalue(0 to pad)) then + VALUE := SIGNED (ivalue (pad to ivalue'high)); + good := true; + else + good := false; + end if; + end if; + else + good := true; + VALUE := SIGNED (ivalue); + end if; + end procedure OREAD; + + procedure OREAD (L : inout LINE; VALUE : out UNSIGNED) is + variable ivalue : BIT_VECTOR(value'range); + begin + OREAD (L => L, + VALUE => ivalue); + VALUE := UNSIGNED (ivalue); + end procedure OREAD; + + procedure OREAD (L : inout LINE; VALUE : out SIGNED) is + constant ne : INTEGER := (value'length+2)/3; + constant pad : INTEGER := ne*3 - value'length; + variable ivalue : BIT_VECTOR(0 to ne*3-1); + begin + OREAD (L => L, + VALUE => ivalue); -- Read padded string + if (pad > 0) then + if (ivalue(0) = '0') then -- positive + if ivalue(0) = or (ivalue(0 to pad)) then + VALUE := SIGNED (ivalue (pad to ivalue'high)); + else + assert false + report "NUMERIC_BIT.OREAD Error: Signed vector truncated" + severity error; + end if; + else -- negative + if ivalue(0) = and (ivalue(0 to pad)) then + VALUE := SIGNED (ivalue (pad to ivalue'high)); + else + assert false + report "NUMERIC_BIT.OREAD Error: Signed vector truncated" + severity error; + end if; + end if; + else + VALUE := SIGNED (ivalue); + end if; + end procedure OREAD; + + procedure HREAD (L : inout LINE; VALUE : out UNSIGNED; GOOD : out BOOLEAN) is + variable ivalue : BIT_VECTOR(value'range); + begin + HREAD (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := UNSIGNED(ivalue); + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out SIGNED; GOOD : out BOOLEAN) is + constant ne : INTEGER := (value'length+3)/4; + constant pad : INTEGER := ne*4 - value'length; + variable ivalue : BIT_VECTOR(0 to ne*4-1); + variable ok : BOOLEAN; + begin + HREAD (L => L, + VALUE => ivalue, -- Read padded STRING + good => ok); + if not ok then + good := false; + return; + end if; + if (pad > 0) then + if (ivalue(0) = '0') then -- positive + if ivalue(0) = or (ivalue(0 to pad)) then + GOOD := true; + VALUE := SIGNED (ivalue (pad to ivalue'high)); + else + GOOD := false; + end if; + else -- negative + if ivalue(0) = and (ivalue(0 to pad)) then + GOOD := true; + VALUE := SIGNED (ivalue (pad to ivalue'high)); + else + GOOD := false; + end if; + end if; + else + GOOD := true; + VALUE := SIGNED (ivalue); + end if; + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out UNSIGNED) is + variable ivalue : BIT_VECTOR(value'range); + begin + HREAD (L => L, + VALUE => ivalue); + VALUE := UNSIGNED (ivalue); + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out SIGNED) is + constant ne : INTEGER := (value'length+3)/4; + constant pad : INTEGER := ne*4 - value'length; + variable ivalue : BIT_VECTOR(0 to ne*4-1); + begin + HREAD (L => L, + VALUE => ivalue); -- Read padded string + if (pad > 0) then + if (ivalue(0) = '0') then -- positive + if ivalue(0) = or (ivalue(0 to pad)) then + VALUE := SIGNED (ivalue (pad to ivalue'high)); + else + assert false + report "NUMERIC_BIT.HREAD Error: Signed vector truncated" + severity error; + end if; + else -- negative + if ivalue(0) = and (ivalue(0 to pad)) then + VALUE := SIGNED (ivalue (pad to ivalue'high)); + else + assert false + report "NUMERIC_BIT.HREAD Error: Signed vector truncated" + severity error; + end if; + end if; + else + VALUE := SIGNED (ivalue); + end if; + end procedure HREAD; + + procedure OWRITE (L : inout LINE; VALUE : in UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : BIT_VECTOR(value'range); + begin + ivalue := BIT_VECTOR (VALUE); + OWRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure OWRITE; + + procedure OWRITE (L : inout LINE; VALUE : in SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + constant ne : INTEGER := (VALUE'length+2)/3; + constant pad : BIT_VECTOR(0 to (ne*3 - VALUE'length) - 1) + := (others => VALUE (VALUE'left)); + variable ivalue : BIT_VECTOR(value'range); + begin + ivalue := BIT_VECTOR (VALUE); + OWRITE (L => L, + VALUE => pad & ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure OWRITE; + + procedure HWRITE (L : inout LINE; VALUE : in UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : BIT_VECTOR(value'range); + begin + ivalue := BIT_VECTOR (VALUE); + HWRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure HWRITE; + + procedure HWRITE (L : inout LINE; VALUE : in SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : BIT_VECTOR(value'range); + constant ne : INTEGER := (value'length+3)/4; + constant pad : BIT_VECTOR(0 to (ne*4 - value'length) - 1) + := (others => VALUE(VALUE'left)); + begin + ivalue := BIT_VECTOR (VALUE); + HWRITE (L => L, + VALUE => pad & ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure HWRITE; + +end package body NUMERIC_BIT; diff --git a/libraries/ieee2008/numeric_bit.vhdl b/libraries/ieee2008/numeric_bit.vhdl new file mode 100644 index 000000000..fa28d6385 --- /dev/null +++ b/libraries/ieee2008/numeric_bit.vhdl @@ -0,0 +1,1589 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Synthesis Packages +-- : (NUMERIC_BIT package declaration) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC Synthesis Working Group, +-- : Accellera VHDL-TC, and IEEE P1076 Working Group +-- : +-- Purpose : This package defines numeric types and arithmetic functions +-- : for use with synthesis tools. Two numeric types are defined: +-- : -- > UNSIGNED: represents an UNSIGNED number in vector form +-- : -- > SIGNED: represents a SIGNED number in vector form +-- : The base element type is type BIT. +-- : The leftmost bit is treated as the most significant bit. +-- : Signed vectors are represented in two's complement form. +-- : This package contains overloaded arithmetic operators on +-- : the SIGNED and UNSIGNED types. The package also contains +-- : useful type conversions functions, clock detection +-- : functions, and other utility functions. +-- : +-- : If any argument to a function is a null array, a null array +-- : is returned (exceptions, if any, are noted individually). +-- +-- 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) $ +-- -------------------------------------------------------------------- + +use STD.TEXTIO.all; + +package NUMERIC_BIT is + constant CopyRightNotice : STRING + := "Copyright 2008 IEEE. All rights reserved."; + + --============================================================================ + -- Numeric Array Type Definitions + --============================================================================ + + type UNSIGNED is array (NATURAL range <>) of BIT; + type SIGNED is array (NATURAL range <>) of BIT; + + --============================================================================ + -- Arithmetic Operators: + --============================================================================ + + -- Id: A.1 + function "abs" (ARG : SIGNED) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Returns the absolute value of a SIGNED vector ARG. + + -- Id: A.2 + function "-" (ARG : SIGNED) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Returns the value of the unary minus operation on a + -- SIGNED vector ARG. + + --============================================================================ + + -- Id: A.3 + function "+" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Adds two UNSIGNED vectors that may be of different lengths. + + -- Id: A.3R + function "+"(L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.3 where R is a one bit UNSIGNED + + -- Id: A.3L + function "+"(L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.3 where L is a one bit UNSIGNED + + -- Id: A.4 + function "+" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Adds two SIGNED vectors that may be of different lengths. + + -- Id: A.4R + function "+"(L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.4 where R is bit 0 of a non-negative. + + -- Id: A.4L + function "+"(L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.4 where L is bit 0 of a non-negative. + + -- Id: A.5 + function "+" (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Adds an UNSIGNED vector, L, with a nonnegative INTEGER, R. + + -- Id: A.6 + function "+" (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Adds a nonnegative INTEGER, L, with an UNSIGNED vector, R. + + -- Id: A.7 + function "+" (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Adds an INTEGER, L(may be positive or negative), to a SIGNED + -- vector, R. + + -- Id: A.8 + function "+" (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Adds a SIGNED vector, L, to an INTEGER, R. + + --============================================================================ + + -- Id: A.9 + function "-" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Subtracts two UNSIGNED vectors that may be of different lengths. + + -- Id: A.9R + function "-"(L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.9 where R is a one bit UNSIGNED + + -- Id: A.9L + function "-"(L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.9 where L is a one bit UNSIGNED + + -- Id: A.10 + function "-" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Subtracts a SIGNED vector, R, from another SIGNED vector, L, + -- that may possibly be of different lengths. + + -- Id: A.10R + function "-"(L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.10 where R is bit 0 of a non-negative. + + -- Id: A.10L + function "-"(L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.10 where R is bit 0 of a non-negative. + + -- Id: A.11 + function "-" (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Subtracts a nonnegative INTEGER, R, from an UNSIGNED vector, L. + + -- Id: A.12 + function "-" (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Subtracts an UNSIGNED vector, R, from a nonnegative INTEGER, L. + + -- Id: A.13 + function "-" (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Subtracts an INTEGER, R, from a SIGNED vector, L. + + -- Id: A.14 + function "-" (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Subtracts a SIGNED vector, R, from an INTEGER, L. + + --============================================================================ + + -- Id: A.15 + function "*" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0) + -- Result: Performs the multiplication operation on two UNSIGNED vectors + -- that may possibly be of different lengths. + + -- Id: A.16 + function "*" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED((L'LENGTH+R'LENGTH-1) downto 0) + -- Result: Multiplies two SIGNED vectors that may possibly be of + -- different lengths. + + -- Id: A.17 + function "*" (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0) + -- Result: Multiplies an UNSIGNED vector, L, with a nonnegative + -- INTEGER, R. R is converted to an UNSIGNED vector of + -- size L'LENGTH before multiplication. + + -- Id: A.18 + function "*" (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0) + -- Result: Multiplies an UNSIGNED vector, R, with a nonnegative + -- INTEGER, L. L is converted to an UNSIGNED vector of + -- size R'LENGTH before multiplication. + + -- Id: A.19 + function "*" (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED((L'LENGTH+L'LENGTH-1) downto 0) + -- Result: Multiplies a SIGNED vector, L, with an INTEGER, R. R is + -- converted to a SIGNED vector of size L'LENGTH before + -- multiplication. + + -- Id: A.20 + function "*" (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED((R'LENGTH+R'LENGTH-1) downto 0) + -- Result: Multiplies a SIGNED vector, R, with an INTEGER, L. L is + -- converted to a SIGNED vector of size R'LENGTH before + -- multiplication. + + --============================================================================ + -- + -- NOTE: If second argument is zero for "/" operator, a severity level + -- of ERROR is issued. + + -- Id: A.21 + function "/" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R. + + -- Id: A.22 + function "/" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Divides an SIGNED vector, L, by another SIGNED vector, R. + + -- Id: A.23 + function "/" (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Divides an UNSIGNED vector, L, by a nonnegative INTEGER, R. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.24 + function "/" (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Divides a nonnegative INTEGER, L, by an UNSIGNED vector, R. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + -- Id: A.25 + function "/" (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Divides a SIGNED vector, L, by an INTEGER, R. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.26 + function "/" (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Divides an INTEGER, L, by a SIGNED vector, R. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + --============================================================================ + -- + -- NOTE: If second argument is zero for "rem" operator, a severity level + -- of ERROR is issued. + + -- Id: A.27 + function "rem" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L and R are UNSIGNED vectors. + + -- Id: A.28 + function "rem" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L and R are SIGNED vectors. + + -- Id: A.29 + function "rem" (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L is an UNSIGNED vector and R is a + -- nonnegative INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.30 + function "rem" (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where R is an UNSIGNED vector and L is a + -- nonnegative INTEGER. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + -- Id: A.31 + function "rem" (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L is SIGNED vector and R is an INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.32 + function "rem" (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where R is SIGNED vector and L is an INTEGER. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + --============================================================================ + -- + -- NOTE: If second argument is zero for "mod" operator, a severity level + -- of ERROR is issued. + + -- Id: A.33 + function "mod" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L and R are UNSIGNED vectors. + + -- Id: A.34 + function "mod" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L and R are SIGNED vectors. + + -- Id: A.35 + function "mod" (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L is an UNSIGNED vector and R + -- is a nonnegative INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.36 + function "mod" (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where R is an UNSIGNED vector and L + -- is a nonnegative INTEGER. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + -- Id: A.37 + function "mod" (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L is a SIGNED vector and + -- R is an INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.38 + function "mod" (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L is an INTEGER and + -- R is a SIGNED vector. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + --============================================================================ + -- Id: A.39 + function find_leftmost (ARG : UNSIGNED; Y : BIT) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + -- Id: A.40 + function find_leftmost (ARG : SIGNED; Y : BIT) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + -- Id: A.41 + function find_rightmost (ARG : UNSIGNED; Y : BIT) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + -- Id: A.42 + function find_rightmost (ARG : SIGNED; Y : BIT) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + --============================================================================ + -- Comparison Operators + --============================================================================ + + -- Id: C.1 + function ">" (L, R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.2 + function ">" (L, R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.3 + function ">" (L : NATURAL; R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.4 + function ">" (L : INTEGER; R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is a INTEGER and + -- R is a SIGNED vector. + + -- Id: C.5 + function ">" (L : UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.6 + function ">" (L : SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is a SIGNED vector and + -- R is a INTEGER. + + --============================================================================ + + -- Id: C.7 + function "<" (L, R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.8 + function "<" (L, R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.9 + function "<" (L : NATURAL; R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.10 + function "<" (L : INTEGER; R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.11 + function "<" (L : UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.12 + function "<" (L : SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.13 + function "<=" (L, R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.14 + function "<=" (L, R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.15 + function "<=" (L : NATURAL; R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.16 + function "<=" (L : INTEGER; R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.17 + function "<=" (L : UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.18 + function "<=" (L : SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.19 + function ">=" (L, R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.20 + function ">=" (L, R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.21 + function ">=" (L : NATURAL; R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.22 + function ">=" (L : INTEGER; R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.23 + function ">=" (L : UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.24 + function ">=" (L : SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.25 + function "=" (L, R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.26 + function "=" (L, R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.27 + function "=" (L : NATURAL; R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.28 + function "=" (L : INTEGER; R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.29 + function "=" (L : UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.30 + function "=" (L : SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.31 + function "/=" (L, R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.32 + function "/=" (L, R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.33 + function "/=" (L : NATURAL; R : UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.34 + function "/=" (L : INTEGER; R : SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.35 + function "/=" (L : UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.36 + function "/=" (L : SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.37 + function MINIMUM (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED + -- Result: Returns the lesser of two UNSIGNED vectors that may be + -- of different lengths. + + -- Id: C.38 + function MINIMUM (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED + -- Result: Returns the lesser of two SIGNED vectors that may be + -- of different lengths. + + -- Id: C.39 + function MINIMUM (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED + -- Result: Returns the lesser of a nonnegative INTEGER, L, and + -- an UNSIGNED vector, R. + + -- Id: C.40 + function MINIMUM (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED + -- Result: Returns the lesser of an INTEGER, L, and a SIGNED + -- vector, R. + + -- Id: C.41 + function MINIMUM (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED + -- Result: Returns the lesser of an UNSIGNED vector, L, and + -- a nonnegative INTEGER, R. + + -- Id: C.42 + function MINIMUM (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED + -- Result: Returns the lesser of a SIGNED vector, L, and + -- an INTEGER, R. + + --============================================================================ + + -- Id: C.43 + function MAXIMUM (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED + -- Result: Returns the greater of two UNSIGNED vectors that may be + -- of different lengths. + + -- Id: C.44 + function MAXIMUM (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED + -- Result: Returns the greater of two SIGNED vectors that may be + -- of different lengths. + + -- Id: C.45 + function MAXIMUM (L : NATURAL; R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED + -- Result: Returns the greater of a nonnegative INTEGER, L, and + -- an UNSIGNED vector, R. + + -- Id: C.46 + function MAXIMUM (L : INTEGER; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED + -- Result: Returns the greater of an INTEGER, L, and a SIGNED + -- vector, R. + + -- Id: C.47 + function MAXIMUM (L : UNSIGNED; R : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED + -- Result: Returns the greater of an UNSIGNED vector, L, and + -- a nonnegative INTEGER, R. + + -- Id: C.48 + function MAXIMUM (L : SIGNED; R : INTEGER) return SIGNED; + -- Result subtype: SIGNED + -- Result: Returns the greater of a SIGNED vector, L, and + -- an INTEGER, R. + + --============================================================================ + + -- Id: C.49 + function "?>" (L, R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.50 + function "?>" (L, R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L > R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.51 + function "?>" (L : NATURAL; R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L > R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.52 + function "?>" (L : INTEGER; R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L > R" where L is a INTEGER and + -- R is a SIGNED vector. + + -- Id: C.53 + function "?>" (L : UNSIGNED; R : NATURAL) return BIT; + -- Result subtype: BIT + -- Result: Computes "L > R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.54 + function "?>" (L : SIGNED; R : INTEGER) return BIT; + -- Result subtype: BIT + -- Result: Computes "L > R" where L is a SIGNED vector and + -- R is a INTEGER. + + --============================================================================ + + -- Id: C.55 + function "?<" (L, R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.56 + function "?<" (L, R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L < R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.57 + function "?<" (L : NATURAL; R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L < R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.58 + function "?<" (L : INTEGER; R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L < R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.59 + function "?<" (L : UNSIGNED; R : NATURAL) return BIT; + -- Result subtype: BIT + -- Result: Computes "L < R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.60 + function "?<" (L : SIGNED; R : INTEGER) return BIT; + -- Result subtype: BIT + -- Result: Computes "L < R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.61 + function "?<=" (L, R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.62 + function "?<=" (L, R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L <= R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.63 + function "?<=" (L : NATURAL; R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L <= R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.64 + function "?<=" (L : INTEGER; R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L <= R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.65 + function "?<=" (L : UNSIGNED; R : NATURAL) return BIT; + -- Result subtype: BIT + -- Result: Computes "L <= R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.66 + function "?<=" (L : SIGNED; R : INTEGER) return BIT; + -- Result subtype: BIT + -- Result: Computes "L <= R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.67 + function "?>=" (L, R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.68 + function "?>=" (L, R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L >= R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.69 + function "?>=" (L : NATURAL; R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L >= R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.70 + function "?>=" (L : INTEGER; R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L >= R" where L is an INTEGER and + -- R is a SIGNED vector. + + -- Id: C.71 + function "?>=" (L : UNSIGNED; R : NATURAL) return BIT; + -- Result subtype: BIT + -- Result: Computes "L >= R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.72 + function "?>=" (L : SIGNED; R : INTEGER) return BIT; + -- Result subtype: BIT + -- Result: Computes "L >= R" where L is a SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.73 + function "?=" (L, R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.74 + function "?=" (L, R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L = R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.75 + function "?=" (L : NATURAL; R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L = R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.76 + function "?=" (L : INTEGER; R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L = R" where L is an INTEGER and + -- R is an SIGNED vector. + + -- Id: C.77 + function "?=" (L : UNSIGNED; R : NATURAL) return BIT; + -- Result subtype: BIT + -- Result: Computes "L = R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.78 + function "?=" (L : SIGNED; R : INTEGER) return BIT; + -- Result subtype: BIT + -- Result: Computes "L = R" where L is an SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.79 + function "?/=" (L, R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.80 + function "?/=" (L, R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L /= R" where L and R are SIGNED vectors possibly + -- of different lengths. + + -- Id: C.81 + function "?/=" (L : NATURAL; R : UNSIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L /= R" where L is a nonnegative INTEGER and + -- R is an UNSIGNED vector. + + -- Id: C.82 + function "?/=" (L : INTEGER; R : SIGNED) return BIT; + -- Result subtype: BIT + -- Result: Computes "L /= R" where L is an INTEGER and + -- R is an SIGNED vector. + + -- Id: C.83 + function "?/=" (L : UNSIGNED; R : NATURAL) return BIT; + -- Result subtype: BIT + -- Result: Computes "L /= R" where L is an UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.84 + function "?/=" (L : SIGNED; R : INTEGER) return BIT; + -- Result subtype: BIT + -- Result: Computes "L /= R" where L is an SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + -- Shift and Rotate Functions + --============================================================================ + + -- Id: S.1 + function SHIFT_LEFT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-left on an UNSIGNED vector COUNT times. + -- The vacated positions are filled with Bit '0'. + -- The COUNT leftmost bits are lost. + + -- Id: S.2 + function SHIFT_RIGHT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-right on an UNSIGNED vector COUNT times. + -- The vacated positions are filled with Bit '0'. + -- The COUNT rightmost bits are lost. + + -- Id: S.3 + function SHIFT_LEFT (ARG : SIGNED; COUNT : NATURAL) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-left on a SIGNED vector COUNT times. + -- The vacated positions are filled with Bit '0'. + -- The COUNT leftmost bits are lost. + + -- Id: S.4 + function SHIFT_RIGHT (ARG : SIGNED; COUNT : NATURAL) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-right on a SIGNED vector COUNT times. + -- The vacated positions are filled with the leftmost bit, ARG'LEFT. + -- The COUNT rightmost bits are lost. + + --============================================================================ + + -- Id: S.5 + function ROTATE_LEFT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a rotate-left of an UNSIGNED vector COUNT times. + + -- Id: S.6 + function ROTATE_RIGHT (ARG : UNSIGNED; COUNT : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a rotate-right of an UNSIGNED vector COUNT times. + + -- Id: S.7 + function ROTATE_LEFT (ARG : SIGNED; COUNT : NATURAL) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a logical rotate-left of a SIGNED vector COUNT times. + + -- Id: S.8 + function ROTATE_RIGHT (ARG : SIGNED; COUNT : NATURAL) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a logical rotate-right of a SIGNED vector COUNT times. + + --============================================================================ + + ------------------------------------------------------------------------------ + -- Note: Function S.9 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.9 + function "sll" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.10 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.10 + function "sll" (ARG : SIGNED; COUNT : INTEGER) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.11 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.11 + function "srl" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.12 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.12 + function "srl" (ARG : SIGNED; COUNT : INTEGER) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT)) + + ------------------------------------------------------------------------------ + -- Note: Function S.13 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.13 + function "rol" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.14 + function "rol" (ARG : SIGNED; COUNT : INTEGER) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.15 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.15 + function "ror" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.16 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.16 + function "ror" (ARG : SIGNED; COUNT : INTEGER) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.17 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.17 + function "sla" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.18 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.18 + function "sla" (ARG : SIGNED; COUNT : INTEGER) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.19 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.19 + function "sra" (ARG : UNSIGNED; COUNT : INTEGER) return UNSIGNED; + -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.20 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.20 + function "sra" (ARG : SIGNED; COUNT : INTEGER) return SIGNED; + -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_RIGHT(ARG, COUNT) + + --============================================================================ + -- RESIZE Functions + --============================================================================ + + -- Id: R.1 + function RESIZE (ARG : SIGNED; NEW_SIZE : NATURAL) return SIGNED; + -- Result subtype: SIGNED(NEW_SIZE-1 downto 0) + -- Result: Resizes the SIGNED vector ARG to the specified size. + -- To create a larger vector, the new [leftmost] bit positions + -- are filled with the sign bit (ARG'LEFT). When truncating, + -- the sign bit is retained along with the rightmost part. + + -- Id: R.2 + function RESIZE (ARG : UNSIGNED; NEW_SIZE : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(NEW_SIZE-1 downto 0) + -- Result: Resizes the UNSIGNED vector ARG to the specified size. + -- To create a larger vector, the new [leftmost] bit positions + -- are filled with '0'. When truncating, the leftmost bits + -- are dropped. + + function RESIZE (ARG, SIZE_RES : UNSIGNED) return UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED (SIZE_RES'length-1 downto 0) + + function RESIZE (ARG, SIZE_RES : SIGNED) return SIGNED; + -- Result subtype: UNRESOLVED_SIGNED (SIZE_RES'length-1 downto 0) + + --============================================================================ + -- Conversion Functions + --============================================================================ + + -- Id: D.1 + function TO_INTEGER (ARG : UNSIGNED) return NATURAL; + -- Result subtype: NATURAL. Value cannot be negative since parameter is an + -- UNSIGNED vector. + -- Result: Converts the UNSIGNED vector to an INTEGER. + + -- Id: D.2 + function TO_INTEGER (ARG : SIGNED) return INTEGER; + -- Result subtype: INTEGER + -- Result: Converts a SIGNED vector to an INTEGER. + + -- Id: D.3 + function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNSIGNED; + -- Result subtype: UNSIGNED(SIZE-1 downto 0) + -- Result: Converts a nonnegative INTEGER to an UNSIGNED vector with + -- the specified size. + + -- Id: D.4 + function TO_SIGNED (ARG : INTEGER; SIZE : NATURAL) return SIGNED; + -- Result subtype: SIGNED(SIZE-1 downto 0) + -- Result: Converts an INTEGER to a SIGNED vector of the specified size. + + function TO_UNSIGNED (ARG : NATURAL; SIZE_RES : UNSIGNED) return UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(SIZE_RES'length-1 downto 0) + + function TO_SIGNED (ARG : INTEGER; SIZE_RES : SIGNED) return SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(SIZE_RES'length-1 downto 0) + + --============================================================================ + -- Logical Operators + --============================================================================ + + -- Id: L.1 + function "not" (L : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Termwise inversion + + -- Id: L.2 + function "and" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector AND operation + + -- Id: L.3 + function "or" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector OR operation + + -- Id: L.4 + function "nand" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NAND operation + + -- Id: L.5 + function "nor" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NOR operation + + -- Id: L.6 + function "xor" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.7 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.7 + function "xnor" (L, R : UNSIGNED) return UNSIGNED; + -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XNOR operation + + -- Id: L.8 + function "not" (L : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Termwise inversion + + -- Id: L.9 + function "and" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector AND operation + + -- Id: L.10 + function "or" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector OR operation + + -- Id: L.11 + function "nand" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NAND operation + + -- Id: L.12 + function "nor" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NOR operation + + -- Id: L.13 + function "xor" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.14 + function "xnor" (L, R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XNOR operation + + -- Id: L.15 + function "and" (L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector AND operation + + -- Id: L.16 + function "and" (L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar AND operation + + -- Id: L.17 + function "or" (L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector OR operation + + -- Id: L.18 + function "or" (L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar OR operation + + -- Id: L.19 + function "nand" (L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NAND operation + + -- Id: L.20 + function "nand" (L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NAND operation + + -- Id: L.21 + function "nor" (L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NOR operation + + -- Id: L.22 + function "nor" (L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NOR operation + + -- Id: L.23 + function "xor" (L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XOR operation + + -- Id: L.24 + function "xor" (L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.25 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.25 + function "xnor" (L : BIT; R : UNSIGNED) return UNSIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XNOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.26 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.26 + function "xnor" (L : UNSIGNED; R : BIT) return UNSIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XNOR operation + + -- Id: L.27 + function "and" (L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector AND operation + + -- Id: L.28 + function "and" (L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar AND operation + + -- Id: L.29 + function "or" (L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector OR operation + + -- Id: L.30 + function "or" (L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar OR operation + + -- Id: L.31 + function "nand" (L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NAND operation + + -- Id: L.32 + function "nand" (L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NAND operation + + -- Id: L.33 + function "nor" (L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NOR operation + + -- Id: L.34 + function "nor" (L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NOR operation + + -- Id: L.35 + function "xor" (L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XOR operation + + -- Id: L.36 + function "xor" (L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.37 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.37 + function "xnor" (L : BIT; R : SIGNED) return SIGNED; + -- Result subtype: SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XNOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.38 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.38 + function "xnor" (L : SIGNED; R : BIT) return SIGNED; + -- Result subtype: SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XNOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.39 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.39 + function "and" (L : SIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of and'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.40 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.40 + function "nand" (L : SIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of nand'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.41 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.41 + function "or" (L : SIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of or'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.42 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.42 + function "nor" (L : SIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of nor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.43 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.43 + function "xor" (L : SIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of xor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.44 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.44 + function "xnor" (L : SIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of xnor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.45 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.45 + function "and" (L : UNSIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of and'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.46 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.46 + function "nand" (L : UNSIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of nand'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.47 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.47 + function "or" (L : UNSIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of or'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.48 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.48 + function "nor" (L : UNSIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of nor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.49 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.49 + function "xor" (L : UNSIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of xor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.50 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.50 + function "xnor" (L : UNSIGNED) return BIT; + -- Result subtype: BIT. + -- Result: Result of xnor'ing all of the bits of the vector. + + --============================================================================ + -- Edge Detection Functions + --============================================================================ + + -- Id: E.1 + alias RISING_EDGE is STD.STANDARD.RISING_EDGE + [STD.STANDARD.BIT return STD.STANDARD.BOOLEAN]; + -- Result subtype: BOOLEAN + -- Result: Returns TRUE if an event is detected on signal S and the + -- value changed from a '0' to a '1'. + + -- Id: E.2 + alias FALLING_EDGE is STD.STANDARD.FALLING_EDGE + [STD.STANDARD.BIT return STD.STANDARD.BOOLEAN]; + -- Result subtype: BOOLEAN + -- Result: Returns TRUE if an event is detected on signal S and the + -- value changed from a '1' to a '0'. + + --============================================================================ + -- string conversion and write operations + --============================================================================ + -- the following operations are predefined + + -- FUNCTION to_string ( value : UNSIGNED ) RETURN string; + -- FUNCTION to_string ( value : SIGNED ) RETURN string; + + -- explicitly defined operations + + alias to_bstring is to_string [UNSIGNED return STRING]; + alias to_bstring is to_string [SIGNED return STRING]; + alias to_binary_string is to_string [UNSIGNED return STRING]; + alias to_binary_string is to_string [SIGNED return STRING]; + + function to_ostring (value : UNSIGNED) return STRING; + function to_ostring (value : SIGNED) return STRING; + alias to_octal_string is to_ostring [UNSIGNED return STRING]; + alias to_octal_string is to_ostring [SIGNED return STRING]; + + function to_hstring (value : UNSIGNED) return STRING; + function to_hstring (value : SIGNED) return STRING; + alias to_hex_string is to_hstring [UNSIGNED return STRING]; + alias to_hex_string is to_hstring [SIGNED return STRING]; + + procedure READ(L : inout LINE; VALUE : out UNSIGNED; GOOD : out BOOLEAN); + + procedure READ(L : inout LINE; VALUE : out UNSIGNED); + + procedure READ(L : inout LINE; VALUE : out SIGNED; GOOD : out BOOLEAN); + + procedure READ(L : inout LINE; VALUE : out SIGNED); + + procedure WRITE (L : inout LINE; VALUE : in UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + procedure WRITE (L : inout LINE; VALUE : in SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + alias BREAD is READ [LINE, UNSIGNED, BOOLEAN]; + alias BREAD is READ [LINE, SIGNED, BOOLEAN]; + + alias BREAD is READ [LINE, UNSIGNED]; + alias BREAD is READ [LINE, SIGNED]; + + alias BINARY_READ is READ [LINE, UNSIGNED, BOOLEAN]; + alias BINARY_READ is READ [LINE, SIGNED, BOOLEAN]; + + alias BINARY_READ is READ [LINE, UNSIGNED]; + alias BINARY_READ is READ [LINE, SIGNED]; + + procedure OREAD (L : inout LINE; VALUE : out UNSIGNED; GOOD : out BOOLEAN); + procedure OREAD (L : inout LINE; VALUE : out SIGNED; GOOD : out BOOLEAN); + + procedure OREAD (L : inout LINE; VALUE : out UNSIGNED); + procedure OREAD (L : inout LINE; VALUE : out SIGNED); + + alias OCTAL_READ is OREAD [LINE, UNSIGNED, BOOLEAN]; + alias OCTAL_READ is OREAD [LINE, SIGNED, BOOLEAN]; + + alias OCTAL_READ is OREAD [LINE, UNSIGNED]; + alias OCTAL_READ is OREAD [LINE, SIGNED]; + + procedure HREAD (L : inout LINE; VALUE : out UNSIGNED; GOOD : out BOOLEAN); + procedure HREAD (L : inout LINE; VALUE : out SIGNED; GOOD : out BOOLEAN); + + procedure HREAD (L : inout LINE; VALUE : out UNSIGNED); + procedure HREAD (L : inout LINE; VALUE : out SIGNED); + + alias HEX_READ is HREAD [LINE, UNSIGNED, BOOLEAN]; + alias HEX_READ is HREAD [LINE, SIGNED, BOOLEAN]; + + alias HEX_READ is HREAD [LINE, UNSIGNED]; + alias HEX_READ is HREAD [LINE, SIGNED]; + + alias BWRITE is WRITE [LINE, UNSIGNED, SIDE, WIDTH]; + alias BWRITE is WRITE [LINE, SIGNED, SIDE, WIDTH]; + + alias BINARY_WRITE is WRITE [LINE, UNSIGNED, SIDE, WIDTH]; + alias BINARY_WRITE is WRITE [LINE, SIGNED, SIDE, WIDTH]; + + procedure OWRITE (L : inout LINE; VALUE : in UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + procedure OWRITE (L : inout LINE; VALUE : in SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + alias OCTAL_WRITE is OWRITE [LINE, UNSIGNED, SIDE, WIDTH]; + alias OCTAL_WRITE is OWRITE [LINE, SIGNED, SIDE, WIDTH]; + + procedure HWRITE (L : inout LINE; VALUE : in UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + procedure HWRITE (L : inout LINE; VALUE : in SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + alias HEX_WRITE is HWRITE [LINE, UNSIGNED, SIDE, WIDTH]; + alias HEX_WRITE is HWRITE [LINE, SIGNED, SIDE, WIDTH]; + +end package NUMERIC_BIT; diff --git a/libraries/ieee2008/numeric_bit_unsigned-body.vhdl b/libraries/ieee2008/numeric_bit_unsigned-body.vhdl new file mode 100644 index 000000000..bf9978235 --- /dev/null +++ b/libraries/ieee2008/numeric_bit_unsigned-body.vhdl @@ -0,0 +1,589 @@ +-- --------------------------------------------------------------------
+--
+-- 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 : Standard VHDL Synthesis Packages
+-- : (NUMERIC_BIT_UNSIGNED 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 package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Values of type BIT_VECTOR
+-- : are interpreted as unsigned numbers in vector form.
+-- : The leftmost bit is treated as the most significant bit.
+-- : This package contains overloaded arithmetic operators on
+-- : the BIT_VECTOR type. The package also contains
+-- : useful type conversions functions, clock detection
+-- : functions, and other utility functions.
+-- :
+-- : If any argument to a function is a null array, a null array
+-- : is returned (exceptions, if any, are noted individually).
+--
+-- 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.numeric_bit.all;
+
+package body NUMERIC_BIT_UNSIGNED is
+
+ -- Id: A.3
+ function "+" (L, R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) + UNSIGNED(R));
+ end function "+";
+
+ -- Id: A.3R
+ function "+"(L : BIT_VECTOR; R : BIT) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) + R);
+ end function "+";
+
+ -- Id: A.3L
+ function "+"(L : BIT; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L + UNSIGNED(R));
+ end function "+";
+
+ -- Id: A.5
+ function "+" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) + R);
+ end function "+";
+
+ -- Id: A.6
+ function "+" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L + UNSIGNED(R));
+ end function "+";
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) - UNSIGNED(R));
+ end function "-";
+
+ -- Id: A.9R
+ function "-"(L : BIT_VECTOR; R : BIT) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) - R);
+ end function "-";
+
+ -- Id: A.9L
+ function "-"(L : BIT; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L - UNSIGNED(R));
+ end function "-";
+
+ -- Id: A.11
+ function "-" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) - R);
+ end function "-";
+
+ -- Id: A.12
+ function "-" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L - UNSIGNED(R));
+ end function "-";
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) * UNSIGNED(R));
+ end function "*";
+
+ -- Id: A.17
+ function "*" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) * R);
+ end function "*";
+
+ -- Id: A.18
+ function "*" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L * UNSIGNED(R));
+ end function "*";
+
+ --============================================================================
+
+ -- Id: A.21
+ function "/" (L, R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) / UNSIGNED(R));
+ end function "/";
+
+ -- Id: A.23
+ function "/" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) / R);
+ end function "/";
+
+ -- Id: A.24
+ function "/" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L / UNSIGNED(R));
+ end function "/";
+
+ --============================================================================
+
+ -- Id: A.27
+ function "rem" (L, R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) rem UNSIGNED(R));
+ end function "rem";
+
+ -- Id: A.29
+ function "rem" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) rem R);
+ end function "rem";
+
+ -- Id: A.30
+ function "rem" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L rem UNSIGNED(R));
+ end function "rem";
+
+ --============================================================================
+
+ -- Id: A.33
+ function "mod" (L, R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) mod UNSIGNED(R));
+ end function "mod";
+
+ -- Id: A.35
+ function "mod" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(L) mod R);
+ end function "mod";
+
+ -- Id: A.36
+ function "mod" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (L mod UNSIGNED(R));
+ end function "mod";
+
+ --============================================================================
+ -- Id: A.39
+ function find_leftmost (ARG: BIT_VECTOR; Y: BIT) return INTEGER is
+ begin
+ return find_leftmost(UNSIGNED(ARG), Y);
+ end function find_leftmost;
+
+ -- Id: A.41
+ function find_rightmost (ARG: BIT_VECTOR; Y: BIT) return INTEGER is
+ begin
+ return find_rightmost(UNSIGNED(ARG), Y);
+ end function find_rightmost;
+
+ --============================================================================
+ -- Id: C.1
+ function ">" (L, R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) > UNSIGNED(R);
+ end function ">";
+
+ -- Id: C.3
+ function ">" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return L > UNSIGNED(R);
+ end function ">";
+
+ -- Id: C.5
+ function ">" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) > R;
+ end function ">";
+
+ --============================================================================
+ -- Id: C.7
+ function "<" (L, R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) < UNSIGNED(R);
+ end function "<";
+
+ -- Id: C.9
+ function "<" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return L < UNSIGNED(R);
+ end function "<";
+
+ -- Id: C.11
+ function "<" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) < R;
+ end function "<";
+
+ --============================================================================
+ -- Id: C.13
+ function "<=" (L, R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) <= UNSIGNED(R);
+ end function "<=";
+
+ -- Id: C.15
+ function "<=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return L <= UNSIGNED(R);
+ end function "<=";
+
+ -- Id: C.17
+ function "<=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) <= R;
+ end function "<=";
+
+ --============================================================================
+ -- Id: C.19
+ function ">=" (L, R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) >= UNSIGNED(R);
+ end function ">=";
+
+ -- Id: C.21
+ function ">=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return L >= UNSIGNED(R);
+ end function ">=";
+
+ -- Id: C.23
+ function ">=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) >= R;
+ end function ">=";
+
+ --============================================================================
+ -- Id: C.25
+ function "=" (L, R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) = UNSIGNED(R);
+ end function "=";
+
+ -- Id: C.27
+ function "=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return L = UNSIGNED(R);
+ end function "=";
+
+ -- Id: C.29
+ function "=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) = R;
+ end function "=";
+
+ --============================================================================
+ -- Id: C.31
+ function "/=" (L, R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) /= UNSIGNED(R);
+ end function "/=";
+
+ -- Id: C.33
+ function "/=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN is
+ begin
+ return L /= UNSIGNED(R);
+ end function "/=";
+
+ -- Id: C.35
+ function "/=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) /= R;
+ end function "/=";
+
+ --============================================================================
+ -- Id: C.37
+ function MINIMUM (L, R: BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (MINIMUM(UNSIGNED(L), UNSIGNED(R)));
+ end function MINIMUM;
+
+ -- Id: C.39
+ function MINIMUM (L: NATURAL; R: BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (MINIMUM(L, UNSIGNED(R)));
+ end function MINIMUM;
+
+ -- Id: C.41
+ function MINIMUM (L: BIT_VECTOR; R: NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (MINIMUM(UNSIGNED(L), R));
+ end function MINIMUM;
+
+ --============================================================================
+ -- Id: C.43
+ function MAXIMUM (L, R: BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (MAXIMUM(UNSIGNED(L), UNSIGNED(R)));
+ end function MAXIMUM;
+
+ -- Id: C.45
+ function MAXIMUM (L: NATURAL; R: BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (MAXIMUM(L, UNSIGNED(R)));
+ end function MAXIMUM;
+
+ -- Id: C.47
+ function MAXIMUM (L: BIT_VECTOR; R: NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (MAXIMUM(UNSIGNED(L), R));
+ end function MAXIMUM;
+
+ --============================================================================
+
+ -- Id: C.49
+ function "?>" (L, R: BIT_VECTOR) return BIT is
+ begin
+ return UNSIGNED(L) ?> UNSIGNED(R);
+ end function "?>";
+
+ -- Id: C.51
+ function "?>" (L: NATURAL; R: BIT_VECTOR) return BIT is
+ begin
+ return L ?> UNSIGNED(R);
+ end function "?>";
+
+ -- Id: C.53
+ function "?>" (L: BIT_VECTOR; R: NATURAL) return BIT is
+ begin
+ return UNSIGNED(L) ?> R;
+ end function "?>";
+
+ --============================================================================
+
+ -- Id: C.55
+ function "?<" (L, R: BIT_VECTOR) return BIT is
+ begin
+ return UNSIGNED(L) ?< UNSIGNED(R);
+ end function "?<";
+
+ -- Id: C.57
+ function "?<" (L: NATURAL; R: BIT_VECTOR) return BIT is
+ begin
+ return L ?< UNSIGNED(R);
+ end function "?<";
+
+ -- Id: C.59
+ function "?<" (L: BIT_VECTOR; R: NATURAL) return BIT is
+ begin
+ return UNSIGNED(L) ?< R;
+ end function "?<";
+
+ --============================================================================
+
+ -- Id: C.61
+ function "?<=" (L, R: BIT_VECTOR) return BIT is
+ begin
+ return UNSIGNED(L) ?<= UNSIGNED(R);
+ end function "?<=";
+
+ -- Id: C.63
+ function "?<=" (L: NATURAL; R: BIT_VECTOR) return BIT is
+ begin
+ return L ?<= UNSIGNED(R);
+ end function "?<=";
+
+ -- Id: C.65
+ function "?<=" (L: BIT_VECTOR; R: NATURAL) return BIT is
+ begin
+ return UNSIGNED(L) ?<= R;
+ end function "?<=";
+
+ --============================================================================
+
+ -- Id: C.67
+ function "?>=" (L, R: BIT_VECTOR) return BIT is
+ begin
+ return UNSIGNED(L) ?>= UNSIGNED(R);
+ end function "?>=";
+
+ -- Id: C.69
+ function "?>=" (L: NATURAL; R: BIT_VECTOR) return BIT is
+ begin
+ return L ?>= UNSIGNED(R);
+ end function "?>=";
+
+ -- Id: C.71
+ function "?>=" (L: BIT_VECTOR; R: NATURAL) return BIT is
+ begin
+ return UNSIGNED(L) ?>= R;
+ end function "?>=";
+
+ --============================================================================
+
+ -- Id: C.73
+ function "?=" (L, R: BIT_VECTOR) return BIT is
+ begin
+ return UNSIGNED(L) ?= UNSIGNED(R);
+ end function "?=";
+
+ -- Id: C.75
+ function "?=" (L: NATURAL; R: BIT_VECTOR) return BIT is
+ begin
+ return L ?= UNSIGNED(R);
+ end function "?=";
+
+ -- Id: C.77
+ function "?=" (L: BIT_VECTOR; R: NATURAL) return BIT is
+ begin
+ return UNSIGNED(L) ?= R;
+ end function "?=";
+
+ --============================================================================
+
+ -- Id: C.79
+ function "?/=" (L, R: BIT_VECTOR) return BIT is
+ begin
+ return UNSIGNED(L) ?/= UNSIGNED(R);
+ end function "?/=";
+
+ -- Id: C.81
+ function "?/=" (L: NATURAL; R: BIT_VECTOR) return BIT is
+ begin
+ return L ?/= UNSIGNED(R);
+ end function "?/=";
+
+ -- Id: C.83
+ function "?/=" (L: BIT_VECTOR; R: NATURAL) return BIT is
+ begin
+ return UNSIGNED(L) ?/= R;
+ end function "?/=";
+
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (shift_left (ARG => UNSIGNED(ARG),
+ COUNT => COUNT));
+ end function SHIFT_LEFT;
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (shift_right (ARG => UNSIGNED(ARG),
+ COUNT => COUNT));
+ end function SHIFT_RIGHT;
+
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (rotate_left (ARG => UNSIGNED(ARG),
+ COUNT => COUNT));
+ end function ROTATE_LEFT;
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (rotate_right (ARG => UNSIGNED(ARG),
+ COUNT => COUNT));
+ end function ROTATE_RIGHT;
+
+ --============================================================================
+
+ -- Id: S.9
+ function "sll" (ARG: BIT_VECTOR; COUNT: INTEGER) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(ARG) sll COUNT);
+ end function "sll";
+
+ -- Id: S.11
+ function "srl" (ARG: BIT_VECTOR; COUNT: INTEGER) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(ARG) srl COUNT);
+ end function "srl";
+
+ -- Id: S.13
+ function "rol" (ARG: BIT_VECTOR; COUNT: INTEGER) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(ARG) rol COUNT);
+ end function "rol";
+
+ -- Id: S.15
+ function "ror" (ARG: BIT_VECTOR; COUNT: INTEGER) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(ARG) ror COUNT);
+ end function "ror";
+
+ -- Id: S.17
+ function "sla" (ARG: BIT_VECTOR; COUNT: INTEGER) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(ARG) sla COUNT);
+ end function "sla";
+
+ -- Id: S.19
+ function "sra" (ARG: BIT_VECTOR; COUNT: INTEGER) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (UNSIGNED(ARG) sra COUNT);
+ end function "sra";
+
+ --============================================================================
+
+ -- Id: R.2
+ function RESIZE (ARG : BIT_VECTOR; NEW_SIZE : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (
+ resize (arg => UNSIGNED(ARG),
+ NEW_SIZE => NEW_SIZE));
+ end function RESIZE;
+
+ function RESIZE (ARG, SIZE_RES : BIT_VECTOR) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (
+ RESIZE (ARG => UNSIGNED(ARG),
+ NEW_SIZE => SIZE_RES'length));
+ end function RESIZE;
+
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG : BIT_VECTOR) return NATURAL is
+ begin
+ return TO_INTEGER (UNSIGNED(ARG));
+ end function TO_INTEGER;
+
+ -- Id: D.3
+ function To_BitVector (ARG, SIZE : NATURAL) return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (TO_UNSIGNED(ARG, SIZE));
+ end function To_BitVector;
+
+ function To_BitVector (ARG : NATURAL; SIZE_RES : BIT_VECTOR)
+ return BIT_VECTOR is
+ begin
+ return BIT_VECTOR (TO_UNSIGNED(ARG, SIZE_RES'length));
+ end function To_BitVector;
+
+end package body NUMERIC_BIT_UNSIGNED;
diff --git a/libraries/ieee2008/numeric_bit_unsigned.vhdl b/libraries/ieee2008/numeric_bit_unsigned.vhdl new file mode 100644 index 000000000..1d76ed477 --- /dev/null +++ b/libraries/ieee2008/numeric_bit_unsigned.vhdl @@ -0,0 +1,620 @@ +-- --------------------------------------------------------------------
+--
+-- 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 : Standard VHDL Synthesis Packages
+-- : (NUMERIC_BIT_UNSIGNED package declaration)
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers: Accellera VHDL-TC, and IEEE P1076 Working Group
+-- :
+-- Purpose : This package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Values of type BIT_VECTOR
+-- : are interpreted as unsigned numbers in vector form.
+-- : The leftmost bit is treated as the most significant bit.
+-- : This package contains overloaded arithmetic operators on
+-- : the BIT_VECTOR type. The package also contains
+-- : useful type conversions functions, clock detection
+-- : functions, and other utility functions.
+-- :
+-- : If any argument to a function is a null array, a null array
+-- : is returned (exceptions, if any, are noted individually).
+--
+-- 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) $
+-- --------------------------------------------------------------------
+
+package NUMERIC_BIT_UNSIGNED is
+ constant CopyRightNotice : STRING :=
+ "Copyright 2008 IEEE. All rights reserved.";
+
+ -- Id: A.3
+ function "+" (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Adds two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.3R
+ function "+"(L : BIT_VECTOR; R : BIT) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0)
+ -- Result: Similar to A.3 where R is a one bit bit_vector
+
+ -- Id: A.3L
+ function "+"(L : BIT; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0)
+ -- Result: Similar to A.3 where L is a one bit UNSIGNED
+
+ -- Id: A.5
+ function "+" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0).
+ -- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.
+
+ -- Id: A.6
+ function "+" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0).
+ -- Result: Adds a non-negative INTEGER, L, with an UNSIGNED vector, R.
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: UNSIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Subtracts two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.9R
+ function "-"(L : BIT_VECTOR; R : BIT) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0)
+ -- Result: Similar to A.9 where R is a one bit UNSIGNED
+
+ -- Id: A.9L
+ function "-"(L : BIT; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0)
+ -- Result: Similar to A.9 where L is a one bit UNSIGNED
+
+ -- Id: A.11
+ function "-" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0).
+ -- Result: Subtracts a non-negative INTEGER, R, from an UNSIGNED vector, L.
+
+ -- Id: A.12
+ function "-" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0).
+ -- Result: Subtracts an UNSIGNED vector, R, from a non-negative INTEGER, L.
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector((L'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Performs the multiplication operation on two UNSIGNED vectors
+ -- that may possibly be of different lengths.
+
+ -- Id: A.17
+ function "*" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector((L'LENGTH+L'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, L, with a non-negative
+ -- INTEGER, R. R is converted to an UNSIGNED vector of
+ -- SIZE L'LENGTH before multiplication.
+
+ -- Id: A.18
+ function "*" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector((R'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, R, with a non-negative
+ -- INTEGER, L. L is converted to an UNSIGNED vector of
+ -- SIZE R'LENGTH before multiplication.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "/" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.21
+ function "/" (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R.
+
+ -- Id: A.23
+ function "/" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by a non-negative INTEGER, R.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.24
+ function "/" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0)
+ -- Result: Divides a non-negative INTEGER, L, by an UNSIGNED vector, R.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "rem" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.27
+ function "rem" (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.29
+ function "rem" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L is an UNSIGNED vector and R is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.30
+ function "rem" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where R is an UNSIGNED vector and L is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "mod" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.33
+ function "mod" (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.35
+ function "mod" (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(L'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is an UNSIGNED vector and R
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.36
+ function "mod" (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: bit_vector(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where R is an UNSIGNED vector and L
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ -- Id: A.39
+ function find_leftmost (ARG : BIT_VECTOR; Y : BIT) return INTEGER;
+ -- Result subtype: INTEGER
+ -- Result: Finds the leftmost occurrence of the value of Y in ARG.
+ -- Returns the index of the occurrence if it exists, or -1 otherwise.
+
+ -- Id: A.41
+ function find_rightmost (ARG : BIT_VECTOR; Y : BIT) return INTEGER;
+ -- Result subtype: INTEGER
+ -- Result: Finds the leftmost occurrence of the value of Y in ARG.
+ -- Returns the index of the occurrence if it exists, or -1 otherwise.
+
+ --============================================================================
+ -- Comparison Operators
+ --============================================================================
+ -- Id: C.1
+ function ">" (L, R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.3
+ function ">" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.5
+ function ">" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+ -- Id: C.7
+ function "<" (L, R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.9
+ function "<" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.11
+ function "<" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+ -- Id: C.13
+ function "<=" (L, R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.15
+ function "<=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.17
+ function "<=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+ -- Id: C.19
+ function ">=" (L, R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.21
+ function ">=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.23
+ function ">=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+ -- Id: C.25
+ function "=" (L, R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.27
+ function "=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.29
+ function "=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.31
+ function "/=" (L, R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.33
+ function "/=" (L : NATURAL; R : BIT_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.35
+ function "/=" (L : BIT_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.37
+ function MINIMUM (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR
+ -- Result: Returns the lesser of two UNSIGNED vectors that may be
+ -- of different lengths.
+
+ -- Id: C.39
+ function MINIMUM (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR
+ -- Result: Returns the lesser of a nonnegative INTEGER, L, and
+ -- an UNSIGNED vector, R.
+
+ -- Id: C.41
+ function MINIMUM (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR
+ -- Result: Returns the lesser of an UNSIGNED vector, L, and
+ -- a nonnegative INTEGER, R.
+
+ --============================================================================
+
+ -- Id: C.43
+ function MAXIMUM (L, R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR
+ -- Result: Returns the greater of two UNSIGNED vectors that may be
+ -- of different lengths.
+
+ -- Id: C.45
+ function MAXIMUM (L : NATURAL; R : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR
+ -- Result: Returns the greater of a nonnegative INTEGER, L, and
+ -- an UNSIGNED vector, R.
+
+ -- Id: C.47
+ function MAXIMUM (L : BIT_VECTOR; R : NATURAL) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR
+ -- Result: Returns the greater of an UNSIGNED vector, L, and
+ -- a nonnegative INTEGER, R.
+
+ --============================================================================
+ -- Id: C.49
+ function "?>" (L, R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.51
+ function "?>" (L : NATURAL; R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L > R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.53
+ function "?>" (L : BIT_VECTOR; R : NATURAL) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L > R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.55
+ function "?<" (L, R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.57
+ function "?<" (L : NATURAL; R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L < R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.59
+ function "?<" (L : BIT_VECTOR; R : NATURAL) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L < R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.61
+ function "?<=" (L, R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.63
+ function "?<=" (L : NATURAL; R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L <= R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.65
+ function "?<=" (L : BIT_VECTOR; R : NATURAL) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L <= R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.67
+ function "?>=" (L, R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.69
+ function "?>=" (L : NATURAL; R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L >= R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.71
+ function "?>=" (L : BIT_VECTOR; R : NATURAL) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L >= R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.73
+ function "?=" (L, R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.75
+ function "?=" (L : NATURAL; R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L = R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.77
+ function "?=" (L : BIT_VECTOR; R : NATURAL) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L = R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.79
+ function "?/=" (L, R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.81
+ function "?/=" (L : NATURAL; R : BIT_VECTOR) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L /= R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.83
+ function "?/=" (L : BIT_VECTOR; R : NATURAL) return BIT;
+ -- Result subtype: BIT
+ -- Result: Computes "L /= R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+ -- Shift and Rotate Functions
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-left on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with '0'.
+ -- The COUNT leftmost elements are lost.
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-right on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with '0'.
+ -- The COUNT rightmost elements are lost.
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-left of an UNSIGNED vector COUNT times.
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG : BIT_VECTOR; COUNT : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-right of an UNSIGNED vector COUNT times.
+
+
+ --============================================================================
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.9 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.9
+ function "sll" (ARG : BIT_VECTOR; COUNT : INTEGER) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.11 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.11
+ function "srl" (ARG : BIT_VECTOR; COUNT : INTEGER) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_RIGHT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.13 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.13
+ function "rol" (ARG : BIT_VECTOR; COUNT : INTEGER) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.15 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.15
+ function "ror" (ARG : BIT_VECTOR; COUNT : INTEGER) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_RIGHT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.17 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.17
+ function "sla" (ARG : BIT_VECTOR; COUNT : INTEGER) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.19 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.19
+ function "sra" (ARG : BIT_VECTOR; COUNT : INTEGER) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_RIGHT(ARG, COUNT)
+
+
+ --============================================================================
+ -- RESIZE Functions
+ --============================================================================
+
+ -- Id: R.2
+ function RESIZE (ARG : BIT_VECTOR; NEW_SIZE : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(NEW_SIZE-1 downto 0)
+ -- Result: Resizes the UNSIGNED vector ARG to the specified size.
+ -- To create a larger vector, the new [leftmost] bit positions
+ -- are filled with '0'. When truncating, the leftmost bits
+ -- are dropped.
+
+ function RESIZE (ARG, SIZE_RES : BIT_VECTOR) return BIT_VECTOR;
+ -- Result subtype: BIT_VECTOR (SIZE_RES'length-1 downto 0)
+
+ --============================================================================
+ -- Conversion Functions
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG : BIT_VECTOR) return NATURAL;
+ -- Result subtype: NATURAL. Value cannot be negative since parameter is an
+ -- UNSIGNED vector.
+ -- Result: Converts the UNSIGNED vector to an INTEGER.
+
+ -- Id: D.3
+ function To_BitVector (ARG, SIZE : NATURAL) return BIT_VECTOR;
+ -- Result subtype: bit_vector(SIZE-1 downto 0)
+ -- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
+ -- the specified size.
+
+ function To_BitVector (ARG : NATURAL; SIZE_RES : BIT_VECTOR)
+ return BIT_VECTOR;
+ -- Result subtype: STD_LOGIC_VECTOR(SIZE_RES'length-1 downto 0)
+
+-- begin LCS-2006-130
+ alias To_Bit_Vector is
+ To_BitVector[NATURAL, NATURAL return BIT_VECTOR];
+ alias To_BV is
+ To_BitVector[NATURAL, NATURAL return BIT_VECTOR];
+
+ alias To_Bit_Vector is
+ To_BitVector[NATURAL, BIT_VECTOR return BIT_VECTOR];
+ alias To_BV is
+ To_BitVector[NATURAL, BIT_VECTOR return BIT_VECTOR];
+
+end package NUMERIC_BIT_UNSIGNED;
diff --git a/libraries/ieee2008/numeric_std-body.vhdl b/libraries/ieee2008/numeric_std-body.vhdl new file mode 100644 index 000000000..9fe0db6a8 --- /dev/null +++ b/libraries/ieee2008/numeric_std-body.vhdl @@ -0,0 +1,4087 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Synthesis Packages +-- : (NUMERIC_STD package body) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC Synthesis Working Group, +-- : Accellera VHDL-TC, and IEEE P1076 Working Group +-- : +-- Purpose : This package defines numeric types and arithmetic functions +-- : for use with synthesis tools. Two numeric types are defined: +-- : -- > UNRESOLVED_UNSIGNED: represents an UNSIGNED number +-- : in vector form +-- : -- > UNRESOLVED_SIGNED: represents a SIGNED number +-- : in vector form +-- : The base element type is type STD_ULOGIC. +-- : Aliases U_UNSIGNED and U_SIGNED are defined for the types +-- : UNRESOLVED_UNSIGNED and UNRESOLVED_SIGNED, respectively. +-- : Two numeric subtypes are defined: +-- : -- > UNSIGNED: represents UNSIGNED number in vector form +-- : -- > SIGNED: represents a SIGNED number in vector form +-- : The element subtypes are the same subtype as STD_LOGIC. +-- : The leftmost bit is treated as the most significant bit. +-- : Signed vectors are represented in two's complement form. +-- : This package contains overloaded arithmetic operators on +-- : the SIGNED and UNSIGNED types. The package also contains +-- : useful type conversions functions, clock detection +-- : functions, and other utility functions. +-- : +-- : If any argument to a function is a null array, a null array +-- : is returned (exceptions, if any, are noted individually). +-- +-- 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) $ +-- -------------------------------------------------------------------- + +package body NUMERIC_STD is + + -- null range array constants + + constant NAU : UNRESOLVED_UNSIGNED (0 downto 1) := (others => '0'); + constant NAS : UNRESOLVED_SIGNED (0 downto 1) := (others => '0'); + + -- implementation controls + + constant NO_WARNING : BOOLEAN := false; -- default to emit warnings + + -- =========================Local Subprograms ================================= + + function SIGNED_NUM_BITS (ARG : INTEGER) return NATURAL is + variable NBITS : NATURAL; + variable N : NATURAL; + begin + if ARG >= 0 then + N := ARG; + else + N := -(ARG+1); + end if; + NBITS := 1; + while N > 0 loop + NBITS := NBITS+1; + N := N / 2; + end loop; + return NBITS; + end function SIGNED_NUM_BITS; + + function UNSIGNED_NUM_BITS (ARG : NATURAL) return NATURAL is + variable NBITS : NATURAL; + variable N : NATURAL; + begin + N := ARG; + NBITS := 1; + while N > 1 loop + NBITS := NBITS+1; + N := N / 2; + end loop; + return NBITS; + end function UNSIGNED_NUM_BITS; + + ------------------------------------------------------------------------ + + -- this internal function computes the addition of two UNRESOLVED_UNSIGNED + -- with input CARRY + -- * the two arguments are of the same length + + function ADD_UNSIGNED (L, R : UNRESOLVED_UNSIGNED; C : STD_LOGIC) + return UNRESOLVED_UNSIGNED + is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is R; + variable RESULT : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable CBIT : STD_LOGIC := C; + begin + for I in 0 to L_LEFT loop + RESULT(I) := CBIT xor XL(I) xor XR(I); + CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I)); + end loop; + return RESULT; + end function ADD_UNSIGNED; + + -- this internal function computes the addition of two UNRESOLVED_SIGNED + -- with input CARRY + -- * the two arguments are of the same length + + function ADD_SIGNED (L, R : UNRESOLVED_SIGNED; C : STD_LOGIC) + return UNRESOLVED_SIGNED + is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(L_LEFT downto 0) is R; + variable RESULT : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable CBIT : STD_LOGIC := C; + begin + for I in 0 to L_LEFT loop + RESULT(I) := CBIT xor XL(I) xor XR(I); + CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I)); + end loop; + return RESULT; + end function ADD_SIGNED; + + ----------------------------------------------------------------------------- + + -- this internal procedure computes UNSIGNED division + -- giving the quotient and remainder. + procedure DIVMOD (NUM, XDENOM : UNRESOLVED_UNSIGNED; + XQUOT, XREMAIN : out UNRESOLVED_UNSIGNED) is + variable TEMP : UNRESOLVED_UNSIGNED(NUM'length downto 0); + variable QUOT : UNRESOLVED_UNSIGNED(MAXIMUM(NUM'length, XDENOM'length)-1 + downto 0); + alias DENOM : UNRESOLVED_UNSIGNED(XDENOM'length-1 downto 0) is XDENOM; + variable TOPBIT : INTEGER; + begin + TEMP := "0"&NUM; + QUOT := (others => '0'); + TOPBIT := -1; + for J in DENOM'range loop + if DENOM(J) = '1' then + TOPBIT := J; + exit; + end if; + end loop; + assert TOPBIT >= 0 report "NUMERIC_STD.DIVMOD: DIV, MOD, or REM by zero" + severity error; + + for J in NUM'length-(TOPBIT+1) downto 0 loop + if TEMP(TOPBIT+J+1 downto J) >= "0"&DENOM(TOPBIT downto 0) then + TEMP(TOPBIT+J+1 downto J) := (TEMP(TOPBIT+J+1 downto J)) + -("0"&DENOM(TOPBIT downto 0)); + QUOT(J) := '1'; + end if; + assert TEMP(TOPBIT+J+1) = '0' + report "NUMERIC_STD.DIVMOD: internal error in the division algorithm" + severity error; + end loop; + XQUOT := RESIZE(QUOT, XQUOT'length); + XREMAIN := RESIZE(TEMP, XREMAIN'length); + end procedure DIVMOD; + + -----------------Local Subprograms - shift/rotate ops------------------------- + + function XSLL (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL) + return STD_ULOGIC_VECTOR + is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : STD_ULOGIC_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : STD_ULOGIC_VECTOR(ARG_L downto 0) := (others => '0'); + begin + if COUNT <= ARG_L then + RESULT(ARG_L downto COUNT) := XARG(ARG_L-COUNT downto 0); + end if; + return RESULT; + end function XSLL; + + function XSRL (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL) + return STD_ULOGIC_VECTOR + is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : STD_ULOGIC_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : STD_ULOGIC_VECTOR(ARG_L downto 0) := (others => '0'); + begin + if COUNT <= ARG_L then + RESULT(ARG_L-COUNT downto 0) := XARG(ARG_L downto COUNT); + end if; + return RESULT; + end function XSRL; + + function XSRA (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL) + return STD_ULOGIC_VECTOR + is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : STD_ULOGIC_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : STD_ULOGIC_VECTOR(ARG_L downto 0); + variable XCOUNT : NATURAL := COUNT; + begin + if ((ARG'length <= 1) or (XCOUNT = 0)) then return ARG; + else + if (XCOUNT > ARG_L) then XCOUNT := ARG_L; + end if; + RESULT(ARG_L-XCOUNT downto 0) := XARG(ARG_L downto XCOUNT); + RESULT(ARG_L downto (ARG_L - XCOUNT + 1)) := (others => XARG(ARG_L)); + end if; + return RESULT; + end function XSRA; + + function XROL (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL) + return STD_ULOGIC_VECTOR + is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : STD_ULOGIC_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : STD_ULOGIC_VECTOR(ARG_L downto 0) := XARG; + variable COUNTM : INTEGER; + begin + COUNTM := COUNT mod (ARG_L + 1); + if COUNTM /= 0 then + RESULT(ARG_L downto COUNTM) := XARG(ARG_L-COUNTM downto 0); + RESULT(COUNTM-1 downto 0) := XARG(ARG_L downto ARG_L-COUNTM+1); + end if; + return RESULT; + end function XROL; + + function XROR (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL) + return STD_ULOGIC_VECTOR + is + constant ARG_L : INTEGER := ARG'length-1; + alias XARG : STD_ULOGIC_VECTOR(ARG_L downto 0) is ARG; + variable RESULT : STD_ULOGIC_VECTOR(ARG_L downto 0) := XARG; + variable COUNTM : INTEGER; + begin + COUNTM := COUNT mod (ARG_L + 1); + if COUNTM /= 0 then + RESULT(ARG_L-COUNTM downto 0) := XARG(ARG_L downto COUNTM); + RESULT(ARG_L downto ARG_L-COUNTM+1) := XARG(COUNTM-1 downto 0); + end if; + return RESULT; + end function XROR; + + -----------------Local Subprograms - Relational ops--------------------------- + + -- + -- General "=" for UNRESOLVED_UNSIGNED vectors, same length + -- + function UNSIGNED_EQUAL (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + begin + return STD_ULOGIC_VECTOR(L) = STD_ULOGIC_VECTOR(R); + end function UNSIGNED_EQUAL; + + -- + -- General "=" for UNRESOLVED_SIGNED vectors, same length + -- + function SIGNED_EQUAL (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + begin + return STD_ULOGIC_VECTOR(L) = STD_ULOGIC_VECTOR(R); + end function SIGNED_EQUAL; + + -- + -- General "<" for UNRESOLVED_UNSIGNED vectors, same length + -- + function UNSIGNED_LESS (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + begin + return STD_ULOGIC_VECTOR(L) < STD_ULOGIC_VECTOR(R); + end function UNSIGNED_LESS; + + -- + -- General "<" function for UNRESOLVED_SIGNED vectors, same length + -- + function SIGNED_LESS (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + variable INTERN_L : UNRESOLVED_SIGNED(0 to L'length-1); + variable INTERN_R : UNRESOLVED_SIGNED(0 to R'length-1); + begin + INTERN_L := L; + INTERN_R := R; + INTERN_L(0) := not INTERN_L(0); + INTERN_R(0) := not INTERN_R(0); + return STD_ULOGIC_VECTOR(INTERN_L) < STD_ULOGIC_VECTOR(INTERN_R); + end function SIGNED_LESS; + + -- + -- General "<=" function for UNRESOLVED_UNSIGNED vectors, same length + -- + function UNSIGNED_LESS_OR_EQUAL (L, R : UNRESOLVED_UNSIGNED) + return BOOLEAN is + begin + return STD_ULOGIC_VECTOR(L) <= STD_ULOGIC_VECTOR(R); + end function UNSIGNED_LESS_OR_EQUAL; + + -- + -- General "<=" function for UNRESOLVED_SIGNED vectors, same length + -- + function SIGNED_LESS_OR_EQUAL (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + -- Need aliases to assure index direction + variable INTERN_L : UNRESOLVED_SIGNED(0 to L'length-1); + variable INTERN_R : UNRESOLVED_SIGNED(0 to R'length-1); + begin + INTERN_L := L; + INTERN_R := R; + INTERN_L(0) := not INTERN_L(0); + INTERN_R(0) := not INTERN_R(0); + return STD_ULOGIC_VECTOR(INTERN_L) <= STD_ULOGIC_VECTOR(INTERN_R); + end function SIGNED_LESS_OR_EQUAL; + + -- =========================Exported Functions ========================== + + -- Id: A.1 + function "abs" (ARG : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is ARG; + variable RESULT : UNRESOLVED_SIGNED(ARG_LEFT downto 0); + begin + if ARG'length < 1 then return NAS; + end if; + RESULT := TO_01(XARG, 'X'); + if (RESULT(RESULT'left) = 'X') then return RESULT; + end if; + if RESULT(RESULT'left) = '1' then + RESULT := -RESULT; + end if; + return RESULT; + end function "abs"; + + -- Id: A.2 + function "-" (ARG : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is ARG; + variable RESULT, XARG01 : UNRESOLVED_SIGNED(ARG_LEFT downto 0); + variable CBIT : STD_LOGIC := '1'; + begin + if ARG'length < 1 then return NAS; + end if; + XARG01 := TO_01(ARG, 'X'); + if (XARG01(XARG01'left) = 'X') then return XARG01; + end if; + for I in 0 to RESULT'left loop + RESULT(I) := not(XARG01(I)) xor CBIT; + CBIT := CBIT and not(XARG01(I)); + end loop; + return RESULT; + end function "-"; + + -- ============================================================================ + + -- Id: A.3 + function "+" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + return ADD_UNSIGNED(L01, R01, '0'); + end function "+"; + + -- Id: A.3R + function "+" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED + is + variable XR : UNRESOLVED_UNSIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L + XR); + end function "+"; + + -- Id: A.3L + function "+" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED + is + variable XL : UNRESOLVED_UNSIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL + R); + end function "+"; + + -- Id: A.4 + function "+" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + return ADD_SIGNED(L01, R01, '0'); + end function "+"; + + -- Id: A.4R + function "+" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED + is + variable XR : UNRESOLVED_SIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L + XR); + end function "+"; + + -- Id: A.4L + function "+" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED + is + variable XL : UNRESOLVED_SIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL + R); + end function "+"; + + -- Id: A.5 + function "+" (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + return L + TO_UNSIGNED(R, L'length); + end function "+"; + + -- Id: A.6 + function "+" (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return TO_UNSIGNED(L, R'length) + R; + end function "+"; + + -- Id: A.7 + function "+" (L : UNRESOLVED_SIGNED; R : INTEGER) + return UNRESOLVED_SIGNED is + begin + return L + TO_SIGNED(R, L'length); + end function "+"; + + -- Id: A.8 + function "+" (L : INTEGER; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return TO_SIGNED(L, R'length) + R; + end function "+"; + + -- ============================================================================ + + -- Id: A.9 + function "-" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + return ADD_UNSIGNED(L01, not(R01), '1'); + end function "-"; + + -- Id: A.9R + function "-" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED + is + variable XR : UNRESOLVED_UNSIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L - XR); + end function "-"; + + -- Id: A.9L + function "-" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED + is + variable XL : UNRESOLVED_UNSIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL - R); + end function "-"; + + -- Id: A.10 + function "-" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + return ADD_SIGNED(L01, not(R01), '1'); + end function "-"; + + -- Id: A.10R + function "-" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED + is + variable XR : UNRESOLVED_SIGNED(L'length-1 downto 0) := (others => '0'); + begin + XR(0) := R; + return (L - XR); + end function "-"; + + -- Id: A.10L + function "-" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED + is + variable XL : UNRESOLVED_SIGNED(R'length-1 downto 0) := (others => '0'); + begin + XL(0) := L; + return (XL - R); + end function "-"; + + -- Id: A.11 + function "-" (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + return L - TO_UNSIGNED(R, L'length); + end function "-"; + + -- Id: A.12 + function "-" (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return TO_UNSIGNED(L, R'length) - R; + end function "-"; + + -- Id: A.13 + function "-" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED is + begin + return L - TO_SIGNED(R, L'length); + end function "-"; + + -- Id: A.14 + function "-" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + begin + return TO_SIGNED(L, R'length) - R; + end function "-"; + + -- ============================================================================ + + -- Id: A.15 + function "*" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XXL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XXR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + variable RESULT : UNRESOLVED_UNSIGNED((L'length+R'length-1) downto 0) := + (others => '0'); + variable ADVAL : UNRESOLVED_UNSIGNED((L'length+R'length-1) downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + XL := TO_01(XXL, 'X'); + XR := TO_01(XXR, 'X'); + if ((XL(XL'left) = 'X') or (XR(XR'left) = 'X')) then + RESULT := (others => 'X'); + return RESULT; + end if; + ADVAL := RESIZE(XR, RESULT'length); + for I in 0 to L_LEFT loop + if XL(I) = '1' then RESULT := RESULT + ADVAL; + end if; + ADVAL := SHIFT_LEFT(ADVAL, 1); + end loop; + return RESULT; + end function "*"; + + -- Id: A.16 + function "*" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + variable XL : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable XR : UNRESOLVED_SIGNED(R_LEFT downto 0); + variable RESULT : UNRESOLVED_SIGNED((L_LEFT+R_LEFT+1) downto 0) := + (others => '0'); + variable ADVAL : UNRESOLVED_SIGNED((L_LEFT+R_LEFT+1) downto 0); + begin + if ((L_LEFT < 0) or (R_LEFT < 0)) then return NAS; + end if; + XL := TO_01(L, 'X'); + XR := TO_01(R, 'X'); + if ((XL(L_LEFT) = 'X') or (XR(R_LEFT) = 'X')) then + RESULT := (others => 'X'); + return RESULT; + end if; + ADVAL := RESIZE(XR, RESULT'length); + for I in 0 to L_LEFT-1 loop + if XL(I) = '1' then RESULT := RESULT + ADVAL; + end if; + ADVAL := SHIFT_LEFT(ADVAL, 1); + end loop; + if XL(L_LEFT) = '1' then + RESULT := RESULT - ADVAL; + end if; + return RESULT; + end function "*"; + + -- Id: A.17 + function "*" (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + return L * TO_UNSIGNED(R, L'length); + end function "*"; + + -- Id: A.18 + function "*" (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return TO_UNSIGNED(L, R'length) * R; + end function "*"; + + -- Id: A.19 + function "*" (L : UNRESOLVED_SIGNED; R : INTEGER) + return UNRESOLVED_SIGNED is + begin + return L * TO_SIGNED(R, L'length); + end function "*"; + + -- Id: A.20 + function "*" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + begin + return TO_SIGNED(L, R'length) * R; + end function "*"; + + -- ============================================================================ + + -- Id: A.21 + function "/" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XXL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XXR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + variable FQUOT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + XL := TO_01(XXL, 'X'); + XR := TO_01(XXR, 'X'); + if ((XL(XL'left) = 'X') or (XR(XR'left) = 'X')) then + FQUOT := (others => 'X'); + return FQUOT; + end if; + DIVMOD(XL, XR, FQUOT, FREMAIN); + return FQUOT; + end function "/"; + + -- Id: A.22 + function "/" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XXL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XXR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable XL : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable XR : UNRESOLVED_SIGNED(R_LEFT downto 0); + variable FQUOT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + variable XNUM : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable XDENOM : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + variable QNEG : BOOLEAN := false; + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + XL := TO_01(XXL, 'X'); + XR := TO_01(XXR, 'X'); + if ((XL(XL'left) = 'X') or (XR(XR'left) = 'X')) then + FQUOT := (others => 'X'); + return UNRESOLVED_SIGNED(FQUOT); + end if; + if XL(XL'left) = '1' then + XNUM := UNRESOLVED_UNSIGNED(-XL); + QNEG := true; + else + XNUM := UNRESOLVED_UNSIGNED(XL); + end if; + if XR(XR'left) = '1' then + XDENOM := UNRESOLVED_UNSIGNED(-XR); + QNEG := not QNEG; + else + XDENOM := UNRESOLVED_UNSIGNED(XR); + end if; + DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); + if QNEG then FQUOT := "0"-FQUOT; + end if; + return UNRESOLVED_SIGNED(FQUOT); + end function "/"; + + -- Id: A.23 + function "/" (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED + is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, UNSIGNED_NUM_BITS(R)); + variable XR, QUOT : UNRESOLVED_UNSIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAU; + end if; + if (R_LENGTH > L'length) then + QUOT := (others => '0'); + return RESIZE(QUOT, L'length); + end if; + XR := TO_UNSIGNED(R, R_LENGTH); + QUOT := RESIZE((L / XR), QUOT'length); + return RESIZE(QUOT, L'length); + end function "/"; + + -- Id: A.24 + function "/" (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED + is + constant L_LENGTH : NATURAL := MAXIMUM(UNSIGNED_NUM_BITS(L), R'length); + variable XL, QUOT : UNRESOLVED_UNSIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAU; + end if; + XL := TO_UNSIGNED(L, L_LENGTH); + QUOT := RESIZE((XL / R), QUOT'length); + if L_LENGTH > R'length and QUOT(0) /= 'X' + and QUOT(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => '0') + then + assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated" + severity warning; + end if; + return RESIZE(QUOT, R'length); + end function "/"; + + -- Id: A.25 + function "/" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, SIGNED_NUM_BITS(R)); + variable XR, QUOT : UNRESOLVED_SIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAS; + end if; + if (R_LENGTH > L'length) then + QUOT := (others => '0'); + return RESIZE(QUOT, L'length); + end if; + XR := TO_SIGNED(R, R_LENGTH); + QUOT := RESIZE((L / XR), QUOT'length); + return RESIZE(QUOT, L'length); + end function "/"; + + -- Id: A.26 + function "/" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant L_LENGTH : NATURAL := MAXIMUM(SIGNED_NUM_BITS(L), R'length); + variable XL, QUOT : UNRESOLVED_SIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAS; + end if; + XL := TO_SIGNED(L, L_LENGTH); + QUOT := RESIZE((XL / R), QUOT'length); + if L_LENGTH > R'length and QUOT(0) /= 'X' + and QUOT(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => QUOT(R'length-1)) + then + assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated" + severity warning; + end if; + return RESIZE(QUOT, R'length); + end function "/"; + + -- ============================================================================ + + -- Id: A.27 + function "rem" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XXL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XXR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + variable FQUOT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + XL := TO_01(XXL, 'X'); + XR := TO_01(XXR, 'X'); + if ((XL(XL'left) = 'X') or (XR(XR'left) = 'X')) then + FREMAIN := (others => 'X'); + return FREMAIN; + end if; + DIVMOD(XL, XR, FQUOT, FREMAIN); + return FREMAIN; + end function "rem"; + + -- Id: A.28 + function "rem" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XXL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XXR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable FQUOT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + variable XNUM : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable XDENOM : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + variable RNEG : BOOLEAN := false; + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + XNUM := UNRESOLVED_UNSIGNED(TO_01(XXL, 'X')); + XDENOM := UNRESOLVED_UNSIGNED(TO_01(XXR, 'X')); + if ((XNUM(XNUM'left) = 'X') or (XDENOM(XDENOM'left) = 'X')) then + FREMAIN := (others => 'X'); + return UNRESOLVED_SIGNED(FREMAIN); + end if; + if XNUM(XNUM'left) = '1' then + XNUM := UNRESOLVED_UNSIGNED(-UNRESOLVED_SIGNED(XNUM)); + RNEG := true; + else + XNUM := UNRESOLVED_UNSIGNED(XNUM); + end if; + if XDENOM(XDENOM'left) = '1' then + XDENOM := UNRESOLVED_UNSIGNED(-UNRESOLVED_SIGNED(XDENOM)); + else + XDENOM := UNRESOLVED_UNSIGNED(XDENOM); + end if; + DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); + if RNEG then + FREMAIN := "0"-FREMAIN; + end if; + return UNRESOLVED_SIGNED(FREMAIN); + end function "rem"; + + -- Id: A.29 + function "rem" (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED + is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, UNSIGNED_NUM_BITS(R)); + variable XR, XREM : UNRESOLVED_UNSIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAU; + end if; + XR := TO_UNSIGNED(R, R_LENGTH); + XREM := L rem XR; + if R_LENGTH > L'length and XREM(0) /= 'X' + and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => '0') + then + assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "rem"; + + -- Id: A.30 + function "rem" (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED + is + constant L_LENGTH : NATURAL := MAXIMUM(UNSIGNED_NUM_BITS(L), R'length); + variable XL, XREM : UNRESOLVED_UNSIGNED(L_LENGTH-1 downto 0); + begin + XL := TO_UNSIGNED(L, L_LENGTH); + XREM := XL rem R; + if L_LENGTH > R'length and XREM(0) /= 'X' + and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => '0') + then + assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "rem"; + + -- Id: A.31 + function "rem" (L : UNRESOLVED_SIGNED; R : INTEGER) + return UNRESOLVED_SIGNED + is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, SIGNED_NUM_BITS(R)); + variable XR, XREM : UNRESOLVED_SIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAS; + end if; + XR := TO_SIGNED(R, R_LENGTH); + XREM := RESIZE((L rem XR), XREM'length); + if R_LENGTH > L'length and XREM(0) /= 'X' + and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => XREM(L'length-1)) + then + assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "rem"; + + -- Id: A.32 + function "rem" (L : INTEGER; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED + is + constant L_LENGTH : NATURAL := MAXIMUM(SIGNED_NUM_BITS(L), R'length); + variable XL, XREM : UNRESOLVED_SIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAS; + end if; + XL := TO_SIGNED(L, L_LENGTH); + XREM := RESIZE((XL rem R), XREM'length); + if L_LENGTH > R'length and XREM(0) /= 'X' + and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => XREM(R'length-1)) + then + assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "rem"; + + -- ============================================================================ + + -- Id: A.33 + function "mod" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XXL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XXR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + variable FQUOT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + XL := TO_01(XXL, 'X'); + XR := TO_01(XXR, 'X'); + if ((XL(XL'left) = 'X') or (XR(XR'left) = 'X')) then + FREMAIN := (others => 'X'); + return FREMAIN; + end if; + DIVMOD(XL, XR, FQUOT, FREMAIN); + return FREMAIN; + end function "mod"; + + -- Id: A.34 + function "mod" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XXL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XXR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable XL : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable XR : UNRESOLVED_SIGNED(R_LEFT downto 0); + variable FQUOT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable FREMAIN : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + variable XNUM : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + variable XDENOM : UNRESOLVED_UNSIGNED(R'length-1 downto 0); + variable RNEG : BOOLEAN := false; + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + XL := TO_01(XXL, 'X'); + XR := TO_01(XXR, 'X'); + if ((XL(XL'left) = 'X') or (XR(XR'left) = 'X')) then + FREMAIN := (others => 'X'); + return UNRESOLVED_SIGNED(FREMAIN); + end if; + if XL(XL'left) = '1' then + XNUM := UNRESOLVED_UNSIGNED(-XL); + else + XNUM := UNRESOLVED_UNSIGNED(XL); + end if; + if XR(XR'left) = '1' then + XDENOM := UNRESOLVED_UNSIGNED(-XR); + RNEG := true; + else + XDENOM := UNRESOLVED_UNSIGNED(XR); + end if; + DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); + if RNEG and L(L'left) = '1' then + FREMAIN := "0"-FREMAIN; + elsif RNEG and FREMAIN /= "0" then + FREMAIN := FREMAIN-XDENOM; + elsif L(L'left) = '1' and FREMAIN /= "0" then + FREMAIN := XDENOM-FREMAIN; + end if; + return UNRESOLVED_SIGNED(FREMAIN); + end function "mod"; + + -- Id: A.35 + function "mod" (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED + is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, UNSIGNED_NUM_BITS(R)); + variable XR, XREM : UNRESOLVED_UNSIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAU; + end if; + XR := TO_UNSIGNED(R, R_LENGTH); + XREM := RESIZE((L mod XR), XREM'length); + if R_LENGTH > L'length and XREM(0) /= 'X' + and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => '0') + then + assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "mod"; + + -- Id: A.36 + function "mod" (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED + is + constant L_LENGTH : NATURAL := MAXIMUM(UNSIGNED_NUM_BITS(L), R'length); + variable XL, XREM : UNRESOLVED_UNSIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAU; + end if; + XL := TO_UNSIGNED(L, L_LENGTH); + XREM := RESIZE((XL mod R), XREM'length); + if L_LENGTH > R'length and XREM(0) /= 'X' + and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => '0') + then + assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "mod"; + + -- Id: A.37 + function "mod" (L : UNRESOLVED_SIGNED; R : INTEGER) + return UNRESOLVED_SIGNED + is + constant R_LENGTH : NATURAL := MAXIMUM(L'length, SIGNED_NUM_BITS(R)); + variable XR, XREM : UNRESOLVED_SIGNED(R_LENGTH-1 downto 0); + begin + if (L'length < 1) then return NAS; + end if; + XR := TO_SIGNED(R, R_LENGTH); + XREM := RESIZE((L mod XR), XREM'length); + if R_LENGTH > L'length and XREM(0) /= 'X' + and XREM(R_LENGTH-1 downto L'length) + /= (R_LENGTH-1 downto L'length => XREM(L'length-1)) + then + assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, L'length); + end function "mod"; + + -- Id: A.38 + function "mod" (L : INTEGER; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED + is + constant L_LENGTH : NATURAL := MAXIMUM(SIGNED_NUM_BITS(L), R'length); + variable XL, XREM : UNRESOLVED_SIGNED(L_LENGTH-1 downto 0); + begin + if (R'length < 1) then return NAS; + end if; + XL := TO_SIGNED(L, L_LENGTH); + XREM := RESIZE((XL mod R), XREM'length); + if L_LENGTH > R'length and XREM(0) /= 'X' + and XREM(L_LENGTH-1 downto R'length) + /= (L_LENGTH-1 downto R'length => XREM(R'length-1)) + then + assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" + severity warning; + end if; + return RESIZE(XREM, R'length); + end function "mod"; + + -- ============================================================================ + -- Id: A.39 + function find_leftmost (ARG : UNRESOLVED_UNSIGNED; Y : STD_ULOGIC) + return INTEGER is + begin + for INDEX in ARG'range loop + if ARG(INDEX) ?= Y then + return INDEX; + end if; + end loop; + return -1; + end function find_leftmost; + + -- Id: A.40 + function find_leftmost (ARG : UNRESOLVED_SIGNED; Y : STD_ULOGIC) + return INTEGER is + begin + for INDEX in ARG'range loop + if ARG(INDEX) ?= Y then + return INDEX; + end if; + end loop; + return -1; + end function find_leftmost; + + -- Id: A.41 + function find_rightmost (ARG : UNRESOLVED_UNSIGNED; Y : STD_ULOGIC) + return INTEGER is + begin + for INDEX in ARG'reverse_range loop + if ARG(INDEX) ?= Y then + return INDEX; + end if; + end loop; + return -1; + end function find_rightmost; + + -- Id: A.42 + function find_rightmost (ARG : UNRESOLVED_SIGNED; Y : STD_ULOGIC) + return INTEGER is + begin + for INDEX in ARG'reverse_range loop + if ARG(INDEX) ?= Y then + return INDEX; + end if; + end loop; + return -1; + end function find_rightmost; + + -- ============================================================================ + + -- Id: C.1 + function ">" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD."">"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return not UNSIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function ">"; + + -- Id: C.2 + function ">" (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD."">"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return not SIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function ">"; + + -- Id: C.3 + function ">" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return true; + end if; + return not UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R01'length), R01); + end function ">"; + + -- Id: C.4 + function ">" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L > 0; + end if; + return not SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R01'length), R01); + end function ">"; + + -- Id: C.5 + function ">" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return false; + end if; + return not UNSIGNED_LESS_OR_EQUAL(L01, TO_UNSIGNED(R, L01'length)); + end function ">"; + + -- Id: C.6 + function ">" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 > R; + end if; + return not SIGNED_LESS_OR_EQUAL(L01, TO_SIGNED(R, L01'length)); + end function ">"; + + -- ============================================================================ + + -- Id: C.7 + function "<" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""<"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return UNSIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function "<"; + + -- Id: C.8 + function "<" (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""<"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return SIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function "<"; + + -- Id: C.9 + function "<" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return UNSIGNED_LESS(TO_UNSIGNED(L, R01'length), R01); + end function "<"; + + -- Id: C.10 + function "<" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return SIGNED_LESS(TO_SIGNED(L, R01'length), R01); + end function "<"; + + -- Id: C.11 + function "<" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return UNSIGNED_LESS(L01, TO_UNSIGNED(R, L01'length)); + end function "<"; + + -- Id: C.12 + function "<" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""<"": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<"": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return SIGNED_LESS(L01, TO_SIGNED(R, L01'length)); + end function "<"; + + -- ============================================================================ + + -- Id: C.13 + function "<=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""<="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return UNSIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function "<="; + + -- Id: C.14 + function "<=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""<="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return SIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function "<="; + + -- Id: C.15 + function "<=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R01'length), R01); + end function "<="; + + -- Id: C.16 + function "<=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L < 0; + end if; + return SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R01'length), R01); + end function "<="; + + -- Id: C.17 + function "<=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + begin + if (L_LEFT < 0) then + assert NO_WARNING + report "NUMERIC_STD.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return UNSIGNED_LESS_OR_EQUAL(L01, TO_UNSIGNED(R, L01'length)); + end function "<="; + + -- Id: C.18 + function "<=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + begin + if (L_LEFT < 0) then + assert NO_WARNING + report "NUMERIC_STD.""<="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""<="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 < R; + end if; + return SIGNED_LESS_OR_EQUAL(L01, TO_SIGNED(R, L01'length)); + end function "<="; + + -- ============================================================================ + + -- Id: C.19 + function ">=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD."">="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return not UNSIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function ">="; + + -- Id: C.20 + function ">=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD."">="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return not SIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function ">="; + + -- Id: C.21 + function ">=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return L > 0; + end if; + return not UNSIGNED_LESS(TO_UNSIGNED(L, R01'length), R01); + end function ">="; + + -- Id: C.22 + function ">=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return L > 0; + end if; + return not SIGNED_LESS(TO_SIGNED(L, R01'length), R01); + end function ">="; + + -- Id: C.23 + function ">=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return 0 > R; + end if; + return not UNSIGNED_LESS(L01, TO_UNSIGNED(R, L01'length)); + end function ">="; + + -- Id: C.24 + function ">=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD."">="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD."">="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return 0 > R; + end if; + return not SIGNED_LESS(L01, TO_SIGNED(R, L01'length)); + end function ">="; + + -- ============================================================================ + + -- Id: C.25 + function "=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return UNSIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function "="; + + -- Id: C.26 + function "=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + return SIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)); + end function "="; + + -- Id: C.27 + function "=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return false; + end if; + return UNSIGNED_EQUAL(TO_UNSIGNED(L, R01'length), R01); + end function "="; + + -- Id: C.28 + function "=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(L) > R'length then return false; + end if; + return SIGNED_EQUAL(TO_SIGNED(L, R01'length), R01); + end function "="; + + -- Id: C.29 + function "=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return false; + end if; + return UNSIGNED_EQUAL(L01, TO_UNSIGNED(R, L01'length)); + end function "="; + + -- Id: C.30 + function "=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""="": null argument detected, returning FALSE" + severity warning; + return false; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""="": metavalue detected, returning FALSE" + severity warning; + return false; + end if; + if SIGNED_NUM_BITS(R) > L'length then return false; + end if; + return SIGNED_EQUAL(L01, TO_SIGNED(R, L01'length)); + end function "="; + + -- ============================================================================ + + -- Id: C.31 + function "/=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""/="": metavalue detected, returning TRUE" + severity warning; + return true; + end if; + return not(UNSIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE))); + end function "/="; + + -- Id: C.32 + function "/=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + L01 := TO_01(XL, 'X'); + R01 := TO_01(XR, 'X'); + if ((L01(L01'left) = 'X') or (R01(R01'left) = 'X')) then + assert NO_WARNING + report "NUMERIC_STD.""/="": metavalue detected, returning TRUE" + severity warning; + return true; + end if; + return not(SIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE))); + end function "/="; + + -- Id: C.33 + function "/=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_UNSIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""/="": metavalue detected, returning TRUE" + severity warning; + return true; + end if; + if UNSIGNED_NUM_BITS(L) > R'length then return true; + end if; + return not(UNSIGNED_EQUAL(TO_UNSIGNED(L, R01'length), R01)); + end function "/="; + + -- Id: C.34 + function "/=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN is + constant R_LEFT : INTEGER := R'length-1; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + variable R01 : UNRESOLVED_SIGNED(R_LEFT downto 0); + begin + if (R'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + R01 := TO_01(XR, 'X'); + if (R01(R01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""/="": metavalue detected, returning TRUE" + severity warning; + return true; + end if; + if SIGNED_NUM_BITS(L) > R'length then return true; + end if; + return not(SIGNED_EQUAL(TO_SIGNED(L, R01'length), R01)); + end function "/="; + + -- Id: C.35 + function "/=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_UNSIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""/="": metavalue detected, returning TRUE" + severity warning; + return true; + end if; + if UNSIGNED_NUM_BITS(R) > L'length then return true; + end if; + return not(UNSIGNED_EQUAL(L01, TO_UNSIGNED(R, L01'length))); + end function "/="; + + -- Id: C.36 + function "/=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN is + constant L_LEFT : INTEGER := L'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + variable L01 : UNRESOLVED_SIGNED(L_LEFT downto 0); + begin + if (L'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.""/="": null argument detected, returning TRUE" + severity warning; + return true; + end if; + L01 := TO_01(XL, 'X'); + if (L01(L01'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.""/="": metavalue detected, returning TRUE" + severity warning; + return true; + end if; + if SIGNED_NUM_BITS(R) > L'length then return true; + end if; + return not(SIGNED_EQUAL(L01, TO_SIGNED(R, L01'length))); + end function "/="; + + -- ============================================================================ + + -- Id: C.37 + function MINIMUM (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + if UNSIGNED_LESS(L01, R01) then + return L01; + else + return R01; + end if; + end function MINIMUM; + + -- Id: C.38 + function MINIMUM (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + if SIGNED_LESS(L01, R01) then + return L01; + else + return R01; + end if; + end function MINIMUM; + + -- Id: C.39 + function MINIMUM (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return MINIMUM(TO_UNSIGNED(L, R'length), R); + end function MINIMUM; + + -- Id: C.40 + function MINIMUM (L : INTEGER; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return MINIMUM(TO_SIGNED(L, R'length), R); + end function MINIMUM; + + -- Id: C.41 + function MINIMUM (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + return MINIMUM(L, TO_UNSIGNED(R, L'length)); + end function MINIMUM; + + -- Id: C.42 + function MINIMUM (L : UNRESOLVED_SIGNED; R : INTEGER) + return UNRESOLVED_SIGNED is + begin + return MINIMUM(L, TO_SIGNED(R, L'length)); + end function MINIMUM; + + -- ============================================================================ + + -- Id: C.43 + function MAXIMUM (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAU; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + if UNSIGNED_LESS(L01, R01) then + return R01; + else + return L01; + end if; + end function MAXIMUM; + + -- Id: C.44 + function MAXIMUM (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable L01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable R01 : UNRESOLVED_SIGNED(SIZE-1 downto 0); + begin + if ((L'length < 1) or (R'length < 1)) then return NAS; + end if; + L01 := TO_01(RESIZE(L, SIZE), 'X'); + if (L01(L01'left) = 'X') then return L01; + end if; + R01 := TO_01(RESIZE(R, SIZE), 'X'); + if (R01(R01'left) = 'X') then return R01; + end if; + if SIGNED_LESS(L01, R01) then + return R01; + else + return L01; + end if; + end function MAXIMUM; + + -- Id: C.45 + function MAXIMUM (L : NATURAL; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return MAXIMUM(TO_UNSIGNED(L, R'length), R); + end function MAXIMUM; + + -- Id: C.46 + function MAXIMUM (L : INTEGER; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return MAXIMUM(TO_SIGNED(L, R'length), R); + end function MAXIMUM; + + -- Id: C.47 + function MAXIMUM (L : UNRESOLVED_UNSIGNED; R : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + return MAXIMUM(L, TO_UNSIGNED(R, L'length)); + end function MAXIMUM; + + -- Id: C.48 + function MAXIMUM (L : UNRESOLVED_SIGNED; R : INTEGER) + return UNRESOLVED_SIGNED is + begin + return MAXIMUM(L, TO_SIGNED(R, L'length)); + end function MAXIMUM; + + -- ============================================================================ + + -- Id: C.49 + function "?>" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?>"": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?>"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?>"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L > R then + return '1'; + else + return '0'; + end if; + end if; + end function "?>"; + + -- Id: C.50 + function "?>" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?>"": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?>"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?>"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L > R then + return '1'; + else + return '0'; + end if; + end if; + end function "?>"; + + -- Id: C.51 + function "?>" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return TO_UNSIGNED(L, R'length) ?> R; + end function "?>"; + + -- Id: C.52 + function "?>" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return TO_SIGNED(L, R'length) ?> R; + end function "?>"; + + -- Id: C.53 + function "?>" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC is + begin + return L ?> TO_UNSIGNED(R, L'length); + end function "?>"; + + -- Id: C.54 + function "?>" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC is + begin + return L ?> TO_SIGNED(R, L'length); + end function "?>"; + + -- ============================================================================ + + -- Id: C.55 + function "?<" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?<"": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?<"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?<"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L < R then + return '1'; + else + return '0'; + end if; + end if; + end function "?<"; + + -- Id: C.56 + function "?<" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?<"": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?<"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?<"": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L < R then + return '1'; + else + return '0'; + end if; + end if; + end function "?<"; + + -- Id: C.57 + function "?<" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return TO_UNSIGNED(L, R'length) ?< R; + end function "?<"; + + -- Id: C.58 + function "?<" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return TO_SIGNED(L, R'length) ?< R; + end function "?<"; + + -- Id: C.59 + function "?<" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC is + begin + return L ?< TO_UNSIGNED(R, L'length); + end function "?<"; + + -- Id: C.60 + function "?<" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC is + begin + return L ?< TO_SIGNED(R, L'length); + end function "?<"; + + -- ============================================================================ + + -- Id: C.61 + function "?<=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?<="": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?<="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?<="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L <= R then + return '1'; + else + return '0'; + end if; + end if; + end function "?<="; + + -- Id: C.62 + function "?<=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?<="": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?<="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?<="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L <= R then + return '1'; + else + return '0'; + end if; + end if; + end function "?<="; + + -- Id: C.63 + function "?<=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return TO_UNSIGNED(L, R'length) ?<= R; + end function "?<="; + + -- Id: C.64 + function "?<=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return TO_SIGNED(L, R'length) ?<= R; + end function "?<="; + + -- Id: C.65 + function "?<=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC is + begin + return L ?<= TO_UNSIGNED(R, L'length); + end function "?<="; + + -- Id: C.66 + function "?<=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC is + begin + return L ?<= TO_SIGNED(R, L'length); + end function "?<="; + + -- ============================================================================ + + -- Id: C.67 + function "?>=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?>="": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?>="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?>="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L >= R then + return '1'; + else + return '0'; + end if; + end if; + end function "?>="; + + -- Id: C.68 + function "?>=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?>="": null detected, returning X" + severity warning; + return 'X'; + else + for i in L'range loop + if L(i) = '-' then + report "NUMERIC_STD.""?>="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + for i in R'range loop + if R(i) = '-' then + report "NUMERIC_STD.""?>="": '-' found in compare string" + severity error; + return 'X'; + end if; + end loop; + if Is_X(L) or Is_X(R) then + return 'X'; + elsif L >= R then + return '1'; + else + return '0'; + end if; + end if; + end function "?>="; + + -- Id: C.69 + function "?>=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return TO_UNSIGNED(L, R'length) ?>= R; + end function "?>="; + + -- Id: C.70 + function "?>=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return TO_SIGNED(L, R'length) ?>= R; + end function "?>="; + + -- Id: C.71 + function "?>=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC is + begin + return L ?>= TO_UNSIGNED(R, L'length); + end function "?>="; + + -- Id: C.72 + function "?>=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC is + begin + return L ?>= TO_SIGNED(R, L'length); + end function "?>="; + + -- ============================================================================ + + -- Id: C.73 + function "?=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable LX : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable RX : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable result, result1 : STD_ULOGIC; -- result + begin + -- Logically identical to an "=" operator. + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?="": null detected, returning X" + severity warning; + return 'X'; + else + LX := RESIZE(XL, SIZE); + RX := RESIZE(XR, SIZE); + result := '1'; + for i in LX'low to LX'high loop + result1 := LX(i) ?= RX(i); + if result1 = 'U' then + return 'U'; + elsif result1 = 'X' or result = 'X' then + result := 'X'; + else + result := result and result1; + end if; + end loop; + return result; + end if; + end function "?="; + + -- Id: C.74 + function "?=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable LX : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable RX : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable result, result1 : STD_ULOGIC; -- result + begin -- ?= + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?="": null detected, returning X" + severity warning; + return 'X'; + else + LX := RESIZE(XL, SIZE); + RX := RESIZE(XR, SIZE); + result := '1'; + for i in LX'low to LX'high loop + result1 := LX(i) ?= RX(i); + if result1 = 'U' then + return 'U'; + elsif result1 = 'X' or result = 'X' then + result := 'X'; + else + result := result and result1; + end if; + end loop; + return result; + end if; + end function "?="; + + -- Id: C.75 + function "?=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return TO_UNSIGNED(L, R'length) ?= R; + end function "?="; + + -- Id: C.76 + function "?=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return TO_SIGNED(L, R'length) ?= R; + end function "?="; + + -- Id: C.77 + function "?=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC is + begin + return L ?= TO_UNSIGNED(R, L'length); + end function "?="; + + -- Id: C.78 + function "?=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC is + begin + return L ?= TO_SIGNED(R, L'length); + end function "?="; + + -- ============================================================================ + + -- Id: C.79 + function "?/=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_UNSIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_UNSIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable LX : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable RX : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable result, result1 : STD_ULOGIC; -- result + begin -- ?= + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?/="": null detected, returning X" + severity warning; + return 'X'; + else + LX := RESIZE(XL, SIZE); + RX := RESIZE(XR, SIZE); + result := '0'; + for i in LX'low to LX'high loop + result1 := LX(i) ?/= RX(i); + if result1 = 'U' then + return 'U'; + elsif result1 = 'X' or result = 'X' then + result := 'X'; + else + result := result or result1; + end if; + end loop; + return result; + end if; + end function "?/="; + + -- Id: C.80 + function "?/=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC is + constant L_LEFT : INTEGER := L'length-1; + constant R_LEFT : INTEGER := R'length-1; + alias XL : UNRESOLVED_SIGNED(L_LEFT downto 0) is L; + alias XR : UNRESOLVED_SIGNED(R_LEFT downto 0) is R; + constant SIZE : NATURAL := MAXIMUM(L'length, R'length); + variable LX : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable RX : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable result, result1 : STD_ULOGIC; -- result + begin -- ?= + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.""?/="": null detected, returning X" + severity warning; + return 'X'; + else + LX := RESIZE(XL, SIZE); + RX := RESIZE(XR, SIZE); + result := '0'; + for i in LX'low to LX'high loop + result1 := LX(i) ?/= RX(i); + if result1 = 'U' then + return 'U'; + elsif result1 = 'X' or result = 'X' then + result := 'X'; + else + result := result or result1; + end if; + end loop; + return result; + end if; + end function "?/="; + + -- Id: C.81 + function "?/=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return TO_UNSIGNED(L, R'length) ?/= R; + end function "?/="; + + -- Id: C.82 + function "?/=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return TO_SIGNED(L, R'length) ?/= R; + end function "?/="; + + -- Id: C.83 + function "?/=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC is + begin + return L ?/= TO_UNSIGNED(R, L'length); + end function "?/="; + + -- Id: C.84 + function "?/=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC is + begin + return L ?/= TO_SIGNED(R, L'length); + end function "?/="; + + -- ============================================================================ + + -- Id: S.1 + function SHIFT_LEFT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNRESOLVED_UNSIGNED(XSLL(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function SHIFT_LEFT; + + -- Id: S.2 + function SHIFT_RIGHT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNRESOLVED_UNSIGNED(XSRL(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function SHIFT_RIGHT; + + -- Id: S.3 + function SHIFT_LEFT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) + return UNRESOLVED_SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return UNRESOLVED_SIGNED(XSLL(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function SHIFT_LEFT; + + -- Id: S.4 + function SHIFT_RIGHT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) + return UNRESOLVED_SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return UNRESOLVED_SIGNED(XSRA(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function SHIFT_RIGHT; + + -- ============================================================================ + + -- Id: S.5 + function ROTATE_LEFT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNRESOLVED_UNSIGNED(XROL(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function ROTATE_LEFT; + + -- Id: S.6 + function ROTATE_RIGHT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) + return UNRESOLVED_UNSIGNED is + begin + if (ARG'length < 1) then return NAU; + end if; + return UNRESOLVED_UNSIGNED(XROR(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function ROTATE_RIGHT; + + + -- Id: S.7 + function ROTATE_LEFT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) + return UNRESOLVED_SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return UNRESOLVED_SIGNED(XROL(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function ROTATE_LEFT; + + -- Id: S.8 + function ROTATE_RIGHT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) + return UNRESOLVED_SIGNED is + begin + if (ARG'length < 1) then return NAS; + end if; + return UNRESOLVED_SIGNED(XROR(STD_ULOGIC_VECTOR(ARG), COUNT)); + end function ROTATE_RIGHT; + + -- ============================================================================ + + ------------------------------------------------------------------------------ + -- Note: Function S.9 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.9 + function "sll" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) + return UNRESOLVED_UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return SHIFT_RIGHT(ARG, -COUNT); + end if; + end function "sll"; + + ------------------------------------------------------------------------------ + -- Note: Function S.10 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.10 + function "sll" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) + return UNRESOLVED_SIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return UNRESOLVED_SIGNED(SHIFT_RIGHT(UNRESOLVED_UNSIGNED(ARG), -COUNT)); + end if; + end function "sll"; + + ------------------------------------------------------------------------------ + -- Note: Function S.11 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.11 + function "srl" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) + return UNRESOLVED_UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_RIGHT(ARG, COUNT); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "srl"; + + ------------------------------------------------------------------------------ + -- Note: Function S.12 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.12 + function "srl" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) + return UNRESOLVED_SIGNED is + begin + if (COUNT >= 0) then + return UNRESOLVED_SIGNED(SHIFT_RIGHT(UNRESOLVED_UNSIGNED(ARG), COUNT)); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "srl"; + + ------------------------------------------------------------------------------ + -- Note: Function S.13 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.13 + function "rol" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) + return UNRESOLVED_UNSIGNED is + begin + if (COUNT >= 0) then + return ROTATE_LEFT(ARG, COUNT); + else + return ROTATE_RIGHT(ARG, -COUNT); + end if; + end function "rol"; + + ------------------------------------------------------------------------------ + -- Note: Function S.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.14 + function "rol" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) + return UNRESOLVED_SIGNED is + begin + if (COUNT >= 0) then + return ROTATE_LEFT(ARG, COUNT); + else + return ROTATE_RIGHT(ARG, -COUNT); + end if; + end function "rol"; + + ------------------------------------------------------------------------------ + -- Note: Function S.15 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.15 + function "ror" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) + return UNRESOLVED_UNSIGNED is + begin + if (COUNT >= 0) then + return ROTATE_RIGHT(ARG, COUNT); + else + return ROTATE_LEFT(ARG, -COUNT); + end if; + end function "ror"; + + ------------------------------------------------------------------------------ + -- Note: Function S.16 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.16 + function "ror" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) + return UNRESOLVED_SIGNED is + begin + if (COUNT >= 0) then + return ROTATE_RIGHT(ARG, COUNT); + else + return ROTATE_LEFT(ARG, -COUNT); + end if; + end function "ror"; + + ------------------------------------------------------------------------------ + -- Note: Function S.17 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.17 + function "sla" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) + return UNRESOLVED_UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return SHIFT_RIGHT(ARG, -COUNT); + end if; + end function "sla"; + + ------------------------------------------------------------------------------ + -- Note: Function S.18 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.18 + function "sla" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) + return UNRESOLVED_SIGNED is + begin + if (COUNT >= 0) then + return SHIFT_LEFT(ARG, COUNT); + else + return SHIFT_RIGHT(ARG, -COUNT); + end if; + end function "sla"; + + ------------------------------------------------------------------------------ + -- Note: Function S.19 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.19 + function "sra" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) + return UNRESOLVED_UNSIGNED is + begin + if (COUNT >= 0) then + return SHIFT_RIGHT(ARG, COUNT); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "sra"; + + ------------------------------------------------------------------------------ + -- Note: Function S.20 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.20 + function "sra" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) + return UNRESOLVED_SIGNED is + begin + if (COUNT >= 0) then + return SHIFT_RIGHT(ARG, COUNT); + else + return SHIFT_LEFT(ARG, -COUNT); + end if; + end function "sra"; + + -- ============================================================================ + + -- Id: D.1 + function TO_INTEGER (ARG : UNRESOLVED_UNSIGNED) return NATURAL is + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XXARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is ARG; + variable XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0); + variable RESULT : NATURAL := 0; + begin + if (ARG'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.TO_INTEGER: null detected, returning 0" + severity warning; + return 0; + end if; + XARG := TO_01(XXARG, 'X'); + if (XARG(XARG'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0" + severity warning; + return 0; + end if; + for I in XARG'range loop + RESULT := RESULT+RESULT; + if XARG(I) = '1' then + RESULT := RESULT + 1; + end if; + end loop; + return RESULT; + end function TO_INTEGER; + + -- Id: D.2 + function TO_INTEGER (ARG : UNRESOLVED_SIGNED) return INTEGER is + variable XARG : UNRESOLVED_SIGNED(ARG'length-1 downto 0); + begin + if (ARG'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.TO_INTEGER: null detected, returning 0" + severity warning; + return 0; + end if; + XARG := TO_01(ARG, 'X'); + if (XARG(XARG'left) = 'X') then + assert NO_WARNING + report "NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0" + severity warning; + return 0; + end if; + if XARG(XARG'left) = '0' then + return TO_INTEGER(UNRESOLVED_UNSIGNED(XARG)); + else + return (- (TO_INTEGER(UNRESOLVED_UNSIGNED(- (XARG + 1)))) -1); + end if; + end function TO_INTEGER; + + -- Id: D.3 + function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(SIZE-1 downto 0); + variable I_VAL : NATURAL := ARG; + begin + if (SIZE < 1) then return NAU; + end if; + for I in 0 to RESULT'left loop + if (I_VAL mod 2) = 0 then + RESULT(I) := '0'; + else RESULT(I) := '1'; + end if; + I_VAL := I_VAL/2; + end loop; + if not(I_VAL = 0) then + assert NO_WARNING + report "NUMERIC_STD.TO_UNSIGNED: vector truncated" + severity warning; + end if; + return RESULT; + end function TO_UNSIGNED; + + -- Id: D.4 + function TO_SIGNED (ARG : INTEGER; SIZE : NATURAL) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(SIZE-1 downto 0); + variable B_VAL : STD_LOGIC := '0'; + variable I_VAL : INTEGER := ARG; + begin + if (SIZE < 1) then return NAS; + end if; + if (ARG < 0) then + B_VAL := '1'; + I_VAL := -(ARG+1); + end if; + for I in 0 to RESULT'left loop + if (I_VAL mod 2) = 0 then + RESULT(I) := B_VAL; + else + RESULT(I) := not B_VAL; + end if; + I_VAL := I_VAL/2; + end loop; + if ((I_VAL /= 0) or (B_VAL /= RESULT(RESULT'left))) then + assert NO_WARNING + report "NUMERIC_STD.TO_SIGNED: vector truncated" + severity warning; + end if; + return RESULT; + end function TO_SIGNED; + + function TO_UNSIGNED (ARG : NATURAL; SIZE_RES : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return TO_UNSIGNED (ARG => ARG, + SIZE => SIZE_RES'length); + end function TO_UNSIGNED; + + function TO_SIGNED (ARG : INTEGER; SIZE_RES : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return TO_SIGNED (ARG => ARG, + SIZE => SIZE_RES'length); + end function TO_SIGNED; + + -- ============================================================================ + + -- Id: R.1 + function RESIZE (ARG : UNRESOLVED_SIGNED; NEW_SIZE : NATURAL) + return UNRESOLVED_SIGNED + is + alias INVEC : UNRESOLVED_SIGNED(ARG'length-1 downto 0) is ARG; + variable RESULT : UNRESOLVED_SIGNED(NEW_SIZE-1 downto 0) := + (others => '0'); + constant BOUND : INTEGER := MINIMUM(ARG'length, RESULT'length)-2; + begin + if (NEW_SIZE < 1) then return NAS; + end if; + if (ARG'length = 0) then return RESULT; + end if; + RESULT := (others => ARG(ARG'left)); + if BOUND >= 0 then + RESULT(BOUND downto 0) := INVEC(BOUND downto 0); + end if; + return RESULT; + end function RESIZE; + + -- Id: R.2 + function RESIZE (ARG : UNRESOLVED_UNSIGNED; NEW_SIZE : NATURAL) + return UNRESOLVED_UNSIGNED + is + constant ARG_LEFT : INTEGER := ARG'length-1; + alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is ARG; + variable RESULT : UNRESOLVED_UNSIGNED(NEW_SIZE-1 downto 0) := + (others => '0'); + begin + if (NEW_SIZE < 1) then return NAU; + end if; + if XARG'length = 0 then return RESULT; + end if; + if (RESULT'length < ARG'length) then + RESULT(RESULT'left downto 0) := XARG(RESULT'left downto 0); + else + RESULT(RESULT'left downto XARG'left+1) := (others => '0'); + RESULT(XARG'left downto 0) := XARG; + end if; + return RESULT; + end function RESIZE; + + function RESIZE (ARG, SIZE_RES : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return RESIZE (ARG => ARG, + NEW_SIZE => SIZE_RES'length); + end function RESIZE; + + function RESIZE (ARG, SIZE_RES : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return RESIZE (ARG => ARG, + NEW_SIZE => SIZE_RES'length); + end function RESIZE; + + -- ============================================================================ + + -- Id: L.1 + function "not" (L : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_UNSIGNED(not(STD_ULOGIC_VECTOR(L))); + return RESULT; + end function "not"; + + -- Id: L.2 + function "and" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_UNSIGNED(STD_ULOGIC_VECTOR(L) and + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "and"; + + -- Id: L.3 + function "or" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_UNSIGNED(STD_ULOGIC_VECTOR(L) or + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "or"; + + -- Id: L.4 + function "nand" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_UNSIGNED(STD_ULOGIC_VECTOR(L) nand + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "nand"; + + -- Id: L.5 + function "nor" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_UNSIGNED(STD_ULOGIC_VECTOR(L) nor + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "nor"; + + -- Id: L.6 + function "xor" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_UNSIGNED(STD_ULOGIC_VECTOR(L) xor + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.7 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.7 + function "xnor" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + variable RESULT : UNRESOLVED_UNSIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_UNSIGNED(STD_ULOGIC_VECTOR(L) xnor + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "xnor"; + + -- Id: L.8 + function "not" (L : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_SIGNED(not(STD_ULOGIC_VECTOR(L))); + return RESULT; + end function "not"; + + -- Id: L.9 + function "and" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_SIGNED(STD_ULOGIC_VECTOR(L) and STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "and"; + + -- Id: L.10 + function "or" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_SIGNED(STD_ULOGIC_VECTOR(L) or STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "or"; + + -- Id: L.11 + function "nand" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_SIGNED(STD_ULOGIC_VECTOR(L) nand + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "nand"; + + -- Id: L.12 + function "nor" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_SIGNED(STD_ULOGIC_VECTOR(L) nor STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "nor"; + + -- Id: L.13 + function "xor" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_SIGNED(STD_ULOGIC_VECTOR(L) xor STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.14 + function "xnor" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + variable RESULT : UNRESOLVED_SIGNED(L'length-1 downto 0); + begin + RESULT := UNRESOLVED_SIGNED(STD_ULOGIC_VECTOR(L) xnor + STD_ULOGIC_VECTOR(R)); + return RESULT; + end function "xnor"; + + -- Id: L.15 + function "and" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (L and STD_ULOGIC_VECTOR(R)); + end function "and"; + + -- Id: L.16 + function "and" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (STD_ULOGIC_VECTOR(L) and R); + end function "and"; + + -- Id: L.17 + function "or" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (L or STD_ULOGIC_VECTOR(R)); + end function "or"; + + -- Id: L.18 + function "or" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (STD_ULOGIC_VECTOR(L) or R); + end function "or"; + + -- Id: L.19 + function "nand" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (L nand STD_ULOGIC_VECTOR(R)); + end function "nand"; + + -- Id: L.20 + function "nand" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (STD_ULOGIC_VECTOR(L) nand R); + end function "nand"; + + -- Id: L.21 + function "nor" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (L nor STD_ULOGIC_VECTOR(R)); + end function "nor"; + + -- Id: L.22 + function "nor" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (STD_ULOGIC_VECTOR(L) nor R); + end function "nor"; + + -- Id: L.23 + function "xor" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (L xor STD_ULOGIC_VECTOR(R)); + end function "xor"; + + -- Id: L.24 + function "xor" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (STD_ULOGIC_VECTOR(L) xor R); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.25 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.25 + function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (L xnor STD_ULOGIC_VECTOR(R)); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.26 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.26 + function "xnor" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) + return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED (STD_ULOGIC_VECTOR(L) xnor R); + end function "xnor"; + + -- Id: L.27 + function "and" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (L and STD_ULOGIC_VECTOR(R)); + end function "and"; + + -- Id: L.28 + function "and" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (STD_ULOGIC_VECTOR(L) and R); + end function "and"; + + -- Id: L.29 + function "or" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (L or STD_ULOGIC_VECTOR(R)); + end function "or"; + + -- Id: L.30 + function "or" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (STD_ULOGIC_VECTOR(L) or R); + end function "or"; + + -- Id: L.31 + function "nand" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (L nand STD_ULOGIC_VECTOR(R)); + end function "nand"; + + -- Id: L.32 + function "nand" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (STD_ULOGIC_VECTOR(L) nand R); + end function "nand"; + + -- Id: L.33 + function "nor" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (L nor STD_ULOGIC_VECTOR(R)); + end function "nor"; + + -- Id: L.34 + function "nor" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (STD_ULOGIC_VECTOR(L) nor R); + end function "nor"; + + -- Id: L.35 + function "xor" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (L xor STD_ULOGIC_VECTOR(R)); + end function "xor"; + + -- Id: L.36 + function "xor" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (STD_ULOGIC_VECTOR(L) xor R); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.37 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.37 + function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (L xnor STD_ULOGIC_VECTOR(R)); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.38 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.38 + function "xnor" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) + return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED (STD_ULOGIC_VECTOR(L) xnor R); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.39 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.39 + function "and" (L : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return and (STD_ULOGIC_VECTOR (L)); + end function "and"; + + ------------------------------------------------------------------------------ + -- Note: Function L.40 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.40 + function "and" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return and (STD_ULOGIC_VECTOR (L)); + end function "and"; + + ------------------------------------------------------------------------------ + -- Note: Function L.41 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.41 + function "nand" (L : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return nand (STD_ULOGIC_VECTOR (L)); + end function "nand"; + + ------------------------------------------------------------------------------ + -- Note: Function L.42 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.42 + function "nand" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return nand (STD_ULOGIC_VECTOR (L)); + end function "nand"; + + ------------------------------------------------------------------------------ + -- Note: Function L.43 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.43 + function "or" (L : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return or (STD_ULOGIC_VECTOR (L)); + end function "or"; + + ------------------------------------------------------------------------------ + -- Note: Function L.44 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.44 + function "or" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return or (STD_ULOGIC_VECTOR (L)); + end function "or"; + + ------------------------------------------------------------------------------ + -- Note: Function L.45 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.45 + function "nor" (L : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return nor (STD_ULOGIC_VECTOR (L)); + end function "nor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.46 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.46 + function "nor" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return nor (STD_ULOGIC_VECTOR (L)); + end function "nor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.47 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.47 + function "xor" (L : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return xor (STD_ULOGIC_VECTOR (L)); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.48 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.48 + function "xor" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return xor (STD_ULOGIC_VECTOR (L)); + end function "xor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.49 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.49 + function "xnor" (L : UNRESOLVED_SIGNED) return STD_ULOGIC is + begin + return xnor (STD_ULOGIC_VECTOR (L)); + end function "xnor"; + + ------------------------------------------------------------------------------ + -- Note: Function L.50 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.50 + function "xnor" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC is + begin + return xnor (STD_ULOGIC_VECTOR (L)); + end function "xnor"; + + -- ============================================================================ + + -- support constants for STD_MATCH: + + type BOOLEAN_TABLE is array(STD_ULOGIC, STD_ULOGIC) of BOOLEAN; + + constant MATCH_TABLE : BOOLEAN_TABLE := ( + -------------------------------------------------------------------------- + -- U X 0 1 Z W L H - + -------------------------------------------------------------------------- + (false, false, false, false, false, false, false, false, true), -- | U | + (false, false, false, false, false, false, false, false, true), -- | X | + (false, false, true, false, false, false, true, false, true), -- | 0 | + (false, false, false, true, false, false, false, true, true), -- | 1 | + (false, false, false, false, false, false, false, false, true), -- | Z | + (false, false, false, false, false, false, false, false, true), -- | W | + (false, false, true, false, false, false, true, false, true), -- | L | + (false, false, false, true, false, false, false, true, true), -- | H | + (true, true, true, true, true, true, true, true, true) -- | - | + ); + + -- Id: M.1 + function STD_MATCH (L, R : STD_ULOGIC) return BOOLEAN is + variable VALUE : STD_ULOGIC; + begin + return MATCH_TABLE(L, R); + end function STD_MATCH; + + -- Id: M.2 + function STD_MATCH (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN is + alias LV : UNRESOLVED_UNSIGNED(1 to L'length) is L; + alias RV : UNRESOLVED_UNSIGNED(1 to R'length) is R; + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE" + severity warning; + return false; + end if; + if LV'length /= RV'length then + assert NO_WARNING + report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE" + severity warning; + return false; + else + for I in LV'low to LV'high loop + if not (MATCH_TABLE(LV(I), RV(I))) then + return false; + end if; + end loop; + return true; + end if; + end function STD_MATCH; + + -- Id: M.3 + function STD_MATCH (L, R : UNRESOLVED_SIGNED) return BOOLEAN is + alias LV : UNRESOLVED_SIGNED(1 to L'length) is L; + alias RV : UNRESOLVED_SIGNED(1 to R'length) is R; + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE" + severity warning; + return false; + end if; + if LV'length /= RV'length then + assert NO_WARNING + report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE" + severity warning; + return false; + else + for I in LV'low to LV'high loop + if not (MATCH_TABLE(LV(I), RV(I))) then + return false; + end if; + end loop; + return true; + end if; + end function STD_MATCH; + + -- Id: M.5 + function STD_MATCH (L, R : STD_ULOGIC_VECTOR) return BOOLEAN is + alias LV : STD_ULOGIC_VECTOR(1 to L'length) is L; + alias RV : STD_ULOGIC_VECTOR(1 to R'length) is R; + begin + if ((L'length < 1) or (R'length < 1)) then + assert NO_WARNING + report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE" + severity warning; + return false; + end if; + if LV'length /= RV'length then + assert NO_WARNING + report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE" + severity warning; + return false; + else + for I in LV'low to LV'high loop + if not (MATCH_TABLE(LV(I), RV(I))) then + return false; + end if; + end loop; + return true; + end if; + end function STD_MATCH; + + -- ============================================================================ + + -- function TO_01 is used to convert vectors to the + -- correct form for exported functions, + -- and to report if there is an element which + -- is not in (0, 1, H, L). + + -- Id: T.1 + function TO_01 (S : UNRESOLVED_UNSIGNED; XMAP : STD_ULOGIC := '0') + return UNRESOLVED_UNSIGNED is + begin + if (S'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.TO_01: null detected, returning NAU" + severity warning; + return NAU; + end if; + return UNRESOLVED_UNSIGNED(TO_01(STD_ULOGIC_VECTOR(S), XMAP)); + end function TO_01; + + -- Id: T.2 + function TO_01 (S : UNRESOLVED_SIGNED; XMAP : STD_ULOGIC := '0') + return UNRESOLVED_SIGNED is + begin + if (S'length < 1) then + assert NO_WARNING + report "NUMERIC_STD.TO_01: null detected, returning NAS" + severity warning; + return NAS; + end if; + return UNRESOLVED_SIGNED(TO_01(STD_ULOGIC_VECTOR(S), XMAP)); + end function TO_01; + + -- Id: T.3 + function TO_X01 (S : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED(TO_X01(STD_ULOGIC_VECTOR(S))); + end function TO_X01; + + -- Id: T.4 + function TO_X01 (S : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED(TO_X01(STD_ULOGIC_VECTOR(S))); + end function TO_X01; + + -- Id: T.5 + function TO_X01Z (S : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED(TO_X01Z(STD_ULOGIC_VECTOR(S))); + end function TO_X01Z; + + -- Id: T.6 + function TO_X01Z (S : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED(TO_X01Z(STD_ULOGIC_VECTOR(S))); + end function TO_X01Z; + + -- Id: T.7 + function TO_UX01 (S : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED is + begin + return UNRESOLVED_UNSIGNED(TO_UX01(STD_ULOGIC_VECTOR(S))); + end function TO_UX01; + + -- Id: T.8 + function TO_UX01 (S : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED is + begin + return UNRESOLVED_SIGNED(TO_UX01(STD_ULOGIC_VECTOR(S))); + end function TO_UX01; + + -- Id: T.9 + function IS_X (S : UNRESOLVED_UNSIGNED) return BOOLEAN is + begin + return IS_X(STD_ULOGIC_VECTOR(S)); + end function IS_X; + + -- Id: T.10 + function IS_X (S : UNRESOLVED_SIGNED) return BOOLEAN is + begin + return IS_X(STD_ULOGIC_VECTOR(S)); + end function IS_X; + + -- ============================================================================ + -- string conversion and write operations + -- ============================================================================ + function to_ostring (value : UNRESOLVED_UNSIGNED) return STRING is + begin + return to_ostring(STD_ULOGIC_VECTOR (value)); + end function to_ostring; + + function to_ostring (value : UNRESOLVED_SIGNED) return STRING is + constant result_length : INTEGER := (value'length+2)/3; + constant pad : STD_ULOGIC_VECTOR(1 to (result_length*3 - + value'length)) + := (others => value (value'left)); -- Extend sign bit + begin + return to_ostring(pad & STD_ULOGIC_VECTOR (value)); + end function to_ostring; + + function to_hstring (value : UNRESOLVED_UNSIGNED) return STRING is + begin + return to_hstring(STD_ULOGIC_VECTOR (value)); + end function to_hstring; + + function to_hstring (value : UNRESOLVED_SIGNED) return STRING is + constant result_length : INTEGER := (value'length+3)/4; + constant pad : STD_ULOGIC_VECTOR(1 to (result_length*4 - + value'length)) + := (others => value (value'left)); -- Extend sign bit + begin + return to_hstring(pad & STD_ULOGIC_VECTOR (value)); + end function to_hstring; + + procedure READ (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED; + GOOD : out BOOLEAN) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := UNSIGNED(ivalue); + end procedure READ; + + procedure READ (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue); + VALUE := UNSIGNED (ivalue); + end procedure READ; + + procedure READ (L : inout LINE; VALUE : out UNRESOLVED_SIGNED; + GOOD : out BOOLEAN) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := SIGNED(ivalue); + end procedure READ; + + procedure READ (L : inout LINE; VALUE : out UNRESOLVED_SIGNED) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + READ (L => L, + VALUE => ivalue); + VALUE := SIGNED (ivalue); + end procedure READ; + + procedure WRITE (L : inout LINE; VALUE : in UNRESOLVED_UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + ivalue := STD_ULOGIC_VECTOR (VALUE); + WRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure WRITE; + + procedure WRITE (L : inout LINE; VALUE : in UNRESOLVED_SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + ivalue := STD_ULOGIC_VECTOR (VALUE); + WRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure WRITE; + + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED; + GOOD : out BOOLEAN) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + OREAD (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := UNSIGNED(ivalue); + end procedure OREAD; + + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED; + GOOD : out BOOLEAN) is + constant ne : INTEGER := (value'length+2)/3; + constant pad : INTEGER := ne*3 - value'length; + variable ivalue : STD_ULOGIC_VECTOR(0 to ne*3-1); + variable ok : BOOLEAN; + variable expected_padding : STD_ULOGIC_VECTOR(0 to pad-1); + begin + OREAD (L => L, + VALUE => ivalue, -- Read padded STRING + GOOD => ok); + -- Bail out if there was a bad read + if not ok then + GOOD := false; + return; + end if; + expected_padding := (others => ivalue(pad)); + if ivalue(0 to pad-1) /= expected_padding then + GOOD := false; + else + GOOD := true; + VALUE := UNRESOLVED_SIGNED (ivalue (pad to ivalue'high)); + end if; + end procedure OREAD; + + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + OREAD (L => L, + VALUE => ivalue); + VALUE := UNSIGNED (ivalue); + end procedure OREAD; + + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED) is + constant ne : INTEGER := (value'length+2)/3; + constant pad : INTEGER := ne*3 - value'length; + variable ivalue : STD_ULOGIC_VECTOR(0 to ne*3-1); + variable expected_padding : STD_ULOGIC_VECTOR(0 to pad-1); + begin + OREAD (L => L, + VALUE => ivalue); -- Read padded string + expected_padding := (others => ivalue(pad)); + if ivalue(0 to pad-1) /= expected_padding then + assert false + report "NUMERIC_STD.OREAD Error: Signed vector truncated" + severity error; + else + VALUE := UNRESOLVED_SIGNED (ivalue (pad to ivalue'high)); + end if; + end procedure OREAD; + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED; + GOOD : out BOOLEAN) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + HREAD (L => L, + VALUE => ivalue, + GOOD => GOOD); + VALUE := UNSIGNED(ivalue); + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED; + GOOD : out BOOLEAN) is + constant ne : INTEGER := (value'length+3)/4; + constant pad : INTEGER := ne*4 - value'length; + variable ivalue : STD_ULOGIC_VECTOR(0 to ne*4-1); + variable ok : BOOLEAN; + variable expected_padding : STD_ULOGIC_VECTOR(0 to pad-1); + begin + HREAD (L => L, + VALUE => ivalue, -- Read padded STRING + GOOD => ok); + if not ok then + GOOD := false; + return; + end if; + expected_padding := (others => ivalue(pad)); + if ivalue(0 to pad-1) /= expected_padding then + GOOD := false; + else + GOOD := true; + VALUE := UNRESOLVED_SIGNED (ivalue (pad to ivalue'high)); + end if; + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + HREAD (L => L, + VALUE => ivalue); + VALUE := UNSIGNED (ivalue); + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED) is + constant ne : INTEGER := (value'length+3)/4; + constant pad : INTEGER := ne*4 - value'length; + variable ivalue : STD_ULOGIC_VECTOR(0 to ne*4-1); + variable expected_padding : STD_ULOGIC_VECTOR(0 to pad-1); + begin + HREAD (L => L, + VALUE => ivalue); -- Read padded string + expected_padding := (others => ivalue(pad)); + if ivalue(0 to pad-1) /= expected_padding then + assert false + report "NUMERIC_STD.HREAD Error: Signed vector truncated" + severity error; + else + VALUE := UNRESOLVED_SIGNED (ivalue (pad to ivalue'high)); + end if; + end procedure HREAD; + + procedure OWRITE (L : inout LINE; VALUE : in UNRESOLVED_UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + ivalue := STD_ULOGIC_VECTOR (VALUE); + OWRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure OWRITE; + + procedure OWRITE (L : inout LINE; VALUE : in UNRESOLVED_SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + constant ne : INTEGER := (VALUE'length+2)/3; + constant pad : STD_ULOGIC_VECTOR(0 to (ne*3 - VALUE'length) - 1) + := (others => VALUE (VALUE'left)); + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + ivalue := STD_ULOGIC_VECTOR (VALUE); + OWRITE (L => L, + VALUE => pad & ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure OWRITE; + + procedure HWRITE (L : inout LINE; VALUE : in UNRESOLVED_UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + begin + ivalue := STD_ULOGIC_VECTOR (VALUE); + HWRITE (L => L, + VALUE => ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure HWRITE; + + procedure HWRITE (L : inout LINE; VALUE : in UNRESOLVED_SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable ivalue : STD_ULOGIC_VECTOR(value'range); + constant ne : INTEGER := (value'length+3)/4; + constant pad : STD_ULOGIC_VECTOR(0 to (ne*4 - value'length) - 1) + := (others => VALUE(VALUE'left)); + begin + ivalue := STD_ULOGIC_VECTOR (VALUE); + HWRITE (L => L, + VALUE => pad & ivalue, + JUSTIFIED => JUSTIFIED, + FIELD => FIELD); + end procedure HWRITE; + +end package body NUMERIC_STD; diff --git a/libraries/ieee2008/numeric_std.vhdl b/libraries/ieee2008/numeric_std.vhdl new file mode 100644 index 000000000..3ce4357d2 --- /dev/null +++ b/libraries/ieee2008/numeric_std.vhdl @@ -0,0 +1,1683 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard VHDL Synthesis Packages +-- : (NUMERIC_STD package declaration) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE DASC Synthesis Working Group, +-- : Accellera VHDL-TC, and IEEE P1076 Working Group +-- : +-- Purpose : This package defines numeric types and arithmetic functions +-- : for use with synthesis tools. Two numeric types are defined: +-- : -- > UNRESOLVED_UNSIGNED: represents an UNSIGNED number +-- : in vector form +-- : -- > UNRESOLVED_SIGNED: represents a SIGNED number +-- : in vector form +-- : The base element type is type STD_ULOGIC. +-- : Aliases U_UNSIGNED and U_SIGNED are defined for the types +-- : UNRESOLVED_UNSIGNED and UNRESOLVED_SIGNED, respectively. +-- : Two numeric subtypes are defined: +-- : -- > UNSIGNED: represents UNSIGNED number in vector form +-- : -- > SIGNED: represents a SIGNED number in vector form +-- : The element subtypes are the same subtype as STD_LOGIC. +-- : The leftmost bit is treated as the most significant bit. +-- : Signed vectors are represented in two's complement form. +-- : This package contains overloaded arithmetic operators on +-- : the SIGNED and UNSIGNED types. The package also contains +-- : useful type conversions functions, clock detection +-- : functions, and other utility functions. +-- : +-- : If any argument to a function is a null array, a null array +-- : is returned (exceptions, if any, are noted individually). +-- +-- 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) $ +-- -------------------------------------------------------------------- + +use STD.TEXTIO.all; +library IEEE; +use IEEE.STD_LOGIC_1164.all; + +package NUMERIC_STD is + constant CopyRightNotice : STRING + := "Copyright 2008 IEEE. All rights reserved."; + + + --============================================================================ + -- Numeric Array Type Definitions + --============================================================================ + + type UNRESOLVED_UNSIGNED is array (NATURAL range <>) of STD_ULOGIC; + type UNRESOLVED_SIGNED is array (NATURAL range <>) of STD_ULOGIC; + + -- FIXME: was alias + subtype U_UNSIGNED is UNRESOLVED_UNSIGNED; + subtype U_SIGNED is UNRESOLVED_SIGNED; + + subtype UNSIGNED is (resolved) UNRESOLVED_UNSIGNED; + subtype SIGNED is (resolved) UNRESOLVED_SIGNED; + + --============================================================================ + -- Arithmetic Operators: + --=========================================================================== + + -- Id: A.1 + function "abs" (ARG : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Returns the absolute value of an UNRESOLVED_SIGNED vector ARG. + + -- Id: A.2 + function "-" (ARG : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Returns the value of the unary minus operation on a + -- UNRESOLVED_SIGNED vector ARG. + + --============================================================================ + + -- Id: A.3 + function "+" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Adds two UNRESOLVED_UNSIGNED vectors that may be of different lengths. + + -- Id: A.3R + function "+"(L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.3 where R is a one bit UNRESOLVED_UNSIGNED + + -- Id: A.3L + function "+"(L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.3 where L is a one bit UNRESOLVED_UNSIGNED + + -- Id: A.4 + function "+" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Adds two UNRESOLVED_SIGNED vectors that may be of different lengths. + + -- Id: A.4R + function "+"(L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.4 where R is bit 0 of a non-negative. + + -- Id: A.4L + function "+"(L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.4 where L is bit 0 of a non-negative. + + -- Id: A.5 + function "+" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Adds an UNRESOLVED_UNSIGNED vector, L, with a nonnegative INTEGER, R. + + -- Id: A.6 + function "+" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Adds a nonnegative INTEGER, L, with an UNRESOLVED_UNSIGNED vector, R. + + -- Id: A.7 + function "+" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Adds an INTEGER, L(may be positive or negative), to an UNRESOLVED_SIGNED + -- vector, R. + + -- Id: A.8 + function "+" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Adds an UNRESOLVED_SIGNED vector, L, to an INTEGER, R. + + --============================================================================ + + -- Id: A.9 + function "-" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Subtracts two UNRESOLVED_UNSIGNED vectors that may be of different lengths. + + -- Id: A.9R + function "-"(L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.9 where R is a one bit UNRESOLVED_UNSIGNED + + -- Id: A.9L + function "-"(L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.9 where L is a one bit UNRESOLVED_UNSIGNED + + -- Id: A.10 + function "-" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0) + -- Result: Subtracts an UNRESOLVED_SIGNED vector, R, from another UNRESOLVED_SIGNED vector, L, + -- that may possibly be of different lengths. + + -- Id: A.10R + function "-"(L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Similar to A.10 where R is bit 0 of a non-negative. + + -- Id: A.10L + function "-"(L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Similar to A.10 where R is bit 0 of a non-negative. + + -- Id: A.11 + function "-" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Subtracts a nonnegative INTEGER, R, from an UNRESOLVED_UNSIGNED vector, L. + + -- Id: A.12 + function "-" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Subtracts an UNRESOLVED_UNSIGNED vector, R, from a nonnegative INTEGER, L. + + -- Id: A.13 + function "-" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Subtracts an INTEGER, R, from an UNRESOLVED_SIGNED vector, L. + + -- Id: A.14 + function "-" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Subtracts an UNRESOLVED_SIGNED vector, R, from an INTEGER, L. + + --============================================================================ + + -- Id: A.15 + function "*" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0) + -- Result: Performs the multiplication operation on two UNRESOLVED_UNSIGNED vectors + -- that may possibly be of different lengths. + + -- Id: A.16 + function "*" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED((L'LENGTH+R'LENGTH-1) downto 0) + -- Result: Multiplies two UNRESOLVED_SIGNED vectors that may possibly be of + -- different lengths. + + -- Id: A.17 + function "*" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0) + -- Result: Multiplies an UNRESOLVED_UNSIGNED vector, L, with a nonnegative + -- INTEGER, R. R is converted to an UNRESOLVED_UNSIGNED vector of + -- SIZE L'LENGTH before multiplication. + + -- Id: A.18 + function "*" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0) + -- Result: Multiplies an UNRESOLVED_UNSIGNED vector, R, with a nonnegative + -- INTEGER, L. L is converted to an UNRESOLVED_UNSIGNED vector of + -- SIZE R'LENGTH before multiplication. + + -- Id: A.19 + function "*" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED((L'LENGTH+L'LENGTH-1) downto 0) + -- Result: Multiplies an UNRESOLVED_SIGNED vector, L, with an INTEGER, R. R is + -- converted to an UNRESOLVED_SIGNED vector of SIZE L'LENGTH before + -- multiplication. + + -- Id: A.20 + function "*" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED((R'LENGTH+R'LENGTH-1) downto 0) + -- Result: Multiplies an UNRESOLVED_SIGNED vector, R, with an INTEGER, L. L is + -- converted to an UNRESOLVED_SIGNED vector of SIZE R'LENGTH before + -- multiplication. + + --============================================================================ + -- + -- NOTE: If second argument is zero for "/" operator, a severity level + -- of ERROR is issued. + + -- Id: A.21 + function "/" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Divides an UNRESOLVED_UNSIGNED vector, L, by another UNRESOLVED_UNSIGNED vector, R. + + -- Id: A.22 + function "/" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Divides an UNRESOLVED_SIGNED vector, L, by another UNRESOLVED_SIGNED vector, R. + + -- Id: A.23 + function "/" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Divides an UNRESOLVED_UNSIGNED vector, L, by a nonnegative INTEGER, R. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.24 + function "/" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Divides a nonnegative INTEGER, L, by an UNRESOLVED_UNSIGNED vector, R. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + -- Id: A.25 + function "/" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Divides an UNRESOLVED_SIGNED vector, L, by an INTEGER, R. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.26 + function "/" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Divides an INTEGER, L, by an UNRESOLVED_SIGNED vector, R. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + --============================================================================ + -- + -- NOTE: If second argument is zero for "rem" operator, a severity level + -- of ERROR is issued. + + -- Id: A.27 + function "rem" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L and R are UNRESOLVED_UNSIGNED vectors. + + -- Id: A.28 + function "rem" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L and R are UNRESOLVED_SIGNED vectors. + + -- Id: A.29 + function "rem" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L is an UNRESOLVED_UNSIGNED vector and R is a + -- nonnegative INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.30 + function "rem" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where R is an UNRESOLVED_UNSIGNED vector and L is a + -- nonnegative INTEGER. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + -- Id: A.31 + function "rem" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where L is UNRESOLVED_SIGNED vector and R is an INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.32 + function "rem" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L rem R" where R is UNRESOLVED_SIGNED vector and L is an INTEGER. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + --============================================================================ + -- + -- NOTE: If second argument is zero for "mod" operator, a severity level + -- of ERROR is issued. + + -- Id: A.33 + function "mod" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L and R are UNRESOLVED_UNSIGNED vectors. + + -- Id: A.34 + function "mod" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L and R are UNRESOLVED_SIGNED vectors. + + -- Id: A.35 + function "mod" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L is an UNRESOLVED_UNSIGNED vector and R + -- is a nonnegative INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.36 + function "mod" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where R is an UNRESOLVED_UNSIGNED vector and L + -- is a nonnegative INTEGER. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + -- Id: A.37 + function "mod" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. + + -- Id: A.38 + function "mod" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Computes "L mod R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. + + --============================================================================ + -- Id: A.39 + function find_leftmost (ARG : UNRESOLVED_UNSIGNED; Y : STD_ULOGIC) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + -- Id: A.40 + function find_leftmost (ARG : UNRESOLVED_SIGNED; Y : STD_ULOGIC) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + -- Id: A.41 + function find_rightmost (ARG : UNRESOLVED_UNSIGNED; Y : STD_ULOGIC) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + -- Id: A.42 + function find_rightmost (ARG : UNRESOLVED_SIGNED; Y : STD_ULOGIC) return INTEGER; + -- Result subtype: INTEGER + -- Result: Finds the leftmost occurrence of the value of Y in ARG. + -- Returns the index of the occurrence if it exists, or -1 otherwise. + + --============================================================================ + -- Comparison Operators + --============================================================================ + + -- Id: C.1 + function ">" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.2 + function ">" (L, R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.3 + function ">" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.4 + function ">" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is a INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.5 + function ">" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.6 + function ">" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L > R" where L is an UNRESOLVED_SIGNED vector and + -- R is a INTEGER. + + --============================================================================ + + -- Id: C.7 + function "<" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.8 + function "<" (L, R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.9 + function "<" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.10 + function "<" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.11 + function "<" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.12 + function "<" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L < R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.13 + function "<=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.14 + function "<=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.15 + function "<=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.16 + function "<=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.17 + function "<=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.18 + function "<=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L <= R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.19 + function ">=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.20 + function ">=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.21 + function ">=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.22 + function ">=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.23 + function ">=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.24 + function ">=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L >= R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.25 + function "=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.26 + function "=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.27 + function "=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.28 + function "=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.29 + function "=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.30 + function "=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L = R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.31 + function "/=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.32 + function "/=" (L, R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.33 + function "/=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.34 + function "/=" (L : INTEGER; R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.35 + function "/=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.36 + function "/=" (L : UNRESOLVED_SIGNED; R : INTEGER) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: Computes "L /= R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.37 + function MINIMUM (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED + -- Result: Returns the lesser of two UNRESOLVED_UNSIGNED vectors that may be + -- of different lengths. + + -- Id: C.38 + function MINIMUM (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED + -- Result: Returns the lesser of two UNRESOLVED_SIGNED vectors that may be + -- of different lengths. + + -- Id: C.39 + function MINIMUM (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED + -- Result: Returns the lesser of a nonnegative INTEGER, L, and + -- an UNRESOLVED_UNSIGNED vector, R. + + -- Id: C.40 + function MINIMUM (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED + -- Result: Returns the lesser of an INTEGER, L, and an UNRESOLVED_SIGNED + -- vector, R. + + -- Id: C.41 + function MINIMUM (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED + -- Result: Returns the lesser of an UNRESOLVED_UNSIGNED vector, L, and + -- a nonnegative INTEGER, R. + + -- Id: C.42 + function MINIMUM (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED + -- Result: Returns the lesser of an UNRESOLVED_SIGNED vector, L, and + -- an INTEGER, R. + + --============================================================================ + + -- Id: C.43 + function MAXIMUM (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED + -- Result: Returns the greater of two UNRESOLVED_UNSIGNED vectors that may be + -- of different lengths. + + -- Id: C.44 + function MAXIMUM (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED + -- Result: Returns the greater of two UNRESOLVED_SIGNED vectors that may be + -- of different lengths. + + -- Id: C.45 + function MAXIMUM (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED + -- Result: Returns the greater of a nonnegative INTEGER, L, and + -- an UNRESOLVED_UNSIGNED vector, R. + + -- Id: C.46 + function MAXIMUM (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED + -- Result: Returns the greater of an INTEGER, L, and an UNRESOLVED_SIGNED + -- vector, R. + + -- Id: C.47 + function MAXIMUM (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED + -- Result: Returns the greater of an UNRESOLVED_UNSIGNED vector, L, and + -- a nonnegative INTEGER, R. + + -- Id: C.48 + function MAXIMUM (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED + -- Result: Returns the greater of an UNRESOLVED_SIGNED vector, L, and + -- an INTEGER, R. + + --============================================================================ + + -- Id: C.49 + function "?>" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L > R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.50 + function "?>" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L > R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.51 + function "?>" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L > R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.52 + function "?>" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L > R" where L is a INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.53 + function "?>" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L > R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.54 + function "?>" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L > R" where L is an UNRESOLVED_SIGNED vector and + -- R is a INTEGER. + + --============================================================================ + + -- Id: C.55 + function "?<" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L < R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.56 + function "?<" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L < R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.57 + function "?<" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L < R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.58 + function "?<" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L < R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.59 + function "?<" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L < R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.60 + function "?<" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L < R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.61 + function "?<=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L <= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.62 + function "?<=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L <= R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.63 + function "?<=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L <= R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.64 + function "?<=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L <= R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.65 + function "?<=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L <= R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.66 + function "?<=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L <= R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.67 + function "?>=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L >= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.68 + function "?>=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L >= R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.69 + function "?>=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L >= R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.70 + function "?>=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L >= R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.71 + function "?>=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L >= R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.72 + function "?>=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L >= R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.73 + function "?=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L = R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.74 + function "?=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L = R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.75 + function "?=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L = R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.76 + function "?=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L = R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.77 + function "?=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L = R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.78 + function "?=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L = R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + + -- Id: C.79 + function "?/=" (L, R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L /= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly + -- of different lengths. + + -- Id: C.80 + function "?/=" (L, R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L /= R" where L and R are UNRESOLVED_SIGNED vectors possibly + -- of different lengths. + + -- Id: C.81 + function "?/=" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L /= R" where L is a nonnegative INTEGER and + -- R is an UNRESOLVED_UNSIGNED vector. + + -- Id: C.82 + function "?/=" (L : INTEGER; R : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L /= R" where L is an INTEGER and + -- R is an UNRESOLVED_SIGNED vector. + + -- Id: C.83 + function "?/=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L /= R" where L is an UNRESOLVED_UNSIGNED vector and + -- R is a nonnegative INTEGER. + + -- Id: C.84 + function "?/=" (L : UNRESOLVED_SIGNED; R : INTEGER) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC + -- Result: Computes "L /= R" where L is an UNRESOLVED_SIGNED vector and + -- R is an INTEGER. + + --============================================================================ + -- Shift and Rotate Functions + --============================================================================ + + -- Id: S.1 + function SHIFT_LEFT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-left on an UNRESOLVED_UNSIGNED vector COUNT times. + -- The vacated positions are filled with '0'. + -- The COUNT leftmost elements are lost. + + -- Id: S.2 + function SHIFT_RIGHT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-right on an UNRESOLVED_UNSIGNED vector COUNT times. + -- The vacated positions are filled with '0'. + -- The COUNT rightmost elements are lost. + + -- Id: S.3 + function SHIFT_LEFT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-left on an UNRESOLVED_SIGNED vector COUNT times. + -- The vacated positions are filled with '0'. + -- The COUNT leftmost elements are lost. + + -- Id: S.4 + function SHIFT_RIGHT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a shift-right on an UNRESOLVED_SIGNED vector COUNT times. + -- The vacated positions are filled with the leftmost + -- element, ARG'LEFT. The COUNT rightmost elements are lost. + + --============================================================================ + + -- Id: S.5 + function ROTATE_LEFT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a rotate-left of an UNRESOLVED_UNSIGNED vector COUNT times. + + -- Id: S.6 + function ROTATE_RIGHT (ARG : UNRESOLVED_UNSIGNED; COUNT : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a rotate-right of an UNRESOLVED_UNSIGNED vector COUNT times. + + -- Id: S.7 + function ROTATE_LEFT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a logical rotate-left of an UNRESOLVED_SIGNED + -- vector COUNT times. + + -- Id: S.8 + function ROTATE_RIGHT (ARG : UNRESOLVED_SIGNED; COUNT : NATURAL) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: Performs a logical rotate-right of an UNRESOLVED_SIGNED + -- vector COUNT times. + + --============================================================================ + + --============================================================================ + + ------------------------------------------------------------------------------ + -- Note: Function S.9 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.9 + function "sll" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.10 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.10 + function "sll" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.11 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE StdL 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.11 + function "srl" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.12 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.12 + function "srl" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: UNRESOLVED_SIGNED(SHIFT_RIGHT(UNRESOLVED_UNSIGNED(ARG), COUNT)) + + ------------------------------------------------------------------------------ + -- Note: Function S.13 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.13 + function "rol" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.14 + function "rol" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.15 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.15 + function "ror" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.16 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.16 + function "ror" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: ROTATE_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.17 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.17 + function "sla" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.18 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.18 + function "sla" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_LEFT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.19 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.19 + function "sra" (ARG : UNRESOLVED_UNSIGNED; COUNT : INTEGER) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_RIGHT(ARG, COUNT) + + ------------------------------------------------------------------------------ + -- Note: Function S.20 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: S.20 + function "sra" (ARG : UNRESOLVED_SIGNED; COUNT : INTEGER) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(ARG'LENGTH-1 downto 0) + -- Result: SHIFT_RIGHT(ARG, COUNT) + + --============================================================================ + -- RESIZE Functions + --============================================================================ + + -- Id: R.1 + function RESIZE (ARG : UNRESOLVED_SIGNED; NEW_SIZE : NATURAL) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(NEW_SIZE-1 downto 0) + -- Result: Resizes the UNRESOLVED_SIGNED vector ARG to the specified size. + -- To create a larger vector, the new [leftmost] bit positions + -- are filled with the sign bit (ARG'LEFT). When truncating, + -- the sign bit is retained along with the rightmost part. + + -- Id: R.2 + function RESIZE (ARG : UNRESOLVED_UNSIGNED; NEW_SIZE : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(NEW_SIZE-1 downto 0) + -- Result: Resizes the UNRESOLVED_SIGNED vector ARG to the specified size. + -- To create a larger vector, the new [leftmost] bit positions + -- are filled with '0'. When truncating, the leftmost bits + -- are dropped. + + function RESIZE (ARG, SIZE_RES : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED (SIZE_RES'length-1 downto 0) + + function RESIZE (ARG, SIZE_RES : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED (SIZE_RES'length-1 downto 0) + + --============================================================================ + -- Conversion Functions + --============================================================================ + + -- Id: D.1 + function TO_INTEGER (ARG : UNRESOLVED_UNSIGNED) return NATURAL; + -- Result subtype: NATURAL. Value cannot be negative since parameter is an + -- UNRESOLVED_UNSIGNED vector. + -- Result: Converts the UNRESOLVED_UNSIGNED vector to an INTEGER. + + -- Id: D.2 + function TO_INTEGER (ARG : UNRESOLVED_SIGNED) return INTEGER; + -- Result subtype: INTEGER + -- Result: Converts an UNRESOLVED_SIGNED vector to an INTEGER. + + -- Id: D.3 + function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(SIZE-1 downto 0) + -- Result: Converts a nonnegative INTEGER to an UNRESOLVED_UNSIGNED vector with + -- the specified SIZE. + + -- Id: D.4 + function TO_SIGNED (ARG : INTEGER; SIZE : NATURAL) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(SIZE-1 downto 0) + -- Result: Converts an INTEGER to a UNRESOLVED_SIGNED vector of the specified SIZE. + + function TO_UNSIGNED (ARG : NATURAL; SIZE_RES : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(SIZE_RES'length-1 downto 0) + + function TO_SIGNED (ARG : INTEGER; SIZE_RES : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(SIZE_RES'length-1 downto 0) + + --============================================================================ + -- Logical Operators + --============================================================================ + + -- Id: L.1 + function "not" (L : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Termwise inversion + + -- Id: L.2 + function "and" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector AND operation + + -- Id: L.3 + function "or" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector OR operation + + -- Id: L.4 + function "nand" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NAND operation + + -- Id: L.5 + function "nor" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NOR operation + + -- Id: L.6 + function "xor" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XOR operation + + -- --------------------------------------------------------------------------- + -- Note: Function L.7 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + -- --------------------------------------------------------------------------- + -- Id: L.7 + function "xnor" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XNOR operation + + -- Id: L.8 + function "not" (L : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Termwise inversion + + -- Id: L.9 + function "and" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector AND operation + + -- Id: L.10 + function "or" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector OR operation + + -- Id: L.11 + function "nand" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NAND operation + + -- Id: L.12 + function "nor" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector NOR operation + + -- Id: L.13 + function "xor" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XOR operation + + -- --------------------------------------------------------------------------- + -- Note: Function L.14 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + -- --------------------------------------------------------------------------- + -- Id: L.14 + function "xnor" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector XNOR operation + + -- Id: L.15 + function "and" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector AND operation + + -- Id: L.16 + function "and" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar AND operation + + -- Id: L.17 + function "or" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector OR operation + + -- Id: L.18 + function "or" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar OR operation + + -- Id: L.19 + function "nand" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NAND operation + + -- Id: L.20 + function "nand" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NAND operation + + -- Id: L.21 + function "nor" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NOR operation + + -- Id: L.22 + function "nor" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NOR operation + + -- Id: L.23 + function "xor" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XOR operation + + -- Id: L.24 + function "xor" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.25 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.25 + function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XNOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.26 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.26 + function "xnor" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XNOR operation + + -- Id: L.27 + function "and" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector AND operation + + -- Id: L.28 + function "and" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar AND operation + + -- Id: L.29 + function "or" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector OR operation + + -- Id: L.30 + function "or" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar OR operation + + -- Id: L.31 + function "nand" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NAND operation + + -- Id: L.32 + function "nand" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NAND operation + + -- Id: L.33 + function "nor" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector NOR operation + + -- Id: L.34 + function "nor" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar NOR operation + + -- Id: L.35 + function "xor" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XOR operation + + -- Id: L.36 + function "xor" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.37 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.37 + function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(R'LENGTH-1 downto 0) + -- Result: Scalar/Vector XNOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.38 is not compatible with IEEE Std 1076-1987. Comment + -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility. + ------------------------------------------------------------------------------ + -- Id: L.38 + function "xnor" (L : UNRESOLVED_SIGNED; R : STD_ULOGIC) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(L'LENGTH-1 downto 0) + -- Result: Vector/Scalar XNOR operation + + ------------------------------------------------------------------------------ + -- Note: Function L.39 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.39 + function "and" (L : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of and'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.40 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.40 + function "nand" (L : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of nand'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.41 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.41 + function "or" (L : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of or'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.42 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.42 + function "nor" (L : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of nor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.43 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.43 + function "xor" (L : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of xor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.44 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.44 + function "xnor" (L : UNRESOLVED_SIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of xnor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.45 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.45 + function "and" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of and'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.46 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.46 + function "nand" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of nand'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.47 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.47 + function "or" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of or'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.48 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.48 + function "nor" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of nor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.49 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.49 + function "xor" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of xor'ing all of the bits of the vector. + + ------------------------------------------------------------------------------ + -- Note: Function L.50 is not compatible with editions of IEEE Std 1076 from + -- 1987 through 2002. Comment out the function (declaration and body) for + -- compatibility with these editions. + ------------------------------------------------------------------------------ + -- Id: L.50 + function "xnor" (L : UNRESOLVED_UNSIGNED) return STD_ULOGIC; + -- Result subtype: STD_ULOGIC. + -- Result: Result of xnor'ing all of the bits of the vector. + + --============================================================================ + -- Match Functions + --============================================================================ + + -- Id: M.1 + function STD_MATCH (L, R : STD_ULOGIC) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: terms compared per STD_LOGIC_1164 intent + + -- Id: M.2 + function STD_MATCH (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: terms compared per STD_LOGIC_1164 intent + + -- Id: M.3 + function STD_MATCH (L, R : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: terms compared per STD_LOGIC_1164 intent + + -- Id: M.5 + function STD_MATCH (L, R : STD_ULOGIC_VECTOR) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: terms compared per STD_LOGIC_1164 intent + + --============================================================================ + -- Translation Functions + --============================================================================ + + -- Id: T.1 + function TO_01 (S : UNRESOLVED_UNSIGNED; XMAP : STD_ULOGIC := '0') return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', and 'L' is translated + -- to '0'. If a value other than '0'|'1'|'H'|'L' is found, + -- the array is set to (others => XMAP), and a warning is + -- issued. + + -- Id: T.2 + function TO_01 (S : UNRESOLVED_SIGNED; XMAP : STD_ULOGIC := '0') return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', and 'L' is translated + -- to '0'. If a value other than '0'|'1'|'H'|'L' is found, + -- the array is set to (others => XMAP), and a warning is + -- issued. + + -- Id: T.3 + function TO_X01 (S : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', 'L' is translated to '0', + -- and values other than '0'|'1'|'H'|'L' are translated to 'X'. + + -- Id: T.4 + function TO_X01 (S : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', 'L' is translated to '0', + -- and values other than '0'|'1'|'H'|'L' are translated to 'X'. + + -- Id: T.5 + function TO_X01Z (S : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', 'L' is translated to '0', + -- and values other than '0'|'1'|'H'|'L'|'Z' are translated to 'X'. + + -- Id: T.6 + function TO_X01Z (S : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', 'L' is translated to '0', + -- and values other than '0'|'1'|'H'|'L'|'Z' are translated to 'X'. + + -- Id: T.7 + function TO_UX01 (S : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED; + -- Result subtype: UNRESOLVED_UNSIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', 'L' is translated to '0', + -- and values other than 'U'|'0'|'1'|'H'|'L' are translated to 'X'. + + -- Id: T.8 + function TO_UX01 (S : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED; + -- Result subtype: UNRESOLVED_SIGNED(S'RANGE) + -- Result: Termwise, 'H' is translated to '1', 'L' is translated to '0', + -- and values other than 'U'|'0'|'1'|'H'|'L' are translated to 'X'. + + -- Id: T.9 + function IS_X (S : UNRESOLVED_UNSIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: TRUE if S contains a 'U'|'X'|'Z'|'W'|'-' value, FALSE otherwise. + + -- Id: T.10 + function IS_X (S : UNRESOLVED_SIGNED) return BOOLEAN; + -- Result subtype: BOOLEAN + -- Result: TRUE if S contains a 'U'|'X'|'Z'|'W'|'-' value, FALSE otherwise. + + --============================================================================ + -- string conversion and write operations + --============================================================================ + -- the following operations are predefined + + -- function to_string (value : UNRESOLVED_UNSIGNED) return STRING; + -- function to_string (value : UNRESOLVED_SIGNED) return STRING; + + -- explicitly defined operations + + alias to_bstring is to_string [UNRESOLVED_UNSIGNED return STRING]; + alias to_bstring is to_string [UNRESOLVED_SIGNED return STRING]; + alias to_binary_string is to_string [UNRESOLVED_UNSIGNED return STRING]; + alias to_binary_string is to_string [UNRESOLVED_SIGNED return STRING]; + + function to_ostring (value : UNRESOLVED_UNSIGNED) return STRING; + function to_ostring (value : UNRESOLVED_SIGNED) return STRING; + alias to_octal_string is to_ostring [UNRESOLVED_UNSIGNED return STRING]; + alias to_octal_string is to_ostring [UNRESOLVED_SIGNED return STRING]; + + function to_hstring (value : UNRESOLVED_UNSIGNED) return STRING; + function to_hstring (value : UNRESOLVED_SIGNED) return STRING; + alias to_hex_string is to_hstring [UNRESOLVED_UNSIGNED return STRING]; + alias to_hex_string is to_hstring [UNRESOLVED_SIGNED return STRING]; + + procedure READ(L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED; GOOD : out BOOLEAN); + + procedure READ(L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED); + + procedure READ(L : inout LINE; VALUE : out UNRESOLVED_SIGNED; GOOD : out BOOLEAN); + + procedure READ(L : inout LINE; VALUE : out UNRESOLVED_SIGNED); + + procedure WRITE (L : inout LINE; VALUE : in UNRESOLVED_UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + procedure WRITE (L : inout LINE; VALUE : in UNRESOLVED_SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + alias BREAD is READ [LINE, UNRESOLVED_UNSIGNED, BOOLEAN]; + alias BREAD is READ [LINE, UNRESOLVED_SIGNED, BOOLEAN]; + + alias BREAD is READ [LINE, UNRESOLVED_UNSIGNED]; + alias BREAD is READ [LINE, UNRESOLVED_SIGNED]; + + alias BINARY_READ is READ [LINE, UNRESOLVED_UNSIGNED, BOOLEAN]; + alias BINARY_READ is READ [LINE, UNRESOLVED_SIGNED, BOOLEAN]; + + alias BINARY_READ is READ [LINE, UNRESOLVED_UNSIGNED]; + alias BINARY_READ is READ [LINE, UNRESOLVED_SIGNED]; + + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED; GOOD : out BOOLEAN); + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED; GOOD : out BOOLEAN); + + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED); + procedure OREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED); + + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_UNSIGNED, BOOLEAN]; + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_SIGNED, BOOLEAN]; + + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_UNSIGNED]; + alias OCTAL_READ is OREAD [LINE, UNRESOLVED_SIGNED]; + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED; GOOD : out BOOLEAN); + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED; GOOD : out BOOLEAN); + + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_UNSIGNED); + procedure HREAD (L : inout LINE; VALUE : out UNRESOLVED_SIGNED); + + alias HEX_READ is HREAD [LINE, UNRESOLVED_UNSIGNED, BOOLEAN]; + alias HEX_READ is HREAD [LINE, UNRESOLVED_SIGNED, BOOLEAN]; + + alias HEX_READ is HREAD [LINE, UNRESOLVED_UNSIGNED]; + alias HEX_READ is HREAD [LINE, UNRESOLVED_SIGNED]; + + alias BWRITE is WRITE [LINE, UNRESOLVED_UNSIGNED, SIDE, WIDTH]; + alias BWRITE is WRITE [LINE, UNRESOLVED_SIGNED, SIDE, WIDTH]; + + alias BINARY_WRITE is WRITE [LINE, UNRESOLVED_UNSIGNED, SIDE, WIDTH]; + alias BINARY_WRITE is WRITE [LINE, UNRESOLVED_SIGNED, SIDE, WIDTH]; + + procedure OWRITE (L : inout LINE; VALUE : in UNRESOLVED_UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + procedure OWRITE (L : inout LINE; VALUE : in UNRESOLVED_SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + alias OCTAL_WRITE is OWRITE [LINE, UNRESOLVED_UNSIGNED, SIDE, WIDTH]; + alias OCTAL_WRITE is OWRITE [LINE, UNRESOLVED_SIGNED, SIDE, WIDTH]; + + procedure HWRITE (L : inout LINE; VALUE : in UNRESOLVED_UNSIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + procedure HWRITE (L : inout LINE; VALUE : in UNRESOLVED_SIGNED; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + alias HEX_WRITE is HWRITE [LINE, UNRESOLVED_UNSIGNED, SIDE, WIDTH]; + alias HEX_WRITE is HWRITE [LINE, UNRESOLVED_SIGNED, SIDE, WIDTH]; + +end package NUMERIC_STD; diff --git a/libraries/ieee2008/numeric_std_unsigned-body.vhdl b/libraries/ieee2008/numeric_std_unsigned-body.vhdl new file mode 100644 index 000000000..cb01bc0f1 --- /dev/null +++ b/libraries/ieee2008/numeric_std_unsigned-body.vhdl @@ -0,0 +1,592 @@ +-- --------------------------------------------------------------------
+--
+-- 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 : Standard VHDL Synthesis Packages
+-- : (NUMERIC_STD_UNSIGNED 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 package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Values of type STD_ULOGIC_VECTOR
+-- : are interpreted as unsigned numbers in vector form.
+-- : The leftmost bit is treated as the most significant bit.
+-- : This package contains overloaded arithmetic operators on
+-- : the STD_ULOGIC_VECTOR type. The package also contains
+-- : useful type conversions functions, clock detection
+-- : functions, and other utility functions.
+-- :
+-- : If any argument to a function is a null array, a null array
+-- : is returned (exceptions, if any, are noted individually).
+--
+-- 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.numeric_std.all;
+
+package body NUMERIC_STD_UNSIGNED is
+
+ -- Id: A.3
+ function "+" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) + UNSIGNED(R));
+ end function "+";
+
+ -- Id: A.3R
+ function "+"(L : STD_ULOGIC_VECTOR; R : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) + R);
+ end function "+";
+
+ -- Id: A.3L
+ function "+"(L : STD_ULOGIC; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L + UNSIGNED(R));
+ end function "+";
+
+ -- Id: A.5
+ function "+" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) + R);
+ end function "+";
+
+ -- Id: A.6
+ function "+" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L + UNSIGNED(R));
+ end function "+";
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) - UNSIGNED(R));
+ end function "-";
+
+ -- Id: A.9R
+ function "-"(L : STD_ULOGIC_VECTOR; R : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) - R);
+ end function "-";
+
+ -- Id: A.9L
+ function "-"(L : STD_ULOGIC; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L - UNSIGNED(R));
+ end function "-";
+
+ -- Id: A.11
+ function "-" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) - R);
+ end function "-";
+
+ -- Id: A.12
+ function "-" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L - UNSIGNED(R));
+ end function "-";
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) * UNSIGNED(R));
+ end function "*";
+
+ -- Id: A.17
+ function "*" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) * R);
+ end function "*";
+
+ -- Id: A.18
+ function "*" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L * UNSIGNED(R));
+ end function "*";
+
+ --============================================================================
+
+ -- Id: A.21
+ function "/" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) / UNSIGNED(R));
+ end function "/";
+
+ -- Id: A.23
+ function "/" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) / R);
+ end function "/";
+
+ -- Id: A.24
+ function "/" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L / UNSIGNED(R));
+ end function "/";
+
+ --============================================================================
+
+ -- Id: A.27
+ function "rem" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) rem UNSIGNED(R));
+ end function "rem";
+
+ -- Id: A.29
+ function "rem" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) rem R);
+ end function "rem";
+
+ -- Id: A.30
+ function "rem" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L rem UNSIGNED(R));
+ end function "rem";
+
+ --============================================================================
+
+ -- Id: A.33
+ function "mod" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) mod UNSIGNED(R));
+ end function "mod";
+
+ -- Id: A.35
+ function "mod" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(L) mod R);
+ end function "mod";
+
+ -- Id: A.36
+ function "mod" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (L mod UNSIGNED(R));
+ end function "mod";
+
+ --============================================================================
+ -- Id: A.39
+ function find_leftmost (ARG: STD_ULOGIC_VECTOR; Y: STD_ULOGIC) return INTEGER is
+ begin
+ return find_leftmost(UNSIGNED(ARG), Y);
+ end function find_leftmost;
+
+ -- Id: A.41
+ function find_rightmost (ARG: STD_ULOGIC_VECTOR; Y: STD_ULOGIC) return INTEGER is
+ begin
+ return find_rightmost(UNSIGNED(ARG), Y);
+ end function find_rightmost;
+
+ --============================================================================
+
+ -- Id: C.1
+ function ">" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) > UNSIGNED(R);
+ end function ">";
+
+ -- Id: C.3
+ function ">" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L > UNSIGNED(R);
+ end function ">";
+
+ -- Id: C.5
+ function ">" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) > R;
+ end function ">";
+
+ --============================================================================
+
+ -- Id: C.7
+ function "<" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) < UNSIGNED(R);
+ end function "<";
+
+ -- Id: C.9
+ function "<" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L < UNSIGNED(R);
+ end function "<";
+
+ -- Id: C.11
+ function "<" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) < R;
+ end function "<";
+
+ --============================================================================
+
+ -- Id: C.13
+ function "<=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) <= UNSIGNED(R);
+ end function "<=";
+
+ -- Id: C.15
+ function "<=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L <= UNSIGNED(R);
+ end function "<=";
+
+ -- Id: C.17
+ function "<=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) <= R;
+ end function "<=";
+
+ --============================================================================
+
+ -- Id: C.19
+ function ">=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) >= UNSIGNED(R);
+ end function ">=";
+
+ -- Id: C.21
+ function ">=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L >= UNSIGNED(R);
+ end function ">=";
+
+ -- Id: C.23
+ function ">=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) >= R;
+ end function ">=";
+
+ --============================================================================
+
+ -- Id: C.25
+ function "=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) = UNSIGNED(R);
+ end function "=";
+
+ -- Id: C.27
+ function "=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L = UNSIGNED(R);
+ end function "=";
+
+ -- Id: C.29
+ function "=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) = R;
+ end function "=";
+
+ --============================================================================
+
+ -- Id: C.31
+ function "/=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) /= UNSIGNED(R);
+ end function "/=";
+
+ -- Id: C.33
+ function "/=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L /= UNSIGNED(R);
+ end function "/=";
+
+ -- Id: C.35
+ function "/=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN is
+ begin
+ return UNSIGNED(L) /= R;
+ end function "/=";
+
+ --============================================================================
+
+ -- Id: C.37
+ function MINIMUM (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (MINIMUM(UNSIGNED(L), UNSIGNED(R)));
+ end function MINIMUM;
+
+ -- Id: C.39
+ function MINIMUM (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (MINIMUM(L, UNSIGNED(R)));
+ end function MINIMUM;
+
+ -- Id: C.41
+ function MINIMUM (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (MINIMUM(UNSIGNED(L), R));
+ end function MINIMUM;
+
+ --============================================================================
+ -- Id: C.43
+ function MAXIMUM (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (MAXIMUM(UNSIGNED(L), UNSIGNED(R)));
+ end function MAXIMUM;
+
+ -- Id: C.45
+ function MAXIMUM (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (MAXIMUM(L, UNSIGNED(R)));
+ end function MAXIMUM;
+
+ -- Id: C.47
+ function MAXIMUM (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (MAXIMUM(UNSIGNED(L), R));
+ end function MAXIMUM;
+
+ --============================================================================
+
+ -- Id: C.49
+ function "?>" (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?> UNSIGNED(R);
+ end function "?>";
+
+ -- Id: C.51
+ function "?>" (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return L ?> UNSIGNED(R);
+ end function "?>";
+
+ -- Id: C.53
+ function "?>" (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?> R;
+ end function "?>";
+
+ --============================================================================
+
+ -- Id: C.55
+ function "?<" (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?< UNSIGNED(R);
+ end function "?<";
+
+ -- Id: C.57
+ function "?<" (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return L ?< UNSIGNED(R);
+ end function "?<";
+
+ -- Id: C.59
+ function "?<" (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?< R;
+ end function "?<";
+
+ --============================================================================
+
+ -- Id: C.61
+ function "?<=" (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?<= UNSIGNED(R);
+ end function "?<=";
+
+ -- Id: C.63
+ function "?<=" (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return L ?<= UNSIGNED(R);
+ end function "?<=";
+
+ -- Id: C.65
+ function "?<=" (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?<= R;
+ end function "?<=";
+
+ --============================================================================
+
+ -- Id: C.67
+ function "?>=" (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?>= UNSIGNED(R);
+ end function "?>=";
+
+ -- Id: C.69
+ function "?>=" (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return L ?>= UNSIGNED(R);
+ end function "?>=";
+
+ -- Id: C.71
+ function "?>=" (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?>= R;
+ end function "?>=";
+
+ --============================================================================
+
+ -- Id: C.73
+ function "?=" (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?= UNSIGNED(R);
+ end function "?=";
+
+ -- Id: C.75
+ function "?=" (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return L ?= UNSIGNED(R);
+ end function "?=";
+
+ -- Id: C.77
+ function "?=" (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?= R;
+ end function "?=";
+
+ --============================================================================
+
+ -- Id: C.79
+ function "?/=" (L, R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?/= UNSIGNED(R);
+ end function "?/=";
+
+ -- Id: C.81
+ function "?/=" (L: NATURAL; R: STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return L ?/= UNSIGNED(R);
+ end function "?/=";
+
+ -- Id: C.83
+ function "?/=" (L: STD_ULOGIC_VECTOR; R: NATURAL) return STD_ULOGIC is
+ begin
+ return UNSIGNED(L) ?/= R;
+ end function "?/=";
+
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return std_logic_vector (SHIFT_LEFT(unsigned(ARG), COUNT));
+ end function SHIFT_LEFT;
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return std_logic_vector (SHIFT_RIGHT(unsigned(ARG), COUNT));
+ end function SHIFT_RIGHT;
+
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return std_logic_vector (ROTATE_LEFT(unsigned(ARG), COUNT));
+ end function ROTATE_LEFT;
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return std_logic_vector (ROTATE_RIGHT(unsigned(ARG), COUNT));
+ end function ROTATE_RIGHT;
+
+ --============================================================================
+
+ -- Id: S.17
+ function "sla" (ARG: STD_ULOGIC_VECTOR; COUNT: INTEGER)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(ARG) sla COUNT);
+ end function "sla";
+
+ -- Id: S.19
+ function "sra" (ARG: STD_ULOGIC_VECTOR; COUNT: INTEGER)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (UNSIGNED(ARG) sra COUNT);
+ end function "sra";
+
+ --============================================================================
+
+ -- Id: R.2
+ function RESIZE (ARG : STD_ULOGIC_VECTOR; NEW_SIZE : NATURAL)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (
+ RESIZE (ARG => UNSIGNED(ARG),
+ NEW_SIZE => NEW_SIZE));
+ end function RESIZE;
+
+ function RESIZE (ARG, SIZE_RES : STD_ULOGIC_VECTOR)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (
+ RESIZE (ARG => UNSIGNED(ARG),
+ NEW_SIZE => SIZE_RES'length));
+ end function RESIZE;
+
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG : STD_ULOGIC_VECTOR) return NATURAL is
+ begin
+ return TO_INTEGER(UNSIGNED(ARG));
+ end function TO_INTEGER;
+
+ -- Id: D.3
+ function To_StdLogicVector (ARG, SIZE : NATURAL) return STD_LOGIC_VECTOR is
+ begin
+ return STD_LOGIC_VECTOR (TO_UNSIGNED(ARG => ARG,
+ SIZE => SIZE));
+ end function To_StdLogicVector;
+
+ -- Id: D.5
+ function To_StdULogicVector (ARG, SIZE : NATURAL) return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (TO_UNSIGNED(ARG => ARG,
+ SIZE => SIZE));
+ end function To_StdULogicVector;
+
+ function To_StdLogicVector (ARG : NATURAL; SIZE_RES : STD_ULOGIC_VECTOR)
+ return STD_LOGIC_VECTOR is
+ begin
+ return STD_LOGIC_VECTOR (TO_UNSIGNED (ARG => ARG,
+ SIZE => SIZE_RES'length));
+ end function To_StdLogicVector;
+
+ function To_StdULogicVector (ARG : NATURAL; SIZE_RES : STD_ULOGIC_VECTOR)
+ return STD_ULOGIC_VECTOR is
+ begin
+ return STD_ULOGIC_VECTOR (TO_UNSIGNED (ARG => ARG,
+ SIZE => SIZE_RES'length));
+ end function To_StdULogicVector;
+
+end package body NUMERIC_STD_UNSIGNED;
diff --git a/libraries/ieee2008/numeric_std_unsigned.vhdl b/libraries/ieee2008/numeric_std_unsigned.vhdl new file mode 100644 index 000000000..b9359e0eb --- /dev/null +++ b/libraries/ieee2008/numeric_std_unsigned.vhdl @@ -0,0 +1,613 @@ +-- --------------------------------------------------------------------
+--
+-- 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 : Standard VHDL Synthesis Packages
+-- : (NUMERIC_STD_UNSIGNED package declaration)
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers: Accellera VHDL-TC, and IEEE P1076 Working Group
+-- :
+-- Purpose : This package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Values of type STD_ULOGIC_VECTOR
+-- : are interpreted as unsigned numbers in vector form.
+-- : The leftmost bit is treated as the most significant bit.
+-- : This package contains overloaded arithmetic operators on
+-- : the STD_ULOGIC_VECTOR type. The package also contains
+-- : useful type conversions functions, clock detection
+-- : functions, and other utility functions.
+-- :
+-- : If any argument to a function is a null array, a null array
+-- : is returned (exceptions, if any, are noted individually).
+--
+-- 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.STD_LOGIC_1164.all;
+package NUMERIC_STD_UNSIGNED is
+ constant CopyRightNotice : STRING :=
+ "Copyright 2008 IEEE. All rights reserved.";
+
+ -- Id: A.3
+ function "+" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Adds two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.3R
+ function "+"(L : STD_ULOGIC_VECTOR; R : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0)
+ -- Result: Similar to A.3 where R is a one bit STD_ULOGIC_VECTOR
+
+ -- Id: A.3L
+ function "+"(L : STD_ULOGIC; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0)
+ -- Result: Similar to A.3 where L is a one bit UNSIGNED
+
+ -- Id: A.5
+ function "+" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0).
+ -- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.
+
+ -- Id: A.6
+ function "+" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0).
+ -- Result: Adds a non-negative INTEGER, L, with an UNSIGNED vector, R.
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: UNSIGNED(MAXIMUM(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Subtracts two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.9R
+ function "-"(L : STD_ULOGIC_VECTOR; R : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0)
+ -- Result: Similar to A.9 where R is a one bit UNSIGNED
+
+ -- Id: A.9L
+ function "-"(L : STD_ULOGIC; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0)
+ -- Result: Similar to A.9 where L is a one bit UNSIGNED
+
+ -- Id: A.11
+ function "-" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0).
+ -- Result: Subtracts a non-negative INTEGER, R, from an UNSIGNED vector, L.
+
+ -- Id: A.12
+ function "-" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0).
+ -- Result: Subtracts an UNSIGNED vector, R, from a non-negative INTEGER, L.
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR((L'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Performs the multiplication operation on two UNSIGNED vectors
+ -- that may possibly be of different lengths.
+
+ -- Id: A.17
+ function "*" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR((L'LENGTH+L'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, L, with a non-negative
+ -- INTEGER, R. R is converted to an UNSIGNED vector of
+ -- SIZE L'LENGTH before multiplication.
+
+ -- Id: A.18
+ function "*" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR((R'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, R, with a non-negative
+ -- INTEGER, L. L is converted to an UNSIGNED vector of
+ -- SIZE R'LENGTH before multiplication.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "/" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.21
+ function "/" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R.
+
+ -- Id: A.23
+ function "/" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by a non-negative INTEGER, R.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.24
+ function "/" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0)
+ -- Result: Divides a non-negative INTEGER, L, by an UNSIGNED vector, R.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "rem" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.27
+ function "rem" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.29
+ function "rem" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L is an UNSIGNED vector and R is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.30
+ function "rem" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where R is an UNSIGNED vector and L is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "mod" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.33
+ function "mod" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.35
+ function "mod" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(L'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is an UNSIGNED vector and R
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.36
+ function "mod" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where R is an UNSIGNED vector and L
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ -- Id: A.39
+ function find_leftmost (ARG : STD_ULOGIC_VECTOR; Y : STD_ULOGIC) return INTEGER;
+ -- Result subtype: INTEGER
+ -- Result: Finds the leftmost occurrence of the value of Y in ARG.
+ -- Returns the index of the occurrence if it exists, or -1 otherwise.
+
+ -- Id: A.41
+ function find_rightmost (ARG : STD_ULOGIC_VECTOR; Y : STD_ULOGIC) return INTEGER;
+ -- Result subtype: INTEGER
+ -- Result: Finds the leftmost occurrence of the value of Y in ARG.
+ -- Returns the index of the occurrence if it exists, or -1 otherwise.
+
+ --============================================================================
+ -- Comparison Operators
+ --============================================================================
+
+ -- Id: C.1
+ function ">" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.3
+ function ">" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.5
+ function ">" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.7
+ function "<" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.9
+ function "<" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.11
+ function "<" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.13
+ function "<=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.15
+ function "<=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.17
+ function "<=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.19
+ function ">=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.21
+ function ">=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.23
+ function ">=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.25
+ function "=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.27
+ function "=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.29
+ function "=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.31
+ function "/=" (L, R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.33
+ function "/=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.35
+ function "/=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.37
+ function MINIMUM (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR
+ -- Result: Returns the lesser of two UNSIGNED vectors that may be
+ -- of different lengths.
+
+ -- Id: C.39
+ function MINIMUM (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR
+ -- Result: Returns the lesser of a nonnegative INTEGER, L, and
+ -- an UNSIGNED vector, R.
+
+ -- Id: C.41
+ function MINIMUM (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR
+ -- Result: Returns the lesser of an UNSIGNED vector, L, and
+ -- a nonnegative INTEGER, R.
+
+ --============================================================================
+
+ -- Id: C.43
+ function MAXIMUM (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR
+ -- Result: Returns the greater of two UNSIGNED vectors that may be
+ -- of different lengths.
+
+ -- Id: C.45
+ function MAXIMUM (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR
+ -- Result: Returns the greater of a nonnegative INTEGER, L, and
+ -- an UNSIGNED vector, R.
+
+ -- Id: C.47
+ function MAXIMUM (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR
+ -- Result: Returns the greater of an UNSIGNED vector, L, and
+ -- a nonnegative INTEGER, R.
+
+ --============================================================================
+ -- Id: C.49
+ function "?>" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.51
+ function "?>" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L > R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.53
+ function "?>" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L > R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.55
+ function "?<" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.57
+ function "?<" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L < R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.59
+ function "?<" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L < R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.61
+ function "?<=" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.63
+ function "?<=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L <= R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.65
+ function "?<=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L <= R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.67
+ function "?>=" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.69
+ function "?>=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L >= R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.71
+ function "?>=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L >= R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.73
+ function "?=" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.75
+ function "?=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L = R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.77
+ function "?=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L = R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+
+ -- Id: C.79
+ function "?/=" (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.81
+ function "?/=" (L : NATURAL; R : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L /= R" where L is a nonnegative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.83
+ function "?/=" (L : STD_ULOGIC_VECTOR; R : NATURAL) return STD_ULOGIC;
+ -- Result subtype: STD_ULOGIC
+ -- Result: Computes "L /= R" where L is an UNSIGNED vector and
+ -- R is a nonnegative INTEGER.
+
+ --============================================================================
+ -- Shift and Rotate Functions
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-left on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with '0'.
+ -- The COUNT leftmost elements are lost.
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-right on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with '0'.
+ -- The COUNT rightmost elements are lost.
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-left of an UNSIGNED vector COUNT times.
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG : STD_ULOGIC_VECTOR; COUNT : NATURAL)
+ return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-right of an UNSIGNED vector COUNT times.
+
+
+ --============================================================================
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.17 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.17
+ function "sla" (ARG : STD_ULOGIC_VECTOR; COUNT : INTEGER) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note: Function S.19 is not compatible with IEEE Std 1076-1987. Comment
+ -- out the function (declaration and body) for IEEE Std 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.19
+ function "sra" (ARG : STD_ULOGIC_VECTOR; COUNT : INTEGER) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_RIGHT(ARG, COUNT)
+
+
+ --============================================================================
+ -- RESIZE Functions
+ --============================================================================
+
+ -- Id: R.2
+ function RESIZE (ARG : STD_ULOGIC_VECTOR; NEW_SIZE : NATURAL)
+ return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(NEW_SIZE-1 downto 0)
+ -- Result: Resizes the UNSIGNED vector ARG to the specified size.
+ -- To create a larger vector, the new [leftmost] bit positions
+ -- are filled with '0'. When truncating, the leftmost bits
+ -- are dropped.
+
+ function RESIZE (ARG, SIZE_RES : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR (SIZE_RES'length-1 downto 0)
+
+ --============================================================================
+ -- Conversion Functions
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG : STD_ULOGIC_VECTOR) return NATURAL;
+ -- Result subtype: NATURAL. Value cannot be negative since parameter is an
+ -- UNSIGNED vector.
+ -- Result: Converts the UNSIGNED vector to an INTEGER.
+
+ -- Id: D.3
+ function To_StdLogicVector (ARG, SIZE : NATURAL) return STD_LOGIC_VECTOR;
+ -- Result subtype: STD_LOGIC_VECTOR(SIZE-1 downto 0)
+ -- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
+ -- the specified SIZE.
+
+ function To_StdLogicVector (ARG : NATURAL; SIZE_RES : STD_ULOGIC_VECTOR)
+ return STD_LOGIC_VECTOR;
+ -- Result subtype: STD_LOGIC_VECTOR(SIZE_RES'length-1 downto 0)
+
+ alias To_Std_Logic_Vector is
+ To_StdLogicVector[NATURAL, NATURAL return STD_LOGIC_VECTOR];
+ alias To_SLV is
+ To_StdLogicVector[NATURAL, NATURAL return STD_LOGIC_VECTOR];
+ alias To_Std_Logic_Vector is
+ To_StdLogicVector[NATURAL, STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR];
+ alias To_SLV is
+ To_StdLogicVector[NATURAL, STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR];
+
+ -- Id: D.5
+ function To_StdULogicVector (ARG, SIZE : NATURAL) return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_ULOGIC_VECTOR(SIZE-1 downto 0)
+ -- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
+ -- the specified SIZE.
+
+ function To_StdULogicVector (ARG : NATURAL; SIZE_RES : STD_ULOGIC_VECTOR)
+ return STD_ULOGIC_VECTOR;
+ -- Result subtype: STD_LOGIC_VECTOR(SIZE_RES'length-1 downto 0)
+
+ alias To_Std_ULogic_Vector is
+ To_StdULogicVector[NATURAL, NATURAL return STD_ULOGIC_VECTOR];
+ alias To_SULV is
+ To_StdULogicVector[NATURAL, NATURAL return STD_ULOGIC_VECTOR];
+ alias To_Std_ULogic_Vector is
+ To_StdULogicVector[NATURAL, STD_ULOGIC_VECTOR return STD_ULOGIC_VECTOR];
+ alias To_SULV is
+ To_StdULogicVector[NATURAL, STD_ULOGIC_VECTOR return STD_ULOGIC_VECTOR];
+
+end package NUMERIC_STD_UNSIGNED;
diff --git a/libraries/ieee2008/std_logic_1164-body.vhdl b/libraries/ieee2008/std_logic_1164-body.vhdl new file mode 100644 index 000000000..7a9c91d9e --- /dev/null +++ b/libraries/ieee2008/std_logic_1164-body.vhdl @@ -0,0 +1,1569 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard multivalue logic package +-- : (STD_LOGIC_1164 package body) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE model standards group (PAR 1164), +-- : Accellera VHDL-TC, and IEEE P1076 Working Group +-- : +-- Purpose : This packages defines a standard for designers +-- : to use in describing the interconnection data types +-- : used in vhdl modeling. +-- : +-- Limitation: The logic system defined in this package may +-- : be insufficient for modeling switched transistors, +-- : since such a requirement is out of the scope of this +-- : effort. Furthermore, mathematics, primitives, +-- : timing standards, etc. are considered orthogonal +-- : issues as it relates to this package and are therefore +-- : beyond the scope of this effort. +-- : +-- 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) $ +-- -------------------------------------------------------------------- + +package body std_logic_1164 is + ------------------------------------------------------------------- + -- local types + ------------------------------------------------------------------- + type stdlogic_1d is array (STD_ULOGIC) of STD_ULOGIC; + type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC; + + ------------------------------------------------------------------- + -- resolution function + ------------------------------------------------------------------- + constant resolution_table : stdlogic_table := ( + -- --------------------------------------------------------- + -- | U X 0 1 Z W L H - | | + -- --------------------------------------------------------- + ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U | + ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'), -- | X | + ('U', 'X', '0', 'X', '0', '0', '0', '0', 'X'), -- | 0 | + ('U', 'X', 'X', '1', '1', '1', '1', '1', 'X'), -- | 1 | + ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X'), -- | Z | + ('U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X'), -- | W | + ('U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X'), -- | L | + ('U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X'), -- | H | + ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X') -- | - | + ); + + function resolved (s : STD_ULOGIC_VECTOR) return STD_ULOGIC is + variable result : STD_ULOGIC := 'Z'; -- weakest state default + begin + -- the test for a single driver is essential otherwise the + -- loop would return 'X' for a single driver of '-' and that + -- would conflict with the value of a single driver unresolved + -- signal. + if (s'length = 1) then return s(s'low); + else + for i in s'range loop + result := resolution_table(result, s(i)); + end loop; + end if; + return result; + end function resolved; + + ------------------------------------------------------------------- + -- tables for logical operations + ------------------------------------------------------------------- + + -- truth table for "and" function + constant and_table : stdlogic_table := ( + -- ---------------------------------------------------- + -- | U X 0 1 Z W L H - | | + -- ---------------------------------------------------- + ('U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U'), -- | U | + ('U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X'), -- | X | + ('0', '0', '0', '0', '0', '0', '0', '0', '0'), -- | 0 | + ('U', 'X', '0', '1', 'X', 'X', '0', '1', 'X'), -- | 1 | + ('U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X'), -- | Z | + ('U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X'), -- | W | + ('0', '0', '0', '0', '0', '0', '0', '0', '0'), -- | L | + ('U', 'X', '0', '1', 'X', 'X', '0', '1', 'X'), -- | H | + ('U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X') -- | - | + ); + + -- truth table for "or" function + constant or_table : stdlogic_table := ( + -- ---------------------------------------------------- + -- | U X 0 1 Z W L H - | | + -- ---------------------------------------------------- + ('U', 'U', 'U', '1', 'U', 'U', 'U', '1', 'U'), -- | U | + ('U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X'), -- | X | + ('U', 'X', '0', '1', 'X', 'X', '0', '1', 'X'), -- | 0 | + ('1', '1', '1', '1', '1', '1', '1', '1', '1'), -- | 1 | + ('U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X'), -- | Z | + ('U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X'), -- | W | + ('U', 'X', '0', '1', 'X', 'X', '0', '1', 'X'), -- | L | + ('1', '1', '1', '1', '1', '1', '1', '1', '1'), -- | H | + ('U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X') -- | - | + ); + + -- truth table for "xor" function + constant xor_table : stdlogic_table := ( + -- ---------------------------------------------------- + -- | U X 0 1 Z W L H - | | + -- ---------------------------------------------------- + ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U | + ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'), -- | X | + ('U', 'X', '0', '1', 'X', 'X', '0', '1', 'X'), -- | 0 | + ('U', 'X', '1', '0', 'X', 'X', '1', '0', 'X'), -- | 1 | + ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'), -- | Z | + ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'), -- | W | + ('U', 'X', '0', '1', 'X', 'X', '0', '1', 'X'), -- | L | + ('U', 'X', '1', '0', 'X', 'X', '1', '0', 'X'), -- | H | + ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X') -- | - | + ); + + -- truth table for "not" function + constant not_table : stdlogic_1d := + -- ------------------------------------------------- + -- | U X 0 1 Z W L H - | + -- ------------------------------------------------- + ('U', 'X', '1', '0', 'X', 'X', '1', '0', 'X'); + + ------------------------------------------------------------------- + -- overloaded logical operators ( with optimizing hints ) + ------------------------------------------------------------------- + + function "and" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is + begin + return (and_table(l, r)); + end function "and"; + + function "nand" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is + begin + return (not_table (and_table(l, r))); + end function "nand"; + + function "or" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is + begin + return (or_table(l, r)); + end function "or"; + + function "nor" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is + begin + return (not_table (or_table(l, r))); + end function "nor"; + + function "xor" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is + begin + return (xor_table(l, r)); + end function "xor"; + + function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC) return ux01 is + begin + return not_table(xor_table(l, r)); + end function "xnor"; + + function "not" (l : STD_ULOGIC) return UX01 is + begin + return (not_table(l)); + end function "not"; + + ------------------------------------------------------------------- + -- and + ------------------------------------------------------------------- + function "and" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + if (l'length /= r'length) then + assert false + report "STD_LOGIC_1164.""and"": " + & "arguments of overloaded 'and' operator are not of the same length" + severity failure; + else + for i in result'range loop + result(i) := and_table (lv(i), rv(i)); + end loop; + end if; + return result; + end function "and"; + ------------------------------------------------------------------- + -- nand + ------------------------------------------------------------------- + function "nand" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + if (l'length /= r'length) then + assert false + report "STD_LOGIC_1164.""nand"": " + & "arguments of overloaded 'nand' operator are not of the same length" + severity failure; + else + for i in result'range loop + result(i) := not_table(and_table (lv(i), rv(i))); + end loop; + end if; + return result; + end function "nand"; + ------------------------------------------------------------------- + -- or + ------------------------------------------------------------------- + function "or" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + if (l'length /= r'length) then + assert false + report "STD_LOGIC_1164.""or"": " + & "arguments of overloaded 'or' operator are not of the same length" + severity failure; + else + for i in result'range loop + result(i) := or_table (lv(i), rv(i)); + end loop; + end if; + return result; + end function "or"; + ------------------------------------------------------------------- + -- nor + ------------------------------------------------------------------- + function "nor" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + if (l'length /= r'length) then + assert false + report "STD_LOGIC_1164.""nor"": " + & "arguments of overloaded 'nor' operator are not of the same length" + severity failure; + else + for i in result'range loop + result(i) := not_table(or_table (lv(i), rv(i))); + end loop; + end if; + return result; + end function "nor"; + --------------------------------------------------------------------- + -- xor + ------------------------------------------------------------------- + function "xor" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + if (l'length /= r'length) then + assert false + report "STD_LOGIC_1164.""xor"": " + & "arguments of overloaded 'xor' operator are not of the same length" + severity failure; + else + for i in result'range loop + result(i) := xor_table (lv(i), rv(i)); + end loop; + end if; + return result; + end function "xor"; + ------------------------------------------------------------------- + -- xnor + ------------------------------------------------------------------- + function "xnor" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + if (l'length /= r'length) then + assert false + report "STD_LOGIC_1164.""xnor"": " + & "arguments of overloaded 'xnor' operator are not of the same length" + severity failure; + else + for i in result'range loop + result(i) := not_table(xor_table (lv(i), rv(i))); + end loop; + end if; + return result; + end function "xnor"; + ------------------------------------------------------------------- + -- not + ------------------------------------------------------------------- + function "not" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => 'X'); + begin + for i in result'range loop + result(i) := not_table(lv(i)); + end loop; + return result; + end function "not"; + + ------------------------------------------------------------------- + -- and + ------------------------------------------------------------------- + function "and" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + for i in result'range loop + result(i) := and_table (lv(i), r); + end loop; + return result; + end function "and"; + ------------------------------------------------------------------- + function "and" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) + return STD_ULOGIC_VECTOR + is + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to r'length); + begin + for i in result'range loop + result(i) := and_table (l, rv(i)); + end loop; + return result; + end function "and"; + + ------------------------------------------------------------------- + -- nand + ------------------------------------------------------------------- + function "nand" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + for i in result'range loop + result(i) := not_table(and_table (lv(i), r)); + end loop; + return result; + end function "nand"; + ------------------------------------------------------------------- + function "nand" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) + return STD_ULOGIC_VECTOR + is + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to r'length); + begin + for i in result'range loop + result(i) := not_table(and_table (l, rv(i))); + end loop; + return result; + end function "nand"; + + ------------------------------------------------------------------- + -- or + ------------------------------------------------------------------- + function "or" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + for i in result'range loop + result(i) := or_table (lv(i), r); + end loop; + return result; + end function "or"; + ------------------------------------------------------------------- + function "or" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) + return STD_ULOGIC_VECTOR + is + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to r'length); + begin + for i in result'range loop + result(i) := or_table (l, rv(i)); + end loop; + return result; + end function "or"; + + ------------------------------------------------------------------- + -- nor + ------------------------------------------------------------------- + function "nor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + for i in result'range loop + result(i) := not_table(or_table (lv(i), r)); + end loop; + return result; + end function "nor"; + ------------------------------------------------------------------- + function "nor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) + return STD_ULOGIC_VECTOR + is + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to r'length); + begin + for i in result'range loop + result(i) := not_table(or_table (l, rv(i))); + end loop; + return result; + end function "nor"; + + ------------------------------------------------------------------- + -- xor + ------------------------------------------------------------------- + function "xor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + for i in result'range loop + result(i) := xor_table (lv(i), r); + end loop; + return result; + end function "xor"; + ------------------------------------------------------------------- + function "xor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) + return STD_ULOGIC_VECTOR + is + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to r'length); + begin + for i in result'range loop + result(i) := xor_table (l, rv(i)); + end loop; + return result; + end function "xor"; + + ------------------------------------------------------------------- + -- xnor + ------------------------------------------------------------------- + function "xnor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + begin + for i in result'range loop + result(i) := not_table(xor_table (lv(i), r)); + end loop; + return result; + end function "xnor"; + ------------------------------------------------------------------- + function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) + return STD_ULOGIC_VECTOR + is + alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r; + variable result : STD_ULOGIC_VECTOR (1 to r'length); + begin + for i in result'range loop + result(i) := not_table(xor_table (l, rv(i))); + end loop; + return result; + end function "xnor"; + + ------------------------------------------------------------------- + -- and + ------------------------------------------------------------------- + function "and" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is + variable result : STD_ULOGIC := '1'; + begin + for i in l'reverse_range loop + result := and_table (l(i), result); + end loop; + return result; + end function "and"; + + ------------------------------------------------------------------- + -- nand + ------------------------------------------------------------------- + function "nand" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is + variable result : STD_ULOGIC := '1'; + begin + for i in l'reverse_range loop + result := and_table (l(i), result); + end loop; + return not_table(result); + end function "nand"; + + ------------------------------------------------------------------- + -- or + ------------------------------------------------------------------- + function "or" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is + variable result : STD_ULOGIC := '0'; + begin + for i in l'reverse_range loop + result := or_table (l(i), result); + end loop; + return result; + end function "or"; + + ------------------------------------------------------------------- + -- nor + ------------------------------------------------------------------- + function "nor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is + variable result : STD_ULOGIC := '0'; + begin + for i in l'reverse_range loop + result := or_table (l(i), result); + end loop; + return not_table(result); + end function "nor"; + + ------------------------------------------------------------------- + -- xor + ------------------------------------------------------------------- + function "xor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is + variable result : STD_ULOGIC := '0'; + begin + for i in l'reverse_range loop + result := xor_table (l(i), result); + end loop; + return result; + end function "xor"; + + ------------------------------------------------------------------- + -- xnor + ------------------------------------------------------------------- + function "xnor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is + variable result : STD_ULOGIC := '0'; + begin + for i in l'reverse_range loop + result := xor_table (l(i), result); + end loop; + return not_table(result); + end function "xnor"; + + ------------------------------------------------------------------- + -- shift operators + ------------------------------------------------------------------- + + ------------------------------------------------------------------- + -- sll + ------------------------------------------------------------------- + function "sll" (l : STD_ULOGIC_VECTOR; r : INTEGER) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0'); + begin + if r >= 0 then + result(1 to l'length - r) := lv(r + 1 to l'length); + else + result := l srl -r; + end if; + return result; + end function "sll"; + + ------------------------------------------------------------------- + -- srl + ------------------------------------------------------------------- + function "srl" (l : STD_ULOGIC_VECTOR; r : INTEGER) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0'); + begin + if r >= 0 then + result(r + 1 to l'length) := lv(1 to l'length - r); + else + result := l sll -r; + end if; + return result; + end function "srl"; + + ------------------------------------------------------------------- + -- rol + ------------------------------------------------------------------- + function "rol" (l : STD_ULOGIC_VECTOR; r : INTEGER) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length); + constant rm : INTEGER := r mod l'length; + begin + if r >= 0 then + result(1 to l'length - rm) := lv(rm + 1 to l'length); + result(l'length - rm + 1 to l'length) := lv(1 to rm); + else + result := l ror -r; + end if; + return result; + end function "rol"; + + ------------------------------------------------------------------- + -- ror + ------------------------------------------------------------------- + function "ror" (l : STD_ULOGIC_VECTOR; r : INTEGER) + return STD_ULOGIC_VECTOR + is + alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l; + variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0'); + constant rm : INTEGER := r mod l'length; + begin + if r >= 0 then + result(rm + 1 to l'length) := lv(1 to l'length - rm); + result(1 to rm) := lv(l'length - rm + 1 to l'length); + else + result := l rol -r; + end if; + return result; + end function "ror"; + + ------------------------------------------------------------------- + -- conversion tables + ------------------------------------------------------------------- + type logic_x01_table is array (STD_ULOGIC'low to STD_ULOGIC'high) of X01; + type logic_x01z_table is array (STD_ULOGIC'low to STD_ULOGIC'high) of X01Z; + type logic_ux01_table is array (STD_ULOGIC'low to STD_ULOGIC'high) of UX01; + ---------------------------------------------------------- + -- table name : cvt_to_x01 + -- + -- parameters : + -- in : std_ulogic -- some logic value + -- returns : x01 -- state value of logic value + -- purpose : to convert state-strength to state only + -- + -- example : if (cvt_to_x01 (input_signal) = '1' ) then ... + -- + ---------------------------------------------------------- + constant cvt_to_x01 : logic_x01_table := ( + 'X', -- 'U' + 'X', -- 'X' + '0', -- '0' + '1', -- '1' + 'X', -- 'Z' + 'X', -- 'W' + '0', -- 'L' + '1', -- 'H' + 'X' -- '-' + ); + + ---------------------------------------------------------- + -- table name : cvt_to_x01z + -- + -- parameters : + -- in : std_ulogic -- some logic value + -- returns : x01z -- state value of logic value + -- purpose : to convert state-strength to state only + -- + -- example : if (cvt_to_x01z (input_signal) = '1' ) then ... + -- + ---------------------------------------------------------- + constant cvt_to_x01z : logic_x01z_table := ( + 'X', -- 'U' + 'X', -- 'X' + '0', -- '0' + '1', -- '1' + 'Z', -- 'Z' + 'X', -- 'W' + '0', -- 'L' + '1', -- 'H' + 'X' -- '-' + ); + + ---------------------------------------------------------- + -- table name : cvt_to_ux01 + -- + -- parameters : + -- in : std_ulogic -- some logic value + -- returns : ux01 -- state value of logic value + -- purpose : to convert state-strength to state only + -- + -- example : if (cvt_to_ux01 (input_signal) = '1' ) then ... + -- + ---------------------------------------------------------- + constant cvt_to_ux01 : logic_ux01_table := ( + 'U', -- 'U' + 'X', -- 'X' + '0', -- '0' + '1', -- '1' + 'X', -- 'Z' + 'X', -- 'W' + '0', -- 'L' + '1', -- 'H' + 'X' -- '-' + ); + + ------------------------------------------------------------------- + -- conversion functions + ------------------------------------------------------------------- + function To_bit (s : STD_ULOGIC; xmap : BIT := '0') return BIT is + begin + case s is + when '0' | 'L' => return ('0'); + when '1' | 'H' => return ('1'); + when others => return xmap; + end case; + end function To_bit; + -------------------------------------------------------------------- + function To_bitvector (s : STD_ULOGIC_VECTOR; xmap : BIT := '0') + return BIT_VECTOR + is + alias sv : STD_ULOGIC_VECTOR (s'length-1 downto 0) is s; + variable result : BIT_VECTOR (s'length-1 downto 0); + begin + for i in result'range loop + case sv(i) is + when '0' | 'L' => result(i) := '0'; + when '1' | 'H' => result(i) := '1'; + when others => result(i) := xmap; + end case; + end loop; + return result; + end function To_bitvector; + -------------------------------------------------------------------- + function To_StdULogic (b : BIT) return STD_ULOGIC is + begin + case b is + when '0' => return '0'; + when '1' => return '1'; + end case; + end function To_StdULogic; + -------------------------------------------------------------------- + function To_StdLogicVector (b : BIT_VECTOR) + return STD_LOGIC_VECTOR + is + alias bv : BIT_VECTOR (b'length-1 downto 0) is b; + variable result : STD_LOGIC_VECTOR (b'length-1 downto 0); + begin + for i in result'range loop + case bv(i) is + when '0' => result(i) := '0'; + when '1' => result(i) := '1'; + end case; + end loop; + return result; + end function To_StdLogicVector; + -------------------------------------------------------------------- + function To_StdLogicVector (s : STD_ULOGIC_VECTOR) + return STD_LOGIC_VECTOR + is + alias sv : STD_ULOGIC_VECTOR (s'length-1 downto 0) is s; + variable result : STD_LOGIC_VECTOR (s'length-1 downto 0); + begin + for i in result'range loop + result(i) := sv(i); + end loop; + return result; + end function To_StdLogicVector; + -------------------------------------------------------------------- + function To_StdULogicVector (b : BIT_VECTOR) + return STD_ULOGIC_VECTOR + is + alias bv : BIT_VECTOR (b'length-1 downto 0) is b; + variable result : STD_ULOGIC_VECTOR (b'length-1 downto 0); + begin + for i in result'range loop + case bv(i) is + when '0' => result(i) := '0'; + when '1' => result(i) := '1'; + end case; + end loop; + return result; + end function To_StdULogicVector; + -------------------------------------------------------------------- + function To_StdULogicVector (s : STD_LOGIC_VECTOR) + return STD_ULOGIC_VECTOR + is + alias sv : STD_LOGIC_VECTOR (s'length-1 downto 0) is s; + variable result : STD_ULOGIC_VECTOR (s'length-1 downto 0); + begin + for i in result'range loop + result(i) := sv(i); + end loop; + return result; + end function To_StdULogicVector; + + ------------------------------------------------------------------- + -- strength strippers and type convertors + ------------------------------------------------------------------- + -- to_01 + ------------------------------------------------------------------- + function TO_01 (s : STD_ULOGIC_VECTOR; xmap : STD_ULOGIC := '0') + return STD_ULOGIC_VECTOR + is + variable RESULT : STD_ULOGIC_VECTOR(s'length-1 downto 0); + variable BAD_ELEMENT : BOOLEAN := false; + alias XS : STD_ULOGIC_VECTOR(s'length-1 downto 0) is s; + begin + for I in RESULT'range loop + case XS(I) is + when '0' | 'L' => RESULT(I) := '0'; + when '1' | 'H' => RESULT(I) := '1'; + when others => BAD_ELEMENT := true; + end case; + end loop; + if BAD_ELEMENT then + for I in RESULT'range loop + RESULT(I) := XMAP; -- standard fixup + end loop; + end if; + return RESULT; + end function TO_01; + ------------------------------------------------------------------- + function TO_01 (s : STD_ULOGIC; xmap : STD_ULOGIC := '0') return STD_ULOGIC is + begin + case s is + when '0' | 'L' => RETURN '0'; + when '1' | 'H' => RETURN '1'; + when others => return xmap; + end case; + end function TO_01; + ------------------------------------------------------------------- + function TO_01 (s : BIT_VECTOR; xmap : STD_ULOGIC := '0') + return STD_ULOGIC_VECTOR + is + variable RESULT : STD_ULOGIC_VECTOR(s'length-1 downto 0); + alias XS : BIT_VECTOR(s'length-1 downto 0) is s; + begin + for I in RESULT'range loop + case XS(I) is + when '0' => RESULT(I) := '0'; + when '1' => RESULT(I) := '1'; + end case; + end loop; + return RESULT; + end function TO_01; + ------------------------------------------------------------------- + function TO_01 (s : BIT; xmap : STD_ULOGIC := '0') return STD_ULOGIC is + begin + case s is + when '0' => RETURN '0'; + when '1' => RETURN '1'; + end case; + end function TO_01; + ------------------------------------------------------------------- + -- to_x01 + ------------------------------------------------------------------- + function To_X01 (s : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias sv : STD_ULOGIC_VECTOR (1 to s'length) is s; + variable result : STD_ULOGIC_VECTOR (1 to s'length); + begin + for i in result'range loop + result(i) := cvt_to_x01 (sv(i)); + end loop; + return result; + end function To_X01; + -------------------------------------------------------------------- + function To_X01 (s : STD_ULOGIC) return X01 is + begin + return (cvt_to_x01(s)); + end function To_X01; + -------------------------------------------------------------------- + function To_X01 (b : BIT_VECTOR) return STD_ULOGIC_VECTOR is + alias bv : BIT_VECTOR (1 to b'length) is b; + variable result : STD_ULOGIC_VECTOR (1 to b'length); + begin + for i in result'range loop + case bv(i) is + when '0' => result(i) := '0'; + when '1' => result(i) := '1'; + end case; + end loop; + return result; + end function To_X01; + -------------------------------------------------------------------- + function To_X01 (b : BIT) return X01 is + begin + case b is + when '0' => return('0'); + when '1' => return('1'); + end case; + end function To_X01; + -------------------------------------------------------------------- + -- to_x01z + ------------------------------------------------------------------- + function To_X01Z (s : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias sv : STD_ULOGIC_VECTOR (1 to s'length) is s; + variable result : STD_ULOGIC_VECTOR (1 to s'length); + begin + for i in result'range loop + result(i) := cvt_to_x01z (sv(i)); + end loop; + return result; + end function To_X01Z; + -------------------------------------------------------------------- + function To_X01Z (s : STD_ULOGIC) return X01Z is + begin + return (cvt_to_x01z(s)); + end function To_X01Z; + -------------------------------------------------------------------- + function To_X01Z (b : BIT_VECTOR) return STD_ULOGIC_VECTOR is + alias bv : BIT_VECTOR (1 to b'length) is b; + variable result : STD_ULOGIC_VECTOR (1 to b'length); + begin + for i in result'range loop + case bv(i) is + when '0' => result(i) := '0'; + when '1' => result(i) := '1'; + end case; + end loop; + return result; + end function To_X01Z; + -------------------------------------------------------------------- + function To_X01Z (b : BIT) return X01Z is + begin + case b is + when '0' => return('0'); + when '1' => return('1'); + end case; + end function To_X01Z; + -------------------------------------------------------------------- + -- to_ux01 + ------------------------------------------------------------------- + function To_UX01 (s : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is + alias sv : STD_ULOGIC_VECTOR (1 to s'length) is s; + variable result : STD_ULOGIC_VECTOR (1 to s'length); + begin + for i in result'range loop + result(i) := cvt_to_ux01 (sv(i)); + end loop; + return result; + end function To_UX01; + -------------------------------------------------------------------- + function To_UX01 (s : STD_ULOGIC) return UX01 is + begin + return (cvt_to_ux01(s)); + end function To_UX01; + -------------------------------------------------------------------- + function To_UX01 (b : BIT_VECTOR) return STD_ULOGIC_VECTOR is + alias bv : BIT_VECTOR (1 to b'length) is b; + variable result : STD_ULOGIC_VECTOR (1 to b'length); + begin + for i in result'range loop + case bv(i) is + when '0' => result(i) := '0'; + when '1' => result(i) := '1'; + end case; + end loop; + return result; + end function To_UX01; + -------------------------------------------------------------------- + function To_UX01 (b : BIT) return UX01 is + begin + case b is + when '0' => return('0'); + when '1' => return('1'); + end case; + end function To_UX01; + + function "??" (l : STD_ULOGIC) return BOOLEAN is + begin + return l = '1' or l = 'H'; + end function "??"; + + ------------------------------------------------------------------- + -- edge detection + ------------------------------------------------------------------- + function rising_edge (signal s : STD_ULOGIC) return BOOLEAN is + begin + return (s'event and (To_X01(s) = '1') and + (To_X01(s'last_value) = '0')); + end function rising_edge; + + function falling_edge (signal s : STD_ULOGIC) return BOOLEAN is + begin + return (s'event and (To_X01(s) = '0') and + (To_X01(s'last_value) = '1')); + end function falling_edge; + + ------------------------------------------------------------------- + -- object contains an unknown + ------------------------------------------------------------------- + function Is_X (s : STD_ULOGIC_VECTOR) return BOOLEAN is + begin + for i in s'range loop + case s(i) is + when 'U' | 'X' | 'Z' | 'W' | '-' => return true; + when others => null; + end case; + end loop; + return false; + end function Is_X; + -------------------------------------------------------------------- + function Is_X (s : STD_ULOGIC) return BOOLEAN is + begin + case s is + when 'U' | 'X' | 'Z' | 'W' | '-' => return true; + when others => null; + end case; + return false; + end function Is_X; + + ------------------------------------------------------------------- + -- string conversion and write operations + ------------------------------------------------------------------- + + function to_ostring (value : STD_ULOGIC_VECTOR) return STRING is + constant result_length : NATURAL := (value'length+2)/3; + variable pad : STD_ULOGIC_VECTOR(1 to result_length*3 - value'length); + variable padded_value : STD_ULOGIC_VECTOR(1 to result_length*3); + variable result : STRING(1 to result_length); + variable tri : STD_ULOGIC_VECTOR(1 to 3); + begin + if value (value'left) = 'Z' then + pad := (others => 'Z'); + else + pad := (others => '0'); + end if; + padded_value := pad & value; + for i in 1 to result_length loop + tri := To_X01Z(padded_value(3*i-2 to 3*i)); + case tri is + when o"0" => result(i) := '0'; + when o"1" => result(i) := '1'; + when o"2" => result(i) := '2'; + when o"3" => result(i) := '3'; + when o"4" => result(i) := '4'; + when o"5" => result(i) := '5'; + when o"6" => result(i) := '6'; + when o"7" => result(i) := '7'; + when "ZZZ" => result(i) := 'Z'; + when others => result(i) := 'X'; + end case; + end loop; + return result; + end function to_ostring; + + function to_hstring (value : STD_ULOGIC_VECTOR) return STRING is + constant result_length : NATURAL := (value'length+3)/4; + variable pad : STD_ULOGIC_VECTOR(1 to result_length*4 - value'length); + variable padded_value : STD_ULOGIC_VECTOR(1 to result_length*4); + variable result : STRING(1 to result_length); + variable quad : STD_ULOGIC_VECTOR(1 to 4); + begin + if value (value'left) = 'Z' then + pad := (others => 'Z'); + else + pad := (others => '0'); + end if; + padded_value := pad & value; + for i in 1 to result_length loop + quad := To_X01Z(padded_value(4*i-3 to 4*i)); + case quad is + when x"0" => result(i) := '0'; + when x"1" => result(i) := '1'; + when x"2" => result(i) := '2'; + when x"3" => result(i) := '3'; + when x"4" => result(i) := '4'; + when x"5" => result(i) := '5'; + when x"6" => result(i) := '6'; + when x"7" => result(i) := '7'; + when x"8" => result(i) := '8'; + when x"9" => result(i) := '9'; + when x"A" => result(i) := 'A'; + when x"B" => result(i) := 'B'; + when x"C" => result(i) := 'C'; + when x"D" => result(i) := 'D'; + when x"E" => result(i) := 'E'; + when x"F" => result(i) := 'F'; + when "ZZZZ" => result(i) := 'Z'; + when others => result(i) := 'X'; + end case; + end loop; + return result; + end function to_hstring; + + -- Type and constant definitions used to map STD_ULOGIC values + -- into/from character values. + 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 + + -- 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; + + procedure READ (L : inout LINE; VALUE : out STD_ULOGIC; + GOOD : out BOOLEAN) is + variable c : CHARACTER; + variable readOk : BOOLEAN; + begin + VALUE := 'U'; -- initialize to a "U" + Skip_whitespace (L); + read (l, c, readOk); + if not readOk then + good := false; + else + if char_to_MVL9plus(c) = error then + good := false; + else + VALUE := char_to_MVL9(c); + good := true; + end if; + end if; + end procedure READ; + + procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; + GOOD : out BOOLEAN) is + variable m : STD_ULOGIC; + variable c : CHARACTER; + variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1); + variable readOk : BOOLEAN; + variable i : INTEGER; + variable lastu : BOOLEAN := false; -- last character was an "_" + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then + read (l, c, readOk); + i := 0; + good := true; + while i < VALUE'length loop + if not readOk then -- Bail out if there was a bad read + good := false; + return; + elsif c = '_' then + if i = 0 then + good := false; -- Begins with an "_" + return; + elsif lastu then + good := false; -- "__" detected + return; + else + lastu := true; + end if; + elsif (char_to_MVL9plus(c) = error) then + good := false; -- Illegal character + return; + else + mv(i) := char_to_MVL9(c); + i := i + 1; + if i > mv'high then -- reading done + 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 STD_ULOGIC) is + variable c : CHARACTER; + variable readOk : BOOLEAN; + begin + VALUE := 'U'; -- initialize to a "U" + Skip_whitespace (L); + read (l, c, readOk); + if not readOk then + report "STD_LOGIC_1164.READ(STD_ULOGIC) " + & "End of string encountered" + severity error; + return; + elsif char_to_MVL9plus(c) = error then + report + "STD_LOGIC_1164.READ(STD_ULOGIC) Error: Character '" & + c & "' read, expected STD_ULOGIC literal." + severity error; + else + VALUE := char_to_MVL9(c); + end if; + end procedure READ; + + procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is + variable m : STD_ULOGIC; + variable c : CHARACTER; + variable readOk : BOOLEAN; + variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1); + variable i : INTEGER; + variable lastu : BOOLEAN := false; -- last character was an "_" + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then -- non Null input string + read (l, c, readOk); + i := 0; + while i < VALUE'length loop + if readOk = false then -- Bail out if there was a bad read + report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) " + & "End of string encountered" + severity error; + return; + elsif c = '_' then + if i = 0 then + report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) " + & "String begins with an ""_""" severity error; + return; + elsif lastu then + report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) " + & "Two underscores detected in input string ""__""" + severity error; + return; + else + lastu := true; + end if; + elsif char_to_MVL9plus(c) = error then + report + "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) Error: Character '" & + c & "' read, expected STD_ULOGIC literal." + severity error; + return; + else + mv(i) := char_to_MVL9(c); + i := i + 1; + if i > mv'high then + VALUE := mv; + return; + end if; + lastu := false; + end if; + read(L, c, readOk); + end loop; + end if; + end procedure READ; + + procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + begin + write(l, MVL9_to_char(VALUE), justified, field); + end procedure WRITE; + + procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + variable s : STRING(1 to VALUE'length); + alias m : STD_ULOGIC_VECTOR(1 to VALUE'length) is VALUE; + begin + for i in 1 to VALUE'length loop + s(i) := MVL9_to_char(m(i)); + end loop; + write(l, s, justified, field); + end procedure WRITE; + + procedure Char2TriBits (C : in 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 + "STD_LOGIC_1164.OREAD Error: Read a '" & c & + "', expected an Octal character (0-7)." + severity error; + good := false; + end case; + end procedure Char2TriBits; + + procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; + GOOD : out BOOLEAN) is + variable ok : BOOLEAN; + variable c : CHARACTER; + constant ne : INTEGER := (VALUE'length+2)/3; + constant pad : INTEGER := ne*3 - VALUE'length; + variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1); + variable i : INTEGER; + variable lastu : BOOLEAN := false; -- last character was an "_" + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then + read (l, c, ok); + i := 0; + while i < ne loop + -- Bail out if there was a bad read + if not ok then + good := false; + return; + elsif c = '_' then + if i = 0 then + good := false; -- Begins with an "_" + return; + elsif lastu then + good := false; -- "__" detected + return; + else + lastu := true; + end if; + else + Char2TriBits(c, sv(3*i to 3*i+2), ok, false); + if not ok then + good := false; + return; + end if; + i := i + 1; + lastu := false; + end if; + if i < ne then + read(L, c, ok); + end if; + end loop; + if or (sv (0 to pad-1)) = '1' then + good := false; -- vector was truncated. + else + good := true; + VALUE := sv (pad to sv'high); + end if; + else + good := true; -- read into a null array + end if; + end procedure OREAD; + + procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is + variable c : CHARACTER; + variable ok : BOOLEAN; + constant ne : INTEGER := (VALUE'length+2)/3; + constant pad : INTEGER := ne*3 - VALUE'length; + variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1); + variable i : INTEGER; + variable lastu : BOOLEAN := false; -- last character was an "_" + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then + read (l, c, ok); + i := 0; + while i < ne loop + -- Bail out if there was a bad read + if not ok then + report "STD_LOGIC_1164.OREAD " + & "End of string encountered" + severity error; + return; + elsif c = '_' then + if i = 0 then + report "STD_LOGIC_1164.OREAD " + & "String begins with an ""_""" severity error; + return; + elsif lastu then + report "STD_LOGIC_1164.OREAD " + & "Two underscores detected in input string ""__""" + severity error; + return; + else + lastu := true; + end if; + else + Char2TriBits(c, sv(3*i to 3*i+2), ok, true); + if not ok then + return; + end if; + i := i + 1; + lastu := false; + end if; + if i < ne then + read(L, c, ok); + end if; + end loop; + if or (sv (0 to pad-1)) = '1' then + report "STD_LOGIC_1164.OREAD Vector truncated" + severity error; + else + VALUE := sv (pad to sv'high); + end if; + end if; + end procedure OREAD; + + 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 + "STD_LOGIC_1164.HREAD Error: Read a '" & c & + "', expected a Hex character (0-F)." + severity error; + good := false; + end case; + end procedure Char2QuadBits; + + procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; + GOOD : out BOOLEAN) is + variable ok : BOOLEAN; + variable c : CHARACTER; + constant ne : INTEGER := (VALUE'length+3)/4; + constant pad : INTEGER := ne*4 - VALUE'length; + variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1); + variable i : INTEGER; + variable lastu : BOOLEAN := false; -- last character was an "_" + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then + read (l, c, ok); + i := 0; + while i < ne loop + -- Bail out if there was a bad read + if not ok then + good := false; + return; + elsif c = '_' then + if i = 0 then + good := false; -- Begins with an "_" + return; + elsif lastu then + good := false; -- "__" detected + return; + else + lastu := true; + end if; + else + Char2QuadBits(c, sv(4*i to 4*i+3), ok, false); + if not ok then + good := false; + return; + end if; + i := i + 1; + lastu := false; + end if; + if i < ne then + read(L, c, ok); + end if; + end loop; + if or (sv (0 to pad-1)) = '1' then + good := false; -- vector was truncated. + else + good := true; + VALUE := sv (pad to sv'high); + end if; + else + good := true; -- Null input string, skips whitespace + end if; + end procedure HREAD; + + procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is + variable ok : BOOLEAN; + variable c : CHARACTER; + constant ne : INTEGER := (VALUE'length+3)/4; + constant pad : INTEGER := ne*4 - VALUE'length; + variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1); + variable i : INTEGER; + variable lastu : BOOLEAN := false; -- last character was an "_" + begin + VALUE := (VALUE'range => 'U'); -- initialize to a "U" + Skip_whitespace (L); + if VALUE'length > 0 then -- non Null input string + read (l, c, ok); + i := 0; + while i < ne loop + -- Bail out if there was a bad read + if not ok then + report "STD_LOGIC_1164.HREAD " + & "End of string encountered" + severity error; + return; + end if; + if c = '_' then + if i = 0 then + report "STD_LOGIC_1164.HREAD " + & "String begins with an ""_""" severity error; + return; + elsif lastu then + report "STD_LOGIC_1164.HREAD " + & "Two underscores detected in input string ""__""" + severity error; + return; + else + lastu := true; + end if; + else + Char2QuadBits(c, sv(4*i to 4*i+3), ok, true); + if not ok then + return; + end if; + i := i + 1; + lastu := false; + end if; + if i < ne then + read(L, c, ok); + end if; + end loop; + if or (sv (0 to pad-1)) = '1' then + report "STD_LOGIC_1164.HREAD Vector truncated" + severity error; + else + VALUE := sv (pad to sv'high); + end if; + end if; + end procedure HREAD; + + procedure OWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + begin + write (L, to_ostring(VALUE), JUSTIFIED, FIELD); + end procedure OWRITE; + + procedure HWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is + begin + write (L, to_hstring (VALUE), JUSTIFIED, FIELD); + end procedure HWRITE; + +end package body std_logic_1164; diff --git a/libraries/ieee2008/std_logic_1164.vhdl b/libraries/ieee2008/std_logic_1164.vhdl new file mode 100644 index 000000000..1a503e184 --- /dev/null +++ b/libraries/ieee2008/std_logic_1164.vhdl @@ -0,0 +1,306 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard multivalue logic package +-- : (STD_LOGIC_1164 package declaration) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: IEEE model standards group (PAR 1164), +-- : Accellera VHDL-TC, and IEEE P1076 Working Group +-- : +-- Purpose : This packages defines a standard for designers +-- : to use in describing the interconnection data types +-- : used in vhdl modeling. +-- : +-- Limitation: The logic system defined in this package may +-- : be insufficient for modeling switched transistors, +-- : since such a requirement is out of the scope of this +-- : effort. Furthermore, mathematics, primitives, +-- : timing standards, etc. are considered orthogonal +-- : issues as it relates to this package and are therefore +-- : beyond the scope of this effort. +-- : +-- 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) $ +-- -------------------------------------------------------------------- + +use STD.TEXTIO.all; + +package std_logic_1164 is + + ------------------------------------------------------------------- + -- logic state system (unresolved) + ------------------------------------------------------------------- + type STD_ULOGIC is ( 'U', -- Uninitialized + 'X', -- Forcing Unknown + '0', -- Forcing 0 + '1', -- Forcing 1 + 'Z', -- High Impedance + 'W', -- Weak Unknown + 'L', -- Weak 0 + 'H', -- Weak 1 + '-' -- Don't care + ); + ------------------------------------------------------------------- + -- unconstrained array of std_ulogic for use with the resolution function + -- and for use in declaring signal arrays of unresolved elements + ------------------------------------------------------------------- + type STD_ULOGIC_VECTOR is array (NATURAL range <>) of STD_ULOGIC; + + ------------------------------------------------------------------- + -- resolution function + ------------------------------------------------------------------- + function resolved (s : STD_ULOGIC_VECTOR) return STD_ULOGIC; + + + ------------------------------------------------------------------- + -- logic state system (resolved) + ------------------------------------------------------------------- + subtype STD_LOGIC is resolved STD_ULOGIC; + + ------------------------------------------------------------------- + -- unconstrained array of resolved std_ulogic for use in declaring + -- signal arrays of resolved elements + ------------------------------------------------------------------- + subtype STD_LOGIC_VECTOR is (resolved) STD_ULOGIC_VECTOR; + + ------------------------------------------------------------------- + -- common subtypes + ------------------------------------------------------------------- + subtype X01 is resolved STD_ULOGIC range 'X' to '1'; -- ('X','0','1') + subtype X01Z is resolved STD_ULOGIC range 'X' to 'Z'; -- ('X','0','1','Z') + subtype UX01 is resolved STD_ULOGIC range 'U' to '1'; -- ('U','X','0','1') + subtype UX01Z is resolved STD_ULOGIC range 'U' to 'Z'; -- ('U','X','0','1','Z') + + ------------------------------------------------------------------- + -- overloaded logical operators + ------------------------------------------------------------------- + + function "and" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01; + function "nand" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01; + function "or" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01; + function "nor" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01; + function "xor" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01; + function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC) return ux01; + function "not" (l : STD_ULOGIC) return UX01; + + ------------------------------------------------------------------- + -- vectorized overloaded logical operators + ------------------------------------------------------------------- + function "and" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function "nand" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function "or" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function "nor" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function "xor" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function "xnor" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function "not" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + function "and" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR; + function "and" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + function "nand" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR; + function "nand" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + function "or" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR; + function "or" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + function "nor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR; + function "nor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + function "xor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR; + function "xor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + function "xnor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR; + function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + function "and" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC; + function "nand" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC; + function "or" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC; + function "nor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC; + function "xor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC; + function "xnor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC; + + ------------------------------------------------------------------- + -- shift operators + ------------------------------------------------------------------- + + function "sll" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR; + function "srl" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR; + function "rol" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR; + function "ror" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR; + + ------------------------------------------------------------------- + -- conversion functions + ------------------------------------------------------------------- + function To_bit (s : STD_ULOGIC; xmap : BIT := '0') return BIT; + function To_bitvector (s : STD_ULOGIC_VECTOR; xmap : BIT := '0') return BIT_VECTOR; + + function To_StdULogic (b : BIT) return STD_ULOGIC; + function To_StdLogicVector (b : BIT_VECTOR) return STD_LOGIC_VECTOR; + function To_StdLogicVector (s : STD_ULOGIC_VECTOR) return STD_LOGIC_VECTOR; + function To_StdULogicVector (b : BIT_VECTOR) return STD_ULOGIC_VECTOR; + function To_StdULogicVector (s : STD_LOGIC_VECTOR) return STD_ULOGIC_VECTOR; + + alias To_Bit_Vector is + To_bitvector[STD_ULOGIC_VECTOR, BIT return BIT_VECTOR]; + alias To_BV is + To_bitvector[STD_ULOGIC_VECTOR, BIT return BIT_VECTOR]; + + alias To_Std_Logic_Vector is + To_StdLogicVector[BIT_VECTOR return STD_LOGIC_VECTOR]; + alias To_SLV is + To_StdLogicVector[BIT_VECTOR return STD_LOGIC_VECTOR]; + + alias To_Std_Logic_Vector is + To_StdLogicVector[STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR]; + alias To_SLV is + To_StdLogicVector[STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR]; + + alias To_Std_ULogic_Vector is + To_StdULogicVector[BIT_VECTOR return STD_ULOGIC_VECTOR]; + alias To_SULV is + To_StdULogicVector[BIT_VECTOR return STD_ULOGIC_VECTOR]; + + alias To_Std_ULogic_Vector is + To_StdULogicVector[STD_LOGIC_VECTOR return STD_ULOGIC_VECTOR]; + alias To_SULV is + To_StdULogicVector[STD_LOGIC_VECTOR return STD_ULOGIC_VECTOR]; + + ------------------------------------------------------------------- + -- strength strippers and type convertors + ------------------------------------------------------------------- + + function TO_01 (s : STD_ULOGIC_VECTOR; xmap : STD_ULOGIC := '0') + return STD_ULOGIC_VECTOR; + function TO_01 (s : STD_ULOGIC; xmap : STD_ULOGIC := '0') + return STD_ULOGIC; + function TO_01 (s : BIT_VECTOR; xmap : STD_ULOGIC := '0') + return STD_ULOGIC_VECTOR; + function TO_01 (s : BIT; xmap : STD_ULOGIC := '0') + return STD_ULOGIC; + + function To_X01 (s : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function To_X01 (s : STD_ULOGIC) return X01; + function To_X01 (b : BIT_VECTOR) return STD_ULOGIC_VECTOR; + function To_X01 (b : BIT) return X01; + + function To_X01Z (s : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function To_X01Z (s : STD_ULOGIC) return X01Z; + function To_X01Z (b : BIT_VECTOR) return STD_ULOGIC_VECTOR; + function To_X01Z (b : BIT) return X01Z; + + function To_UX01 (s : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR; + function To_UX01 (s : STD_ULOGIC) return UX01; + function To_UX01 (b : BIT_VECTOR) return STD_ULOGIC_VECTOR; + function To_UX01 (b : BIT) return UX01; + + function "??" (l : STD_ULOGIC) return BOOLEAN; + + ------------------------------------------------------------------- + -- edge detection + ------------------------------------------------------------------- + function rising_edge (signal s : STD_ULOGIC) return BOOLEAN; + function falling_edge (signal s : STD_ULOGIC) return BOOLEAN; + + ------------------------------------------------------------------- + -- object contains an unknown + ------------------------------------------------------------------- + function Is_X (s : STD_ULOGIC_VECTOR) return BOOLEAN; + function Is_X (s : STD_ULOGIC) return BOOLEAN; + + ------------------------------------------------------------------- + -- matching relational operators + ------------------------------------------------------------------- + -- the following operations are predefined + + -- function "?=" (l, r : STD_ULOGIC) return STD_ULOGIC; + -- function "?=" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC; + + -- function "?/=" (l, r : STD_ULOGIC) return STD_ULOGIC; + -- function "?/=" (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC; + + -- function "?<" (l, r : STD_ULOGIC) return STD_ULOGIC; + -- function "?<=" (l, r : STD_ULOGIC) return STD_ULOGIC; + -- function "?>" (l, r : STD_ULOGIC) return STD_ULOGIC; + -- function "?>=" (l, r : STD_ULOGIC) return STD_ULOGIC; + + ------------------------------------------------------------------- + -- string conversion and write operations + ------------------------------------------------------------------- + -- the following operations are predefined + + -- function to_string (value : STD_ULOGIC) return STRING; + -- function to_string (value : STD_ULOGIC_VECTOR) return STRING; + + -- explicitly defined operations + + alias TO_BSTRING is TO_STRING [STD_ULOGIC_VECTOR return STRING]; + alias TO_BINARY_STRING is TO_STRING [STD_ULOGIC_VECTOR return STRING]; + function TO_OSTRING (VALUE : STD_ULOGIC_VECTOR) return STRING; + alias TO_OCTAL_STRING is TO_OSTRING [STD_ULOGIC_VECTOR return STRING]; + function TO_HSTRING (VALUE : STD_ULOGIC_VECTOR) return STRING; + alias TO_HEX_STRING is TO_HSTRING [STD_ULOGIC_VECTOR return STRING]; + + procedure READ (L : inout LINE; VALUE : out STD_ULOGIC; GOOD : out BOOLEAN); + procedure READ (L : inout LINE; VALUE : out STD_ULOGIC); + + procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN); + procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR); + + procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + + alias BREAD is READ [LINE, STD_ULOGIC_VECTOR, BOOLEAN]; + alias BREAD is READ [LINE, STD_ULOGIC_VECTOR]; + alias BINARY_READ is READ [LINE, STD_ULOGIC_VECTOR, BOOLEAN]; + alias BINARY_READ is READ [LINE, STD_ULOGIC_VECTOR]; + + procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN); + procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR); + alias OCTAL_READ is OREAD [LINE, STD_ULOGIC_VECTOR, BOOLEAN]; + alias OCTAL_READ is OREAD [LINE, STD_ULOGIC_VECTOR]; + + procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN); + procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR); + alias HEX_READ is HREAD [LINE, STD_ULOGIC_VECTOR, BOOLEAN]; + alias HEX_READ is HREAD [LINE, STD_ULOGIC_VECTOR]; + + alias BWRITE is WRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH]; + alias BINARY_WRITE is WRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH]; + + procedure OWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + alias OCTAL_WRITE is OWRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH]; + + procedure HWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR; + JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0); + alias HEX_WRITE is HWRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH]; + +end package std_logic_1164; diff --git a/libraries/ieee2008/std_logic_textio.vhdl b/libraries/ieee2008/std_logic_textio.vhdl new file mode 100644 index 000000000..50f20f12e --- /dev/null +++ b/libraries/ieee2008/std_logic_textio.vhdl @@ -0,0 +1,42 @@ +-- -------------------------------------------------------------------- +-- +-- 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 : Standard multivalue logic package +-- : (STD_LOGIC_TEXTIO package declaration) +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers: Accellera VHDL-TC and IEEE P1076 Working Group +-- : +-- Purpose : This packages is provided as a replacement for non-standard +-- : implementations of the package provided by implementers of +-- : previous versions of this standard. The declarations that +-- : appeared in those non-standard implementations appear in the +-- : package STD_LOGIC_1164 in this standard. +-- : +-- Note : No declarations or definitions shall be included in, +-- : or excluded from this package. +-- : +-- -------------------------------------------------------------------- +-- $Revision: 1220 $ +-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $ +-- -------------------------------------------------------------------- + +PACKAGE std_logic_textio IS + + -- This package is empty - see notes above. + +END PACKAGE std_logic_textio; |