diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/bin/vhdl_ls b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/bin/vhdl_ls new file mode 100755 index 00000000..86ddd50b Binary files /dev/null and b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/bin/vhdl_ls differ diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/README.ieee b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/README.ieee new file mode 100644 index 00000000..39bc281b --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/README.ieee @@ -0,0 +1,30 @@ +https://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: https://standards.ieee.org/news/2013/ieee_1076_vhdl.html#sthash.UFLcTc7E.dpuf diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_float_types.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_float_types.vhdl new file mode 100644 index 00000000..6ad3e37e --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_float_types.vhdl @@ -0,0 +1,61 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_generic_pkg-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_generic_pkg-body.vhdl new file mode 100644 index 00000000..6c18fcb9 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_generic_pkg-body.vhdl @@ -0,0 +1,6361 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 + 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 + 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 intermediate_result : UNRESOLVED_ufixed(arg'length-1 downto 0); + begin + if arg'length < 1 then + return NSLV; + end if; + intermediate_result := arg; + return STD_ULOGIC_VECTOR (intermediate_result); + end function to_sulv; + + function to_sulv ( + arg : UNRESOLVED_sfixed) -- fixed point vector + return STD_ULOGIC_VECTOR + is + variable intermediate_result : UNRESOLVED_sfixed(arg'length-1 downto 0); + begin + if arg'length < 1 then + return NSLV; + end if; + intermediate_result := arg; + return STD_ULOGIC_VECTOR (intermediate_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)); + constant rlow : integer := mins(r'low, r'low); + variable lresize : UNRESOLVED_ufixed (maximum(l'high, r'low) downto + rlow-guard_bits); + variable rresize : UNRESOLVED_ufixed (r'high downto rlow-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; + 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 + 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 + 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 c : CHARACTER; + variable left : positive; + begin + while L /= null and L.all'length /= 0 loop + left := L.all'left; + c := L.all(left); + if (c = ' ' or c = NBSP or c = HT) then + read (L, c); + 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 => true, + 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_generic_pkg.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_generic_pkg.vhdl new file mode 100644 index 00000000..df49433d --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_generic_pkg.vhdl @@ -0,0 +1,1439 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 IEEE P1076 WG. Licensed Apache 2.0"; + + -- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_pkg.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_pkg.vhdl new file mode 100644 index 00000000..1436432a --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/fixed_pkg.vhdl @@ -0,0 +1,52 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- +-- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_generic_pkg-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_generic_pkg-body.vhdl new file mode 100644 index 00000000..35a9ce48 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_generic_pkg-body.vhdl @@ -0,0 +1,5712 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 intermediate_result : UNRESOLVED_float(arg'length-1 downto 0); + begin -- function to_std_ulogic_vector + if arg'length < 1 then + return NSLV; + end if; + intermediate_result := arg; + return STD_ULOGIC_VECTOR (intermediate_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 + 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 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 expon_out : SIGNED (exponent_width-1 downto 0); -- output fract + variable fract_out : UNSIGNED (fraction_width downto 0); -- output fract + 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 : 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 + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + constant ARG_LEFT : INTEGER := arg'length-1; + alias XARG : UNRESOLVED_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 : 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 + is + variable result : UNRESOLVED_float (exponent_width downto -fraction_width); + constant ARG_LEFT : INTEGER := arg'length-1; + alias XARG : UNRESOLVED_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 + downto 0); -- unsigned version of argument + variable argx : SIGNED (integer_width - in_fraction_width downto 0); + variable exp, exptmp : SIGNED (exponent_width + 1 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 + arg_int := UNSIGNED(to_x01(not STD_LOGIC_VECTOR (argx))) + 1; -- Make it positive with two's complement + else + result (exponent_width) := '0'; + arg_int := UNSIGNED(to_x01(STD_LOGIC_VECTOR (argx))); -- new line: direct conversion to unsigned + end if; + -- 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); + 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 c : CHARACTER; + variable left : positive; + begin + while L /= null and L.all'length /= 0 loop + left := L.all'left; + c := L.all(left); + if (c = ' ' or c = NBSP or c = HT) then + read (L, c); + 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_generic_pkg.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_generic_pkg.vhdl new file mode 100644 index 00000000..169f141a --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_generic_pkg.vhdl @@ -0,0 +1,1000 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 IEEE P1076 WG. Licensed Apache 2.0"; + + 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_pkg.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_pkg.vhdl new file mode 100644 index 00000000..71df7e11 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/float_pkg.vhdl @@ -0,0 +1,55 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/ieee_bit_context.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/ieee_bit_context.vhdl new file mode 100644 index 00000000..944ab310 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/ieee_bit_context.vhdl @@ -0,0 +1,4 @@ +context IEEE_BIT_CONTEXT is + library IEEE; + use IEEE.NUMERIC_BIT.all; +end context IEEE_BIT_CONTEXT; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/ieee_std_context.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/ieee_std_context.vhdl new file mode 100644 index 00000000..b763dd6d --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/ieee_std_context.vhdl @@ -0,0 +1,5 @@ +context IEEE_STD_CONTEXT is + library IEEE; + use IEEE.STD_LOGIC_1164.all; + use IEEE.NUMERIC_STD.all; +end context IEEE_STD_CONTEXT; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_complex-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_complex-body.vhdl new file mode 100644 index 00000000..6245b8ec --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_complex-body.vhdl @@ -0,0 +1,1602 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 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 + -- + constant 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_complex.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_complex.vhdl new file mode 100644 index 00000000..af7c3c3f --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_complex.vhdl @@ -0,0 +1,1083 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 IEEE P1076 WG. Licensed Apache 2.0"; + + -- + -- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_real-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_real-body.vhdl new file mode 100644 index 00000000..2386f82f --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_real-body.vhdl @@ -0,0 +1,1927 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 + + constant XNEGATIVE : BOOLEAN := X < 0.0; + constant 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; + constant 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 + + constant 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. 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; + + -- 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) 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) 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 + + constant 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 + + constant NEGATIVE : BOOLEAN := X < 0.0; + constant 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 + + constant NEGATIVE : BOOLEAN := X < 0.0; + constant 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; + + constant 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) + + constant NEGATIVE : BOOLEAN := X < 0.0; + constant 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) + + constant 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) + + constant NEGATIVE : BOOLEAN := X < 0.0; + constant 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_real.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_real.vhdl new file mode 100644 index 00000000..37d9a35d --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/math_real.vhdl @@ -0,0 +1,625 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 IEEE P1076 WG. Licensed Apache 2.0"; + + -- + -- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit-body.vhdl new file mode 100644 index 00000000..da139bac --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit-body.vhdl @@ -0,0 +1,3037 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 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 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 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 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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 + constant 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit.vhdl new file mode 100644 index 00000000..bd324b16 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit.vhdl @@ -0,0 +1,1592 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 (c) 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit_unsigned-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit_unsigned-body.vhdl new file mode 100644 index 00000000..3120de69 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit_unsigned-body.vhdl @@ -0,0 +1,592 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit_unsigned.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit_unsigned.vhdl new file mode 100644 index 00000000..71188cb4 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_bit_unsigned.vhdl @@ -0,0 +1,623 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 IEEE P1076 WG. Licensed Apache 2.0"; + + -- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std-body.vhdl new file mode 100644 index 00000000..a876a1fa --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std-body.vhdl @@ -0,0 +1,4088 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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; + 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 + 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std.vhdl new file mode 100644 index 00000000..28e72bf9 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std.vhdl @@ -0,0 +1,1685 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 (c) 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; + + 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std_unsigned-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std_unsigned-body.vhdl new file mode 100644 index 00000000..32a65292 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std_unsigned-body.vhdl @@ -0,0 +1,595 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std_unsigned.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std_unsigned.vhdl new file mode 100644 index 00000000..eb658983 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/numeric_std_unsigned.vhdl @@ -0,0 +1,616 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 IEEE P1076 WG. Licensed Apache 2.0"; + + -- 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_1164-body.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_1164-body.vhdl new file mode 100644 index 00000000..6884f1f4 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_1164-body.vhdl @@ -0,0 +1,1572 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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 c : CHARACTER; + variable left : positive; + begin + while L /= null and L.all'length /= 0 loop + left := L.all'left; + c := L.all(left); + if (c = ' ' or c = NBSP or c = HT) then + read (L, c); + 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 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 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_1164.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_1164.vhdl new file mode 100644 index 00000000..05407123 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_1164.vhdl @@ -0,0 +1,309 @@ +-- ----------------------------------------------------------------- +-- +-- Copyright 2019 IEEE P1076 WG Authors +-- +-- See the LICENSE file distributed with this work for copyright and +-- licensing information and the AUTHORS file. +-- +-- This file to you under the Apache License, Version 2.0 (the "License"). +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +-- implied. See the License for the specific language governing +-- permissions and limitations under the License. +-- +-- 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: 1228 $ +-- $Date: 2008-04-30 10:04:53 +0930 (Wed, 30 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/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_textio.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_textio.vhdl new file mode 100644 index 00000000..5cfe77ac --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/ieee2008/std_logic_textio.vhdl @@ -0,0 +1,3 @@ +package std_logic_textio is + -- empty. +end std_logic_textio; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/env.vhd b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/env.vhd new file mode 100644 index 00000000..abbf2011 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/env.vhd @@ -0,0 +1,11 @@ +-- Package env as defined by IEEE 1076-2008 + +package env is + procedure stop(status : integer); + procedure stop; + + procedure finish(status : integer); + procedure finish; + + function resolution_limit return delay_length; +end package; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/standard.vhd b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/standard.vhd new file mode 100644 index 00000000..e60cc2d9 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/standard.vhd @@ -0,0 +1,94 @@ +-- Package standard as defined by IEEE 1076-2008 + +package standard is + + -- Predefined enumeration types: + type BOOLEAN is (FALSE, TRUE); + type BIT is ('0', '1'); + + type CHARACTER is ( + NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, + BS, HT, LF, VT, FF, CR, SO, SI, + DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, + CAN, EM, SUB, ESC, FSP, GSP, RSP, USP, + + ' ', '!', '"', '#', '$', '%', '&', ''', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\', ']', '^', '_', + + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', DEL, + + C128, C129, C130, C131, C132, C133, C134, C135, + C136, C137, C138, C139, C140, C141, C142, C143, + C144, C145, C146, C147, C148, C149, C150, C151, + C152, C153, C154, C155, C156, C157, C158, C159, + + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', '', + '', '', '', '', '', '', '', ''); + + type SEVERITY_LEVEL is (NOTE, WARNING, ERROR, FAILURE); + type INTEGER is range -2147483647 to 2147483647; + type REAL is range -1.7976931348623157e308 to 1.7976931348623157e308; + + type TIME is range -9223372036854775807 to 9223372036854775807 + units + fs; -- femtosecond + ps = 1000 fs; -- picosecond + ns = 1000 ps; -- nanosecond + us = 1000 ns; -- microsecond + ms = 1000 us; -- millisecond + sec = 1000 ms; -- second + min = 60 sec; -- minute + hr= 60 min; -- hour + end units; + + subtype DELAY_LENGTH is TIME range 0 fs to TIME'HIGH; + impure function NOW return DELAY_LENGTH; + + subtype NATURAL is INTEGER range 0 to INTEGER'HIGH; + subtype POSITIVE is INTEGER range 1 to INTEGER'HIGH; + + type STRING is array (POSITIVE range <>) of CHARACTER; + + type BOOLEAN_VECTOR is array (NATURAL range <>) of BOOLEAN; + type BIT_VECTOR is array (NATURAL range <>) of BIT; + type INTEGER_VECTOR is array (NATURAL range <>) of INTEGER; + type REAL_VECTOR is array (NATURAL range <>) of REAL; + type TIME_VECTOR is array (NATURAL range <>) of TIME; + + type FILE_OPEN_KIND is (READ_MODE, + WRITE_MODE, + APPEND_MODE); + + type FILE_OPEN_STATUS is (OPEN_OK, + STATUS_ERROR, + NAME_ERROR, + MODE_ERROR); + + attribute FOREIGN: STRING; + + function RISING_EDGE(signal S: BOOLEAN) return BOOLEAN; + function RISING_EDGE(signal B: BIT) return BOOLEAN; + function FALLING_EDGE(signal S: BOOLEAN) return BOOLEAN; + function FALLING_EDGE(signal B: BIT) return BOOLEAN; + +end package; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/textio.vhd b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/textio.vhd new file mode 100644 index 00000000..02bbc72e --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/std/textio.vhd @@ -0,0 +1,73 @@ +-- Package texio as defined by IEEE 1076-2008 + +package textio is + type LINE is access STRING; + type TEXT is file of STRING; + + procedure FILE_REWIND (file F: TEXT); + function FILE_MODE (file F: TEXT) return FILE_OPEN_KIND; + function FILE_SIZE (file F: TEXT) return INTEGER; + + type SIDE is (RIGHT, LEFT); + subtype WIDTH is NATURAL; -- For specifying widths of output fields. + + function JUSTIFY (VALUE: STRING; JUSTIFIED: SIDE := RIGHT; FIELD: WIDTH := 0 ) return STRING; + -- Standard text files: + file INPUT: TEXT open READ_MODE is "STD_INPUT"; + file OUTPUT: TEXT open WRITE_MODE is "STD_OUTPUT"; + + -- Input routines for standard types: + procedure READLINE (file F: TEXT; L: inout LINE); + procedure READ (L: inout LINE; VALUE: out BIT; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out BIT); + procedure READ (L: inout LINE; VALUE: out BIT_VECTOR; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out BIT_VECTOR); + procedure READ (L: inout LINE; VALUE: out BOOLEAN; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out CHARACTER; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out CHARACTER); + procedure READ (L: inout LINE; VALUE: out INTEGER; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out INTEGER); + procedure READ (L: inout LINE; VALUE: out REAL; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out REAL); + procedure READ (L: inout LINE; VALUE: out STRING; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out STRING); + procedure READ (L: inout LINE; VALUE: out TIME; GOOD: out BOOLEAN); + procedure READ (L: inout LINE; VALUE: out TIME); + procedure SREAD (L: inout LINE; VALUE: out STRING; STRLEN: out NATURAL); + alias STRING_READ is SREAD [LINE, STRING, NATURAL]; + alias BREAD is READ [LINE, BIT_VECTOR, BOOLEAN]; + alias BREAD is READ [LINE, BIT_VECTOR]; + alias BINARY_READ is READ [LINE, BIT_VECTOR, BOOLEAN]; + alias BINARY_READ is READ [LINE, BIT_VECTOR]; + procedure OREAD (L: inout LINE; VALUE: out BIT_VECTOR; GOOD: out BOOLEAN); + procedure OREAD (L: inout LINE; VALUE: out BIT_VECTOR); + alias OCTAL_READ is OREAD [LINE, BIT_VECTOR, BOOLEAN]; + alias OCTAL_READ is OREAD [LINE, BIT_VECTOR]; + procedure HREAD (L: inout LINE; VALUE: out BIT_VECTOR; GOOD: out BOOLEAN); + procedure HREAD (L: inout LINE; VALUE: out BIT_VECTOR); + alias HEX_READ is HREAD [LINE, BIT_VECTOR, BOOLEAN]; + alias HEX_READ is HREAD [LINE, BIT_VECTOR]; + + -- Output routines for standard types: + procedure WRITELINE (file F: TEXT; L: inout LINE); + procedure TEE (file F: TEXT; L: inout LINE); + procedure WRITE (L: inout LINE; VALUE: in BIT; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0); + procedure WRITE (L: inout LINE; VALUE: in BIT_VECTOR; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0); + procedure WRITE (L: inout LINE; VALUE: in BOOLEAN; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0); + procedure WRITE (L: inout LINE; VALUE: in CHARACTER; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0); + procedure WRITE (L: inout LINE; VALUE: in INTEGER; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0); + procedure WRITE (L: inout LINE; VALUE: in REAL; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0; DIGITS: in NATURAL:= 0); + procedure WRITE (L: inout LINE; VALUE: in REAL; FORMAT: in STRING); + procedure WRITE (L: inout LINE; VALUE: in STRING; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0); + procedure WRITE (L: inout LINE; VALUE: in TIME; JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0; UNIT: in TIME:= ns); + alias SWRITE is WRITE [LINE, STRING, SIDE, WIDTH]; + alias STRING_WRITE is WRITE [LINE, STRING, SIDE, WIDTH]; + alias BWRITE is WRITE [LINE, BIT_VECTOR, SIDE, WIDTH]; + alias BINARY_WRITE is WRITE [LINE, BIT_VECTOR, SIDE, WIDTH]; + procedure OWRITE (L: inout LINE; VALUE: in BIT_VECTOR; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); + alias OCTAL_WRITE is OWRITE [LINE, BIT_VECTOR, SIDE, WIDTH]; + procedure HWRITE (L: inout LINE; VALUE: in BIT_VECTOR; JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0); + alias HEX_WRITE is HWRITE [LINE, BIT_VECTOR, SIDE, WIDTH]; + +end package; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_arith.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_arith.vhdl new file mode 100644 index 00000000..685b6473 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_arith.vhdl @@ -0,0 +1,2391 @@ +-------------------------------------------------------------------------- +-- -- +-- Copyright (c) 1990,1991,1992 by Synopsys, Inc. All rights reserved. -- +-- -- +-- This source file may be used and distributed without restriction -- +-- provided that this copyright statement is not removed from the file -- +-- and that any derivative work contains this copyright notice. -- +-- -- +-- Package name: STD_LOGIC_ARITH -- +-- -- +-- Purpose: -- +-- A set of arithemtic, conversion, and comparison functions -- +-- for SIGNED, UNSIGNED, SMALL_INT, INTEGER, -- +-- STD_ULOGIC, STD_LOGIC, and STD_LOGIC_VECTOR. -- +-- -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; + +package std_logic_arith is + + type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; + type SIGNED is array (NATURAL range <>) of STD_LOGIC; + subtype SMALL_INT is INTEGER range 0 to 1; + + function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED; + function "+"(L: SIGNED; R: SIGNED) return SIGNED; + function "+"(L: UNSIGNED; R: SIGNED) return SIGNED; + function "+"(L: SIGNED; R: UNSIGNED) return SIGNED; + function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED; + function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED; + function "+"(L: SIGNED; R: INTEGER) return SIGNED; + function "+"(L: INTEGER; R: SIGNED) return SIGNED; + function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED; + function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED; + function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED; + function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED; + + function "+"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "+"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR; + function "+"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR; + function "+"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "+"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR; + function "+"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "+"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR; + function "+"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR; + function "+"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR; + function "+"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "+"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR; + function "+"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR; + + function "-"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED; + function "-"(L: SIGNED; R: SIGNED) return SIGNED; + function "-"(L: UNSIGNED; R: SIGNED) return SIGNED; + function "-"(L: SIGNED; R: UNSIGNED) return SIGNED; + function "-"(L: UNSIGNED; R: INTEGER) return UNSIGNED; + function "-"(L: INTEGER; R: UNSIGNED) return UNSIGNED; + function "-"(L: SIGNED; R: INTEGER) return SIGNED; + function "-"(L: INTEGER; R: SIGNED) return SIGNED; + function "-"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED; + function "-"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED; + function "-"(L: SIGNED; R: STD_ULOGIC) return SIGNED; + function "-"(L: STD_ULOGIC; R: SIGNED) return SIGNED; + + function "-"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "-"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR; + function "-"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR; + function "-"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "-"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR; + function "-"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "-"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR; + function "-"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR; + function "-"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR; + function "-"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "-"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR; + function "-"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR; + + function "+"(L: UNSIGNED) return UNSIGNED; + function "+"(L: SIGNED) return SIGNED; + function "-"(L: SIGNED) return SIGNED; + function "ABS"(L: SIGNED) return SIGNED; + + function "+"(L: UNSIGNED) return STD_LOGIC_VECTOR; + function "+"(L: SIGNED) return STD_LOGIC_VECTOR; + function "-"(L: SIGNED) return STD_LOGIC_VECTOR; + function "ABS"(L: SIGNED) return STD_LOGIC_VECTOR; + + function "*"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED; + function "*"(L: SIGNED; R: SIGNED) return SIGNED; + function "*"(L: SIGNED; R: UNSIGNED) return SIGNED; + function "*"(L: UNSIGNED; R: SIGNED) return SIGNED; + + function "*"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "*"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR; + function "*"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR; + function "*"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR; + + function "<"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN; + function "<"(L: SIGNED; R: SIGNED) return BOOLEAN; + function "<"(L: UNSIGNED; R: SIGNED) return BOOLEAN; + function "<"(L: SIGNED; R: UNSIGNED) return BOOLEAN; + function "<"(L: UNSIGNED; R: INTEGER) return BOOLEAN; + function "<"(L: INTEGER; R: UNSIGNED) return BOOLEAN; + function "<"(L: SIGNED; R: INTEGER) return BOOLEAN; + function "<"(L: INTEGER; R: SIGNED) return BOOLEAN; + + function "<="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN; + function "<="(L: SIGNED; R: SIGNED) return BOOLEAN; + function "<="(L: UNSIGNED; R: SIGNED) return BOOLEAN; + function "<="(L: SIGNED; R: UNSIGNED) return BOOLEAN; + function "<="(L: UNSIGNED; R: INTEGER) return BOOLEAN; + function "<="(L: INTEGER; R: UNSIGNED) return BOOLEAN; + function "<="(L: SIGNED; R: INTEGER) return BOOLEAN; + function "<="(L: INTEGER; R: SIGNED) return BOOLEAN; + + function ">"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN; + function ">"(L: SIGNED; R: SIGNED) return BOOLEAN; + function ">"(L: UNSIGNED; R: SIGNED) return BOOLEAN; + function ">"(L: SIGNED; R: UNSIGNED) return BOOLEAN; + function ">"(L: UNSIGNED; R: INTEGER) return BOOLEAN; + function ">"(L: INTEGER; R: UNSIGNED) return BOOLEAN; + function ">"(L: SIGNED; R: INTEGER) return BOOLEAN; + function ">"(L: INTEGER; R: SIGNED) return BOOLEAN; + + function ">="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN; + function ">="(L: SIGNED; R: SIGNED) return BOOLEAN; + function ">="(L: UNSIGNED; R: SIGNED) return BOOLEAN; + function ">="(L: SIGNED; R: UNSIGNED) return BOOLEAN; + function ">="(L: UNSIGNED; R: INTEGER) return BOOLEAN; + function ">="(L: INTEGER; R: UNSIGNED) return BOOLEAN; + function ">="(L: SIGNED; R: INTEGER) return BOOLEAN; + function ">="(L: INTEGER; R: SIGNED) return BOOLEAN; + + function "="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN; + function "="(L: SIGNED; R: SIGNED) return BOOLEAN; + function "="(L: UNSIGNED; R: SIGNED) return BOOLEAN; + function "="(L: SIGNED; R: UNSIGNED) return BOOLEAN; + function "="(L: UNSIGNED; R: INTEGER) return BOOLEAN; + function "="(L: INTEGER; R: UNSIGNED) return BOOLEAN; + function "="(L: SIGNED; R: INTEGER) return BOOLEAN; + function "="(L: INTEGER; R: SIGNED) return BOOLEAN; + + function "/="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN; + function "/="(L: SIGNED; R: SIGNED) return BOOLEAN; + function "/="(L: UNSIGNED; R: SIGNED) return BOOLEAN; + function "/="(L: SIGNED; R: UNSIGNED) return BOOLEAN; + function "/="(L: UNSIGNED; R: INTEGER) return BOOLEAN; + function "/="(L: INTEGER; R: UNSIGNED) return BOOLEAN; + function "/="(L: SIGNED; R: INTEGER) return BOOLEAN; + function "/="(L: INTEGER; R: SIGNED) return BOOLEAN; + + function SHL(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED; + function SHL(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED; + function SHR(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED; + function SHR(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED; + + function CONV_INTEGER(ARG: INTEGER) return INTEGER; + function CONV_INTEGER(ARG: UNSIGNED) return INTEGER; + function CONV_INTEGER(ARG: SIGNED) return INTEGER; + function CONV_INTEGER(ARG: STD_ULOGIC) return SMALL_INT; + + function CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER) return UNSIGNED; + function CONV_UNSIGNED(ARG: UNSIGNED; SIZE: INTEGER) return UNSIGNED; + function CONV_UNSIGNED(ARG: SIGNED; SIZE: INTEGER) return UNSIGNED; + function CONV_UNSIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return UNSIGNED; + + function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) return SIGNED; + function CONV_SIGNED(ARG: UNSIGNED; SIZE: INTEGER) return SIGNED; + function CONV_SIGNED(ARG: SIGNED; SIZE: INTEGER) return SIGNED; + function CONV_SIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return SIGNED; + + function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) + return STD_LOGIC_VECTOR; + function CONV_STD_LOGIC_VECTOR(ARG: UNSIGNED; SIZE: INTEGER) + return STD_LOGIC_VECTOR; + function CONV_STD_LOGIC_VECTOR(ARG: SIGNED; SIZE: INTEGER) + return STD_LOGIC_VECTOR; + function CONV_STD_LOGIC_VECTOR(ARG: STD_ULOGIC; SIZE: INTEGER) + return STD_LOGIC_VECTOR; + -- zero extend STD_LOGIC_VECTOR (ARG) to SIZE, + -- SIZE < 0 is same as SIZE = 0 + -- returns STD_LOGIC_VECTOR(SIZE-1 downto 0) + function EXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR; + + -- sign extend STD_LOGIC_VECTOR (ARG) to SIZE, + -- SIZE < 0 is same as SIZE = 0 + -- return STD_LOGIC_VECTOR(SIZE-1 downto 0) + function SXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR; + +end Std_logic_arith; + + + +library IEEE; +use IEEE.std_logic_1164.all; + +package body std_logic_arith is + + function max(L, R: INTEGER) return INTEGER is + begin + if L > R then + return L; + else + return R; + end if; + end; + + + function min(L, R: INTEGER) return INTEGER is + begin + if L < R then + return L; + else + return R; + end if; + end; + + -- synopsys synthesis_off + type tbl_type is array (STD_ULOGIC) of STD_ULOGIC; + constant tbl_BINARY : tbl_type := + ('X', 'X', '0', '1', 'X', 'X', '0', '1', 'X'); + -- synopsys synthesis_on + + -- synopsys synthesis_off + type tbl_mvl9_boolean is array (STD_ULOGIC) of boolean; + constant IS_X : tbl_mvl9_boolean := + (true, true, false, false, true, true, false, false, true); + -- synopsys synthesis_on + + + + function MAKE_BINARY(A : STD_ULOGIC) return STD_ULOGIC is + -- synopsys built_in SYN_FEED_THRU + begin + -- synopsys synthesis_off + if (IS_X(A)) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + return ('X'); + end if; + return tbl_BINARY(A); + -- synopsys synthesis_on + end; + + function MAKE_BINARY(A : UNSIGNED) return UNSIGNED is + -- synopsys built_in SYN_FEED_THRU + variable one_bit : STD_ULOGIC; + variable result : UNSIGNED (A'range); + begin + -- synopsys synthesis_off + for i in A'range loop + if (IS_X(A(i))) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + result := (others => 'X'); + return result; + end if; + result(i) := tbl_BINARY(A(i)); + end loop; + return result; + -- synopsys synthesis_on + end; + + function MAKE_BINARY(A : UNSIGNED) return SIGNED is + -- synopsys built_in SYN_FEED_THRU + variable one_bit : STD_ULOGIC; + variable result : SIGNED (A'range); + begin + -- synopsys synthesis_off + for i in A'range loop + if (IS_X(A(i))) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + result := (others => 'X'); + return result; + end if; + result(i) := tbl_BINARY(A(i)); + end loop; + return result; + -- synopsys synthesis_on + end; + + function MAKE_BINARY(A : SIGNED) return UNSIGNED is + -- synopsys built_in SYN_FEED_THRU + variable one_bit : STD_ULOGIC; + variable result : UNSIGNED (A'range); + begin + -- synopsys synthesis_off + for i in A'range loop + if (IS_X(A(i))) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + result := (others => 'X'); + return result; + end if; + result(i) := tbl_BINARY(A(i)); + end loop; + return result; + -- synopsys synthesis_on + end; + + function MAKE_BINARY(A : SIGNED) return SIGNED is + -- synopsys built_in SYN_FEED_THRU + variable one_bit : STD_ULOGIC; + variable result : SIGNED (A'range); + begin + -- synopsys synthesis_off + for i in A'range loop + if (IS_X(A(i))) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + result := (others => 'X'); + return result; + end if; + result(i) := tbl_BINARY(A(i)); + end loop; + return result; + -- synopsys synthesis_on + end; + + function MAKE_BINARY(A : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- synopsys built_in SYN_FEED_THRU + variable one_bit : STD_ULOGIC; + variable result : STD_LOGIC_VECTOR (A'range); + begin + -- synopsys synthesis_off + for i in A'range loop + if (IS_X(A(i))) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + result := (others => 'X'); + return result; + end if; + result(i) := tbl_BINARY(A(i)); + end loop; + return result; + -- synopsys synthesis_on + end; + + function MAKE_BINARY(A : UNSIGNED) return STD_LOGIC_VECTOR is + -- synopsys built_in SYN_FEED_THRU + variable one_bit : STD_ULOGIC; + variable result : STD_LOGIC_VECTOR (A'range); + begin + -- synopsys synthesis_off + for i in A'range loop + if (IS_X(A(i))) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + result := (others => 'X'); + return result; + end if; + result(i) := tbl_BINARY(A(i)); + end loop; + return result; + -- synopsys synthesis_on + end; + + function MAKE_BINARY(A : SIGNED) return STD_LOGIC_VECTOR is + -- synopsys built_in SYN_FEED_THRU + variable one_bit : STD_ULOGIC; + variable result : STD_LOGIC_VECTOR (A'range); + begin + -- synopsys synthesis_off + for i in A'range loop + if (IS_X(A(i))) then + assert false + report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." + severity warning; + result := (others => 'X'); + return result; + end if; + result(i) := tbl_BINARY(A(i)); + end loop; + return result; + -- synopsys synthesis_on + end; + + + + -- Type propagation function which returns a signed type with the + -- size of the left arg. + function LEFT_SIGNED_ARG(A,B: SIGNED) return SIGNED is + variable Z: SIGNED (A'left downto 0); + -- pragma return_port_name Z + begin + return(Z); + end; + + -- Type propagation function which returns an unsigned type with the + -- size of the left arg. + function LEFT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is + variable Z: UNSIGNED (A'left downto 0); + -- pragma return_port_name Z + begin + return(Z); + end; + + -- Type propagation function which returns a signed type with the + -- size of the result of a signed multiplication + function MULT_SIGNED_ARG(A,B: SIGNED) return SIGNED is + variable Z: SIGNED ((A'length+B'length-1) downto 0); + -- pragma return_port_name Z + begin + return(Z); + end; + + -- Type propagation function which returns an unsigned type with the + -- size of the result of a unsigned multiplication + function MULT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is + variable Z: UNSIGNED ((A'length+B'length-1) downto 0); + -- pragma return_port_name Z + begin + return(Z); + end; + + + + function mult(A,B: SIGNED) return SIGNED is + + variable BA: SIGNED((A'length+B'length-1) downto 0); + variable PA: SIGNED((A'length+B'length-1) downto 0); + variable AA: SIGNED(A'length downto 0); + variable neg: STD_ULOGIC; + constant one : UNSIGNED(1 downto 0) := "01"; + + -- pragma map_to_operator MULT_TC_OP + -- pragma type_function MULT_SIGNED_ARG + -- pragma return_port_name Z + + begin + if (A(A'left) = 'X' or B(B'left) = 'X') then + PA := (others => 'X'); + return(PA); + end if; + PA := (others => '0'); + neg := B(B'left) xor A(A'left); + BA := CONV_SIGNED(('0' & ABS(B)),(A'length+B'length)); + AA := '0' & ABS(A); + for i in integer range 0 to A'length-1 loop + if AA(i) = '1' then + PA := PA+BA; + end if; + BA := SHL(BA,one); + end loop; + if (neg= '1') then + return(-PA); + else + return(PA); + end if; + end; + + function mult(A,B: UNSIGNED) return UNSIGNED is + + variable BA: UNSIGNED((A'length+B'length-1) downto 0); + variable PA: UNSIGNED((A'length+B'length-1) downto 0); + constant one : UNSIGNED(1 downto 0) := "01"; + + -- pragma map_to_operator MULT_UNS_OP + -- pragma type_function MULT_UNSIGNED_ARG + -- pragma return_port_name Z + + begin + if (A(A'left) = 'X' or B(B'left) = 'X') then + PA := (others => 'X'); + return(PA); + end if; + PA := (others => '0'); + BA := CONV_UNSIGNED(B,(A'length+B'length)); + for i in integer range 0 to A'length-1 loop + if A(i) = '1' then + PA := PA+BA; + end if; + BA := SHL(BA,one); + end loop; + return(PA); + end; + + -- subtract two signed numbers of the same length + -- both arrays must have range (msb downto 0) + function minus(A, B: SIGNED) return SIGNED is + variable carry: STD_ULOGIC; + variable BV: STD_ULOGIC_VECTOR (A'left downto 0); + variable sum: SIGNED (A'left downto 0); + + -- pragma map_to_operator SUB_TC_OP + + -- pragma type_function LEFT_SIGNED_ARG + -- pragma return_port_name Z + + begin + if (A(A'left) = 'X' or B(B'left) = 'X') then + sum := (others => 'X'); + return(sum); + end if; + carry := '1'; + BV := not STD_ULOGIC_VECTOR(B); + + for i in 0 to A'left loop + sum(i) := A(i) xor BV(i) xor carry; + carry := (A(i) and BV(i)) or + (A(i) and carry) or + (carry and BV(i)); + end loop; + return sum; + end; + + -- add two signed numbers of the same length + -- both arrays must have range (msb downto 0) + function plus(A, B: SIGNED) return SIGNED is + variable carry: STD_ULOGIC; + variable BV, sum: SIGNED (A'left downto 0); + + -- pragma map_to_operator ADD_TC_OP + -- pragma type_function LEFT_SIGNED_ARG + -- pragma return_port_name Z + + begin + if (A(A'left) = 'X' or B(B'left) = 'X') then + sum := (others => 'X'); + return(sum); + end if; + carry := '0'; + BV := B; + + for i in 0 to A'left loop + sum(i) := A(i) xor BV(i) xor carry; + carry := (A(i) and BV(i)) or + (A(i) and carry) or + (carry and BV(i)); + end loop; + return sum; + end; + + + -- subtract two unsigned numbers of the same length + -- both arrays must have range (msb downto 0) + function unsigned_minus(A, B: UNSIGNED) return UNSIGNED is + variable carry: STD_ULOGIC; + variable BV: STD_ULOGIC_VECTOR (A'left downto 0); + variable sum: UNSIGNED (A'left downto 0); + + -- pragma map_to_operator SUB_UNS_OP + -- pragma type_function LEFT_UNSIGNED_ARG + -- pragma return_port_name Z + + begin + if (A(A'left) = 'X' or B(B'left) = 'X') then + sum := (others => 'X'); + return(sum); + end if; + carry := '1'; + BV := not STD_ULOGIC_VECTOR(B); + + for i in 0 to A'left loop + sum(i) := A(i) xor BV(i) xor carry; + carry := (A(i) and BV(i)) or + (A(i) and carry) or + (carry and BV(i)); + end loop; + return sum; + end; + + -- add two unsigned numbers of the same length + -- both arrays must have range (msb downto 0) + function unsigned_plus(A, B: UNSIGNED) return UNSIGNED is + variable carry: STD_ULOGIC; + variable BV, sum: UNSIGNED (A'left downto 0); + + -- pragma map_to_operator ADD_UNS_OP + -- pragma type_function LEFT_UNSIGNED_ARG + -- pragma return_port_name Z + + begin + if (A(A'left) = 'X' or B(B'left) = 'X') then + sum := (others => 'X'); + return(sum); + end if; + carry := '0'; + BV := B; + + for i in 0 to A'left loop + sum(i) := A(i) xor BV(i) xor carry; + carry := (A(i) and BV(i)) or + (A(i) and carry) or + (carry and BV(i)); + end loop; + return sum; + end; + + + + function "*"(L: SIGNED; R: SIGNED) return SIGNED is + -- pragma label_applies_to mult + -- synopsys subpgm_id 296 + begin + return mult(CONV_SIGNED(L, L'length), + CONV_SIGNED(R, R'length)); -- pragma label mult + end; + + function "*"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is + -- pragma label_applies_to mult + -- synopsys subpgm_id 295 + begin + return mult(CONV_UNSIGNED(L, L'length), + CONV_UNSIGNED(R, R'length)); -- pragma label mult + end; + + function "*"(L: UNSIGNED; R: SIGNED) return SIGNED is + -- pragma label_applies_to mult + -- synopsys subpgm_id 297 + begin + return mult(CONV_SIGNED(L, L'length+1), + CONV_SIGNED(R, R'length)); -- pragma label mult + end; + + function "*"(L: SIGNED; R: UNSIGNED) return SIGNED is + -- pragma label_applies_to mult + -- synopsys subpgm_id 298 + begin + return mult(CONV_SIGNED(L, L'length), + CONV_SIGNED(R, R'length+1)); -- pragma label mult + end; + + + function "*"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to mult + -- synopsys subpgm_id 301 + begin + return STD_LOGIC_VECTOR ( + mult(-- pragma label mult + CONV_SIGNED(L, L'length), CONV_SIGNED(R, R'length))); + end; + + function "*"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to mult + -- synopsys subpgm_id 300 + begin + return STD_LOGIC_VECTOR ( + mult(-- pragma label mult + CONV_UNSIGNED(L, L'length), CONV_UNSIGNED(R, R'length))); + end; + + function "*"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to mult + -- synopsys subpgm_id 302 + begin + return STD_LOGIC_VECTOR ( + mult(-- pragma label mult + CONV_SIGNED(L, L'length+1), CONV_SIGNED(R, R'length))); + end; + + function "*"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to mult + -- synopsys subpgm_id 303 + begin + return STD_LOGIC_VECTOR ( + mult(-- pragma label mult + CONV_SIGNED(L, L'length), CONV_SIGNED(R, R'length+1))); + end; + + + function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 236 + constant length: INTEGER := max(L'length, R'length); + begin + return unsigned_plus(CONV_UNSIGNED(L, length), + CONV_UNSIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: SIGNED; R: SIGNED) return SIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 237 + constant length: INTEGER := max(L'length, R'length); + begin + return plus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: UNSIGNED; R: SIGNED) return SIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 238 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return plus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: SIGNED; R: UNSIGNED) return SIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 239 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return plus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 240 + constant length: INTEGER := L'length + 1; + begin + return CONV_UNSIGNED( + plus( -- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1); + end; + + + function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 241 + constant length: INTEGER := R'length + 1; + begin + return CONV_UNSIGNED( + plus( -- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1); + end; + + + function "+"(L: SIGNED; R: INTEGER) return SIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 242 + constant length: INTEGER := L'length; + begin + return plus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: INTEGER; R: SIGNED) return SIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 243 + constant length: INTEGER := R'length; + begin + return plus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 244 + constant length: INTEGER := L'length; + begin + return unsigned_plus(CONV_UNSIGNED(L, length), + CONV_UNSIGNED(R, length)) ; -- pragma label plus + end; + + + function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 245 + constant length: INTEGER := R'length; + begin + return unsigned_plus(CONV_UNSIGNED(L, length), + CONV_UNSIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 246 + constant length: INTEGER := L'length; + begin + return plus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label plus + end; + + + function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED is + -- pragma label_applies_to plus + -- synopsys subpgm_id 247 + constant length: INTEGER := R'length; + begin + return plus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label plus + end; + + + + function "+"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 260 + constant length: INTEGER := max(L'length, R'length); + begin + return STD_LOGIC_VECTOR ( + unsigned_plus(-- pragma label plus + CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length))); + end; + + + function "+"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 261 + constant length: INTEGER := max(L'length, R'length); + begin + return STD_LOGIC_VECTOR ( + plus(-- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "+"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 262 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return STD_LOGIC_VECTOR ( + plus(-- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "+"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 263 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return STD_LOGIC_VECTOR ( + plus(-- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "+"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 264 + constant length: INTEGER := L'length + 1; + begin + return STD_LOGIC_VECTOR (CONV_UNSIGNED( + plus( -- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1)); + end; + + + function "+"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 265 + constant length: INTEGER := R'length + 1; + begin + return STD_LOGIC_VECTOR (CONV_UNSIGNED( + plus( -- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1)); + end; + + + function "+"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 266 + constant length: INTEGER := L'length; + begin + return STD_LOGIC_VECTOR ( + plus(-- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "+"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 267 + constant length: INTEGER := R'length; + begin + return STD_LOGIC_VECTOR ( + plus(-- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "+"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 268 + constant length: INTEGER := L'length; + begin + return STD_LOGIC_VECTOR ( + unsigned_plus(-- pragma label plus + CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length))) ; + end; + + + function "+"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 269 + constant length: INTEGER := R'length; + begin + return STD_LOGIC_VECTOR ( + unsigned_plus(-- pragma label plus + CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length))); + end; + + + function "+"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 270 + constant length: INTEGER := L'length; + begin + return STD_LOGIC_VECTOR ( + plus(-- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "+"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + -- synopsys subpgm_id 271 + constant length: INTEGER := R'length; + begin + return STD_LOGIC_VECTOR ( + plus(-- pragma label plus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + + function "-"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 248 + constant length: INTEGER := max(L'length, R'length); + begin + return unsigned_minus(CONV_UNSIGNED(L, length), + CONV_UNSIGNED(R, length)); -- pragma label minus + end; + + + function "-"(L: SIGNED; R: SIGNED) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 249 + constant length: INTEGER := max(L'length, R'length); + begin + return minus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label minus + end; + + + function "-"(L: UNSIGNED; R: SIGNED) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 250 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return minus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label minus + end; + + + function "-"(L: SIGNED; R: UNSIGNED) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 251 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return minus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label minus + end; + + + function "-"(L: UNSIGNED; R: INTEGER) return UNSIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 252 + constant length: INTEGER := L'length + 1; + begin + return CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1); + end; + + + function "-"(L: INTEGER; R: UNSIGNED) return UNSIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 253 + constant length: INTEGER := R'length + 1; + begin + return CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1); + end; + + + function "-"(L: SIGNED; R: INTEGER) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 254 + constant length: INTEGER := L'length; + begin + return minus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label minus + end; + + + function "-"(L: INTEGER; R: SIGNED) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 255 + constant length: INTEGER := R'length; + begin + return minus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label minus + end; + + + function "-"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 256 + constant length: INTEGER := L'length + 1; + begin + return CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1); + end; + + + function "-"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 257 + constant length: INTEGER := R'length + 1; + begin + return CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1); + end; + + + function "-"(L: SIGNED; R: STD_ULOGIC) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 258 + constant length: INTEGER := L'length; + begin + return minus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label minus + end; + + + function "-"(L: STD_ULOGIC; R: SIGNED) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 259 + constant length: INTEGER := R'length; + begin + return minus(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label minus + end; + + + + + function "-"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 272 + constant length: INTEGER := max(L'length, R'length); + begin + return STD_LOGIC_VECTOR ( + unsigned_minus(-- pragma label minus + CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length))); + end; + + + function "-"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 273 + constant length: INTEGER := max(L'length, R'length); + begin + return STD_LOGIC_VECTOR ( + minus(-- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "-"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 274 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return STD_LOGIC_VECTOR ( + minus(-- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "-"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 275 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return STD_LOGIC_VECTOR ( + minus(-- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "-"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 276 + constant length: INTEGER := L'length + 1; + begin + return STD_LOGIC_VECTOR (CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1)); + end; + + + function "-"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 277 + constant length: INTEGER := R'length + 1; + begin + return STD_LOGIC_VECTOR (CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1)); + end; + + + function "-"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 278 + constant length: INTEGER := L'length; + begin + return STD_LOGIC_VECTOR ( + minus(-- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "-"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 279 + constant length: INTEGER := R'length; + begin + return STD_LOGIC_VECTOR ( + minus(-- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "-"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 280 + constant length: INTEGER := L'length + 1; + begin + return STD_LOGIC_VECTOR (CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1)); + end; + + + function "-"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 281 + constant length: INTEGER := R'length + 1; + begin + return STD_LOGIC_VECTOR (CONV_UNSIGNED( + minus( -- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1)); + end; + + + function "-"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 282 + constant length: INTEGER := L'length; + begin + return STD_LOGIC_VECTOR ( + minus(-- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + function "-"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 283 + constant length: INTEGER := R'length; + begin + return STD_LOGIC_VECTOR ( + minus(-- pragma label minus + CONV_SIGNED(L, length), CONV_SIGNED(R, length))); + end; + + + + + function "+"(L: UNSIGNED) return UNSIGNED is + -- synopsys subpgm_id 284 + begin + return L; + end; + + + function "+"(L: SIGNED) return SIGNED is + -- synopsys subpgm_id 285 + begin + return L; + end; + + + function "-"(L: SIGNED) return SIGNED is + -- pragma label_applies_to minus + -- synopsys subpgm_id 286 + begin + return 0 - L; -- pragma label minus + end; + + + function "ABS"(L: SIGNED) return SIGNED is + -- synopsys subpgm_id 287 + begin + if (L(L'left) = '0' or L(L'left) = 'L') then + return L; + else + return 0 - L; + end if; + end; + + + function "+"(L: UNSIGNED) return STD_LOGIC_VECTOR is + -- synopsys subpgm_id 289 + begin + return STD_LOGIC_VECTOR (L); + end; + + + function "+"(L: SIGNED) return STD_LOGIC_VECTOR is + -- synopsys subpgm_id 290 + begin + return STD_LOGIC_VECTOR (L); + end; + + + function "-"(L: SIGNED) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + -- synopsys subpgm_id 292 + variable tmp: SIGNED(L'length-1 downto 0); + begin + tmp := 0 - L; -- pragma label minus + return STD_LOGIC_VECTOR (tmp); + end; + + + function "ABS"(L: SIGNED) return STD_LOGIC_VECTOR is + -- synopsys subpgm_id 294 + variable tmp: SIGNED(L'length-1 downto 0); + begin + if (L(L'left) = '0' or L(L'left) = 'L') then + return STD_LOGIC_VECTOR (L); + else + tmp := 0 - L; + return STD_LOGIC_VECTOR (tmp); + end if; + end; + + + -- Type propagation function which returns the type BOOLEAN + function UNSIGNED_RETURN_BOOLEAN(A,B: UNSIGNED) return BOOLEAN is + variable Z: BOOLEAN; + -- pragma return_port_name Z + begin + return(Z); + end; + + -- Type propagation function which returns the type BOOLEAN + function SIGNED_RETURN_BOOLEAN(A,B: SIGNED) return BOOLEAN is + variable Z: BOOLEAN; + -- pragma return_port_name Z + begin + return(Z); + end; + + + -- compare two signed numbers of the same length + -- both arrays must have range (msb downto 0) + function is_less(A, B: SIGNED) return BOOLEAN is + constant sign: INTEGER := A'left; + variable a_is_0, b_is_1, result : boolean; + + -- pragma map_to_operator LT_TC_OP + -- pragma type_function SIGNED_RETURN_BOOLEAN + -- pragma return_port_name Z + + begin + if A(sign) /= B(sign) then + result := A(sign) = '1'; + else + result := FALSE; + for i in 0 to sign-1 loop + a_is_0 := A(i) = '0'; + b_is_1 := B(i) = '1'; + result := (a_is_0 and b_is_1) or + (a_is_0 and result) or + (b_is_1 and result); + end loop; + end if; + return result; + end; + + + -- compare two signed numbers of the same length + -- both arrays must have range (msb downto 0) + function is_less_or_equal(A, B: SIGNED) return BOOLEAN is + constant sign: INTEGER := A'left; + variable a_is_0, b_is_1, result : boolean; + + -- pragma map_to_operator LEQ_TC_OP + -- pragma type_function SIGNED_RETURN_BOOLEAN + -- pragma return_port_name Z + + begin + if A(sign) /= B(sign) then + result := A(sign) = '1'; + else + result := TRUE; + for i in 0 to sign-1 loop + a_is_0 := A(i) = '0'; + b_is_1 := B(i) = '1'; + result := (a_is_0 and b_is_1) or + (a_is_0 and result) or + (b_is_1 and result); + end loop; + end if; + return result; + end; + + + + -- compare two unsigned numbers of the same length + -- both arrays must have range (msb downto 0) + function unsigned_is_less(A, B: UNSIGNED) return BOOLEAN is + constant sign: INTEGER := A'left; + variable a_is_0, b_is_1, result : boolean; + + -- pragma map_to_operator LT_UNS_OP + -- pragma type_function UNSIGNED_RETURN_BOOLEAN + -- pragma return_port_name Z + + begin + result := FALSE; + for i in 0 to sign loop + a_is_0 := A(i) = '0'; + b_is_1 := B(i) = '1'; + result := (a_is_0 and b_is_1) or + (a_is_0 and result) or + (b_is_1 and result); + end loop; + return result; + end; + + + -- compare two unsigned numbers of the same length + -- both arrays must have range (msb downto 0) + function unsigned_is_less_or_equal(A, B: UNSIGNED) return BOOLEAN is + constant sign: INTEGER := A'left; + variable a_is_0, b_is_1, result : boolean; + + -- pragma map_to_operator LEQ_UNS_OP + -- pragma type_function UNSIGNED_RETURN_BOOLEAN + -- pragma return_port_name Z + + begin + result := TRUE; + for i in 0 to sign loop + a_is_0 := A(i) = '0'; + b_is_1 := B(i) = '1'; + result := (a_is_0 and b_is_1) or + (a_is_0 and result) or + (b_is_1 and result); + end loop; + return result; + end; + + + + + function "<"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 305 + constant length: INTEGER := max(L'length, R'length); + begin + return unsigned_is_less(CONV_UNSIGNED(L, length), + CONV_UNSIGNED(R, length)); -- pragma label lt + end; + + + function "<"(L: SIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 306 + constant length: INTEGER := max(L'length, R'length); + begin + return is_less(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label lt + end; + + + function "<"(L: UNSIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 307 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return is_less(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label lt + end; + + + function "<"(L: SIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 308 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return is_less(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label lt + end; + + + function "<"(L: UNSIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 309 + constant length: INTEGER := L'length + 1; + begin + return is_less(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label lt + end; + + + function "<"(L: INTEGER; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 310 + constant length: INTEGER := R'length + 1; + begin + return is_less(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label lt + end; + + + function "<"(L: SIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 311 + constant length: INTEGER := L'length; + begin + return is_less(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label lt + end; + + + function "<"(L: INTEGER; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to lt + -- synopsys subpgm_id 312 + constant length: INTEGER := R'length; + begin + return is_less(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label lt + end; + + + + + function "<="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 314 + constant length: INTEGER := max(L'length, R'length); + begin + return unsigned_is_less_or_equal(CONV_UNSIGNED(L, length), + CONV_UNSIGNED(R, length)); -- pragma label leq + end; + + + function "<="(L: SIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 315 + constant length: INTEGER := max(L'length, R'length); + begin + return is_less_or_equal(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label leq + end; + + + function "<="(L: UNSIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 316 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return is_less_or_equal(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label leq + end; + + + function "<="(L: SIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 317 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return is_less_or_equal(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label leq + end; + + + function "<="(L: UNSIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 318 + constant length: INTEGER := L'length + 1; + begin + return is_less_or_equal(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label leq + end; + + + function "<="(L: INTEGER; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 319 + constant length: INTEGER := R'length + 1; + begin + return is_less_or_equal(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label leq + end; + + + function "<="(L: SIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 320 + constant length: INTEGER := L'length; + begin + return is_less_or_equal(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label leq + end; + + + function "<="(L: INTEGER; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to leq + -- synopsys subpgm_id 321 + constant length: INTEGER := R'length; + begin + return is_less_or_equal(CONV_SIGNED(L, length), + CONV_SIGNED(R, length)); -- pragma label leq + end; + + + + + function ">"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 323 + constant length: INTEGER := max(L'length, R'length); + begin + return unsigned_is_less(CONV_UNSIGNED(R, length), + CONV_UNSIGNED(L, length)); -- pragma label gt + end; + + + function ">"(L: SIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 324 + constant length: INTEGER := max(L'length, R'length); + begin + return is_less(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label gt + end; + + + function ">"(L: UNSIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 325 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return is_less(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label gt + end; + + + function ">"(L: SIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 326 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return is_less(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label gt + end; + + + function ">"(L: UNSIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 327 + constant length: INTEGER := L'length + 1; + begin + return is_less(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label gt + end; + + + function ">"(L: INTEGER; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 328 + constant length: INTEGER := R'length + 1; + begin + return is_less(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label gt + end; + + + function ">"(L: SIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 329 + constant length: INTEGER := L'length; + begin + return is_less(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label gt + end; + + + function ">"(L: INTEGER; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to gt + -- synopsys subpgm_id 330 + constant length: INTEGER := R'length; + begin + return is_less(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label gt + end; + + + + + function ">="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 332 + constant length: INTEGER := max(L'length, R'length); + begin + return unsigned_is_less_or_equal(CONV_UNSIGNED(R, length), + CONV_UNSIGNED(L, length)); -- pragma label geq + end; + + + function ">="(L: SIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 333 + constant length: INTEGER := max(L'length, R'length); + begin + return is_less_or_equal(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label geq + end; + + + function ">="(L: UNSIGNED; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 334 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return is_less_or_equal(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label geq + end; + + + function ">="(L: SIGNED; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 335 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return is_less_or_equal(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label geq + end; + + + function ">="(L: UNSIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 336 + constant length: INTEGER := L'length + 1; + begin + return is_less_or_equal(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label geq + end; + + + function ">="(L: INTEGER; R: UNSIGNED) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 337 + constant length: INTEGER := R'length + 1; + begin + return is_less_or_equal(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label geq + end; + + + function ">="(L: SIGNED; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 338 + constant length: INTEGER := L'length; + begin + return is_less_or_equal(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label geq + end; + + + function ">="(L: INTEGER; R: SIGNED) return BOOLEAN is + -- pragma label_applies_to geq + -- synopsys subpgm_id 339 + constant length: INTEGER := R'length; + begin + return is_less_or_equal(CONV_SIGNED(R, length), + CONV_SIGNED(L, length)); -- pragma label geq + end; + + + + + -- for internal use only. Assumes SIGNED arguments of equal length. + function bitwise_eql(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) + return BOOLEAN is + -- pragma built_in SYN_EQL + begin + for i in L'range loop + if L(i) /= R(i) then + return FALSE; + end if; + end loop; + return TRUE; + end; + + -- for internal use only. Assumes SIGNED arguments of equal length. + function bitwise_neq(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) + return BOOLEAN is + -- pragma built_in SYN_NEQ + begin + for i in L'range loop + if L(i) /= R(i) then + return TRUE; + end if; + end loop; + return FALSE; + end; + + + function "="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is + -- synopsys subpgm_id 341 + constant length: INTEGER := max(L'length, R'length); + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); + end; + + + function "="(L: SIGNED; R: SIGNED) return BOOLEAN is + -- synopsys subpgm_id 342 + constant length: INTEGER := max(L'length, R'length); + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "="(L: UNSIGNED; R: SIGNED) return BOOLEAN is + -- synopsys subpgm_id 343 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "="(L: SIGNED; R: UNSIGNED) return BOOLEAN is + -- synopsys subpgm_id 344 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "="(L: UNSIGNED; R: INTEGER) return BOOLEAN is + -- synopsys subpgm_id 345 + constant length: INTEGER := L'length + 1; + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "="(L: INTEGER; R: UNSIGNED) return BOOLEAN is + -- synopsys subpgm_id 346 + constant length: INTEGER := R'length + 1; + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "="(L: SIGNED; R: INTEGER) return BOOLEAN is + -- synopsys subpgm_id 347 + constant length: INTEGER := L'length; + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "="(L: INTEGER; R: SIGNED) return BOOLEAN is + -- synopsys subpgm_id 348 + constant length: INTEGER := R'length; + begin + return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + + + function "/="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is + -- synopsys subpgm_id 350 + constant length: INTEGER := max(L'length, R'length); + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); + end; + + + function "/="(L: SIGNED; R: SIGNED) return BOOLEAN is + -- synopsys subpgm_id 351 + constant length: INTEGER := max(L'length, R'length); + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "/="(L: UNSIGNED; R: SIGNED) return BOOLEAN is + -- synopsys subpgm_id 352 + constant length: INTEGER := max(L'length + 1, R'length); + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "/="(L: SIGNED; R: UNSIGNED) return BOOLEAN is + -- synopsys subpgm_id 353 + constant length: INTEGER := max(L'length, R'length + 1); + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "/="(L: UNSIGNED; R: INTEGER) return BOOLEAN is + -- synopsys subpgm_id 354 + constant length: INTEGER := L'length + 1; + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "/="(L: INTEGER; R: UNSIGNED) return BOOLEAN is + -- synopsys subpgm_id 355 + constant length: INTEGER := R'length + 1; + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "/="(L: SIGNED; R: INTEGER) return BOOLEAN is + -- synopsys subpgm_id 356 + constant length: INTEGER := L'length; + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + function "/="(L: INTEGER; R: SIGNED) return BOOLEAN is + -- synopsys subpgm_id 357 + constant length: INTEGER := R'length; + begin + return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), + STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); + end; + + + + function SHL(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED is + -- synopsys subpgm_id 358 + constant control_msb: INTEGER := COUNT'length - 1; + variable control: UNSIGNED (control_msb downto 0); + constant result_msb: INTEGER := ARG'length-1; + subtype rtype is UNSIGNED (result_msb downto 0); + variable result, temp: rtype; + begin + control := MAKE_BINARY(COUNT); + -- synopsys synthesis_off + if (control(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + -- synopsys synthesis_on + result := ARG; + for i in 0 to control_msb loop + if control(i) = '1' then + temp := rtype'(others => '0'); + if 2**i <= result_msb then + temp(result_msb downto 2**i) := + result(result_msb - 2**i downto 0); + end if; + result := temp; + end if; + end loop; + return result; + end; + + function SHL(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED is + -- synopsys subpgm_id 359 + constant control_msb: INTEGER := COUNT'length - 1; + variable control: UNSIGNED (control_msb downto 0); + constant result_msb: INTEGER := ARG'length-1; + subtype rtype is SIGNED (result_msb downto 0); + variable result, temp: rtype; + begin + control := MAKE_BINARY(COUNT); + -- synopsys synthesis_off + if (control(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + -- synopsys synthesis_on + result := ARG; + for i in 0 to control_msb loop + if control(i) = '1' then + temp := rtype'(others => '0'); + if 2**i <= result_msb then + temp(result_msb downto 2**i) := + result(result_msb - 2**i downto 0); + end if; + result := temp; + end if; + end loop; + return result; + end; + + + function SHR(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED is + -- synopsys subpgm_id 360 + constant control_msb: INTEGER := COUNT'length - 1; + variable control: UNSIGNED (control_msb downto 0); + constant result_msb: INTEGER := ARG'length-1; + subtype rtype is UNSIGNED (result_msb downto 0); + variable result, temp: rtype; + begin + control := MAKE_BINARY(COUNT); + -- synopsys synthesis_off + if (control(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + -- synopsys synthesis_on + result := ARG; + for i in 0 to control_msb loop + if control(i) = '1' then + temp := rtype'(others => '0'); + if 2**i <= result_msb then + temp(result_msb - 2**i downto 0) := + result(result_msb downto 2**i); + end if; + result := temp; + end if; + end loop; + return result; + end; + + function SHR(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED is + -- synopsys subpgm_id 361 + constant control_msb: INTEGER := COUNT'length - 1; + variable control: UNSIGNED (control_msb downto 0); + constant result_msb: INTEGER := ARG'length-1; + subtype rtype is SIGNED (result_msb downto 0); + variable result, temp: rtype; + variable sign_bit: STD_ULOGIC; + begin + control := MAKE_BINARY(COUNT); + -- synopsys synthesis_off + if (control(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + -- synopsys synthesis_on + result := ARG; + sign_bit := ARG(ARG'left); + for i in 0 to control_msb loop + if control(i) = '1' then + temp := rtype'(others => sign_bit); + if 2**i <= result_msb then + temp(result_msb - 2**i downto 0) := + result(result_msb downto 2**i); + end if; + result := temp; + end if; + end loop; + return result; + end; + + + + + function CONV_INTEGER(ARG: INTEGER) return INTEGER is + -- synopsys subpgm_id 365 + begin + return ARG; + end; + + function CONV_INTEGER(ARG: UNSIGNED) return INTEGER is + variable result: INTEGER; + variable tmp: STD_ULOGIC; + -- synopsys built_in SYN_UNSIGNED_TO_INTEGER + -- synopsys subpgm_id 366 + begin + -- synopsys synthesis_off + assert ARG'length <= 31 + report "ARG is too large in CONV_INTEGER" + severity FAILURE; + result := 0; + for i in ARG'range loop + result := result * 2; + tmp := tbl_BINARY(ARG(i)); + if tmp = '1' then + result := result + 1; + elsif tmp = 'X' then + assert false + report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0." + severity WARNING; + end if; + end loop; + return result; + -- synopsys synthesis_on + end; + + + function CONV_INTEGER(ARG: SIGNED) return INTEGER is + variable result: INTEGER; + variable tmp: STD_ULOGIC; + -- synopsys built_in SYN_SIGNED_TO_INTEGER + -- synopsys subpgm_id 367 + begin + -- synopsys synthesis_off + assert ARG'length <= 32 + report "ARG is too large in CONV_INTEGER" + severity FAILURE; + result := 0; + for i in ARG'range loop + if i /= ARG'left then + result := result * 2; + tmp := tbl_BINARY(ARG(i)); + if tmp = '1' then + result := result + 1; + elsif tmp = 'X' then + assert false + report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0." + severity WARNING; + end if; + end if; + end loop; + tmp := MAKE_BINARY(ARG(ARG'left)); + if tmp = '1' then + if ARG'length = 32 then + result := (result - 2**30) - 2**30; + else + result := result - (2 ** (ARG'length-1)); + end if; + end if; + return result; + -- synopsys synthesis_on + end; + + + function CONV_INTEGER(ARG: STD_ULOGIC) return SMALL_INT is + variable tmp: STD_ULOGIC; + -- synopsys built_in SYN_FEED_THRU + -- synopsys subpgm_id 370 + begin + -- synopsys synthesis_off + tmp := tbl_BINARY(ARG); + if tmp = '1' then + return 1; + elsif tmp = 'X' then + assert false + report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0." + severity WARNING; + return 0; + else + return 0; + end if; + -- synopsys synthesis_on + end; + + + -- convert an integer to a unsigned STD_ULOGIC_VECTOR + function CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER) return UNSIGNED is + variable result: UNSIGNED(SIZE-1 downto 0); + variable temp: integer; + -- synopsys built_in SYN_INTEGER_TO_UNSIGNED + -- synopsys subpgm_id 371 + begin + -- synopsys synthesis_off + temp := ARG; + for i in 0 to SIZE-1 loop + if (temp mod 2) = 1 then + result(i) := '1'; + else + result(i) := '0'; + end if; + if temp > 0 then + temp := temp / 2; + else + temp := (temp - 1) / 2; -- simulate ASR + end if; + end loop; + return result; + -- synopsys synthesis_on + end; + + + function CONV_UNSIGNED(ARG: UNSIGNED; SIZE: INTEGER) return UNSIGNED is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is UNSIGNED (SIZE-1 downto 0); + variable new_bounds: UNSIGNED (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_ZERO_EXTEND + -- synopsys subpgm_id 372 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => '0'); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + + function CONV_UNSIGNED(ARG: SIGNED; SIZE: INTEGER) return UNSIGNED is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is UNSIGNED (SIZE-1 downto 0); + variable new_bounds: UNSIGNED (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_SIGN_EXTEND + -- synopsys subpgm_id 373 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => new_bounds(new_bounds'left)); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + + function CONV_UNSIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return UNSIGNED is + subtype rtype is UNSIGNED (SIZE-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_ZERO_EXTEND + -- synopsys subpgm_id 375 + begin + -- synopsys synthesis_off + result := rtype'(others => '0'); + result(0) := MAKE_BINARY(ARG); + if (result(0) = 'X') then + result := rtype'(others => 'X'); + end if; + return result; + -- synopsys synthesis_on + end; + + + -- convert an integer to a 2's complement STD_ULOGIC_VECTOR + function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) return SIGNED is + variable result: SIGNED (SIZE-1 downto 0); + variable temp: integer; + -- synopsys built_in SYN_INTEGER_TO_SIGNED + -- synopsys subpgm_id 376 + begin + -- synopsys synthesis_off + temp := ARG; + for i in 0 to SIZE-1 loop + if (temp mod 2) = 1 then + result(i) := '1'; + else + result(i) := '0'; + end if; + if temp > 0 then + temp := temp / 2; + elsif (temp > integer'low) then + temp := (temp - 1) / 2; -- simulate ASR + else + temp := temp / 2; -- simulate ASR + end if; + end loop; + return result; + -- synopsys synthesis_on + end; + + + function CONV_SIGNED(ARG: UNSIGNED; SIZE: INTEGER) return SIGNED is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is SIGNED (SIZE-1 downto 0); + variable new_bounds : SIGNED (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_ZERO_EXTEND + -- synopsys subpgm_id 377 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => '0'); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + function CONV_SIGNED(ARG: SIGNED; SIZE: INTEGER) return SIGNED is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is SIGNED (SIZE-1 downto 0); + variable new_bounds : SIGNED (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_SIGN_EXTEND + -- synopsys subpgm_id 378 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => new_bounds(new_bounds'left)); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + + function CONV_SIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return SIGNED is + subtype rtype is SIGNED (SIZE-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_ZERO_EXTEND + -- synopsys subpgm_id 380 + begin + -- synopsys synthesis_off + result := rtype'(others => '0'); + result(0) := MAKE_BINARY(ARG); + if (result(0) = 'X') then + result := rtype'(others => 'X'); + end if; + return result; + -- synopsys synthesis_on + end; + + + -- convert an integer to an STD_LOGIC_VECTOR + function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is + variable result: STD_LOGIC_VECTOR (SIZE-1 downto 0); + variable temp: integer; + -- synopsys built_in SYN_INTEGER_TO_SIGNED + -- synopsys subpgm_id 381 + begin + -- synopsys synthesis_off + temp := ARG; + for i in 0 to SIZE-1 loop + if (temp mod 2) = 1 then + result(i) := '1'; + else + result(i) := '0'; + end if; + if temp > 0 then + temp := temp / 2; + elsif (temp > integer'low) then + temp := (temp - 1) / 2; -- simulate ASR + else + temp := temp / 2; -- simulate ASR + end if; + end loop; + return result; + -- synopsys synthesis_on + end; + + + function CONV_STD_LOGIC_VECTOR(ARG: UNSIGNED; SIZE: INTEGER) return STD_LOGIC_VECTOR is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0); + variable new_bounds : STD_LOGIC_VECTOR (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_ZERO_EXTEND + -- synopsys subpgm_id 382 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => '0'); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + function CONV_STD_LOGIC_VECTOR(ARG: SIGNED; SIZE: INTEGER) return STD_LOGIC_VECTOR is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0); + variable new_bounds : STD_LOGIC_VECTOR (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_SIGN_EXTEND + -- synopsys subpgm_id 383 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => new_bounds(new_bounds'left)); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + + function CONV_STD_LOGIC_VECTOR(ARG: STD_ULOGIC; SIZE: INTEGER) return STD_LOGIC_VECTOR is + subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_ZERO_EXTEND + -- synopsys subpgm_id 384 + begin + -- synopsys synthesis_off + result := rtype'(others => '0'); + result(0) := MAKE_BINARY(ARG); + if (result(0) = 'X') then + result := rtype'(others => 'X'); + end if; + return result; + -- synopsys synthesis_on + end; + + function EXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) + return STD_LOGIC_VECTOR is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0); + variable new_bounds: STD_LOGIC_VECTOR (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_ZERO_EXTEND + -- synopsys subpgm_id 385 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => '0'); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + + function SXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR is + constant msb: INTEGER := min(ARG'length, SIZE) - 1; + subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0); + variable new_bounds : STD_LOGIC_VECTOR (ARG'length-1 downto 0); + variable result: rtype; + -- synopsys built_in SYN_SIGN_EXTEND + -- synopsys subpgm_id 386 + begin + -- synopsys synthesis_off + new_bounds := MAKE_BINARY(ARG); + if (new_bounds(0) = 'X') then + result := rtype'(others => 'X'); + return result; + end if; + result := rtype'(others => new_bounds(new_bounds'left)); + result(msb downto 0) := new_bounds(msb downto 0); + return result; + -- synopsys synthesis_on + end; + + +end std_logic_arith; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_misc.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_misc.vhdl new file mode 100644 index 00000000..289102a0 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_misc.vhdl @@ -0,0 +1,967 @@ +-------------------------------------------------------------------------- +-- +-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. All rights reserved. +-- +-- This source file may be used and distributed without restriction +-- provided that this copyright statement is not removed from the file +-- and that any derivative work contains this copyright notice. +-- +-- Package name: std_logic_misc +-- +-- Purpose: This package defines supplemental types, subtypes, +-- constants, and functions for the Std_logic_1164 Package. +-- +-- Author: GWH +-- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; + +-- library SYNOPSYS; +-- use SYNOPSYS.attributes.all; + + +package std_logic_misc is + + -- output-strength types + + type STRENGTH is (strn_X01, strn_X0H, strn_XL1, strn_X0Z, strn_XZ1, + strn_WLH, strn_WLZ, strn_WZH, strn_W0H, strn_WL1); + + +--synopsys synthesis_off + + type MINOMAX is array (1 to 3) of TIME; + + + --------------------------------------------------------------------- + -- + -- functions for mapping the STD_(U)LOGIC according to STRENGTH + -- + --------------------------------------------------------------------- + + function strength_map(input: STD_ULOGIC; strn: STRENGTH) return STD_LOGIC; + + function strength_map_z(input:STD_ULOGIC; strn:STRENGTH) return STD_LOGIC; + + --------------------------------------------------------------------- + -- + -- conversion functions for STD_ULOGIC_VECTOR and STD_LOGIC_VECTOR + -- + --------------------------------------------------------------------- + +--synopsys synthesis_on + function Drive (V: STD_ULOGIC_VECTOR) return STD_LOGIC_VECTOR; + + -- function Drive (V: STD_LOGIC_VECTOR) return STD_ULOGIC_VECTOR; +--synopsys synthesis_off + + -- attribute CLOSELY_RELATED_TCF of Drive: function is TRUE; + + --------------------------------------------------------------------- + -- + -- conversion functions for sensing various types + -- (the second argument allows the user to specify the value to + -- be returned when the network is undriven) + -- + --------------------------------------------------------------------- + + function Sense (V: STD_ULOGIC; vZ, vU, vDC: STD_ULOGIC) return STD_LOGIC; + + -- function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + -- return STD_LOGIC_VECTOR; + function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + return STD_ULOGIC_VECTOR; + + -- function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + -- return STD_LOGIC_VECTOR; + -- function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + -- return STD_ULOGIC_VECTOR; + +--synopsys synthesis_on + + + --------------------------------------------------------------------- + -- + -- Function: STD_LOGIC_VECTORtoBIT_VECTOR STD_ULOGIC_VECTORtoBIT_VECTOR + -- + -- Purpose: Conversion fun. from STD_(U)LOGIC_VECTOR to BIT_VECTOR + -- + -- Mapping: 0, L --> 0 + -- 1, H --> 1 + -- X, W --> vX if Xflag is TRUE + -- X, W --> 0 if Xflag is FALSE + -- Z --> vZ if Zflag is TRUE + -- Z --> 0 if Zflag is FALSE + -- U --> vU if Uflag is TRUE + -- U --> 0 if Uflag is FALSE + -- - --> vDC if DCflag is TRUE + -- - --> 0 if DCflag is FALSE + -- + --------------------------------------------------------------------- + + function STD_LOGIC_VECTORtoBIT_VECTOR (V: STD_LOGIC_VECTOR +--synopsys synthesis_off + ; vX, vZ, vU, vDC: BIT := '0'; + Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE +--synopsys synthesis_on + ) return BIT_VECTOR; + + function STD_ULOGIC_VECTORtoBIT_VECTOR (V: STD_ULOGIC_VECTOR +--synopsys synthesis_off + ; vX, vZ, vU, vDC: BIT := '0'; + Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE +--synopsys synthesis_on + ) return BIT_VECTOR; + + + --------------------------------------------------------------------- + -- + -- Function: STD_ULOGICtoBIT + -- + -- Purpose: Conversion function from STD_(U)LOGIC to BIT + -- + -- Mapping: 0, L --> 0 + -- 1, H --> 1 + -- X, W --> vX if Xflag is TRUE + -- X, W --> 0 if Xflag is FALSE + -- Z --> vZ if Zflag is TRUE + -- Z --> 0 if Zflag is FALSE + -- U --> vU if Uflag is TRUE + -- U --> 0 if Uflag is FALSE + -- - --> vDC if DCflag is TRUE + -- - --> 0 if DCflag is FALSE + -- + --------------------------------------------------------------------- + + function STD_ULOGICtoBIT (V: STD_ULOGIC +--synopsys synthesis_off + ; vX, vZ, vU, vDC: BIT := '0'; + Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE +--synopsys synthesis_on + ) return BIT; + + -------------------------------------------------------------------- + -- function AND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01; + -- function NAND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01; + -- function OR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01; + -- function NOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01; + -- function XOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01; + -- function XNOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01; + + function AND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01; + function NAND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01; + function OR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01; + function NOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01; + function XOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01; + function XNOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01; + +--synopsys synthesis_off + + function fun_BUF3S(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC; + function fun_BUF3SL(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC; + function fun_MUX2x1(Input0, Input1, Sel: UX01) return UX01; + + function fun_MAJ23(Input0, Input1, Input2: UX01) return UX01; + function fun_WiredX(Input0, Input1: std_ulogic) return STD_LOGIC; + +--synopsys synthesis_on + +end; + + +package body std_logic_misc is + +--synopsys synthesis_off + + type STRN_STD_ULOGIC_TABLE is array (STD_ULOGIC,STRENGTH) of STD_ULOGIC; + + -------------------------------------------------------------------- + -- + -- Truth tables for output strength --> STD_ULOGIC lookup + -- + -------------------------------------------------------------------- + + -- truth table for output strength --> STD_ULOGIC lookup + constant tbl_STRN_STD_ULOGIC: STRN_STD_ULOGIC_TABLE := + -- ------------------------------------------------------------------ + -- | X01 X0H XL1 X0Z XZ1 WLH WLZ WZH W0H WL1 | strn/ output| + -- ------------------------------------------------------------------ + (('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U | + ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | X | + ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | 0 | + ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | 1 | + ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | Z | + ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | W | + ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | L | + ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | H | + ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W')); -- | - | + + + + -------------------------------------------------------------------- + -- + -- Truth tables for strength --> STD_ULOGIC mapping ('Z' pass through) + -- + -------------------------------------------------------------------- + + -- truth table for output strength --> STD_ULOGIC lookup + constant tbl_STRN_STD_ULOGIC_Z: STRN_STD_ULOGIC_TABLE := + -- ------------------------------------------------------------------ + -- | X01 X0H XL1 X0Z XZ1 WLH WLZ WZH W0H WL1 | strn/ output| + -- ------------------------------------------------------------------ + (('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U | + ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | X | + ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | 0 | + ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | 1 | + ('Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z'), -- | Z | + ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | W | + ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | L | + ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | H | + ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W')); -- | - | + + + + --------------------------------------------------------------------- + -- + -- functions for mapping the STD_(U)LOGIC according to STRENGTH + -- + --------------------------------------------------------------------- + + function strength_map(input: STD_ULOGIC; strn: STRENGTH) return STD_LOGIC is + -- pragma subpgm_id 387 + begin + return tbl_STRN_STD_ULOGIC(input, strn); + end strength_map; + + + function strength_map_z(input:STD_ULOGIC; strn:STRENGTH) return STD_LOGIC is + -- pragma subpgm_id 388 + begin + return tbl_STRN_STD_ULOGIC_Z(input, strn); + end strength_map_z; + + + --------------------------------------------------------------------- + -- + -- conversion functions for STD_LOGIC_VECTOR and STD_ULOGIC_VECTOR + -- + --------------------------------------------------------------------- + +--synopsys synthesis_on + function Drive (V: STD_LOGIC_VECTOR) return STD_ULOGIC_VECTOR is + -- pragma built_in SYN_FEED_THRU + -- pragma subpgm_id 389 +--synopsys synthesis_off + alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V; +--synopsys synthesis_on + begin +--synopsys synthesis_off + return STD_ULOGIC_VECTOR(Value); +--synopsys synthesis_on + end Drive; + + +-- function Drive (V: STD_ULOGIC_VECTOR) return STD_LOGIC_VECTOR is +-- -- pragma built_in SYN_FEED_THRU +-- -- pragma subpgm_id 390 +-- --synopsys synthesis_off +-- alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V; +-- --synopsys synthesis_on +-- begin +-- --synopsys synthesis_off +-- return STD_LOGIC_VECTOR(Value); +-- --synopsys synthesis_on +-- end Drive; +-- --synopsys synthesis_off + + + --------------------------------------------------------------------- + -- + -- conversion functions for sensing various types + -- + -- (the second argument allows the user to specify the value to + -- be returned when the network is undriven) + -- + --------------------------------------------------------------------- + + function Sense (V: STD_ULOGIC; vZ, vU, vDC: STD_ULOGIC) + return STD_LOGIC is + -- pragma subpgm_id 391 + begin + if V = 'Z' then + return vZ; + elsif V = 'U' then + return vU; + elsif V = '-' then + return vDC; + else + return V; + end if; + end Sense; + + + -- function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + -- return STD_LOGIC_VECTOR is + -- -- pragma subpgm_id 392 + -- alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V; + -- variable Result: STD_LOGIC_VECTOR (V'length-1 downto 0); + -- begin + -- for i in Value'range loop + -- if ( Value(i) = 'Z' ) then + -- Result(i) := vZ; + -- elsif Value(i) = 'U' then + -- Result(i) := vU; + -- elsif Value(i) = '-' then + -- Result(i) := vDC; + -- else + -- Result(i) := Value(i); + -- end if; + -- end loop; + -- return Result; + -- end Sense; + + + function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + return STD_ULOGIC_VECTOR is + -- pragma subpgm_id 393 + alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V; + variable Result: STD_ULOGIC_VECTOR (V'length-1 downto 0); + begin + for i in Value'range loop + if ( Value(i) = 'Z' ) then + Result(i) := vZ; + elsif Value(i) = 'U' then + Result(i) := vU; + elsif Value(i) = '-' then + Result(i) := vDC; + else + Result(i) := Value(i); + end if; + end loop; + return Result; + end Sense; + + + -- function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + -- return STD_LOGIC_VECTOR is + -- -- pragma subpgm_id 394 + -- alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V; + -- variable Result: STD_LOGIC_VECTOR (V'length-1 downto 0); + -- begin + -- for i in Value'range loop + -- if ( Value(i) = 'Z' ) then + -- Result(i) := vZ; + -- elsif Value(i) = 'U' then + -- Result(i) := vU; + -- elsif Value(i) = '-' then + -- Result(i) := vDC; + -- else + -- Result(i) := Value(i); + -- end if; + -- end loop; + -- return Result; + -- end Sense; + + + -- function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC) + -- return STD_ULOGIC_VECTOR is + -- -- pragma subpgm_id 395 + -- alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V; + -- variable Result: STD_ULOGIC_VECTOR (V'length-1 downto 0); + -- begin + -- for i in Value'range loop + -- if ( Value(i) = 'Z' ) then + -- Result(i) := vZ; + -- elsif Value(i) = 'U' then + -- Result(i) := vU; + -- elsif Value(i) = '-' then + -- Result(i) := vDC; + -- else + -- Result(i) := Value(i); + -- end if; + -- end loop; + -- return Result; + -- end Sense; + + --------------------------------------------------------------------- + -- + -- Function: STD_LOGIC_VECTORtoBIT_VECTOR + -- + -- Purpose: Conversion fun. from STD_LOGIC_VECTOR to BIT_VECTOR + -- + -- Mapping: 0, L --> 0 + -- 1, H --> 1 + -- X, W --> vX if Xflag is TRUE + -- X, W --> 0 if Xflag is FALSE + -- Z --> vZ if Zflag is TRUE + -- Z --> 0 if Zflag is FALSE + -- U --> vU if Uflag is TRUE + -- U --> 0 if Uflag is FALSE + -- - --> vDC if DCflag is TRUE + -- - --> 0 if DCflag is FALSE + -- + --------------------------------------------------------------------- + +--synopsys synthesis_on + function STD_LOGIC_VECTORtoBIT_VECTOR (V: STD_LOGIC_VECTOR +--synopsys synthesis_off + ; vX, vZ, vU, vDC: BIT := '0'; + Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE +--synopsys synthesis_on + ) return BIT_VECTOR is + -- pragma built_in SYN_FEED_THRU + -- pragma subpgm_id 396 +--synopsys synthesis_off + alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V; + variable Result: BIT_VECTOR (V'length-1 downto 0); +--synopsys synthesis_on + begin +--synopsys synthesis_off + for i in Value'range loop + case Value(i) is + when '0' | 'L' => + Result(i) := '0'; + when '1' | 'H' => + Result(i) := '1'; + when 'X' => + if ( Xflag ) then + Result(i) := vX; + else + Result(i) := '0'; + assert FALSE + report "STD_LOGIC_VECTORtoBIT_VECTOR: X --> 0" + severity WARNING; + end if; + when 'W' => + if ( Xflag ) then + Result(i) := vX; + else + Result(i) := '0'; + assert FALSE + report "STD_LOGIC_VECTORtoBIT_VECTOR: W --> 0" + severity WARNING; + end if; + when 'Z' => + if ( Zflag ) then + Result(i) := vZ; + else + Result(i) := '0'; + assert FALSE + report "STD_LOGIC_VECTORtoBIT_VECTOR: Z --> 0" + severity WARNING; + end if; + when 'U' => + if ( Uflag ) then + Result(i) := vU; + else + Result(i) := '0'; + assert FALSE + report "STD_LOGIC_VECTORtoBIT_VECTOR: U --> 0" + severity WARNING; + end if; + when '-' => + if ( DCflag ) then + Result(i) := vDC; + else + Result(i) := '0'; + assert FALSE + report "STD_LOGIC_VECTORtoBIT_VECTOR: - --> 0" + severity WARNING; + end if; + end case; + end loop; + return Result; +--synopsys synthesis_on + end STD_LOGIC_VECTORtoBIT_VECTOR; + + + + + --------------------------------------------------------------------- + -- + -- Function: STD_ULOGIC_VECTORtoBIT_VECTOR + -- + -- Purpose: Conversion fun. from STD_ULOGIC_VECTOR to BIT_VECTOR + -- + -- Mapping: 0, L --> 0 + -- 1, H --> 1 + -- X, W --> vX if Xflag is TRUE + -- X, W --> 0 if Xflag is FALSE + -- Z --> vZ if Zflag is TRUE + -- Z --> 0 if Zflag is FALSE + -- U --> vU if Uflag is TRUE + -- U --> 0 if Uflag is FALSE + -- - --> vDC if DCflag is TRUE + -- - --> 0 if DCflag is FALSE + -- + --------------------------------------------------------------------- + + function STD_ULOGIC_VECTORtoBIT_VECTOR (V: STD_ULOGIC_VECTOR +--synopsys synthesis_off + ; vX, vZ, vU, vDC: BIT := '0'; + Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE +--synopsys synthesis_on + ) return BIT_VECTOR is + -- pragma built_in SYN_FEED_THRU + -- pragma subpgm_id 397 +--synopsys synthesis_off + alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V; + variable Result: BIT_VECTOR (V'length-1 downto 0); +--synopsys synthesis_on + begin +--synopsys synthesis_off + for i in Value'range loop + case Value(i) is + when '0' | 'L' => + Result(i) := '0'; + when '1' | 'H' => + Result(i) := '1'; + when 'X' => + if ( Xflag ) then + Result(i) := vX; + else + Result(i) := '0'; + assert FALSE + report "STD_ULOGIC_VECTORtoBIT_VECTOR: X --> 0" + severity WARNING; + end if; + when 'W' => + if ( Xflag ) then + Result(i) := vX; + else + Result(i) := '0'; + assert FALSE + report "STD_ULOGIC_VECTORtoBIT_VECTOR: W --> 0" + severity WARNING; + end if; + when 'Z' => + if ( Zflag ) then + Result(i) := vZ; + else + Result(i) := '0'; + assert FALSE + report "STD_ULOGIC_VECTORtoBIT_VECTOR: Z --> 0" + severity WARNING; + end if; + when 'U' => + if ( Uflag ) then + Result(i) := vU; + else + Result(i) := '0'; + assert FALSE + report "STD_ULOGIC_VECTORtoBIT_VECTOR: U --> 0" + severity WARNING; + end if; + when '-' => + if ( DCflag ) then + Result(i) := vDC; + else + Result(i) := '0'; + assert FALSE + report "STD_ULOGIC_VECTORtoBIT_VECTOR: - --> 0" + severity WARNING; + end if; + end case; + end loop; + return Result; +--synopsys synthesis_on + end STD_ULOGIC_VECTORtoBIT_VECTOR; + + + + + --------------------------------------------------------------------- + -- + -- Function: STD_ULOGICtoBIT + -- + -- Purpose: Conversion function from STD_ULOGIC to BIT + -- + -- Mapping: 0, L --> 0 + -- 1, H --> 1 + -- X, W --> vX if Xflag is TRUE + -- X, W --> 0 if Xflag is FALSE + -- Z --> vZ if Zflag is TRUE + -- Z --> 0 if Zflag is FALSE + -- U --> vU if Uflag is TRUE + -- U --> 0 if Uflag is FALSE + -- - --> vDC if DCflag is TRUE + -- - --> 0 if DCflag is FALSE + -- + --------------------------------------------------------------------- + + function STD_ULOGICtoBIT (V: STD_ULOGIC +--synopsys synthesis_off + ; vX, vZ, vU, vDC: BIT := '0'; + Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE +--synopsys synthesis_on + ) return BIT is + -- pragma built_in SYN_FEED_THRU + -- pragma subpgm_id 398 + variable Result: BIT; + begin +--synopsys synthesis_off + case V is + when '0' | 'L' => + Result := '0'; + when '1' | 'H' => + Result := '1'; + when 'X' => + if ( Xflag ) then + Result := vX; + else + Result := '0'; + assert FALSE + report "STD_ULOGICtoBIT: X --> 0" + severity WARNING; + end if; + when 'W' => + if ( Xflag ) then + Result := vX; + else + Result := '0'; + assert FALSE + report "STD_ULOGICtoBIT: W --> 0" + severity WARNING; + end if; + when 'Z' => + if ( Zflag ) then + Result := vZ; + else + Result := '0'; + assert FALSE + report "STD_ULOGICtoBIT: Z --> 0" + severity WARNING; + end if; + when 'U' => + if ( Uflag ) then + Result := vU; + else + Result := '0'; + assert FALSE + report "STD_ULOGICtoBIT: U --> 0" + severity WARNING; + end if; + when '-' => + if ( DCflag ) then + Result := vDC; + else + Result := '0'; + assert FALSE + report "STD_ULOGICtoBIT: - --> 0" + severity WARNING; + end if; + end case; + return Result; +--synopsys synthesis_on + end STD_ULOGICtoBIT; + + + -------------------------------------------------------------------------- + + -- function AND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is + -- -- pragma subpgm_id 399 + -- variable result: STD_LOGIC; + -- begin + -- result := '1'; + -- for i in ARG'range loop + -- result := result and ARG(i); + -- end loop; + -- return result; + -- end; + + -- function NAND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is + -- -- pragma subpgm_id 400 + -- begin + -- return not AND_REDUCE(ARG); + -- end; + + -- function OR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is + -- -- pragma subpgm_id 401 + -- variable result: STD_LOGIC; + -- begin + -- result := '0'; + -- for i in ARG'range loop + -- result := result or ARG(i); + -- end loop; + -- return result; + -- end; + + -- function NOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is + -- -- pragma subpgm_id 402 + -- begin + -- return not OR_REDUCE(ARG); + -- end; + + -- function XOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is + -- -- pragma subpgm_id 403 + -- variable result: STD_LOGIC; + -- begin + -- result := '0'; + -- for i in ARG'range loop + -- result := result xor ARG(i); + -- end loop; + -- return result; + -- end; + + -- function XNOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is + -- -- pragma subpgm_id 404 + -- begin + -- return not XOR_REDUCE(ARG); + -- end; + + function AND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is + -- pragma subpgm_id 405 + variable result: STD_LOGIC; + begin + result := '1'; + for i in ARG'range loop + result := result and ARG(i); + end loop; + return result; + end; + + function NAND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is + -- pragma subpgm_id 406 + begin + return not AND_REDUCE(ARG); + end; + + function OR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is + -- pragma subpgm_id 407 + variable result: STD_LOGIC; + begin + result := '0'; + for i in ARG'range loop + result := result or ARG(i); + end loop; + return result; + end; + + function NOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is + -- pragma subpgm_id 408 + begin + return not OR_REDUCE(ARG); + end; + + function XOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is + -- pragma subpgm_id 409 + variable result: STD_LOGIC; + begin + result := '0'; + for i in ARG'range loop + result := result xor ARG(i); + end loop; + return result; + end; + + function XNOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is + -- pragma subpgm_id 410 + begin + return not XOR_REDUCE(ARG); + end; + +--synopsys synthesis_off + + function fun_BUF3S(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC is + -- pragma subpgm_id 411 + type TRISTATE_TABLE is array(STRENGTH, UX01, UX01) of STD_LOGIC; + + -- truth table for tristate "buf" function (Enable active Low) + constant tbl_BUF3S: TRISTATE_TABLE := + -- ---------------------------------------------------- + -- | Input U X 0 1 | Enable Strength | + -- ---------------------------------|-----------------| + ((('U', 'U', 'U', 'U'), --| U X01 | + ('U', 'X', 'X', 'X'), --| X X01 | + ('Z', 'Z', 'Z', 'Z'), --| 0 X01 | + ('U', 'X', '0', '1')), --| 1 X01 | + (('U', 'U', 'U', 'U'), --| U X0H | + ('U', 'X', 'X', 'X'), --| X X0H | + ('Z', 'Z', 'Z', 'Z'), --| 0 X0H | + ('U', 'X', '0', 'H')), --| 1 X0H | + (('U', 'U', 'U', 'U'), --| U XL1 | + ('U', 'X', 'X', 'X'), --| X XL1 | + ('Z', 'Z', 'Z', 'Z'), --| 0 XL1 | + ('U', 'X', 'L', '1')), --| 1 XL1 | + (('U', 'U', 'U', 'Z'), --| U X0Z | + ('U', 'X', 'X', 'Z'), --| X X0Z | + ('Z', 'Z', 'Z', 'Z'), --| 0 X0Z | + ('U', 'X', '0', 'Z')), --| 1 X0Z | + (('U', 'U', 'U', 'U'), --| U XZ1 | + ('U', 'X', 'X', 'X'), --| X XZ1 | + ('Z', 'Z', 'Z', 'Z'), --| 0 XZ1 | + ('U', 'X', 'Z', '1')), --| 1 XZ1 | + (('U', 'U', 'U', 'U'), --| U WLH | + ('U', 'W', 'W', 'W'), --| X WLH | + ('Z', 'Z', 'Z', 'Z'), --| 0 WLH | + ('U', 'W', 'L', 'H')), --| 1 WLH | + (('U', 'U', 'U', 'U'), --| U WLZ | + ('U', 'W', 'W', 'Z'), --| X WLZ | + ('Z', 'Z', 'Z', 'Z'), --| 0 WLZ | + ('U', 'W', 'L', 'Z')), --| 1 WLZ | + (('U', 'U', 'U', 'U'), --| U WZH | + ('U', 'W', 'W', 'W'), --| X WZH | + ('Z', 'Z', 'Z', 'Z'), --| 0 WZH | + ('U', 'W', 'Z', 'H')), --| 1 WZH | + (('U', 'U', 'U', 'U'), --| U W0H | + ('U', 'W', 'W', 'W'), --| X W0H | + ('Z', 'Z', 'Z', 'Z'), --| 0 W0H | + ('U', 'W', '0', 'H')), --| 1 W0H | + (('U', 'U', 'U', 'U'), --| U WL1 | + ('U', 'W', 'W', 'W'), --| X WL1 | + ('Z', 'Z', 'Z', 'Z'), --| 0 WL1 | + ('U', 'W', 'L', '1')));--| 1 WL1 | + begin + return tbl_BUF3S(Strn, Enable, Input); + end fun_BUF3S; + + + function fun_BUF3SL(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC is + -- pragma subpgm_id 412 + type TRISTATE_TABLE is array(STRENGTH, UX01, UX01) of STD_LOGIC; + + -- truth table for tristate "buf" function (Enable active Low) + constant tbl_BUF3SL: TRISTATE_TABLE := + -- ---------------------------------------------------- + -- | Input U X 0 1 | Enable Strength | + -- ---------------------------------|-----------------| + ((('U', 'U', 'U', 'U'), --| U X01 | + ('U', 'X', 'X', 'X'), --| X X01 | + ('U', 'X', '0', '1'), --| 0 X01 | + ('Z', 'Z', 'Z', 'Z')), --| 1 X01 | + (('U', 'U', 'U', 'U'), --| U X0H | + ('U', 'X', 'X', 'X'), --| X X0H | + ('U', 'X', '0', 'H'), --| 0 X0H | + ('Z', 'Z', 'Z', 'Z')), --| 1 X0H | + (('U', 'U', 'U', 'U'), --| U XL1 | + ('U', 'X', 'X', 'X'), --| X XL1 | + ('U', 'X', 'L', '1'), --| 0 XL1 | + ('Z', 'Z', 'Z', 'Z')), --| 1 XL1 | + (('U', 'U', 'U', 'Z'), --| U X0Z | + ('U', 'X', 'X', 'Z'), --| X X0Z | + ('U', 'X', '0', 'Z'), --| 0 X0Z | + ('Z', 'Z', 'Z', 'Z')), --| 1 X0Z | + (('U', 'U', 'U', 'U'), --| U XZ1 | + ('U', 'X', 'X', 'X'), --| X XZ1 | + ('U', 'X', 'Z', '1'), --| 0 XZ1 | + ('Z', 'Z', 'Z', 'Z')), --| 1 XZ1 | + (('U', 'U', 'U', 'U'), --| U WLH | + ('U', 'W', 'W', 'W'), --| X WLH | + ('U', 'W', 'L', 'H'), --| 0 WLH | + ('Z', 'Z', 'Z', 'Z')), --| 1 WLH | + (('U', 'U', 'U', 'U'), --| U WLZ | + ('U', 'W', 'W', 'Z'), --| X WLZ | + ('U', 'W', 'L', 'Z'), --| 0 WLZ | + ('Z', 'Z', 'Z', 'Z')), --| 1 WLZ | + (('U', 'U', 'U', 'U'), --| U WZH | + ('U', 'W', 'W', 'W'), --| X WZH | + ('U', 'W', 'Z', 'H'), --| 0 WZH | + ('Z', 'Z', 'Z', 'Z')), --| 1 WZH | + (('U', 'U', 'U', 'U'), --| U W0H | + ('U', 'W', 'W', 'W'), --| X W0H | + ('U', 'W', '0', 'H'), --| 0 W0H | + ('Z', 'Z', 'Z', 'Z')), --| 1 W0H | + (('U', 'U', 'U', 'U'), --| U WL1 | + ('U', 'W', 'W', 'W'), --| X WL1 | + ('U', 'W', 'L', '1'), --| 0 WL1 | + ('Z', 'Z', 'Z', 'Z')));--| 1 WL1 | + begin + return tbl_BUF3SL(Strn, Enable, Input); + end fun_BUF3SL; + + + function fun_MUX2x1(Input0, Input1, Sel: UX01) return UX01 is + -- pragma subpgm_id 413 + type MUX_TABLE is array (UX01, UX01, UX01) of UX01; + + -- truth table for "MUX2x1" function + constant tbl_MUX2x1: MUX_TABLE := + -------------------------------------------- + --| In0 'U' 'X' '0' '1' | Sel In1 | + -------------------------------------------- + ((('U', 'U', 'U', 'U'), --| 'U' 'U' | + ('U', 'U', 'U', 'U'), --| 'X' 'U' | + ('U', 'X', '0', '1'), --| '0' 'U' | + ('U', 'U', 'U', 'U')), --| '1' 'U' | + (('U', 'X', 'U', 'U'), --| 'U' 'X' | + ('U', 'X', 'X', 'X'), --| 'X' 'X' | + ('U', 'X', '0', '1'), --| '0' 'X' | + ('X', 'X', 'X', 'X')), --| '1' 'X' | + (('U', 'U', '0', 'U'), --| 'U' '0' | + ('U', 'X', '0', 'X'), --| 'X' '0' | + ('U', 'X', '0', '1'), --| '0' '0' | + ('0', '0', '0', '0')), --| '1' '0' | + (('U', 'U', 'U', '1'), --| 'U' '1' | + ('U', 'X', 'X', '1'), --| 'X' '1' | + ('U', 'X', '0', '1'), --| '0' '1' | + ('1', '1', '1', '1')));--| '1' '1' | + begin + return tbl_MUX2x1(Input1, Sel, Input0); + end fun_MUX2x1; + + + function fun_MAJ23(Input0, Input1, Input2: UX01) return UX01 is + -- pragma subpgm_id 414 + type MAJ23_TABLE is array (UX01, UX01, UX01) of UX01; + + ---------------------------------------------------------------------------- + -- The "tbl_MAJ23" truth table return 1 if the majority of three + -- inputs is 1, a 0 if the majority is 0, a X if unknown, and a U if + -- uninitialized. + ---------------------------------------------------------------------------- + constant tbl_MAJ23: MAJ23_TABLE := + -------------------------------------------- + --| In0 'U' 'X' '0' '1' | In1 In2 | + -------------------------------------------- + ((('U', 'U', 'U', 'U'), --| 'U' 'U' | + ('U', 'U', 'U', 'U'), --| 'X' 'U' | + ('U', 'U', '0', 'U'), --| '0' 'U' | + ('U', 'U', 'U', '1')), --| '1' 'U' | + (('U', 'U', 'U', 'U'), --| 'U' 'X' | + ('U', 'X', 'X', 'X'), --| 'X' 'X' | + ('U', 'X', '0', 'X'), --| '0' 'X' | + ('U', 'X', 'X', '1')), --| '1' 'X' | + (('U', 'U', '0', 'U'), --| 'U' '0' | + ('U', 'X', '0', 'X'), --| 'X' '0' | + ('0', '0', '0', '0'), --| '0' '0' | + ('U', 'X', '0', '1')), --| '1' '0' | + (('U', 'U', 'U', '1'), --| 'U' '1' | + ('U', 'X', 'X', '1'), --| 'X' '1' | + ('U', 'X', '0', '1'), --| '0' '1' | + ('1', '1', '1', '1')));--| '1' '1' | + + begin + return tbl_MAJ23(Input0, Input1, Input2); + end fun_MAJ23; + + + function fun_WiredX(Input0, Input1: STD_ULOGIC) return STD_LOGIC is + -- pragma subpgm_id 415 + TYPE stdlogic_table IS ARRAY(STD_ULOGIC, STD_ULOGIC) OF STD_LOGIC; + + -- truth table for "WiredX" function + ------------------------------------------------------------------- + -- 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' ));-- | - | + begin + return resolution_table(Input0, Input1); + end fun_WiredX; + +--synopsys synthesis_on + +end; \ No newline at end of file diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_signed.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_signed.vhdl new file mode 100644 index 00000000..27d211be --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_signed.vhdl @@ -0,0 +1,343 @@ +-------------------------------------------------------------------------- +-- -- +-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. -- +-- All rights reserved. -- +-- -- +-- This source file may be used and distributed without restriction -- +-- provided that this copyright statement is not removed from the file -- +-- and that any derivative work contains this copyright notice. -- +-- -- +-- Package name: STD_LOGIC_SIGNED -- +-- -- +-- -- +-- Date: 09/11/91 KN -- +-- 10/08/92 AMT change std_ulogic to signed std_logic -- +-- 10/28/92 AMT added signed functions, -, ABS -- +-- -- +-- Purpose: -- +-- A set of signed arithemtic, conversion, -- +-- and comparision functions for STD_LOGIC_VECTOR. -- +-- -- +-- Note: Comparision of same length std_logic_vector is defined -- +-- in the LRM. The interpretation is for unsigned vectors -- +-- This package will "overload" that definition. -- +-- -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_arith.all; + +package STD_LOGIC_SIGNED is + + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR; + function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR; + function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR; + function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR; + function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "-"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "ABS"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + + function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER; + +-- remove this since it is already in std_logic_arith +-- function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR; + +end STD_LOGIC_SIGNED; + + + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_arith.all; + +package body STD_LOGIC_SIGNED is + + + function maximum(L, R: INTEGER) return INTEGER is + begin + if L > R then + return L; + else + return R; + end if; + end; + + + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + constant length: INTEGER := maximum(L'length, R'length); + variable result : STD_LOGIC_VECTOR (length-1 downto 0); + begin + result := SIGNED(L) + SIGNED(R); -- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := SIGNED(L) + R; -- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L + SIGNED(R); -- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := SIGNED(L) + R; -- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L + SIGNED(R); -- pragma label plus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + constant length: INTEGER := maximum(L'length, R'length); + variable result : STD_LOGIC_VECTOR (length-1 downto 0); + begin + result := SIGNED(L) - SIGNED(R); -- pragma label minus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := SIGNED(L) - R; -- pragma label minus + return std_logic_vector(result); + end; + + function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L - SIGNED(R); -- pragma label minus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := SIGNED(L) - R; -- pragma label minus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L - SIGNED(R); -- pragma label minus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := + SIGNED(L); -- pragma label plus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := - SIGNED(L); -- pragma label minus + return std_logic_vector(result); + end; + + function "ABS"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := ABS( SIGNED(L)); + return std_logic_vector(result); + end; + + function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to mult + constant length: INTEGER := maximum(L'length, R'length); + variable result : STD_LOGIC_VECTOR ((L'length+R'length-1) downto 0); + begin + result := SIGNED(L) * SIGNED(R); -- pragma label mult + return std_logic_vector(result); + end; + + function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to lt + constant length: INTEGER := maximum(L'length, R'length); + begin + return SIGNED(L) < SIGNED(R); -- pragma label lt + end; + + function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to lt + begin + return SIGNED(L) < R; -- pragma label lt + end; + + function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to lt + begin + return L < SIGNED(R); -- pragma label lt + end; + + function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to leq + begin + return SIGNED(L) <= SIGNED(R); -- pragma label leq + end; + + function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to leq + begin + return SIGNED(L) <= R; -- pragma label leq + end; + + function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to leq + begin + return L <= SIGNED(R); -- pragma label leq + end; + + function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to gt + begin + return SIGNED(L) > SIGNED(R); -- pragma label gt + end; + + function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to gt + begin + return SIGNED(L) > R; -- pragma label gt + end; + + function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to gt + begin + return L > SIGNED(R); -- pragma label gt + end; + + function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to geq + begin + return SIGNED(L) >= SIGNED(R); -- pragma label geq + end; + + function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to geq + begin + return SIGNED(L) >= R; -- pragma label geq + end; + + function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to geq + begin + return L >= SIGNED(R); -- pragma label geq + end; + + function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return SIGNED(L) = SIGNED(R); + end; + + function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + begin + return SIGNED(L) = R; + end; + + function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return L = SIGNED(R); + end; + + function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return SIGNED(L) /= SIGNED(R); + end; + + function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + begin + return SIGNED(L) /= R; + end; + + function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return L /= SIGNED(R); + end; + + function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + begin + return STD_LOGIC_VECTOR(SHL(SIGNED(ARG),UNSIGNED(COUNT))); + end; + + function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + begin + return STD_LOGIC_VECTOR(SHR(SIGNED(ARG),UNSIGNED(COUNT))); + end; + + + +-- This function converts std_logic_vector to a signed integer value +-- using a conversion function in std_logic_arith + function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER is + variable result : SIGNED(ARG'range); + begin + result := SIGNED(ARG); + return CONV_INTEGER(result); + end; +end STD_LOGIC_SIGNED; + + diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_unsigned.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_unsigned.vhdl new file mode 100644 index 00000000..3e29847a --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/synopsys/std_logic_unsigned.vhdl @@ -0,0 +1,329 @@ +-------------------------------------------------------------------------- +-- -- +-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. -- +-- All rights reserved. -- +-- -- +-- This source file may be used and distributed without restriction -- +-- provided that this copyright statement is not removed from the file -- +-- and that any derivative work contains this copyright notice. -- +-- -- +-- Package name: STD_LOGIC_UNSIGNED -- +-- -- +-- -- +-- Date: 09/11/92 KN -- +-- 10/08/92 AMT -- +-- -- +-- Purpose: -- +-- A set of unsigned arithemtic, conversion, -- +-- and comparision functions for STD_LOGIC_VECTOR. -- +-- -- +-- Note: comparision of same length discrete arrays is defined -- +-- by the LRM. This package will "overload" those -- +-- definitions -- +-- -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_arith.all; + +package STD_LOGIC_UNSIGNED is + + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR; + function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR; + function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR; + function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR; + function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + + function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN; + function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN; + function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN; + function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + + function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER; + +-- remove this since it is already in std_logic_arith +-- function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR; + +end STD_LOGIC_UNSIGNED; + + + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_arith.all; + +package body STD_LOGIC_UNSIGNED is + + + function maximum(L, R: INTEGER) return INTEGER is + begin + if L > R then + return L; + else + return R; + end if; + end; + + + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + constant length: INTEGER := maximum(L'length, R'length); + variable result : STD_LOGIC_VECTOR (length-1 downto 0); + begin + result := UNSIGNED(L) + UNSIGNED(R);-- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := UNSIGNED(L) + R;-- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L + UNSIGNED(R);-- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := UNSIGNED(L) + R;-- pragma label plus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to plus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L + UNSIGNED(R);-- pragma label plus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + constant length: INTEGER := maximum(L'length, R'length); + variable result : STD_LOGIC_VECTOR (length-1 downto 0); + begin + result := UNSIGNED(L) - UNSIGNED(R); -- pragma label minus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := UNSIGNED(L) - R; -- pragma label minus + return std_logic_vector(result); + end; + + function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L - UNSIGNED(R); -- pragma label minus + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := UNSIGNED(L) - R; + return std_logic_vector(result); + end; + + function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to minus + variable result : STD_LOGIC_VECTOR (R'range); + begin + result := L - UNSIGNED(R); -- pragma label minus + return std_logic_vector(result); + end; + + function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + variable result : STD_LOGIC_VECTOR (L'range); + begin + result := + UNSIGNED(L); + return std_logic_vector(result); + end; + + function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + -- pragma label_applies_to mult + constant length: INTEGER := maximum(L'length, R'length); + variable result : STD_LOGIC_VECTOR ((L'length+R'length-1) downto 0); + begin + result := UNSIGNED(L) * UNSIGNED(R); -- pragma label mult + return std_logic_vector(result); + end; + + function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to lt + constant length: INTEGER := maximum(L'length, R'length); + begin + return UNSIGNED(L) < UNSIGNED(R); -- pragma label lt + end; + + function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to lt + begin + return UNSIGNED(L) < R; -- pragma label lt + end; + + function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to lt + begin + return L < UNSIGNED(R); -- pragma label lt + end; + + function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to leq + begin + return UNSIGNED(L) <= UNSIGNED(R); -- pragma label leq + end; + + function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to leq + begin + return UNSIGNED(L) <= R; -- pragma label leq + end; + + function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to leq + begin + return L <= UNSIGNED(R); -- pragma label leq + end; + + function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to gt + begin + return UNSIGNED(L) > UNSIGNED(R); -- pragma label gt + end; + + function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to gt + begin + return UNSIGNED(L) > R; -- pragma label gt + end; + + function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to gt + begin + return L > UNSIGNED(R); -- pragma label gt + end; + + function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to geq + begin + return UNSIGNED(L) >= UNSIGNED(R); -- pragma label geq + end; + + function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + -- pragma label_applies_to geq + begin + return UNSIGNED(L) >= R; -- pragma label geq + end; + + function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + -- pragma label_applies_to geq + begin + return L >= UNSIGNED(R); -- pragma label geq + end; + + function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return UNSIGNED(L) = UNSIGNED(R); + end; + + function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + begin + return UNSIGNED(L) = R; + end; + + function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return L = UNSIGNED(R); + end; + + function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return UNSIGNED(L) /= UNSIGNED(R); + end; + + function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is + begin + return UNSIGNED(L) /= R; + end; + + function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is + begin + return L /= UNSIGNED(R); + end; + + function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER is + variable result : UNSIGNED(ARG'range); + begin + result := UNSIGNED(ARG); + return CONV_INTEGER(result); + end; + function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + begin + return STD_LOGIC_VECTOR(SHL(UNSIGNED(ARG),UNSIGNED(COUNT))); + end; + + function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + begin + return STD_LOGIC_VECTOR(SHR(UNSIGNED(ARG),UNSIGNED(COUNT))); + end; + + +-- remove this since it is already in std_logic_arith + --function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is + --variable result1 : UNSIGNED (SIZE-1 downto 0); + --variable result2 : STD_LOGIC_VECTOR (SIZE-1 downto 0); + --begin + --result1 := CONV_UNSIGNED(ARG,SIZE); + --return std_logic_vector(result1); + --end; + + +end STD_LOGIC_UNSIGNED; + + diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vhdl_ls.toml b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vhdl_ls.toml new file mode 100644 index 00000000..4de4092d --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vhdl_ls.toml @@ -0,0 +1,7 @@ +[libraries] + +std.files = ['std/*.vhd'] +std.is_third_party = true + +ieee.files = ['ieee2008/*.vhdl', 'synopsys/*.vhdl', 'vital2000/*.vhdl'] +ieee.is_third_party = true diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/memory_b.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/memory_b.vhdl new file mode 100644 index 00000000..39bb38a2 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/memory_b.vhdl @@ -0,0 +1,7151 @@ +-- ---------------------------------------------------------------------------- +-- Title : Standard VITAL Memory Package +-- : +-- Library : Vital_Memory +-- : +-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4 +-- : Ekambaram Balaji, LSI Logic Corporation +-- : Jose De Castro, Consultant +-- : Prakash Bare, GDA Technologies +-- : William Yam, LSI Logic Corporation +-- : Dennis Brophy, Model Technology +-- : +-- Purpose : This packages defines standard types, constants, functions +-- : and procedures for use in developing ASIC memory models. +-- : +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Modification History : +-- ---------------------------------------------------------------------------- +-- Ver:|Auth:| Date:| Changes Made: +-- 0.1 | eb |071796| First prototye as part of VITAL memory proposal +-- 0.2 | jdc |012897| Initial prototyping with proposed MTM scheme +-- 0.3 | jdc |090297| Extensive updates for TAG review (functional) +-- 0.4 | eb |091597| Changed naming conventions for VitalMemoryTable +-- | | | Added interface of VitalMemoryCrossPorts() & +-- | | | VitalMemoryViolation(). +-- 0.5 | jdc |092997| Completed naming changes thoughout package body. +-- | | | Testing with simgle port test model looks ok. +-- 0.6 | jdc |121797| Major updates to the packages: +-- | | | - Implement VitalMemoryCrossPorts() +-- | | | - Use new VitalAddressValueType +-- | | | - Use new VitalCrossPortModeType enum +-- | | | - Overloading without SamePort args +-- | | | - Honor erroneous address values +-- | | | - Honor ports disabled with 'Z' +-- | | | - Implement implicit read 'M' table symbol +-- | | | - Cleanup buses to use (H DOWNTO L) +-- | | | - Message control via MsgOn,HeaderMsg,PortName +-- | | | - Tested with 1P1RW,2P2RW,4P2R2W,4P4RW cases +-- 0.7 | jdc |052698| Bug fixes to the packages: +-- | | | - Fix failure with negative Address values +-- | | | - Added debug messages for VMT table search +-- | | | - Remove 'S' for action column (only 's') +-- | | | - Remove 's' for response column (only 'S') +-- | | | - Remove 'X' for action and response columns +-- 0.8 | jdc |061298| Implemented VitalMemoryViolation() +-- | | | - Minimal functionality violation tables +-- | | | - Missing: +-- | | | - Cannot handle wide violation variables +-- | | | - Cannot handle sub-word cases +-- | | | Fixed IIC version of MemoryMatch +-- | | | Fixed 'M' vs 'm' switched on debug output +-- | | | TO BE DONE: +-- | | | - Implement 'd' corrupting a single bit +-- | | | - Implement 'D' corrupting a single bit +-- 0.9 |eb/sc|080498| Added UNDEF value for VitalPortFlagType +-- 0.10|eb/sc|080798| Added CORRUPT value for VitalPortFlagType +-- 0.11|eb/sc|081798| Added overloaded function interface for +-- | | | VitalDeclareMemory +-- 0.14| jdc |113198| Merging of memory functionality and version +-- | | | 1.4 9/17/98 of timing package from Prakash +-- 0.15| jdc |120198| Major development of VMV functionality +-- 0.16| jdc |120298| Complete VMV functionlality for initial testing +-- | | | - New ViolationTableCorruptMask() procedure +-- | | | - New MemoryTableCorruptMask() procedure +-- | | | - HandleMemoryAction(): +-- | | | - Removed DataOutBus bogus output +-- | | | - Replaced DataOutTmp with DataInTmp +-- | | | - Added CorruptMask input handling +-- | | | - Implemented 'd','D' using CorruptMask +-- | | | - CorruptMask on 'd','C','L','D','E' +-- | | | - CorruptMask ignored on 'c','l','e' +-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT +-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT +-- | | | - Changed 'c','l','d','e' to ignore HighBit, LowBit +-- | | | - Changed 'C','L','D','E' to use HighBit, LowBit +-- | | | - HandleDataAction(): +-- | | | - Added CorruptMask input handling +-- | | | - Implemented 'd','D' using CorruptMask +-- | | | - CorruptMask on 'd','C','L','D','E' +-- | | | - CorruptMask ignored on 'l','e' +-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT +-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT +-- | | | - Changed 'l','d','e' to ignore HighBit, LowBit +-- | | | - Changed 'L','D','E' to use HighBit, LowBit +-- | | | - MemoryTableLookUp(): +-- | | | - Added MsgOn table debug output +-- | | | - Uses new MemoryTableCorruptMask() +-- | | | - ViolationTableLookUp(): +-- | | | - Uses new ViolationTableCorruptMask() +-- 0.17| jdc |120898| - Added VitalMemoryViolationSymbolType, +-- | | | VitalMemoryViolationTableType data +-- | | | types but not used yet (need to discuss) +-- | | | - Added overload for VitalMemoryViolation() +-- | | | which does not have array flags +-- | | | - Bug fixes for VMV functionality: +-- | | | - ViolationTableLookUp() not handling '-' in +-- | | | scalar violation matching +-- | | | - VitalMemoryViolation() now normalizes +-- | | | VFlagArrayTmp'LEFT as LSB before calling +-- | | | ViolationTableLookUp() for proper scanning +-- | | | - ViolationTableCorruptMask() had to remove +-- | | | normalization of CorruptMaskTmp and +-- | | | ViolMaskTmp for proper MSB:LSB corruption +-- | | | - HandleMemoryAction(), HandleDataAction() +-- | | | - Removed 'D','E' since not being used +-- | | | - Use XOR instead of OR for corrupt masks +-- | | | - Now 'd' is sensitive to HighBit, LowBit +-- | | | - Fixed LowBit overflow in bit writeable case +-- | | | - MemoryTableCorruptMask() +-- | | | - ViolationTableCorruptMask() +-- | | | - VitalMemoryTable() +-- | | | - VitalMemoryCrossPorts() +-- | | | - Fixed VitalMemoryViolation() failing on +-- | | | error AddressValue from earlier VMT() +-- | | | - Minor cleanup of code formatting +-- 0.18| jdc |032599| - In VitalDeclareMemory() +-- | | | - Added BinaryLoadFile formal arg and +-- | | | modified LoadMemory() to handle bin +-- | | | - Added NOCHANGE to VitalPortFlagType +-- | | | - For VitalCrossPortModeType +-- | | | - Added CpContention enum +-- | | | - In HandleDataAction() +-- | | | - Set PortFlag := NOCHANGE for 'S' +-- | | | - In HandleMemoryAction() +-- | | | - Set PortFlag := NOCHANGE for 's' +-- | | | - In VitalMemoryTable() and +-- | | | VitalMemoryViolation() +-- | | | - Honor PortFlag = NOCHANGE returned +-- | | | from HandleMemoryAction() +-- | | | - In VitalMemoryCrossPorts() +-- | | | - Fixed Address = AddressJ for all +-- | | | conditions of DoWrCont & DoCpRead +-- | | | - Handle CpContention like WrContOnly +-- | | | under CpReadOnly conditions, with +-- | | | associated memory message changes +-- | | | - Handle PortFlag = NOCHANGE like +-- | | | PortFlag = READ for actions +-- | | | - Modeling change: +-- | | | - Need to init PortFlag every delta +-- | | | PortFlag_A := (OTHES => UNDEF); +-- | | | - Updated InternalTimingCheck code +-- 0.19| jdc |042599| - Fixes for bit-writeable cases +-- | | | - Check PortFlag after HandleDataAction +-- | | | in VitalMemoryViolation() +-- 0.20| jdc |042599| - Merge PortFlag changes from Prakash +-- | | | and Willian: +-- | | | VitalMemorySchedulePathDelay() +-- | | | VitalMemoryExpandPortFlag() +-- 0.21| jdc |072199| - Changed VitalCrossPortModeType enums, +-- | | | added new CpReadAndReadContention. +-- | | | - Fixed VitalMemoryCrossPorts() parameter +-- | | | SamePortFlag to INOUT so that it can +-- | | | set CORRUPT or READ value. +-- | | | - Fixed VitalMemoryTable() where PortFlag +-- | | | setting by HandleDataAction() is being +-- | | | ignored when HandleMemoryAction() sets +-- | | | PortFlagTmp to NOCHANGE. +-- | | | - Fixed VitalMemoryViolation() to set +-- | | | all bits of PortFlag when violating. +-- 0.22| jdc |072399| - Added HIGHZ to PortFlagType. HandleData +-- | | | checks whether the previous state is HIGHZ. +-- | | | If yes then portFlag should be NOCHANGE +-- | | | for VMPD to ignore IORetain corruption. +-- | | | The idea is that the first Z should be +-- | | | propagated but later ones should be ignored. +-- | | | +-- 0.23| jdc |100499| - Took code checked in by Dennis 09/28/99 +-- | | | - Changed VitalPortFlagType to record of +-- | | | new VitalPortStateType to hold current, +-- | | | previous values and separate disable. +-- | | | Also created VitalDefaultPortFlag const. +-- | | | Removed usage of PortFlag NOCHANGE +-- | | | - VitalMemoryTable() changes: +-- | | | Optimized return when all curr = prev +-- | | | AddressValue is now INOUT to optimize +-- | | | Transfer PF.MemoryCurrent to MemoryPrevious +-- | | | Transfer PF.DataCurrent to DataPrevious +-- | | | Reset PF.OutputDisable to FALSE +-- | | | Expects PortFlag init in declaration +-- | | | No need to init PortFlag every delta +-- | | | - VitalMemorySchedulePathDelay() changes: +-- | | | Initialize with VitalDefaultPortFlag +-- | | | Check PortFlag.OutputDisable +-- | | | - HandleMemoryAction() changes: +-- | | | Set value of PortFlag.MemoryCurrent +-- | | | Never set PortFlag.OutputDisable +-- | | | - HandleDataAction() changes: +-- | | | Set value of PortFlag.DataCurrent +-- | | | Set PortFlag.DataCurrent for HIGHZ +-- | | | - VitalMemoryCrossPorts() changes: +-- | | | Check/set value of PF.MemoryCurrent +-- | | | Check value of PF.OutputDisable +-- | | | - VitalMemoryViolation() changes: +-- | | | Fixed bug - not reading inout PF value +-- | | | Clean up setting of PortFlag +-- 0.24| jdc |100899| - Modified update of PF.OutputDisable +-- | | | to correctly accomodate 2P1W1R case: +-- | | | the read port should not exhibit +-- | | | IO retain corrupt when reading +-- | | | addr unrelated to addr being written. +-- 0.25| jdc |100999| - VitalMemoryViolation() change: +-- | | | Fixed bug with RDNWR mode incorrectly +-- | | | updating the PF.OutputDisable +-- 0.26| jdc |100999| - VitalMemoryCrossPorts() change: +-- | | | Fixed bugs with update of PF +-- 0.27| jdc |101499| - VitalMemoryCrossPorts() change: +-- | | | Added DoRdWrCont message (ErrMcpRdWrCo, +-- | | | Memory cross port read/write data only +-- | | | contention) +-- | | | - VitalMemoryTable() change: +-- | | | Set PF.OutputDisable := TRUE for the +-- | | | optimized cases. +-- 0.28| pb |112399| - Added 8 VMPD procedures for vector +-- | | | PathCondition support. Now the total +-- | | | number of overloadings for VMPD is 24. +-- | | | - Number of overloadings for SetupHold +-- | | | procedures increased to 5. Scalar violations +-- | | | are not supported anymore. Vector checkEnabled +-- | | | support is provided through the new overloading +-- 0.29| jdc |120999| - HandleMemoryAction() HandleDataAction() +-- | | | Reinstated 'D' and 'E' actions but +-- | | | with new PortFlagType +-- | | | - Updated file handling syntax, must compile +-- | | | with -93 syntax now. +-- 0.30| jdc |022300| - Formated for 80 column max width +-- ---------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.Vital_Timing.all; +USE IEEE.Vital_Primitives.all; + +LIBRARY STD; +USE STD.TEXTIO.ALL; + +-- ---------------------------------------------------------------------------- +PACKAGE BODY Vital_Memory IS + +-- ---------------------------------------------------------------------------- +-- Timing Section +-- ---------------------------------------------------------------------------- + +FILE LogFile : TEXT OPEN write_mode IS "delayLog"; +FILE Output : TEXT OPEN write_mode IS "STD_OUTPUT"; + +-- Added for turning off the debug msg.. +CONSTANT PrintDebugMsg : STD_ULOGIC := '0'; + -- '0' - don't print in STD OUTPUT + -- '1' - print in STD OUTPUT + +-- Type and constant definitions for type conversion. +TYPE MVL9_TO_CHAR_TBL IS ARRAY (STD_ULOGIC) OF character; + +--constant MVL9_to_char: MVL9_TO_CHAR_TBL := "UX01ZWLH-"; +CONSTANT MVL9_to_char: MVL9_TO_CHAR_TBL := "XX01ZX010"; + +-- ---------------------------------------------------------------------------- +-- STD_LOGIC WRITE UTILITIES +-- ---------------------------------------------------------------------------- +PROCEDURE WRITE( + l : INOUT line; + val : IN std_logic_vector; + justify : IN side := right; + field : IN width := 0 +) IS + VARIABLE invect : std_logic_vector(val'LENGTH DOWNTO 1); + VARIABLE ins : STRING(val'LENGTH DOWNTO 1); +BEGIN + invect := val; + FOR I IN invect'length DOWNTO 1 LOOP + ins(I) := MVL9_to_char(invect(I)); + END LOOP; + WRITE(L, ins, justify, field); +END; + +PROCEDURE WRITE( + l : INOUT line; + val : IN std_ulogic; + justify : IN side := right; + field : in width := 0 +) IS + VARIABLE ins : CHARACTER; +BEGIN + ins := MVL9_to_char(val); + WRITE(L, ins, justify, field); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE DelayValue( + InputTime : IN TIME ; + outline : INOUT LINE +) IS + CONSTANT header : STRING := "TIME'HIGH"; +BEGIN + IF(InputTime = TIME'HIGH) THEN + WRITE(outline, header); + ELSE + WRITE(outline, InputTime); + END IF; +END DelayValue; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintScheduleDataArray ( + ScheduleDataArray : IN VitalMemoryScheduleDataVectorType +) IS + VARIABLE outline1 : LINE; + VARIABLE outline2 : LINE; + VARIABLE value : TIME; + CONSTANT empty : STRING := " "; + CONSTANT header1 : STRING := "i Age PropDly RetainDly"; + CONSTANT header2 : STRING := "i Sc.Value Output Lastvalue Sc.Time"; +BEGIN + WRITE (outline1, empty); + WRITE (outline1, NOW); + outline2 := outline1; + WRITELINE (LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITE (outline1, header1); + outline2 := outline1; + WRITELINE (LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + FOR i IN ScheduleDataArray'RANGE LOOP + WRITE (outline1, i ); + WRITE (outline1, empty); + DelayValue(ScheduleDataArray(i).InputAge, outline1); + WRITE (outline1, empty); + DelayValue(ScheduleDataArray(i).PropDelay, outline1); + WRITE (outline1, empty); + DelayValue(ScheduleDataArray(i).OutputRetainDelay, outline1); + outline2 := outline1; + WRITELINE (LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + END LOOP; + WRITE (outline1, header2); + outline2 := outline1; + WRITELINE (LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + FOR i IN ScheduleDataArray'RANGE LOOP + WRITE (outline1, i ); + WRITE (outline1, empty); + WRITE (outline1, ScheduleDataArray(i).ScheduleValue); + WRITE (outline1, empty); + WRITE (outline1, ScheduleDataArray(i).OutputData); + WRITE (outline1, empty); + WRITE (outline1, ScheduleDataArray(i).LastOutputValue ); + WRITE (outline1, empty); + DelayValue(ScheduleDataArray(i).ScheduleTime, outline1); + outline2 := outline1; + WRITELINE (LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + END LOOP; + WRITE (outline1, empty); + WRITE (outline2, empty); + WRITELINE (LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (Output, outline2); + END IF; +END PrintScheduleDataArray; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintArcType ( + ArcType : IN VitalMemoryArcType +) IS + VARIABLE outline1, outline2 : LINE; + CONSTANT empty : STRING := " "; + CONSTANT cross : STRING := "CrossArc"; + CONSTANT para : STRING := "ParallelArc"; + CONSTANT sub : STRING := "SubWordArc"; + CONSTANT Header1 : STRING := "Path considered @ "; + CONSTANT Header2 : STRING := " is "; +BEGIN + WRITELINE (LogFile, outline1); + WRITE (outline1, header1); + WRITE (outline1, NOW); + WRITE (outline1, empty); + WRITE (outline1, header2); + WRITE (outline1, empty); + case ArcType is + WHEN CrossArc => + WRITE (outline1, cross); + WHEN ParallelArc => + WRITE (outline1, para); + WHEN SubwordArc => + WRITE (outline1, sub); + END CASE; + outline2 := outline1 ; + -- Appears on STD OUT + IF (PrintDebugMsg = '1') THEN + WRITELINE (Output, outline1); + END IF; + WRITELINE (LogFile, outline2); +END PrintArcType; + +-- ---------------------------------------------------------------------------- +-- This returns the value picked from the delay array +-- ---------------------------------------------------------------------------- +PROCEDURE PrintDelay ( + outbitpos : IN INTEGER; + InputArrayLow : IN INTEGER; + InputArrayHigh : IN INTEGER; + debugprop : IN VitalTimeArrayT; + debugretain : IN VitalTimeArrayT +) IS + VARIABLE outline1 : LINE; + VARIABLE outline2 : LINE; + VARIABLE outline3 : LINE; + VARIABLE outline4 : LINE; + VARIABLE outline5 : LINE; + VARIABLE outline6 : LINE; + CONSTANT empty : STRING := " "; + CONSTANT empty5 : STRING := " "; + CONSTANT header1 : STRING := "Prop. delays : "; + CONSTANT header2 : STRING := "Retain delays : "; + CONSTANT header3 : STRING := "output bit : "; +BEGIN + WRITE(outline1, header3); + WRITE(outline1, outbitpos); + outline2 := outline1; + WRITELINE(LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE(output, outline2); + END IF; + WRITE(outline1, header1); + WRITE (outline1, empty5); + FOR i IN InputArrayHigh DOWNTO InputArrayLow LOOP + DelayValue(debugprop(i), outline1); + WRITE(outline1, empty); + END LOOP; + outline2 := outline1; + WRITELINE(LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE(output, outline2); + END IF; + WRITE(outline1, header2); + WRITE (outline1, empty5); + FOR i in InputArrayHigh DOWNTO InputArrayLow LOOP + DelayValue(debugretain(i), outline1); + WRITE(outline1, empty); + END LOOP; + outline2 := outline1; + WRITELINE(LogFile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE(output, outline2); + END IF; +END PrintDelay; + +-- ---------------------------------------------------------------------------- +PROCEDURE DebugMsg1 IS + CONSTANT header1:STRING:= "******************************************"; + CONSTANT header2 :STRING:="Entering the process because of an i/p change"; + variable outline1, outline2 : LINE; +BEGIN + WRITE(outline1, header1); + outline2 := outline1; + WRITELINE (Logfile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITE(outline1, header2); + outline2 := outline1; + WRITELINE (Logfile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITE(outline1, header1); + outline2 := outline1; + WRITELINE (Logfile, outline1); + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; +END DebugMsg1; + +-- ---------------------------------------------------------------------------- +PROCEDURE ScheduleDebugMsg IS + CONSTANT header1 : STRING := "******************************************"; + CONSTANT header2 : STRING := "Finished executing all the procedures"; + VARIABLE outline1 : LINE; + VARIABLE outline2 : LINE; +BEGIN + WRITE(outline1, header1); + outline2 := outline1; + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITELINE (Logfile, outline1); + WRITE(outline1, header2); + outline2 := outline1; + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITELINE (Logfile, outline1); + WRITE(outline1, header1); + outline2 := outline1; + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITELINE (Logfile, outline1); +END ScheduleDebugMsg; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintInputName( + InputSignalName : IN STRING +) IS + VARIABLE outline1 : LINE; + VARIABLE outline2 : LINE; + CONSTANT header1 : STRING := "***Changing input is "; + CONSTANT header2 : STRING := "("; + CONSTANT header3 : STRING := ")"; + CONSTANT header4 : STRING := "****"; + CONSTANT header5 : STRING := "******************************************"; + CONSTANT header6 : STRING:="Entering the process because of an i/p change"; + CONSTANT empty : STRING := " "; +BEGIN + WRITE(outline1, header5); + outline2 := outline1; + WRITELINE (output, outline1); + WRITELINE (Logfile, outline2); + WRITE(outline1, header6); + outline2 := outline1; + WRITELINE (output, outline1); + WRITELINE (Logfile, outline2); + WRITE(outline1, header5); + outline2 := outline1; + WRITELINE (output, outline1); + WRITELINE (Logfile, outline2); + WRITE(outline1, header1); + WRITE(outline1, InputSignalName); + WRITE(outline1, empty); + WRITE(outline1, now); + WRITE(outline1, empty); + WRITE(outline1, header4); + WRITELINE (output, outline1); + WRITELINE (Logfile, outline2); +END PrintInputName; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintInputChangeTime( + ChangeTimeArray : IN VitalTimeArrayT +) IS + VARIABLE outline1 : LINE; + VARIABLE outline2 : LINE; + CONSTANT header5 : STRING := "*************************************"; + CONSTANT header6 : STRING:="ChangeTime Array : "; + CONSTANT empty : STRING := " "; +BEGIN + WRITE(outline1, header5); + outline2 := outline1; + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITELINE (Logfile, outline1); + WRITE(outline1, header6); + FOR i in ChangeTimeArray'range LOOP + WRITE(outline1, ChangeTimeArray(i)); + WRITE(outline1, empty); + END LOOP; + outline2 := outline1; + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITELINE (Logfile, outline1); + WRITE(outline1, header5); + outline2 := outline1; + IF (PrintDebugMsg = '1') THEN + WRITELINE (output, outline2); + END IF; + WRITELINE (Logfile, outline1); +END PrintInputChangeTime; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintInputChangeTime( + ChangeTime : IN Time +) IS + VARIABLE ChangeTimeArray : VitalTimeArrayT(0 DOWNTO 0); +BEGIN + ChangeTimeArray(0) := ChangeTime; + PrintInputChangeTime(ChangeTimeArray); +END PrintInputChangeTime; + +-- ---------------------------------------------------------------------------- +-- for debug purpose +CONSTANT MaxNoInputBits : INTEGER := 1000; + +TYPE VitalMemoryDelayType IS RECORD + PropDelay : TIME; + OutputRetainDelay : TIME; +END RECORD; + +-- ---------------------------------------------------------------------------- +-- PROCEDURE: IntToStr +-- +-- PARAMETERS: InputInt - Integer to be converted to String. +-- ResultStr - String buffer for converted Integer +-- AppendPos - Position in buffer to place result +-- +-- DESCRIPTION: This procedure is used to convert an input integer +-- into a string representation. The converted string +-- may be placed at a specific position in the result +-- buffer. +-- +-- ---------------------------------------------------------------------------- + +PROCEDURE IntToStr ( + InputInt : IN INTEGER ; + ResultStr : INOUT STRING ( 1 TO 256) ; + AppendPos : INOUT NATURAL +) IS + -- Look-up table. Given an int, we can get the character. + TYPE integer_table_type IS ARRAY (0 TO 9) OF CHARACTER ; + CONSTANT integer_table : integer_table_type := + ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ; + -- Local variables used in this function. + VARIABLE inpVal : INTEGER := inputInt ; + VARIABLE divisor : INTEGER := 10 ; + VARIABLE tmpStrIndex : INTEGER := 1 ; + VARIABLE tmpStr : STRING ( 1 TO 256 ) ; +BEGIN + IF ( inpVal = 0 ) THEN + tmpStr(tmpStrIndex) := integer_table ( 0 ) ; + tmpStrIndex := tmpStrIndex + 1 ; + ELSE + WHILE ( inpVal > 0 ) LOOP + tmpStr(tmpStrIndex) := integer_table (inpVal mod divisor); + tmpStrIndex := tmpStrIndex + 1 ; + inpVal := inpVal / divisor ; + END LOOP ; + END IF ; + IF (appendPos /= 1 ) THEN + resultStr(appendPos) := ',' ; + appendPos := appendPos + 1 ; + END IF ; + + FOR i IN tmpStrIndex-1 DOWNTO 1 LOOP + resultStr(appendPos) := tmpStr(i) ; + appendPos := appendPos + 1 ; + END LOOP ; +END IntToStr ; + +-- ---------------------------------------------------------------------------- +TYPE CheckType IS ( + SetupCheck, + HoldCheck, + RecoveryCheck, + RemovalCheck, + PulseWidCheck, + PeriodCheck +); + +TYPE CheckInfoType IS RECORD + Violation : BOOLEAN; + CheckKind : CheckType; + ObsTime : TIME; + ExpTime : TIME; + DetTime : TIME; + State : X01; +END RECORD; + +TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER; +TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4); + +CONSTANT LogicCvtTable : LogicCvtTableType + := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); +CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" ); + +TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN; + +-- last value, present value, edge symbol +CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType := + ( + 'X' => + ( 'X'=>( OTHERS => FALSE), + '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ), + '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE ) + ), + '0' => + ( 'X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ), + '0'=>( OTHERS => FALSE ), + '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE ) + ), + '1' => + ( 'X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ), + '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ), + '1'=>( OTHERS => FALSE ) + ) + ); + +-- ---------------------------------------------------------------------------- +FUNCTION Minimum ( + CONSTANT t1, t2 : IN TIME +) RETURN TIME IS +BEGIN + IF (t1 < t2) THEN RETURN (t1); ELSE RETURN (t2); END IF; +END Minimum; + +-- ---------------------------------------------------------------------------- +FUNCTION Maximum ( + CONSTANT t1, t2 : IN TIME +) RETURN TIME IS +BEGIN + IF (t1 < t2) THEN RETURN (t2); ELSE RETURN (t1); END IF; +END Maximum; + +-- ---------------------------------------------------------------------------- +-- FUNCTION: VitalMemoryCalcDelay +-- Description: Select Transition dependent Delay. +-- Used internally by VitalMemorySelectDelay. +-- ---------------------------------------------------------------------------- +FUNCTION VitalMemoryCalcDelay ( + CONSTANT NewVal : IN STD_ULOGIC := 'X'; + CONSTANT OldVal : IN STD_ULOGIC := 'X'; + CONSTANT Delay : IN VitalDelayType01ZX +) RETURN VitalMemoryDelayType IS + VARIABLE Result : VitalMemoryDelayType; +BEGIN + CASE Oldval IS + WHEN '0' | 'L' => + CASE Newval IS + WHEN '0' | 'L' => + Result.PropDelay := Delay(tr10); + WHEN '1' | 'H' => + Result.PropDelay := Delay(tr01); + WHEN 'Z' => + Result.PropDelay := Delay(tr0Z); + WHEN OTHERS => + Result.PropDelay := Minimum(Delay(tr01), Delay(tr0Z)); + END CASE; + Result.OutputRetainDelay := Delay(tr0X); + WHEN '1' | 'H' => + CASE Newval IS + WHEN '0' | 'L' => + Result.PropDelay := Delay(tr10); + WHEN '1' | 'H' => + Result.PropDelay := Delay(tr01); + WHEN 'Z' => + Result.PropDelay := Delay(tr1Z); + WHEN OTHERS => + Result.PropDelay := Minimum(Delay(tr10), Delay(tr1Z)); + END CASE; + Result.OutputRetainDelay := Delay(tr1X); + WHEN 'Z' => + CASE Newval IS + WHEN '0' | 'L' => + Result.PropDelay := Delay(trZ0); + WHEN '1' | 'H' => + Result.PropDelay := Delay(trZ1); + WHEN 'Z' => + Result.PropDelay := Maximum(Delay(tr1Z), Delay(tr0Z)); + WHEN OTHERS => + Result.PropDelay := Minimum(Delay(trZ1), Delay(trZ0)); + END CASE; + Result.OutputRetainDelay := Delay(trZX); + WHEN OTHERS => + CASE Newval IS + WHEN '0' | 'L' => + Result.PropDelay := Maximum(Delay(tr10), Delay(trZ0)); + WHEN '1' | 'H' => + Result.PropDelay := Maximum(Delay(tr01), Delay(trZ1)); + WHEN 'Z' => + Result.PropDelay := Maximum(Delay(tr1Z), Delay(tr0Z)); + WHEN OTHERS => + Result.PropDelay := Maximum(Delay(tr10), Delay(tr01)); + END CASE; + Result.OutputRetainDelay := Minimum(Delay(tr1X), Delay(tr0X)); + END CASE; + RETURN Result; +END VitalMemoryCalcDelay; + +-- ---------------------------------------------------------------------------- +FUNCTION VitalMemoryCalcDelay ( + CONSTANT NewVal : IN STD_ULOGIC := 'X'; + CONSTANT OldVal : IN STD_ULOGIC := 'X'; + CONSTANT Delay : IN VitalDelayType01Z +) RETURN VitalMemoryDelayType IS + VARIABLE Result : VitalMemoryDelayType; +BEGIN +CASE Oldval IS + WHEN '0' | 'L' => + CASE Newval IS + WHEN '0' | 'L' => Result.PropDelay := Delay(tr10); + WHEN '1' | 'H' => Result.PropDelay := Delay(tr01); + WHEN OTHERS => + Result.PropDelay := Minimum(Delay(tr01), Delay(tr10)); + END CASE; + Result.OutputRetainDelay := Delay(tr0Z); + WHEN '1' | 'H' => + CASE Newval IS + WHEN '0' | 'L' => Result.PropDelay := Delay(tr10); + WHEN '1' | 'H' => Result.PropDelay := Delay(tr01); + WHEN OTHERS => + Result.PropDelay := Minimum(Delay(tr10), Delay(tr01)); + END CASE; + Result.OutputRetainDelay := Delay(tr1Z); + WHEN OTHERS => + Result.PropDelay := Maximum(Delay(tr10),Delay(tr01)); + Result.OutputRetainDelay := Minimum(Delay(tr1Z),Delay(tr0Z)); + END CASE; + RETURN Result; +END VitalMemoryCalcDelay; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryUpdateInputChangeTime ( + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + VARIABLE NumBitsPerSubword : INTEGER +) IS + VARIABLE LastInputValue : STD_LOGIC_VECTOR(InputSignal'LENGTH-1 downto 0); + VARIABLE InSignalNorm : STD_LOGIC_VECTOR(InputSignal'LENGTH-1 downto 0); + VARIABLE ChangeTimeNorm : VitalTimeArrayT(InputSignal'LENGTH-1 downto 0); + VARIABLE BitsPerWord : INTEGER; +BEGIN + LastInputValue := InputSignal'LAST_VALUE; + IF NumBitsPerSubword = DefaultNumBitsPerSubword THEN + BitsPerWord := InputSignal'LENGTH; + ELSE + BitsPerWord := NumBitsPerSubword; + END IF; + + FOR i IN InSignalNorm'RANGE LOOP + IF (InSignalNorm(i) /= LastInputValue(i)) THEN + ChangeTimeNorm(i/BitsPerWord) := NOW - InputSignal'LAST_EVENT; + ELSE + ChangeTimeNorm(i/BitsPerWord) := InputChangeTimeArray(i); + END IF; + END LOOP; + + FOR i IN ChangeTimeNorm'RANGE LOOP + ChangeTimeNorm(i) := ChangeTimeNorm(i/BitsPerword); + END LOOP; + + InputChangeTimeArray := ChangeTimeNorm; + + -- for debug purpose only + PrintInputChangeTime(InputChangeTimeArray); +END VitalMemoryUpdateInputChangeTime; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryUpdateInputChangeTime +-- Description: Time since previous event for each bit of the input +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryUpdateInputChangeTime ( + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR +) IS + VARIABLE LastInputValue : STD_LOGIC_VECTOR(InputSignal'RANGE) ; +BEGIN + LastInputValue := InputSignal'LAST_VALUE; + FOR i IN InputSignal'RANGE LOOP + IF (InputSignal(i) /= LastInputValue(i)) THEN + InputChangeTimeArray(i) := NOW - InputSignal'LAST_EVENT; + END IF; + END LOOP; + -- for debug purpose only + PrintInputChangeTime(InputChangeTimeArray); +END VitalMemoryUpdateInputChangeTime; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryUpdateInputChangeTime ( + VARIABLE InputChangeTime : INOUT TIME; + SIGNAL InputSignal : IN STD_ULOGIC +) IS +BEGIN + InputChangeTime := NOW - InputSignal'LAST_EVENT; + -- for debug purpose only + PrintInputChangeTime(InputChangeTime); +END VitalMemoryUpdateInputChangeTime; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryExpandPortFlag ( + CONSTANT PortFlag : IN VitalPortFlagVectorType; + CONSTANT NumBitsPerSubword : IN INTEGER; + VARIABLE ExpandedPortFlag : OUT VitalPortFlagVectorType +) IS + VARIABLE PortFlagNorm : VitalPortFlagVectorType( + PortFlag'LENGTH-1 downto 0) := PortFlag; + VARIABLE ExpandedPortFlagNorm : VitalPortFlagVectorType( + ExpandedPortFlag'LENGTH-1 downto 0); + VARIABLE SubwordIndex : INTEGER; +BEGIN + FOR Index IN INTEGER RANGE 0 to ExpandedPortFlag'LENGTH-1 LOOP + IF NumBitsPerSubword = DefaultNumBitsPerSubword THEN + SubwordIndex := 0; + ELSE + SubwordIndex := Index / NumBitsPerSubword; + END IF; + ExpandedPortFlagNorm(Index) := PortFlagNorm(SubWordIndex); + END LOOP; + ExpandedPortFlag := ExpandedPortFlagNorm; +END VitalMemoryExpandPortFlag; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemorySelectDelay +-- Description : Select Propagation Delay. Used internally by +-- VitalMemoryAddPathDelay. +-- ---------------------------------------------------------------------------- + +-- ---------------------------------------------------------------------------- +-- VitalDelayArrayType01ZX +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySelectDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + VARIABLE InputChangeTimeArray : IN VitalTimeArrayT; + CONSTANT OutputSignalName : IN STRING :=""; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType; + CONSTANT PathConditionArray : IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN +) IS + VARIABLE InputArrayLow : INTEGER := 0; + VARIABLE InputArrayHigh : INTEGER := 0; + VARIABLE DelayArrayIndex : INTEGER := 0; + VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword; + VARIABLE NewValue : STD_ULOGIC; + VARIABLE OldValue : STD_ULOGIC; + VARIABLE OutputLength : INTEGER := 0; + VARIABLE OutArrayIndex : INTEGER; + VARIABLE PropDelay : TIME; + VARIABLE RetainDelay : TIME; + VARIABLE CurPropDelay : TIME; + VARIABLE CurRetainDelay : TIME; + VARIABLE InputAge : TIME; + VARIABLE CurInputAge : TIME; + VARIABLE InputChangeTimeNorm : VitalTimeArrayT( + InputChangeTimeArray'LENGTH-1 downto 0):=InputChangeTimeArray; + VARIABLE DelayArrayNorm : VitalDelayArrayType01ZX( + PathDelayArray'LENGTH-1 downto 0):= PathDelayArray; + VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType + (ScheduleDataArray'LENGTH-1 downto 0):= ScheduleDataArray; + + -- for debug purpose + VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0); + VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0); + +BEGIN + + -- for debug purpose + PrintArcType(ArcType); + + OutputLength := ScheduleDataArray'LENGTH; + FOR OutBitPos IN 0 to (OutputLength -1) LOOP + NEXT WHEN PathConditionArray(OutBitPos) = FALSE; + + NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue + = ScheduleDataArrayNorm(OutBitPos).OutputData) AND + (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW) AND + (OutputRetainFlag = FALSE )); + + NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData; + OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue; + PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay; + InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge; + RetainDelay:=ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay; + NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord; + + CASE ArcType IS + WHEN ParallelArc => + InputArrayLow := OutBitPos; + InputArrayHigh := OutBitPos; + DelayArrayIndex := OutBitPos; + WHEN CrossArc => + InputArrayLow := 0; + InputArrayHigh := InputChangeTimeArray'LENGTH - 1 ; + DelayArrayIndex := OutBitPos; + WHEN SubwordArc => + InputArrayLow := OutBitPos / NumBitsPerSubWord; + InputArrayHigh := OutBitPos / NumBitsPerSubWord; + DelayArrayIndex := OutBitPos + + (OutputLength * (OutBitPos / NumBitsPerSubWord)); + END CASE; + + FOR i IN InputArrayLow TO InputArrayHigh LOOP + (CurPropDelay,CurRetainDelay) := + VitalMemoryCalcDelay ( + NewValue, OldValue, DelayArrayNorm(DelayArrayIndex) + ); + IF (OutputRetainFlag = FALSE) THEN + CurRetainDelay := TIME'HIGH; + END IF; + + -- for debug purpose + debugprop(i) := CurPropDelay; + debugretain(i) := CurRetainDelay; + + IF ArcType = CrossArc THEN + DelayArrayIndex := DelayArrayIndex + OutputLength; + END IF; + + -- If there is one input change at a time, then choose the + -- delay from that input. If there is simultaneous input + -- change, then choose the minimum of propagation delays + + IF (InputChangeTimeNorm(i) < 0 ns)THEN + CurInputAge := TIME'HIGH; + ELSE + CurInputAge := NOW - InputChangeTimeNorm(i); + END IF; + + IF (CurInputAge < InputAge)THEN + PropDelay := CurPropDelay; + RetainDelay := CurRetainDelay; + InputAge := CurInputAge; + ELSIF (CurInputAge = InputAge)THEN + IF (CurPropDelay < PropDelay) THEN + PropDelay := CurPropDelay; + END IF; + IF (OutputRetainFlag = TRUE) THEN + IF (CurRetainDelay < RetainDelay) THEN + RetainDelay := CurRetainDelay; + END IF; + END IF; + END IF; + END LOOP; + + -- Store it back to data strucutre + ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay; + ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay:= RetainDelay; + ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge; + + -- for debug purpose + PrintDelay(outbitPos,InputArrayLow, InputArrayHigh, + debugprop, debugretain); + END LOOP; + + ScheduleDataArray := ScheduleDataArrayNorm; + +END VitalMemorySelectDelay; + +-- ---------------------------------------------------------------------------- +-- VitalDelayArrayType01Z +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySelectDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + VARIABLE InputChangeTimeArray : IN VitalTimeArrayT; + CONSTANT OutputSignalName : IN STRING :=""; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType; + CONSTANT PathConditionArray : IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN +) IS + VARIABLE InputArrayLow : INTEGER := 0; + VARIABLE InputArrayHigh : INTEGER := 0; + VARIABLE DelayArrayIndex : INTEGER := 0; + VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword; + VARIABLE NewValue : STD_ULOGIC; + VARIABLE OldValue : STD_ULOGIC; + VARIABLE OutputLength : INTEGER := 0; + VARIABLE OutArrayIndex : INTEGER; + VARIABLE PropDelay : TIME; + VARIABLE RetainDelay : TIME; + VARIABLE CurPropDelay : TIME; + VARIABLE CurRetainDelay : TIME; + VARIABLE InputAge : TIME; + VARIABLE CurInputAge : TIME; + VARIABLE InputChangeTimeNorm : VitalTimeArrayT( + InputChangeTimeArray'LENGTH-1 downto 0):=InputChangeTimeArray; + VARIABLE DelayArrayNorm : VitalDelayArrayType01Z( + PathDelayArray'LENGTH-1 downto 0):= PathDelayArray; + VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType + (ScheduleDataArray'LENGTH-1 downto 0):=ScheduleDataArray; + + -- for debug purpose + VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0); + VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0); +BEGIN + + -- for debug purpose + PrintArcType(ArcType); + + OutputLength := ScheduleDataArray'LENGTH; + FOR OutBitPos IN 0 to (OutputLength -1) LOOP + NEXT WHEN PathConditionArray(OutBitPos) = FALSE; + + NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue + = ScheduleDataArrayNorm(OutBitPos).OutputData) AND + (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW) AND + (OutputRetainFlag = FALSE)); + + NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData; + OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue; + PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay; + InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge; + RetainDelay:=ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay; + NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord; + + CASE ArcType IS + WHEN ParallelArc => + InputArrayLow := OutBitPos; + InputArrayHigh := OutBitPos; + DelayArrayIndex := OutBitPos; + WHEN CrossArc => + InputArrayLow := 0; + InputArrayHigh := InputChangeTimeArray'LENGTH-1; + DelayArrayIndex := OutBitPos; + WHEN SubwordArc => + InputArrayLow := OutBitPos / NumBitsPerSubWord; + InputArrayHigh := OutBitPos / NumBitsPerSubWord; + DelayArrayIndex := OutBitPos + + (OutputLength * (OutBitPos / NumBitsPerSubWord)); + END CASE; + + FOR i IN InputArrayLow TO InputArrayHigh LOOP + (CurPropDelay, CurRetainDelay) := + VitalMemoryCalcDelay ( + NewValue, OldValue, DelayArrayNorm(DelayArrayIndex) + ); + IF (OutputRetainFlag = FALSE) THEN + CurRetainDelay := TIME'HIGH; + END IF; + + -- for debug purpose + debugprop(i) := CurPropDelay; + debugretain(i) := CurRetainDelay; + + IF (ArcType = CrossArc) THEN + DelayArrayIndex := DelayArrayIndex + OutputLength; + END IF; + + -- If there is one input change at a time, then choose the + -- delay from that input. If there is simultaneous input + -- change, then choose the minimum of propagation delays + + IF (InputChangeTimeNorm(i) < 0 ns) THEN + CurInputAge := TIME'HIGH; + ELSE + CurInputAge := NOW - InputChangeTimeNorm(i); + END IF; + + IF (CurInputAge < InputAge) THEN + PropDelay := CurPropDelay; + RetainDelay := CurRetainDelay; + InputAge := CurInputAge; + ELSIF (CurInputAge = InputAge) THEN + IF (CurPropDelay < PropDelay) THEN + PropDelay := CurPropDelay; + END IF; + IF (OutputRetainFlag = TRUE) THEN + IF (CurRetainDelay < RetainDelay) THEN + RetainDelay := CurRetainDelay; + END IF; + END IF; + END IF; + END LOOP; + + -- Store it back to data strucutre + ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay; + ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay:= RetainDelay; + ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge; + + -- for debug purpose + PrintDelay(outbitPos, InputArrayLow, InputArrayHigh, + debugprop, debugretain); + END LOOP; + + ScheduleDataArray := ScheduleDataArrayNorm; + +END VitalMemorySelectDelay; + +-- ---------------------------------------------------------------------------- +-- VitalDelayArrayType01 +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySelectDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + VARIABLE InputChangeTimeArray : IN VitalTimeArrayT; + CONSTANT OutputSignalName : IN STRING :=""; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType; + CONSTANT PathConditionArray : IN VitalBoolArrayT +) IS + VARIABLE CurPathDelay : VitalMemoryDelayType; + VARIABLE InputArrayLow : INTEGER := 0; + VARIABLE InputArrayHigh : INTEGER := 0; + VARIABLE DelayArrayIndex : INTEGER := 0; + VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword; + VARIABLE NewValue : STD_ULOGIC; + VARIABLE OldValue : STD_ULOGIC; + VARIABLE OutputLength : INTEGER := 0; + VARIABLE OutArrayIndex : INTEGER; + VARIABLE PropDelay : TIME; + VARIABLE CurPropDelay : TIME; + VARIABLE InputAge : TIME; + VARIABLE CurInputAge : TIME; + VARIABLE InputChangeTimeNorm : VitalTimeArrayT( + InputChangeTimeArray'LENGTH-1 downto 0):= InputChangeTimeArray; + VARIABLE DelayArrayNorm : VitalDelayArrayType01( + PathDelayArray'LENGTH-1 downto 0):= PathDelayArray; + VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType + (ScheduleDataArray'LENGTH-1 downto 0):=ScheduleDataArray; + + -- for debug purpose + VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0); + VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0); +BEGIN + + -- for debug purpose + PrintArcType(ArcType); + + OutputLength := ScheduleDataArray'LENGTH; + FOR OutBitPos IN 0 to (OutputLength -1) LOOP + NEXT WHEN PathConditionArray(OutBitPos) = FALSE; + + NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue + = ScheduleDataArrayNorm(OutBitPos).OutputData) AND + (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW)); + + NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData; + OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue; + PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay; + InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge; + NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord; + + CASE ArcType IS + WHEN ParallelArc => + InputArrayLow := OutBitPos; + InputArrayHigh := OutBitPos; + DelayArrayIndex := OutBitPos; + WHEN CrossArc => + InputArrayLow := 0; + InputArrayHigh := InputChangeTimeArray'LENGTH-1; + DelayArrayIndex := OutBitPos; + WHEN SubwordArc => + InputArrayLow := OutBitPos / NumBitsPerSubWord; + InputArrayHigh := OutBitPos / NumBitsPerSubWord; + DelayArrayIndex := OutBitPos + + (OutputLength * (OutBitPos / NumBitsPerSubWord)); + END CASE; + + FOR i IN InputArrayLow TO InputArrayHigh LOOP + CurPropDelay:= VitalCalcDelay (NewValue, + OldValue, DelayArrayNorm(DelayArrayIndex)); + + -- for debug purpose + debugprop(i) := CurPropDelay; + debugretain(i) := TIME'HIGH; + + IF (ArcType = CrossArc) THEN + DelayArrayIndex := DelayArrayIndex + OutputLength; + END IF; + + -- If there is one input change at a time, then choose the + -- delay from that input. If there is simultaneous input + -- change, then choose the minimum of propagation delays + + IF (InputChangeTimeNorm(i) < 0 ns) THEN + CurInputAge := TIME'HIGH; + ELSE + CurInputAge := NOW - InputChangeTimeNorm(i); + END IF; + IF (CurInputAge < InputAge) THEN + PropDelay := CurPropDelay; + InputAge := CurInputAge; + ELSIF (CurInputAge = InputAge) THEN + IF (CurPropDelay < PropDelay) THEN + PropDelay := CurPropDelay; + END IF; + END IF; + END LOOP; + + -- Store it back to data strucutre + ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay; + ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge; + + -- for debug purpose + PrintDelay(outbitPos, InputArrayLow, InputArrayHigh, + debugprop, debugretain); + END LOOP; + + ScheduleDataArray := ScheduleDataArrayNorm; + +END VitalMemorySelectDelay; + +-- ---------------------------------------------------------------------------- +-- VitalDelayArrayType +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySelectDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + VARIABLE InputChangeTimeArray : IN VitalTimeArrayT; + CONSTANT OutputSignalName : IN STRING :=""; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType; + CONSTANT PathConditionArray : IN VitalBoolArrayT +) IS + VARIABLE InputArrayLow : INTEGER := 0; + VARIABLE InputArrayHigh : INTEGER := 0; + VARIABLE DelayArrayIndex : INTEGER := 0; + VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword; + VARIABLE NewValue : STD_ULOGIC; + VARIABLE OldValue : STD_ULOGIC; + VARIABLE OutputLength : INTEGER := 0; + VARIABLE OutArrayIndex : INTEGER; + VARIABLE PropDelay : TIME; + VARIABLE CurPropDelay : TIME; + VARIABLE InputAge : TIME; + VARIABLE CurInputAge : TIME; + VARIABLE InputChangeTimeNorm : VitalTimeArrayT( + InputChangeTimeArray'LENGTH-1 downto 0) := InputChangeTimeArray; + VARIABLE DelayArrayNorm : VitalDelayArrayType( + PathDelayArray'LENGTH-1 downto 0) := PathDelayArray; + VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType + (ScheduleDataArray'LENGTH-1 downto 0) := ScheduleDataArray; + + -- for debug purpose + VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0); + VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0); +BEGIN + + -- for debug purpose + PrintArcType(ArcType); + + OutputLength := ScheduleDataArray'LENGTH; + FOR OutBitPos IN 0 to (OutputLength -1) LOOP + NEXT WHEN PathConditionArray(OutBitPos) = FALSE; + + NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue + = ScheduleDataArrayNorm(OutBitPos).OutputData) AND + (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW)); + + NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData; + OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue; + PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay; + InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge; + NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord; + + CASE ArcType IS + WHEN ParallelArc => + InputArrayLow := OutBitPos; + InputArrayHigh := OutBitPos; + DelayArrayIndex := OutBitPos; + WHEN CrossArc => + InputArrayLow := 0; + InputArrayHigh := InputChangeTimeArray'LENGTH-1; + DelayArrayIndex := OutBitPos; + WHEN SubwordArc => + InputArrayLow := OutBitPos / NumBitsPerSubWord; + InputArrayHigh := OutBitPos / NumBitsPerSubWord; + DelayArrayIndex := OutBitPos + + (OutputLength * (OutBitPos / NumBitsPerSubWord)); + END CASE; + + FOR i IN InputArrayLow TO InputArrayHigh LOOP + CurPropDelay := VitalCalcDelay (NewValue, + OldValue, DelayArrayNorm(DelayArrayIndex)); + + -- for debug purpose + debugprop(i) := CurPropDelay; + debugretain(i) := TIME'HIGH; + + IF (ArcType = CrossArc) THEN + DelayArrayIndex := DelayArrayIndex + OutputLength; + END IF; + + -- If there is one input change at a time, then choose the + -- delay from that input. If there is simultaneous input + -- change, then choose the minimum of propagation delays + + IF (InputChangeTimeNorm(i) < 0 ns) THEN + CurInputAge := TIME'HIGH; + ELSE + CurInputAge := NOW - InputChangeTimeNorm(i); + END IF; + + IF (CurInputAge < InputAge) THEN + PropDelay := CurPropDelay; + InputAge := CurInputAge; + ELSIF (CurInputAge = InputAge) THEN + IF (CurPropDelay < PropDelay) THEN + PropDelay := CurPropDelay; + END IF; + END IF; + END LOOP; + + -- Store it back to data strucutre + ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay; + ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge; + + -- for debug purpose + PrintDelay(outbitPos, InputArrayLow, InputArrayHigh, + debugprop, debugretain); + END LOOP; + + ScheduleDataArray := ScheduleDataArrayNorm; + +END VitalMemorySelectDelay; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryInitPathDelay +-- Description: To initialize Schedule Data structure for an +-- output. +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryInitPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + VARIABLE OutputDataArray : IN STD_LOGIC_VECTOR; + CONSTANT NumBitsPerSubWord : IN INTEGER := DefaultNumBitsPerSubword +) IS +BEGIN + -- Initialize the ScheduleData Structure. + FOR i IN OutputDataArray'RANGE LOOP + ScheduleDataArray(i).OutputData := OutputDataArray(i); + ScheduleDataArray(i).PropDelay := TIME'HIGH; + ScheduleDataArray(i).OutputRetainDelay := TIME'HIGH; + ScheduleDataArray(i).InputAge := TIME'HIGH; + ScheduleDataArray(i).NumBitsPerSubWord := NumBitsPerSubWord; + + -- Update LastOutputValue of Output if the Output has + -- already been scheduled. + IF ((ScheduleDataArray(i).ScheduleValue /= OutputDataArray(i)) AND + (ScheduleDataArray(i).ScheduleTime <= NOW)) THEN + ScheduleDataArray(i).LastOutputValue + := ScheduleDataArray(i).ScheduleValue; + END IF; + END LOOP; + + -- for debug purpose + DebugMsg1; + PrintScheduleDataArray(ScheduleDataArray); + +END VitalMemoryInitPathDelay; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryInitPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + VARIABLE OutputData : IN STD_ULOGIC +) IS + VARIABLE ScheduledataArray: VitalMemoryScheduleDataVectorType + (0 downto 0); + VARIABLE OutputDataArray : STD_LOGIC_VECTOR(0 downto 0); +BEGIN + ScheduledataArray(0) := ScheduleData; + OutputDataArray(0) := OutputData; + VitalMemoryInitPathDelay ( + ScheduleDataArray => ScheduleDataArray, + OutputDataArray => OutputDataArray, + NumBitsPerSubWord => DefaultNumBitsPerSubword + ); + + -- for debug purpose + DebugMsg1; + PrintScheduleDataArray( ScheduleDataArray); + +END VitalMemoryInitPathDelay; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryAddPathDelay +-- Description: Declare a path for one scalar/vector input to +-- the output for which Schedule Data has been +-- initialized previously. +-- ---------------------------------------------------------------------------- + +-- ---------------------------------------------------------------------------- +-- #1 +-- DelayType - VitalMemoryDelayType +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelay : IN VitalDelayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +) IS + VARIABLE ScheduleDataArray : + VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE PathDelayArray : VitalDelayArrayType(0 downto 0); + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + ScheduleDataArray(0) := ScheduleData; + PathDelayArray(0) := PathDelay; + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #2 +-- DelayType - VitalMemoryDelayType +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray + ); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #3 +-- DelayType - VitalMemoryDelayType +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArrayNorm : + VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR Mem400 + VARIABLE PathConditionArrayExp : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #4 +-- DelayType - VitalMemoryDelayType +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +) IS + VARIABLE ScheduleDataArray : VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + + ScheduleDataArray(0) := ScheduleData; + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #5 +-- DelayType - VitalMemoryDelayType +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +) IS + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #6 +-- DelayType - VitalMemoryDelayType +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT +) IS + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArrayNorm : + VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400; + VARIABLE PathConditionArrayExp : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #7 +-- DelayType - VitalMemoryDelayType01 +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelay : IN VitalDelayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +) IS + VARIABLE ScheduleDataArray : + VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE PathDelayArray : VitalDelayArrayType01(0 downto 0); + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + ScheduleDataArray(0) := ScheduleData; + PathDelayArray(0) := PathDelay; + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #8 +-- DelayType - VitalMemoryDelayType01 +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #9 +-- DelayType - VitalMemoryDelayType01 +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray: IN VitalBoolArrayT +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArrayNorm : + VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400; + VARIABLE PathConditionArrayExp : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #10 +-- DelayType - VitalMemoryDelayType01 +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray: INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +)IS + VARIABLE ScheduleDataArray : + VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + ScheduleDataArray(0) := ScheduleData; + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #11 +-- DelayType - VitalMemoryDelayType01 +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +) IS + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #12 +-- DelayType - VitalMemoryDelayType01 +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT +) IS + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArrayNorm : + VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400; + VARIABLE PathConditionArrayExp : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #13 +-- DelayType - VitalMemoryDelayType01Z +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelay : IN VitalDelayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +) IS + VARIABLE ScheduleDataArray : + VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE PathDelayArray : VitalDelayArrayType01Z(0 downto 0); + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + ScheduleDataArray(0) := ScheduleData; + PathDelayArray(0) := PathDelay; + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #14 +-- DelayType - VitalMemoryDelayType01Z +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); + +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #15 +-- DelayType - VitalMemoryDelayType01Z +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray: IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArrayNorm : VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0); + VARIABLE PathConditionArrayExp : VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #16 +-- DelayType - VitalMemoryDelayType01Z +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +) IS + VARIABLE ScheduleDataArray : + VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + ScheduleDataArray(0) := ScheduleData; + NumBitsPerSubword := ScheduleDataArray(0).NumBitsPerSubword; + IF (OutputRetainBehavior = WordCorrupt AND + ArcType = ParallelArc AND + OutputRetainFlag = TRUE) THEN + VitalMemoryUpdateInputChangeTime( + InputChangeTimeArray, + InputSignal, + NumBitsPerSubword + ); + ELSE + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + END IF; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #17 +-- DelayType - VitalMemoryDelayType01Z +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +) IS + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword; + IF (OutputRetainBehavior = WordCorrupt AND + ArcType = ParallelArc AND + OutputRetainFlag = TRUE) THEN + VitalMemoryUpdateInputChangeTime( + InputChangeTimeArray, + InputSignal, + NumBitsPerSubword + ); + ELSE + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + END IF; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #18 +-- DelayType - VitalMemoryDelayType01Z +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +) IS +VARIABLE NumBitsPerSubword : INTEGER; +VARIABLE PathConditionArrayNorm : + VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0); +VARIABLE PathConditionArrayExp : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + IF (OutputRetainBehavior = WordCorrupt AND + ArcType = ParallelArc AND + OutputRetainFlag = TRUE) THEN + VitalMemoryUpdateInputChangeTime( + InputChangeTimeArray, InputSignal, + NumBitsPerSubword); + ELSE + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + END IF; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #19 +-- DelayType - VitalMemoryDelayType01XZ +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelay : IN VitalDelayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +) IS + VARIABLE ScheduleDataArray : + VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE PathDelayArray : VitalDelayArrayType01ZX(0 downto 0); + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + ScheduleDataArray(0) := ScheduleData; + PathDelayArray(0) := PathDelay; + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #20 +-- DelayType - VitalMemoryDelayType01XZ +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray :INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #21 +-- DelayType - VitalMemoryDelayType01XZ +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray :INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTime : INOUT TIME; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray: IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +) IS + VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0); + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArrayNorm : + VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400; + VARIABLE PathConditionArrayExp : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal); + InputChangeTimeArray(0) := InputChangeTime; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #22 +-- DelayType - VitalMemoryDelayType01XZ +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +) IS + VARIABLE ScheduleDataArray : + VitalMemoryScheduleDataVectorType(0 downto 0); + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0); +BEGIN + PathConditionArray(0) := PathCondition; + ScheduleDataArray(0) := ScheduleData; + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword; + IF (OutputRetainBehavior = WordCorrupt AND + ArcType = ParallelArc AND + OutputRetainFlag = TRUE) THEN + VitalMemoryUpdateInputChangeTime( + InputChangeTimeArray, InputSignal, + NumBitsPerSubword); + ELSE + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + END IF; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #23 +-- DelayType - VitalMemoryDelayType01XZ +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +) IS + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArray : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + FOR i IN PathConditionArray'RANGE LOOP + PathConditionArray(i) := PathCondition; + END LOOP; + + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword; + IF (OutputRetainBehavior = WordCorrupt AND + ArcType = ParallelArc AND + OutputRetainFlag = TRUE) THEN + VitalMemoryUpdateInputChangeTime( + InputChangeTimeArray, InputSignal, + NumBitsPerSubword); + ELSE + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + END IF; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArray, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- #24 +-- DelayType - VitalMemoryDelayType01XZ +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +) IS + VARIABLE NumBitsPerSubword : INTEGER; + VARIABLE PathConditionArrayNorm : + VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400; + VARIABLE PathConditionArrayExp : + VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0); +BEGIN + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword; + FOR i IN PathConditionArrayExp'RANGE LOOP + PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword); + END LOOP; + + IF (OutputRetainBehavior = WordCorrupt AND + ArcType = ParallelArc AND + OutputRetainFlag = TRUE) THEN + VitalMemoryUpdateInputChangeTime( + InputChangeTimeArray, InputSignal, + NumBitsPerSubword); + ELSE + VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal); + END IF; + + VitalMemorySelectDelay( + ScheduleDataArray, InputChangeTimeArray, + OutputSignalName, PathDelayArray, + ArcType, PathConditionArrayExp, OutputRetainFlag); +END VitalMemoryAddPathDelay; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemorySchedulePathDelay +-- Description: Schedule Output after Propagation Delay selected +-- by checking all the paths added thru' +-- VitalMemoryAddPathDelay. +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySchedulePathDelay ( + SIGNAL OutSignal : OUT STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag; + CONSTANT OutputMap : IN VitalOutputMapType:= VitalDefaultOutputMap; + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType +) IS + VARIABLE Age : TIME; + VARIABLE PropDelay : TIME; + VARIABLE RetainDelay : TIME; + VARIABLE Data : STD_ULOGIC; +BEGIN + IF (PortFlag.OutputDisable /= TRUE) THEN + FOR i IN ScheduleDataArray'RANGE LOOP + PropDelay := ScheduleDataArray(i).PropDelay; + RetainDelay := ScheduleDataArray(i).OutputRetainDelay; + + NEXT WHEN PropDelay = TIME'HIGH; + + Age := ScheduleDataArray(i).InputAge; + Data := ScheduleDataArray(i).OutputData; + + IF (Age < RetainDelay and RetainDelay < PropDelay) THEN + OutSignal(i) <= TRANSPORT 'X' AFTER (RetainDelay - Age); + END IF; + + IF (Age <= PropDelay) THEN + OutSignal(i)<= TRANSPORT OutputMap(Data)AFTER (PropDelay-Age); + ScheduleDataArray(i).ScheduleValue := Data; + ScheduleDataArray(i).ScheduleTime := NOW + PropDelay - Age; + END IF; + END LOOP; + END IF; + + -- for debug purpose + PrintScheduleDataArray(ScheduleDataArray); + + -- for debug purpose + ScheduleDebugMsg; +END VitalMemorySchedulePathDelay; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemorySchedulePathDelay +-- Description: Schedule Output after Propagation Delay selected +-- by checking all the paths added thru' +-- VitalMemoryAddPathDelay. +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySchedulePathDelay ( + SIGNAL OutSignal : OUT STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING :=""; + CONSTANT PortFlag : IN VitalPortFlagVectorType; + CONSTANT OutputMap : IN VitalOutputMapType:= VitalDefaultOutputMap; + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType +) IS + VARIABLE Age : TIME; + VARIABLE PropDelay : TIME; + VARIABLE RetainDelay : TIME; + VARIABLE Data : STD_ULOGIC; + VARIABLE ExpandedPortFlag : + VitalPortFlagVectorType(ScheduleDataArray'RANGE); + VARIABLE NumBitsPerSubword : INTEGER; +BEGIN + NumBitsPerSubword := + ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword; + VitalMemoryExpandPortFlag( PortFlag, NumBitsPerSubword, ExpandedPortFlag ); + FOR i IN ScheduleDataArray'RANGE LOOP + NEXT WHEN ExpandedPortFlag(i).OutputDisable = TRUE; + + PropDelay := ScheduleDataArray(i).PropDelay; + RetainDelay := ScheduleDataArray(i).OutputRetainDelay; + + NEXT WHEN PropDelay = TIME'HIGH; + + Age := ScheduleDataArray(i).InputAge; + Data := ScheduleDataArray(i).OutputData; + + IF (Age < RetainDelay and RetainDelay < PropDelay) THEN + OutSignal(i) <= TRANSPORT 'X' AFTER (RetainDelay - Age); + END IF; + + IF (Age <= PropDelay) THEN + OutSignal(i)<= TRANSPORT OutputMap(Data)AFTER (PropDelay-Age); + ScheduleDataArray(i).ScheduleValue := Data; + ScheduleDataArray(i).ScheduleTime := NOW + PropDelay - Age; + END IF; + END LOOP; + + -- for debug purpose + PrintScheduleDataArray(ScheduleDataArray); + + -- for debug purpose + ScheduleDebugMsg; +END VitalMemorySchedulePathDelay; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySchedulePathDelay ( + SIGNAL OutSignal : OUT STD_ULOGIC; + CONSTANT OutputSignalName: IN STRING :=""; + CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag; + CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap; + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType +) IS + VARIABLE Age : TIME; + VARIABLE PropDelay : TIME; + VARIABLE RetainDelay : TIME; + VARIABLE Data : STD_ULOGIC; + VARIABLE ScheduleDataArray : VitalMemoryScheduleDataVectorType (0 downto 0); +BEGIN + IF (PortFlag.OutputDisable /= TRUE) THEN + ScheduledataArray(0) := ScheduleData; + PropDelay := ScheduleDataArray(0).PropDelay; + RetainDelay := ScheduleDataArray(0).OutputRetainDelay; + Age := ScheduleDataArray(0).InputAge; + Data := ScheduleDataArray(0).OutputData; + + IF (Age < RetainDelay and RetainDelay < PropDelay) THEN + OutSignal <= TRANSPORT 'X' AFTER (RetainDelay - Age); + END IF; + + IF (Age <= PropDelay and PropDelay /= TIME'HIGH) THEN + OutSignal <= TRANSPORT OutputMap(Data) AFTER (PropDelay - Age); + ScheduleDataArray(0).ScheduleValue := Data; + ScheduleDataArray(0).ScheduleTime := NOW + PropDelay - Age; + END IF; + END IF; + + -- for debug purpose + PrintScheduleDataArray(ScheduleDataArray); + + -- for debug purpose + ScheduleDebugMsg; + +END VitalMemorySchedulePathDelay; + +-- ---------------------------------------------------------------------------- +-- Procedure : InternalTimingCheck +-- ---------------------------------------------------------------------------- +PROCEDURE InternalTimingCheck ( + CONSTANT TestSignal : IN std_ulogic; + CONSTANT RefSignal : IN std_ulogic; + CONSTANT TestDelay : IN TIME := 0 ns; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN TIME := 0 ns; + CONSTANT SetupLow : IN TIME := 0 ns; + CONSTANT HoldHigh : IN TIME := 0 ns; + CONSTANT HoldLow : IN TIME := 0 ns; + VARIABLE RefTime : IN TIME; + VARIABLE RefEdge : IN BOOLEAN; + VARIABLE TestTime : IN TIME; + VARIABLE TestEvent : IN BOOLEAN; + VARIABLE SetupEn : INOUT BOOLEAN; + VARIABLE HoldEn : INOUT BOOLEAN; + VARIABLE CheckInfo : INOUT CheckInfoType; + CONSTANT MsgOn : IN BOOLEAN +) IS + VARIABLE bias : TIME; + VARIABLE actualObsTime : TIME; + VARIABLE BC : TIME; + VARIABLE Message :LINE; +BEGIN + -- Check SETUP constraint + IF (RefEdge) THEN + IF (SetupEn) THEN + CheckInfo.ObsTime := RefTime - TestTime; + CheckInfo.State := To_X01(TestSignal); + CASE CheckInfo.State IS + WHEN '0' => + CheckInfo.ExpTime := SetupLow; + -- start of new code IR245-246 + BC := HoldHigh; + -- end of new code IR245-246 + WHEN '1' => + CheckInfo.ExpTime := SetupHigh; + -- start of new code IR245-246 + BC := HoldLow; + -- end of new code IR245-246 + WHEN 'X' => + CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow); + -- start of new code IR245-246 + BC := Maximum(HoldHigh,HoldLow); + -- end of new code IR245-246 + END CASE; + -- added the second condition for IR 245-246 + CheckInfo.Violation := + ((CheckInfo.ObsTime < CheckInfo.ExpTime) + AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns)))); + -- start of new code IR245-246 + IF (CheckInfo.ExpTime = 0 ns) THEN + CheckInfo.CheckKind := HoldCheck; + ELSE + CheckInfo.CheckKind := SetupCheck; + END IF; + -- end of new code IR245-246 + SetupEn := FALSE; + ELSE + CheckInfo.Violation := FALSE; + END IF; + + -- Check HOLD constraint + ELSIF (TestEvent) THEN + IF HoldEn THEN + CheckInfo.ObsTime := TestTime - RefTime; + CheckInfo.State := To_X01(TestSignal); + CASE CheckInfo.State IS + WHEN '0' => + CheckInfo.ExpTime := HoldHigh; + -- new code for unnamed IR + CheckInfo.State := '1'; + -- start of new code IR245-246 + BC := SetupLow; + -- end of new code IR245-246 + WHEN '1' => + CheckInfo.ExpTime := HoldLow; + -- new code for unnamed IR + CheckInfo.State := '0'; + -- start of new code IR245-246 + BC := SetupHigh; + -- end of new code IR245-246 + WHEN 'X' => + CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow); + -- start of new code IR245-246 + BC := Maximum(SetupHigh,SetupLow); + -- end of new code IR245-246 + END CASE; + -- added the second condition for IR 245-246 + CheckInfo.Violation := + ((CheckInfo.ObsTime < CheckInfo.ExpTime) + AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns)))); + -- start of new code IR245-246 + IF (CheckInfo.ExpTime = 0 ns) THEN + CheckInfo.CheckKind := SetupCheck; + ELSE + CheckInfo.CheckKind := HoldCheck; + END IF; + -- end of new code IR245-246 + HoldEn := NOT CheckInfo.Violation; + ELSE + CheckInfo.Violation := FALSE; + END IF; + ELSE + CheckInfo.Violation := FALSE; + END IF; + + -- Adjust report values to account for internal model delays + -- Note: TestDelay, RefDelay, TestTime, RefTime are non-negative + -- Note: bias may be negative or positive + IF MsgOn AND CheckInfo.Violation THEN + -- modified the code for correct reporting of violation in case of + -- order of signals being reversed because of internal delays + -- new variable + actualObsTime := (TestTime-TestDelay)-(RefTime-RefDelay); + bias := TestDelay - RefDelay; + IF (actualObsTime < 0 ns) THEN -- It should be a setup check + IF ( CheckInfo.CheckKind = HoldCheck) THEN + CheckInfo.CheckKind := SetupCheck; + CASE CheckInfo.State IS + WHEN '0' => CheckInfo.ExpTime := SetupLow; + WHEN '1' => CheckInfo.ExpTime := SetupHigh; + WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow); + END CASE; + END IF; + CheckInfo.ObsTime := -actualObsTime; + CheckInfo.ExpTime := CheckInfo.ExpTime + bias; + CheckInfo.DetTime := RefTime - RefDelay; + ELSE -- It should be a hold check + IF (CheckInfo.CheckKind = SetupCheck) THEN + CheckInfo.CheckKind := HoldCheck; + CASE CheckInfo.State IS + WHEN '0' => + CheckInfo.ExpTime := HoldHigh; + CheckInfo.State := '1'; + WHEN '1' => + CheckInfo.ExpTime := HoldLow; + CheckInfo.State := '0'; + WHEN 'X' => + CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow); + END CASE; + END IF; + CheckInfo.ObsTime := actualObsTime; + CheckInfo.ExpTime := CheckInfo.ExpTime - bias; + CheckInfo.DetTime := TestTime - TestDelay; + END IF; + END IF; +END InternalTimingCheck; + + +-- ---------------------------------------------------------------------------- +-- Setup and Hold Time Check Routine +-- ---------------------------------------------------------------------------- +PROCEDURE TimingArrayIndex ( + SIGNAL InputSignal : IN Std_logic_vector; + CONSTANT ArrayIndexNorm : IN INTEGER; + VARIABLE Index : OUT INTEGER +) IS +BEGIN + IF (InputSignal'LEFT > InputSignal'RIGHT) THEN + Index := ArrayIndexNorm + InputSignal'RIGHT; + ELSE + Index := InputSignal'RIGHT - ArrayIndexNorm; + END IF; +END TimingArrayIndex; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryReportViolation ( + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT CheckInfo : IN CheckInfoType; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) IS + VARIABLE Message : LINE; +BEGIN + IF (NOT CheckInfo.Violation) THEN + RETURN; + END IF; + Write ( Message, HeaderMsg ); + CASE CheckInfo.CheckKind IS + WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") ); + WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") ); + WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") ); + WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") ); + WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH ")); + WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") ); + END CASE; + Write ( Message, HiLoStr(CheckInfo.State) ); + Write ( Message, STRING'(" VIOLATION ON ") ); + Write ( Message, TestSignalName ); + IF (RefSignalName'LENGTH > 0) THEN + Write ( Message, STRING'(" WITH RESPECT TO ") ); + Write ( Message, RefSignalName ); + END IF; + Write ( Message, ';' & LF ); + Write ( Message, STRING'(" Expected := ") ); + Write ( Message, CheckInfo.ExpTime); + Write ( Message, STRING'("; Observed := ") ); + Write ( Message, CheckInfo.ObsTime); + Write ( Message, STRING'("; At : ") ); + Write ( Message, CheckInfo.DetTime); + ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity; + DEALLOCATE (Message); +END VitalMemoryReportViolation; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryReportViolation ( + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT TestArrayIndex : IN INTEGER; + CONSTANT RefArrayIndex : IN INTEGER; + SIGNAL TestSignal : IN std_logic_vector; + SIGNAL RefSignal : IN std_logic_vector; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT CheckInfo : IN CheckInfoType; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) IS + VARIABLE Message : LINE; + VARIABLE i, j : INTEGER; +BEGIN + IF (NOT CheckInfo.Violation) THEN + RETURN; + END IF; + + Write ( Message, HeaderMsg ); + CASE CheckInfo.CheckKind IS + WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") ); + WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") ); + WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH ")); + WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") ); + WHEN OTHERS => Write ( Message, STRING'(" UNKNOWN ") ); + END CASE; + Write ( Message, HiLoStr(CheckInfo.State) ); + Write ( Message, STRING'(" VIOLATION ON ") ); + Write ( Message, TestSignalName ); + TimingArrayIndex(TestSignal, TestArrayIndex, i); + CASE MsgFormat IS + WHEN Scalar => + NULL; + WHEN VectorEnum => + Write ( Message, '_'); + Write ( Message, i); + WHEN Vector => + Write ( Message, '('); + Write ( Message, i); + Write ( Message, ')'); + END CASE; + + IF (RefSignalName'LENGTH > 0) THEN + Write ( Message, STRING'(" WITH RESPECT TO ") ); + Write ( Message, RefSignalName ); + END IF; + + IF(RefSignal'LENGTH > 0) THEN + TimingArrayIndex(RefSignal, RefArrayIndex, j); + CASE MsgFormat IS + WHEN Scalar => + NULL; + WHEN VectorEnum => + Write ( Message, '_'); + Write ( Message, j); + WHEN Vector => + Write ( Message, '('); + Write ( Message, j); + Write ( Message, ')'); + END CASE; + END IF; + + Write ( Message, ';' & LF ); + Write ( Message, STRING'(" Expected := ") ); + Write ( Message, CheckInfo.ExpTime); + Write ( Message, STRING'("; Observed := ") ); + Write ( Message, CheckInfo.ObsTime); + Write ( Message, STRING'("; At : ") ); + Write ( Message, CheckInfo.DetTime); + + ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity; + + DEALLOCATE (Message); +END VitalMemoryReportViolation; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryReportViolation ( + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT TestArrayIndex : IN INTEGER; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT CheckInfo : IN CheckInfoType; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) IS + VARIABLE Message : LINE; +BEGIN + IF (NOT CheckInfo.Violation) THEN + RETURN; + END IF; + + Write ( Message, HeaderMsg ); + CASE CheckInfo.CheckKind IS + WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") ); + WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") ); + WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH ")); + WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") ); + WHEN OTHERS => Write ( Message, STRING'(" UNKNOWN ") ); + END CASE; + + Write ( Message, HiLoStr(CheckInfo.State) ); + Write ( Message, STRING'(" VIOLATION ON ") ); + Write ( Message, TestSignalName ); + + CASE MsgFormat IS + WHEN Scalar => + NULL; + WHEN VectorEnum => + Write ( Message, '_'); + Write ( Message, TestArrayIndex); + WHEN Vector => + Write ( Message, '('); + Write ( Message, TestArrayIndex); + Write ( Message, ')'); + END CASE; + + IF (RefSignalName'LENGTH > 0) THEN + Write ( Message, STRING'(" WITH RESPECT TO ") ); + Write ( Message, RefSignalName ); + END IF; + + Write ( Message, ';' & LF ); + Write ( Message, STRING'(" Expected := ") ); + Write ( Message, CheckInfo.ExpTime); + Write ( Message, STRING'("; Observed := ") ); + Write ( Message, CheckInfo.ObsTime); + Write ( Message, STRING'("; At : ") ); + Write ( Message, CheckInfo.DetTime); + + ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity; + + DEALLOCATE (Message); +END VitalMemoryReportViolation; + +-- ---------------------------------------------------------------------------- +FUNCTION VitalMemoryTimingDataInit +RETURN VitalMemoryTimingDataType IS +BEGIN + RETURN (FALSE, 'X', 0 ns, FALSE, 'X', 0 ns, FALSE, + NULL, NULL, NULL, NULL, NULL, NULL); +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalSetupHoldCheck +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayType; + CONSTANT SetupLow : IN VitalDelayType; + CONSTANT HoldHigh : IN VitalDelayType; + CONSTANT HoldLow : IN VitalDelayType; + CONSTANT CheckEnabled : IN VitalBoolArrayT; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + --IR252 3/23/98 + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +) IS + VARIABLE CheckInfo : CheckInfoType; + VARIABLE CheckEnScalar : BOOLEAN := FALSE; + VARIABLE ViolationInt : X01ArrayT(CheckEnabled'RANGE); + VARIABLE RefEdge : BOOLEAN; + VARIABLE TestEvent : BOOLEAN; + VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay); + VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); + VARIABLE bias : TIME; +BEGIN + + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLast := To_X01(TestSignal); + TimingData.RefLast := To_X01(RefSignal); + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), + RefTransition); + TimingData.RefLast := To_X01(RefSignal); + IF (RefEdge) THEN + TimingData.RefTime := NOW; + --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE); + --IR252 3/23/98 + TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; + TimingData.HoldEn := EnableHoldOnRef; + END IF; + + -- Detect test (data) changes and record the time of the last change + TestEvent := TimingData.TestLast /= To_X01Z(TestSignal); + TimingData.TestLast := To_X01Z(TestSignal); + IF TestEvent THEN + TimingData.SetupEn := EnableSetupOnTest ; --IR252 3/23/98 + TimingData.HoldEn := TimingData.HoldEn AND EnableHoldOnTest ; + --IR252 3/23/98 + TimingData.TestTime := NOW; + END IF; + + FOR i IN CheckEnabled'RANGE LOOP + IF CheckEnabled(i) = TRUE THEN + CheckEnScalar := TRUE; + END IF; + ViolationInt(i) := '0'; + END LOOP; + + IF (CheckEnScalar) THEN + InternalTimingCheck ( + TestSignal => TestSignal, + RefSignal => RefSignal, + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHigh, + SetupLow => SetupLow, + HoldHigh => HoldHigh, + HoldLow => HoldLow, + RefTime => TimingData.RefTime, + RefEdge => RefEdge, + TestTime => TimingData.TestTime, + TestEvent => TestEvent, + SetupEn => TimingData.SetupEn, + HoldEn => TimingData.HoldEn, + CheckInfo => CheckInfo, + MsgOn => MsgOn + ); + + -- Report any detected violations and set return violation flag + IF CheckInfo.Violation THEN + IF (MsgOn) THEN + VitalMemoryReportViolation (TestSignalName, RefSignalName, + HeaderMsg, CheckInfo, MsgSeverity ); + END IF; + IF (XOn) THEN + FOR i IN CheckEnabled'RANGE LOOP + IF CheckEnabled(i) = TRUE THEN + ViolationInt(i) := 'X'; + END IF; + END LOOP; + END IF; + END IF; + END IF; + Violation := ViolationInt; +END VitalMemorySetupHoldCheck; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayArraytype; + CONSTANT SetupLow : IN VitalDelayArraytype; + CONSTANT HoldHigh : IN VitalDelayArraytype; + CONSTANT HoldLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + --IR252 3/23/98 + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +) IS + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge : BOOLEAN; + VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE); + VARIABLE TestDly : TIME; + VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); + VARIABLE bias : TIME; +BEGIN + + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE); + TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE); + TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + FOR i IN TestSignal'RANGE LOOP + TimingData.TestLastA(i) := To_X01(TestSignal(i)); + END LOOP; + TimingData.RefLast := To_X01(RefSignal); + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), + RefTransition); + TimingData.RefLast := To_X01(RefSignal); + IF (RefEdge) THEN + TimingData.RefTime := NOW; + --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE); + --IR252 3/23/98 + FOR i IN TestSignal'RANGE LOOP + TimingData.SetupEnA(i) + := TimingData.SetupEnA(i) AND EnableSetupOnRef; + TimingData.HoldEnA(i) := EnableHoldOnRef; + END LOOP; + END IF; + + -- Detect test (data) changes and record the time of the last change + FOR i IN TestSignal'RANGE LOOP + TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i)); + TimingData.TestLastA(i) := To_X01Z(TestSignal(i)); + IF TestEvent(i) THEN + TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98 + TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ; + --IR252 3/23/98 + TimingData.TestTimeA(i) := NOW; + --TimingData.SetupEnA(i) := TRUE; + TimingData.TestTime := NOW; + END IF; + END LOOP; + + FOR i IN TestSignal'RANGE LOOP + Violation(i) := '0'; + + IF (CheckEnabled) THEN + TestDly := Maximum(0 ns, TestDelay(i)); + InternalTimingCheck ( + TestSignal => TestSignal(i), + RefSignal => RefSignal, + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHigh(i), + SetupLow => SetupLow(i), + HoldHigh => HoldHigh(i), + HoldLow => HoldLow(i), + RefTime => TimingData.RefTime, + RefEdge => RefEdge, + TestTime => TimingData.TestTimeA(i), + TestEvent => TestEvent(i), + SetupEn => TimingData.SetupEnA(i), + HoldEn => TimingData.HoldEnA(i), + CheckInfo => CheckInfo, + MsgOn => MsgOn + ); + + -- Report any detected violations and set return violation flag + IF CheckInfo.Violation THEN + IF (MsgOn) THEN + VitalMemoryReportViolation (TestSignalName, RefSignalName, i , + HeaderMsg, CheckInfo, MsgFormat, MsgSeverity ); + END IF; + IF (XOn) THEN + Violation(i) := 'X'; + END IF; + END IF; + END IF; + END LOOP; + +END VitalMemorySetupHoldCheck; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayArraytype; + CONSTANT SetupLow : IN VitalDelayArraytype; + CONSTANT HoldHigh : IN VitalDelayArraytype; + CONSTANT HoldLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN VitalBoolArrayT; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + --IR252 3/23/98 + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +) IS + VARIABLE CheckInfo : CheckInfoType; + VARIABLE ViolationInt : X01ArrayT(TestSignal'RANGE); + VARIABLE ViolationIntNorm: X01ArrayT(TestSignal'LENGTH-1 downto 0); + VARIABLE ViolationNorm : X01ArrayT(Violation'LENGTH-1 downto 0); + VARIABLE CheckEnInt : VitalBoolArrayT(TestSignal'RANGE); + VARIABLE CheckEnIntNorm : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0); + VARIABLE CheckEnScalar : BOOLEAN := FALSE; --Mem IR 401 + VARIABLE CheckEnabledNorm: VitalBoolArrayT(CheckEnabled'LENGTH-1 downto 0); + VARIABLE RefEdge : BOOLEAN; + VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE); + VARIABLE TestDly : TIME; + VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); + VARIABLE bias : TIME; +BEGIN + + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE); + TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE); + TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + FOR i IN TestSignal'RANGE LOOP + TimingData.TestLastA(i) := To_X01(TestSignal(i)); + END LOOP; + TimingData.RefLast := To_X01(RefSignal); + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), + RefTransition); + TimingData.RefLast := To_X01(RefSignal); + IF RefEdge THEN + TimingData.RefTime := NOW; + --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE); + --IR252 3/23/98 + FOR i IN TestSignal'RANGE LOOP + TimingData.SetupEnA(i) + := TimingData.SetupEnA(i) AND EnableSetupOnRef; + TimingData.HoldEnA(i) := EnableHoldOnRef; + END LOOP; + END IF; + + -- Detect test (data) changes and record the time of the last change + FOR i IN TestSignal'RANGE LOOP + TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i)); + TimingData.TestLastA(i) := To_X01Z(TestSignal(i)); + IF TestEvent(i) THEN + TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98 + TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ; + --IR252 3/23/98 + TimingData.TestTimeA(i) := NOW; + --TimingData.SetupEnA(i) := TRUE; + TimingData.TestTime := NOW; + END IF; + END LOOP; + + IF ArcType = CrossArc THEN + CheckEnScalar := FALSE; + FOR i IN CheckEnabled'RANGE LOOP + IF CheckEnabled(i) = TRUE THEN + CheckEnScalar := TRUE; + END IF; + END LOOP; + FOR i IN CheckEnInt'RANGE LOOP + CheckEnInt(i) := CheckEnScalar; + END LOOP; + ELSE + FOR i IN CheckEnIntNorm'RANGE LOOP + CheckEnIntNorm(i) := CheckEnabledNorm(i / NumBitsPerSubWord ); + END LOOP; + CheckEnInt := CheckEnIntNorm; + END IF; + + FOR i IN TestSignal'RANGE LOOP + ViolationInt(i) := '0'; + + IF (CheckEnInt(i)) THEN + TestDly := Maximum(0 ns, TestDelay(i)); + InternalTimingCheck ( + TestSignal => TestSignal(i), + RefSignal => RefSignal, + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHigh(i), + SetupLow => SetupLow(i), + HoldHigh => HoldHigh(i), + HoldLow => HoldLow(i), + RefTime => TimingData.RefTime, + RefEdge => RefEdge, + TestTime => TimingData.TestTimeA(i), + TestEvent => TestEvent(i), + SetupEn => TimingData.SetupEnA(i), + HoldEn => TimingData.HoldEnA(i), + CheckInfo => CheckInfo, + MsgOn => MsgOn + ); + + -- Report any detected violations and set return violation flag + IF CheckInfo.Violation THEN + IF (MsgOn) THEN + VitalMemoryReportViolation (TestSignalName, RefSignalName, i , + HeaderMsg, CheckInfo, MsgFormat, MsgSeverity ); + END IF; + IF (XOn) THEN + ViolationInt(i) := 'X'; + END IF; + END IF; + END IF; + END LOOP; + + IF (ViolationInt'LENGTH = Violation'LENGTH) THEN + Violation := ViolationInt; + ELSE + ViolationIntNorm := ViolationInt; + FOR i IN ViolationNorm'RANGE LOOP + ViolationNorm(i) := '0'; + END LOOP; + FOR i IN ViolationIntNorm'RANGE LOOP + IF (ViolationIntNorm(i) = 'X') THEN + ViolationNorm(i / NumBitsPerSubWord) := 'X'; + END IF; + END LOOP; + Violation := ViolationNorm; + END IF; + +END VitalMemorySetupHoldCheck; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + SIGNAL RefSignal : IN std_logic_vector; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN VitalDelayArraytype; + CONSTANT SetupHigh : IN VitalDelayArraytype; + CONSTANT SetupLow : IN VitalDelayArraytype; + CONSTANT HoldHigh : IN VitalDelayArraytype; + CONSTANT HoldLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + --IR252 3/23/98 + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +) IS + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0); + VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0); + VARIABLE TestDly : TIME; + VARIABLE RefDly : TIME; + VARIABLE bias : TIME; + VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH; + VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH; + VARIABLE NumChecks : NATURAL; + + VARIABLE ViolationTest : X01ArrayT(NumTestBits-1 downto 0); + VARIABLE ViolationRef : X01ArrayT(NumRefBits-1 downto 0); + + VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0) + := TestSignal; + VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0) + := TestDelay; + VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0) + := RefSignal; + VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0) + := RefDelay; + VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0) + := SetupHigh; + VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0) + := SetupLow; + VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0) + := HoldHigh; + VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0) + := HoldLow; + + VARIABLE RefBitLow : NATURAL; + VARIABLE RefBitHigh : NATURAL; + VARIABLE EnArrayIndex : NATURAL; + VARIABLE TimingArrayIndex: NATURAL; +BEGIN + + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0); + TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0); + TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0); + TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0); + IF (ArcType = CrossArc) THEN + NumChecks := RefSignal'LENGTH * TestSignal'LENGTH; + ELSE + NumChecks := TestSignal'LENGTH; + END IF; + TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0); + TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0); + + FOR i IN TestSignalNorm'RANGE LOOP + TimingData.TestLastA(i) := To_X01(TestSignalNorm(i)); + END LOOP; + + FOR i IN RefSignalNorm'RANGE LOOP + TimingData.RefLastA(i) := To_X01(RefSignalNorm(i)); + END LOOP; + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + FOR i IN RefSignalNorm'RANGE LOOP + RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i), + To_X01(RefSignalNorm(i)), RefTransition); + TimingData.RefLastA(i) := To_X01(RefSignalNorm(i)); + IF (RefEdge(i)) THEN + TimingData.RefTimeA(i) := NOW; + END IF; + END LOOP; + + -- Detect test (data) changes and record the time of the last change + FOR i IN TestSignalNorm'RANGE LOOP + TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i)); + TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i)); + IF (TestEvent(i)) THEN + TimingData.TestTimeA(i) := NOW; + END IF; + END LOOP; + + FOR i IN ViolationTest'RANGE LOOP + ViolationTest(i) := '0'; + END LOOP; + FOR i IN ViolationRef'RANGE LOOP + ViolationRef(i) := '0'; + END LOOP; + + FOR i IN TestSignalNorm'RANGE LOOP + IF (ArcType = CrossArc) THEN + FOR j IN RefSignalNorm'RANGE LOOP + IF (TestEvent(i)) THEN + --TimingData.SetupEnA(i*NumRefBits+j) := TRUE; + --IR252 + TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest; + TimingData.HoldEnA(i*NumRefBits+j) + := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest; + END IF; + IF (RefEdge(j)) THEN + --TimingData.HoldEnA(i*NumRefBits+j) := TRUE; + --IR252 + TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef; + TimingData.SetupEnA(i*NumRefBits+j) + := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef; + END IF; + END LOOP; + RefBitLow := 0; + RefBitHigh := NumRefBits-1; + TimingArrayIndex := i; + ELSE + IF ArcType = SubwordArc THEN + RefBitLow := i / NumBitsPerSubWord; + TimingArrayIndex := i + NumTestBits * RefBitLow; + ELSE + RefBitLow := i; + TimingArrayIndex := i; + END IF; + RefBitHigh := RefBitLow; + IF TestEvent(i) THEN + --TimingData.SetupEnA(i) := TRUE; + --IR252 + TimingData.SetupEnA(i) := EnableSetupOnTest; + TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest; + END IF; + IF RefEdge(RefBitLow) THEN + --TimingData.HoldEnA(i) := TRUE; + --IR252 + TimingData.HoldEnA(i) := EnableHoldOnRef; + TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef; + END IF; + END IF; + + EnArrayIndex := i; + FOR j IN RefBitLow to RefBitHigh LOOP + + IF (CheckEnabled) THEN + TestDly := Maximum(0 ns, TestDelayNorm(i)); + RefDly := Maximum(0 ns, RefDelayNorm(j)); + + InternalTimingCheck ( + TestSignal => TestSignalNorm(i), + RefSignal => RefSignalNorm(j), + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHighNorm(TimingArrayIndex), + SetupLow => SetupLowNorm(TimingArrayIndex), + HoldHigh => HoldHighNorm(TimingArrayIndex), + HoldLow => HoldLowNorm(TimingArrayIndex), + RefTime => TimingData.RefTimeA(j), + RefEdge => RefEdge(j), + TestTime => TimingData.TestTimeA(i), + TestEvent => TestEvent(i), + SetupEn => TimingData.SetupEnA(EnArrayIndex), + HoldEn => TimingData.HoldEnA(EnArrayIndex), + CheckInfo => CheckInfo, + MsgOn => MsgOn + ); + + -- Report any detected violations and set return violation flag + IF (CheckInfo.Violation) THEN + IF (MsgOn) THEN + VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j, + TestSignal, RefSignal, HeaderMsg, CheckInfo, + MsgFormat, MsgSeverity ); + END IF; + IF (XOn) THEN + ViolationTest(i) := 'X'; + ViolationRef(j) := 'X'; + END IF; + END IF; + END IF; + + TimingArrayIndex := TimingArrayIndex + NumRefBits; + EnArrayIndex := EnArrayIndex + NumRefBits; + + END LOOP; + END LOOP; + + IF (ArcType = CrossArc) THEN + Violation := ViolationRef; + ELSE + IF (Violation'LENGTH = ViolationRef'LENGTH) THEN + Violation := ViolationRef; + ELSE + Violation := ViolationTest; + END IF; + END IF; + +END VitalMemorySetupHoldCheck; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + SIGNAL RefSignal : IN std_logic_vector; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN VitalDelayArraytype; + CONSTANT SetupHigh : IN VitalDelayArraytype; + CONSTANT SetupLow : IN VitalDelayArraytype; + CONSTANT HoldHigh : IN VitalDelayArraytype; + CONSTANT HoldLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN VitalBoolArrayT; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + --IR252 3/23/98 + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +) IS + + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0); + VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0); + VARIABLE TestDly : TIME; + VARIABLE RefDly : TIME; + VARIABLE bias : TIME; + VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH; + VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH; + VARIABLE NumChecks : NATURAL; + + VARIABLE ViolationTest : X01ArrayT(NumTestBits-1 downto 0); + VARIABLE ViolationRef : X01ArrayT(NumRefBits-1 downto 0); + + VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0) + := TestSignal; + VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0) + := TestDelay; + VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0) + := RefSignal; + VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0) + := RefDelay; + VARIABLE CheckEnNorm : VitalBoolArrayT(NumRefBits-1 downto 0) + := CheckEnabled; + VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0) + := SetupHigh; + VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0) + := SetupLow; + VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0) + := HoldHigh; + VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0) + := HoldLow; + + VARIABLE RefBitLow : NATURAL; + VARIABLE RefBitHigh : NATURAL; + VARIABLE EnArrayIndex : NATURAL; + VARIABLE TimingArrayIndex: NATURAL; +BEGIN + + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0); + TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0); + TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0); + TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0); + IF ArcType = CrossArc THEN + NumChecks := RefSignal'LENGTH * TestSignal'LENGTH; + ELSE + NumChecks := TestSignal'LENGTH; + END IF; + TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0); + TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0); + + FOR i IN TestSignalNorm'RANGE LOOP + TimingData.TestLastA(i) := To_X01(TestSignalNorm(i)); + END LOOP; + + FOR i IN RefSignalNorm'RANGE LOOP + TimingData.RefLastA(i) := To_X01(RefSignalNorm(i)); + END LOOP; + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + FOR i IN RefSignalNorm'RANGE LOOP + RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i), + To_X01(RefSignalNorm(i)), RefTransition); + TimingData.RefLastA(i) := To_X01(RefSignalNorm(i)); + IF RefEdge(i) THEN + TimingData.RefTimeA(i) := NOW; + END IF; + END LOOP; + + -- Detect test (data) changes and record the time of the last change + FOR i IN TestSignalNorm'RANGE LOOP + TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i)); + TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i)); + IF TestEvent(i) THEN + TimingData.TestTimeA(i) := NOW; + END IF; + END LOOP; + + FOR i IN ViolationTest'RANGE LOOP + ViolationTest(i) := '0'; + END LOOP; + FOR i IN ViolationRef'RANGE LOOP + ViolationRef(i) := '0'; + END LOOP; + + FOR i IN TestSignalNorm'RANGE LOOP + IF (ArcType = CrossArc) THEN + FOR j IN RefSignalNorm'RANGE LOOP + IF (TestEvent(i)) THEN + --TimingData.SetupEnA(i*NumRefBits+j) := TRUE; + --IR252 + TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest; + TimingData.HoldEnA(i*NumRefBits+j) + := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest; + END IF; + IF (RefEdge(j)) THEN + --TimingData.HoldEnA(i*NumRefBits+j) := TRUE; + --IR252 + TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef; + TimingData.SetupEnA(i*NumRefBits+j) + := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef; + END IF; + END LOOP; + RefBitLow := 0; + RefBitHigh := NumRefBits-1; + TimingArrayIndex := i; + ELSE + IF (ArcType = SubwordArc) THEN + RefBitLow := i / NumBitsPerSubWord; + TimingArrayIndex := i + NumTestBits * RefBitLow; + ELSE + RefBitLow := i; + TimingArrayIndex := i; + END IF; + RefBitHigh := RefBitLow; + IF (TestEvent(i)) THEN + --TimingData.SetupEnA(i) := TRUE; + --IR252 + TimingData.SetupEnA(i) := EnableSetupOnTest; + TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest; + END IF; + IF (RefEdge(RefBitLow)) THEN + --TimingData.HoldEnA(i) := TRUE; + --IR252 + TimingData.HoldEnA(i) := EnableHoldOnRef; + TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef; + END IF; + END IF; + + EnArrayIndex := i; + FOR j IN RefBitLow to RefBitHigh LOOP + IF (CheckEnNorm(j)) THEN + TestDly := Maximum(0 ns, TestDelayNorm(i)); + RefDly := Maximum(0 ns, RefDelayNorm(j)); + + InternalTimingCheck ( + TestSignal => TestSignalNorm(i), + RefSignal => RefSignalNorm(j), + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHighNorm(TimingArrayIndex), + SetupLow => SetupLowNorm(TimingArrayIndex), + HoldHigh => HoldHighNorm(TimingArrayIndex), + HoldLow => HoldLowNorm(TimingArrayIndex), + RefTime => TimingData.RefTimeA(j), + RefEdge => RefEdge(j), + TestTime => TimingData.TestTimeA(i), + TestEvent => TestEvent(i), + SetupEn => TimingData.SetupEnA(EnArrayIndex), + HoldEn => TimingData.HoldEnA(EnArrayIndex), + CheckInfo => CheckInfo, + MsgOn => MsgOn + ); + + -- Report any detected violations and set return violation flag + IF (CheckInfo.Violation) THEN + IF (MsgOn) THEN + VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j, + TestSignal, RefSignal, HeaderMsg, CheckInfo, + MsgFormat, MsgSeverity ); + END IF; + + IF (XOn) THEN + ViolationTest(i) := 'X'; + ViolationRef(j) := 'X'; + END IF; + END IF; + END IF; + + TimingArrayIndex := TimingArrayIndex + NumRefBits; + EnArrayIndex := EnArrayIndex + NumRefBits; + END LOOP; + END LOOP; + + IF (ArcType = CrossArc) THEN + Violation := ViolationRef; + ELSE + IF (Violation'LENGTH = ViolationRef'LENGTH) THEN + Violation := ViolationRef; + ELSE + Violation := ViolationTest; + END IF; + END IF; + +END VitalMemorySetupHoldCheck; + +-- ---------------------------------------------------------------------------- +-- scalar violations not needed +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayArraytype; + CONSTANT SetupLow : IN VitalDelayArraytype; + CONSTANT HoldHigh : IN VitalDelayArraytype; + CONSTANT HoldLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + --IR252 3/23/98 + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +) IS + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge : BOOLEAN; + VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE); + VARIABLE TestDly : TIME; + VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); + VARIABLE bias : TIME; + +BEGIN + + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE); + TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE); + TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + FOR i IN TestSignal'RANGE LOOP + TimingData.TestLastA(i) := To_X01(TestSignal(i)); + END LOOP; + TimingData.RefLast := To_X01(RefSignal); + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), + RefTransition); + TimingData.RefLast := To_X01(RefSignal); + IF (RefEdge) THEN + TimingData.RefTime := NOW; + --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE); + --IR252 3/23/98 + FOR i IN TestSignal'RANGE LOOP + TimingData.SetupEnA(i) + := TimingData.SetupEnA(i) AND EnableSetupOnRef; + TimingData.HoldEnA(i) := EnableHoldOnRef; + END LOOP; + END IF; + + -- Detect test (data) changes and record the time of the last change + FOR i IN TestSignal'RANGE LOOP + TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i)); + TimingData.TestLastA(i) := To_X01Z(TestSignal(i)); + IF TestEvent(i) THEN + TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98 + TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ; + --IR252 3/23/98 + TimingData.TestTimeA(i) := NOW; + --TimingData.SetupEnA(i) := TRUE; + TimingData.TestTime := NOW; + END IF; + END LOOP; + + Violation := '0'; + FOR i IN TestSignal'RANGE LOOP + IF (CheckEnabled) THEN + TestDly := Maximum(0 ns, TestDelay(i)); + InternalTimingCheck ( + TestSignal => TestSignal(i), + RefSignal => RefSignal, + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHigh(i), + SetupLow => SetupLow(i), + HoldHigh => HoldHigh(i), + HoldLow => HoldLow(i), + RefTime => TimingData.RefTime, + RefEdge => RefEdge, + TestTime => TimingData.TestTimeA(i), + TestEvent => TestEvent(i), + SetupEn => TimingData.SetupEnA(i), + HoldEn => TimingData.HoldEnA(i), + CheckInfo => CheckInfo, + MsgOn => MsgOn + ); + + -- Report any detected violations and set return violation flag + IF CheckInfo.Violation THEN + IF (MsgOn) THEN + VitalMemoryReportViolation (TestSignalName, RefSignalName, i , + HeaderMsg, CheckInfo, MsgFormat, MsgSeverity ); + END IF; + IF (XOn) THEN + Violation := 'X'; + END IF; + END IF; + END IF; + END LOOP; + +END VitalMemorySetupHoldCheck; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + SIGNAL RefSignal : IN std_logic_vector; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN VitalDelayArraytype; + CONSTANT SetupHigh : IN VitalDelayArraytype; + CONSTANT SetupLow : IN VitalDelayArraytype; + CONSTANT HoldHigh : IN VitalDelayArraytype; + CONSTANT HoldLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + --IR252 3/23/98 + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +) IS + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0); + VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0); + VARIABLE TestDly : TIME; + VARIABLE RefDly : TIME; + VARIABLE bias : TIME; + VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH; + VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH; + VARIABLE NumChecks : NATURAL; + + VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0) + := TestSignal; + VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0) + := TestDelay; + VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0) + := RefSignal; + VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0) + := RefDelay; + VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0) + := SetupHigh; + VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0) + := SetupLow; + VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0) + := HoldHigh; + VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0) + := HoldLow; + + VARIABLE RefBitLow : NATURAL; + VARIABLE RefBitHigh : NATURAL; + VARIABLE EnArrayIndex : NATURAL; + VARIABLE TimingArrayIndex: NATURAL; +BEGIN + + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0); + TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0); + TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0); + TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0); + IF (ArcType = CrossArc) THEN + NumChecks := RefSignal'LENGTH * TestSignal'LENGTH; + ELSE + NumChecks := TestSignal'LENGTH; + END IF; + TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0); + TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0); + + FOR i IN TestSignalNorm'RANGE LOOP + TimingData.TestLastA(i) := To_X01(TestSignalNorm(i)); + END LOOP; + + FOR i IN RefSignalNorm'RANGE LOOP + TimingData.RefLastA(i) := To_X01(RefSignalNorm(i)); + END LOOP; + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + FOR i IN RefSignalNorm'RANGE LOOP + RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i), + To_X01(RefSignalNorm(i)), RefTransition); + TimingData.RefLastA(i) := To_X01(RefSignalNorm(i)); + IF (RefEdge(i)) THEN + TimingData.RefTimeA(i) := NOW; + END IF; + END LOOP; + + -- Detect test (data) changes and record the time of the last change + FOR i IN TestSignalNorm'RANGE LOOP + TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i)); + TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i)); + IF (TestEvent(i)) THEN + TimingData.TestTimeA(i) := NOW; + END IF; + END LOOP; + + FOR i IN TestSignalNorm'RANGE LOOP + IF (ArcType = CrossArc) THEN + FOR j IN RefSignalNorm'RANGE LOOP + IF (TestEvent(i)) THEN + --TimingData.SetupEnA(i*NumRefBits+j) := TRUE; + --IR252 + TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest; + TimingData.HoldEnA(i*NumRefBits+j) + := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest; + END IF; + IF (RefEdge(j)) THEN + --TimingData.HoldEnA(i*NumRefBits+j) := TRUE; + --IR252 + TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef; + TimingData.SetupEnA(i*NumRefBits+j) + := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef; + END IF; + END LOOP; + RefBitLow := 0; + RefBitHigh := NumRefBits-1; + TimingArrayIndex := i; + ELSE + IF (ArcType = SubwordArc) THEN + RefBitLow := i / NumBitsPerSubWord; + TimingArrayIndex := i + NumTestBits * RefBitLow; + ELSE + RefBitLow := i; + TimingArrayIndex := i; + END IF; + RefBitHigh := RefBitLow; + IF (TestEvent(i)) THEN + --TimingData.SetupEnA(i) := TRUE; + --IR252 + TimingData.SetupEnA(i) := EnableSetupOnTest; + TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest; + END IF; + IF (RefEdge(RefBitLow)) THEN + --TimingData.HoldEnA(i) := TRUE; + --IR252 + TimingData.HoldEnA(i) := EnableHoldOnRef; + TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef; + END IF; + END IF; + + EnArrayIndex := i; + Violation := '0'; + FOR j IN RefBitLow to RefBitHigh LOOP + + IF (CheckEnabled) THEN + TestDly := Maximum(0 ns, TestDelayNorm(i)); + RefDly := Maximum(0 ns, RefDelayNorm(j)); + + InternalTimingCheck ( + TestSignal => TestSignalNorm(i), + RefSignal => RefSignalNorm(j), + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHighNorm(TimingArrayIndex), + SetupLow => SetupLowNorm(TimingArrayIndex), + HoldHigh => HoldHighNorm(TimingArrayIndex), + HoldLow => HoldLowNorm(TimingArrayIndex), + RefTime => TimingData.RefTimeA(j), + RefEdge => RefEdge(j), + TestTime => TimingData.TestTimeA(i), + TestEvent => TestEvent(i), + SetupEn => TimingData.SetupEnA(EnArrayIndex), + HoldEn => TimingData.HoldEnA(EnArrayIndex), + CheckInfo => CheckInfo, + MsgOn => MsgOn + ); + + -- Report any detected violations and set return violation flag + IF (CheckInfo.Violation) THEN + IF (MsgOn) THEN + VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j, + TestSignal, RefSignal, HeaderMsg, CheckInfo, + MsgFormat, MsgSeverity ); + END IF; + + IF (XOn) THEN + Violation := 'X'; + END IF; + END IF; + END IF; + + TimingArrayIndex := TimingArrayIndex + NumRefBits; + EnArrayIndex := EnArrayIndex + NumRefBits; + + END LOOP; + END LOOP; + +END VitalMemorySetupHoldCheck; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryPeriodPulseCheck ( + VARIABLE Violation : OUT X01; + VARIABLE PeriodData : INOUT VitalPeriodDataArrayType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + CONSTANT Period : IN VitalDelayArraytype; + CONSTANT PulseWidthHigh : IN VitalDelayArraytype; + CONSTANT PulseWidthLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType +) IS + VARIABLE TestDly : VitalDelayType; + VARIABLE CheckInfo : CheckInfoType; + VARIABLE PeriodObs : VitalDelayType; + VARIABLE PulseTest : BOOLEAN; + VARIABLE PeriodTest: BOOLEAN; + VARIABLE TestValue : X01; +BEGIN + + -- Initialize for no violation + Violation := '0'; --MEM IR 402 + + FOR i IN TestSignal'RANGE LOOP + TestDly := Maximum(0 ns, TestDelay(i)); + TestValue := To_X01(TestSignal(i)); + + IF (PeriodData(i).NotFirstFlag = FALSE) THEN + PeriodData(i).Rise := -Maximum(Period(i), + Maximum(PulseWidthHigh(i),PulseWidthLow(i))); + PeriodData(i).Fall := -Maximum(Period(i), + Maximum(PulseWidthHigh(i),PulseWidthLow(i))); + PeriodData(i).Last := TestValue; + PeriodData(i).NotFirstFlag := TRUE; + END IF; + + -- Initialize for no violation + -- Violation := '0'; --Mem IR 402 + + -- No violation possible if no test signal change + NEXT WHEN (PeriodData(i).Last = TestValue); + + -- record starting pulse times + IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'P')) THEN + -- Compute period times, then record the High Rise Time + PeriodObs := NOW - PeriodData(i).Rise; + PeriodData(i).Rise := NOW; + PeriodTest := TRUE; + ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'N')) THEN + -- Compute period times, then record the Low Fall Time + PeriodObs := NOW - PeriodData(i).Fall; + PeriodData(i).Fall := NOW; + PeriodTest := TRUE; + ELSE + PeriodTest := FALSE; + END IF; + + -- do checks on pulse ends + IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'p')) THEN + -- Compute pulse times + CheckInfo.ObsTime := NOW - PeriodData(i).Fall; + CheckInfo.ExpTime := PulseWidthLow(i); + PulseTest := TRUE; + ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'n')) THEN + -- Compute pulse times + CheckInfo.ObsTime := NOW - PeriodData(i).Rise; + CheckInfo.ExpTime := PulseWidthHigh(i); + PulseTest := TRUE; + ELSE + PulseTest := FALSE; + END IF; + + IF (PulseTest AND CheckEnabled) THEN + -- Verify Pulse Width [ignore 1st edge] + IF (CheckInfo.ObsTime < CheckInfo.ExpTime) THEN + IF (XOn) THEN + Violation := 'X'; + END IF; + IF (MsgOn) THEN + CheckInfo.Violation := TRUE; + CheckInfo.CheckKind := PulseWidCheck; + CheckInfo.DetTime := NOW - TestDly; + CheckInfo.State := PeriodData(i).Last; + VitalMemoryReportViolation (TestSignalName, "", i, + HeaderMsg, CheckInfo, MsgFormat, MsgSeverity ); + END IF; -- MsgOn + END IF; + END IF; + + IF (PeriodTest AND CheckEnabled) THEN + -- Verify the Period [ignore 1st edge] + CheckInfo.ObsTime := PeriodObs; + CheckInfo.ExpTime := Period(i); + IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN + IF (XOn) THEN + Violation := 'X'; + END IF; + IF (MsgOn) THEN + CheckInfo.Violation := TRUE; + CheckInfo.CheckKind := PeriodCheck; + CheckInfo.DetTime := NOW - TestDly; + CheckInfo.State := TestValue; + VitalMemoryReportViolation (TestSignalName, "", i, + HeaderMsg, CheckInfo, MsgFormat, MsgSeverity ); + END IF; -- MsgOn + END IF; + END IF; + + PeriodData(i).Last := TestValue; + END LOOP; + +END VitalMemoryPeriodPulseCheck; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryPeriodPulseCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE PeriodData : INOUT VitalPeriodDataArrayType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArraytype; + CONSTANT Period : IN VitalDelayArraytype; + CONSTANT PulseWidthHigh : IN VitalDelayArraytype; + CONSTANT PulseWidthLow : IN VitalDelayArraytype; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType +)IS + VARIABLE TestDly : VitalDelayType; + VARIABLE CheckInfo : CheckInfoType; + VARIABLE PeriodObs : VitalDelayType; + VARIABLE PulseTest : BOOLEAN; + VARIABLE PeriodTest: BOOLEAN; + VARIABLE TestValue : X01; +BEGIN + + FOR i IN TestSignal'RANGE LOOP + TestDly := Maximum(0 ns, TestDelay(i)); + TestValue := To_X01(TestSignal(i)); + + IF (PeriodData(i).NotFirstFlag = FALSE) THEN + PeriodData(i).Rise := -Maximum(Period(i), + Maximum(PulseWidthHigh(i),PulseWidthLow(i))); + PeriodData(i).Fall := -Maximum(Period(i), + Maximum(PulseWidthHigh(i),PulseWidthLow(i))); + PeriodData(i).Last := TestValue; + PeriodData(i).NotFirstFlag := TRUE; + END IF; + + -- Initialize for no violation + Violation(i) := '0'; + + -- No violation possible if no test signal change + NEXT WHEN (PeriodData(i).Last = TestValue); + + -- record starting pulse times + IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'P')) THEN + -- Compute period times, then record the High Rise Time + PeriodObs := NOW - PeriodData(i).Rise; + PeriodData(i).Rise := NOW; + PeriodTest := TRUE; + ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'N')) THEN + -- Compute period times, then record the Low Fall Time + PeriodObs := NOW - PeriodData(i).Fall; + PeriodData(i).Fall := NOW; + PeriodTest := TRUE; + ELSE + PeriodTest := FALSE; + END IF; + + -- do checks on pulse ends + IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'p')) THEN + -- Compute pulse times + CheckInfo.ObsTime := NOW - PeriodData(i).Fall; + CheckInfo.ExpTime := PulseWidthLow(i); + PulseTest := TRUE; + ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'n')) THEN + -- Compute pulse times + CheckInfo.ObsTime := NOW - PeriodData(i).Rise; + CheckInfo.ExpTime := PulseWidthHigh(i); + PulseTest := TRUE; + ELSE + PulseTest := FALSE; + END IF; + + IF (PulseTest AND CheckEnabled) THEN + -- Verify Pulse Width [ignore 1st edge] + IF (CheckInfo.ObsTime < CheckInfo.ExpTime) THEN + IF (XOn) THEN + Violation(i) := 'X'; + END IF; + IF (MsgOn) THEN + CheckInfo.Violation := TRUE; + CheckInfo.CheckKind := PulseWidCheck; + CheckInfo.DetTime := NOW - TestDly; + CheckInfo.State := PeriodData(i).Last; + VitalMemoryReportViolation (TestSignalName, "", i, + HeaderMsg, CheckInfo, MsgFormat, MsgSeverity ); + END IF; -- MsgOn + END IF; + END IF; + + IF (PeriodTest AND CheckEnabled) THEN + -- Verify the Period [ignore 1st edge] + CheckInfo.ObsTime := PeriodObs; + CheckInfo.ExpTime := Period(i); + IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN + IF (XOn) THEN + Violation(i) := 'X'; + END IF; + IF (MsgOn) THEN + CheckInfo.Violation := TRUE; + CheckInfo.CheckKind := PeriodCheck; + CheckInfo.DetTime := NOW - TestDly; + CheckInfo.State := TestValue; + VitalMemoryReportViolation (TestSignalName, "", i, + HeaderMsg, CheckInfo, MsgFOrmat, MsgSeverity ); + END IF; -- MsgOn + END IF; + END IF; + + PeriodData(i).Last := TestValue; + END LOOP; + +END VitalMemoryPeriodPulseCheck; + +-- ---------------------------------------------------------------------------- +-- Functionality Section +-- ---------------------------------------------------------------------------- + +-- Look-up table. Given an int, we can get the 4-bit bit_vector. +TYPE HexToBitvTableType IS ARRAY (NATURAL RANGE <>) OF + std_logic_vector(3 DOWNTO 0) ; + +CONSTANT HexToBitvTable : HexToBitvTableType (0 TO 15) := + ( + "0000", "0001", "0010", "0011", + "0100", "0101", "0110", "0111", + "1000", "1001", "1010", "1011", + "1100", "1101", "1110", "1111" + ) ; + +-- ---------------------------------------------------------------------------- +-- Misc Utilities Local Utilities +-- ---------------------------------------------------------------------------- + +-- ---------------------------------------------------------------------------- +-- Procedure: IsSpace +-- Parameters: ch -- input character +-- Description: Returns TRUE or FALSE depending on the input character +-- being white space or not. +-- ---------------------------------------------------------------------------- +FUNCTION IsSpace (ch : character) +RETURN boolean IS +BEGIN + RETURN ((ch = ' ') OR (ch = CR) OR (ch = HT) OR (ch = NUL)); +END IsSpace; + +-- ---------------------------------------------------------------------------- +-- Procedure: LenOfString +-- Parameters: Str -- input string +-- Description: Returns the NATURAL length of the input string. +-- as terminated by the first NUL character. +-- ---------------------------------------------------------------------------- +FUNCTION LenOfString (Str : STRING) +RETURN NATURAL IS + VARIABLE StrRight : NATURAL; +BEGIN + StrRight := Str'RIGHT; + FOR i IN Str'RANGE LOOP + IF (Str(i) = NUL) THEN + StrRight := i - 1; + EXIT; + END IF; + END LOOP; + RETURN (StrRight); +END LenOfString; + +-- ---------------------------------------------------------------------------- +-- Procedure: HexToInt +-- Parameters: Hex -- input character or string +-- Description: Converts input character or string interpreted as a +-- hexadecimal representation to integer value. +-- ---------------------------------------------------------------------------- +FUNCTION HexToInt(Hex : CHARACTER) RETURN INTEGER IS + CONSTANT HexChars : STRING := "0123456789ABCDEFabcdef"; + CONSTANT XHiChar : CHARACTER := 'X'; + CONSTANT XLoChar : CHARACTER := 'x'; +BEGIN + IF (Hex = XLoChar OR Hex = XHiChar) THEN + RETURN (23); + END IF; + FOR i IN 1 TO 16 LOOP + IF(Hex = HexChars(i)) THEN + RETURN (i-1); + END IF; + END LOOP; + FOR i IN 17 TO 22 LOOP + IF (Hex = HexChars(i)) THEN + RETURN (i-7); + END IF; + END LOOP; + ASSERT FALSE REPORT + "Invalid character received by HexToInt function" + SEVERITY WARNING; + RETURN (0); +END HexToInt; + +-- ---------------------------------------------------------------------------- +FUNCTION HexToInt (Hex : STRING) RETURN INTEGER IS + VARIABLE Value : INTEGER := 0; + VARIABLE Length : INTEGER; +BEGIN + Length := LenOfString(hex); + IF (Length > 8) THEN + ASSERT FALSE REPORT + "Invalid string length received by HexToInt function" + SEVERITY WARNING; + ELSE + FOR i IN 1 TO Length LOOP + Value := Value + HexToInt(Hex(i)) * 16 ** (Length - i); + END LOOP; + END IF; + RETURN (Value); +END HexToInt; + +-- ---------------------------------------------------------------------------- +-- Procedure: HexToBitv +-- Parameters: Hex -- Input hex string +-- Description: Converts input hex string to a std_logic_vector +-- ---------------------------------------------------------------------------- +FUNCTION HexToBitv( + Hex : STRING +) RETURN std_logic_vector is + VARIABLE Index : INTEGER := 0 ; + VARIABLE ValHexToInt : INTEGER ; + VARIABLE BitsPerHex : INTEGER := 4 ; -- Denotes no. of bits per hex char. + VARIABLE HexLen : NATURAL := (BitsPerHex * LenOfString(Hex)) ; + VARIABLE TableVal : std_logic_vector(3 DOWNTO 0) ; + VARIABLE Result : std_logic_vector(HexLen-1 DOWNTO 0) ; +BEGIN + -- Assign 4-bit wide bit vector to result directly from a look-up table. + Index := 0 ; + WHILE ( Index < HexLen ) LOOP + ValHexToInt := HexToInt( Hex((HexLen - Index)/BitsPerHex ) ); + IF ( ValHexToInt = 23 ) THEN + TableVal := "XXXX"; + ELSE + -- Look up from the table. + TableVal := HexToBitvTable( ValHexToInt ) ; + END IF; + -- Assign now. + Result(Index+3 DOWNTO Index) := TableVal ; + -- Get ready for next block of 4-bits. + Index := Index + 4 ; + END LOOP ; + RETURN Result ; +END HexToBitv ; + +-- ---------------------------------------------------------------------------- +-- Procedure: BinToBitv +-- Parameters: Bin -- Input bin string +-- Description: Converts input bin string to a std_logic_vector +-- ---------------------------------------------------------------------------- +FUNCTION BinToBitv( + Bin : STRING +) RETURN std_logic_vector is + VARIABLE Index : INTEGER := 0 ; + VARIABLE Length : NATURAL := LenOfString(Bin); + VARIABLE BitVal : std_ulogic; + VARIABLE Result : std_logic_vector(Length-1 DOWNTO 0) ; +BEGIN + Index := 0 ; + WHILE ( Index < Length ) LOOP + IF (Bin(Length-Index) = '0') THEN + BitVal := '0'; + ELSIF (Bin(Length-Index) = '1') THEN + BitVal := '1'; + ELSE + BitVal := 'X'; + END IF ; + -- Assign now. + Result(Index) := BitVal ; + Index := Index + 1 ; + END LOOP ; + RETURN Result ; +END BinToBitv ; + +-- ---------------------------------------------------------------------------- +-- For Memory Table Modeling +-- ---------------------------------------------------------------------------- + +TYPE To_MemoryCharType IS ARRAY (VitalMemorySymbolType) OF CHARACTER; +CONSTANT To_MemoryChar : To_MemoryCharType := + ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v', + 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S', + 'g', 'u', 'i', 'G', 'U', 'I', + 'w', 's', + 'c', 'l', 'd', 'e', 'C', 'L', + 'M', 'm', 't' ); + +TYPE ValidMemoryTableInputType IS ARRAY (VitalMemorySymbolType) OF BOOLEAN; +CONSTANT ValidMemoryTableInput : ValidMemoryTableInputType := + -- '/', '\', 'P', 'N', 'r', 'f', + ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, + -- 'p', 'n', 'R', 'F', '^', 'v', + TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, + -- 'E', 'A', 'D', '*', + TRUE, TRUE, TRUE, TRUE, + -- 'X', '0', '1', '-', 'B', 'Z', + TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, + -- 'S', + TRUE, + -- 'g', 'u', 'i', 'G', 'U', 'I', + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + -- 'w', 's', + FALSE, FALSE, + -- 'c', 'l', 'd', 'e', 'C', 'L', + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + -- 'M', 'm', 't' + FALSE, FALSE, FALSE); + +TYPE MemoryTableMatchType IS ARRAY (X01,X01,VitalMemorySymbolType) OF BOOLEAN; +-- last value, present value, table symbol +CONSTANT MemoryTableMatch : MemoryTableMatchType := ( + ( -- X (lastvalue) + -- / \ P N r f + -- p n R F ^ v + -- E A D * + -- X 0 1 - B Z S + -- g u i G U I + -- w s + -- c l d e, C L + -- m t + ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE, + TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE), + ( FALSE,FALSE,FALSE,TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,TRUE, FALSE,TRUE, + TRUE, FALSE,TRUE, TRUE, + FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE), + ( FALSE,FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,FALSE,TRUE, FALSE,TRUE, FALSE, + TRUE, TRUE, FALSE,TRUE, + FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE) + ), + + (-- 0 (lastvalue) + -- / \ P N r f + -- p n R F ^ v + -- E A D * + -- X 0 1 - B Z S + -- g u i G U I + -- w s + -- c l d e, C L + -- m t + ( FALSE,FALSE,FALSE,FALSE,TRUE, FALSE, + TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,TRUE, FALSE,TRUE, + TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE), + ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE, + FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE), + ( TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, + TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,TRUE, + FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE) + ), + + (-- 1 (lastvalue) + -- / \ P N r f + -- p n R F ^ v + -- E A D * + -- X 0 1 - B Z S + -- g u i G U I + -- w s + -- c l d e, C L + -- m t + ( FALSE,FALSE,FALSE,FALSE,FALSE,TRUE , + FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, + FALSE,FALSE,TRUE, TRUE, + TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE), + ( FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, + FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,TRUE, + FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE), + ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE) + ) + ); + + +-- ---------------------------------------------------------------------------- +-- Error Message Types and Tables +-- ---------------------------------------------------------------------------- + +TYPE VitalMemoryErrorType IS ( + ErrGoodAddr, -- 'g' Good address (no transition) + ErrUnknAddr, -- 'u' 'X' levels in address (no transition) + ErrInvaAddr, -- 'i' Invalid address (no transition) + ErrGoodTrAddr, -- 'G' Good address (with transition) + ErrUnknTrAddr, -- 'U' 'X' levels in address (with transition) + ErrInvaTrAddr, -- 'I' Invalid address (with transition) + ErrWrDatMem, -- 'w' Writing data to memory + ErrNoChgMem, -- 's' Retaining previous memory contents + ErrCrAllMem, -- 'c' Corrupting entire memory with 'X' + ErrCrWrdMem, -- 'l' Corrupting a word in memory with 'X' + ErrCrBitMem, -- 'd' Corrupting a single bit in memory with 'X' + ErrCrDatMem, -- 'e' Corrupting a word with 'X' based on data in + ErrCrAllSubMem,-- 'C' Corrupting a sub-word entire memory with 'X' + ErrCrWrdSubMem,-- 'L' Corrupting a sub-word in memory with 'X' + ErrCrBitSubMem,-- 'D' Corrupting a single bit of a memory sub-word with 'X' + ErrCrDatSubMem,-- 'E' Corrupting a sub-word with 'X' based on data in + ErrCrWrdOut, -- 'l' Corrupting data out with 'X' + ErrCrBitOut, -- 'd' Corrupting a single bit of data out with 'X' + ErrCrDatOut, -- 'e' Corrupting data out with 'X' based on data in + ErrCrWrdSubOut,-- 'L' Corrupting data out sub-word with 'X' + ErrCrBitSubOut,-- 'D' Corrupting a single bit of data out sub-word with 'X' + ErrCrDatSubOut,-- 'E' Corrupting data out sub-word with 'X' based on data in + ErrImplOut, -- 'M' Implicit read from memory to data out + ErrReadOut, -- 'm' Reading data from memory to data out + ErrAssgOut, -- 't' Transferring from data in to data out + ErrAsgXOut, -- 'X' Assigning unknown level to data out + ErrAsg0Out, -- '0' Assigning low level to data out + ErrAsg1Out, -- '1' Assigning high level to data out + ErrAsgZOut, -- 'Z' Assigning high impedence to data out + ErrAsgSOut, -- 'S' Keeping data out at steady value + ErrAsgXMem, -- 'X' Assigning unknown level to memory location + ErrAsg0Mem, -- '0' Assigning low level to memory location + ErrAsg1Mem, -- '1' Assigning high level to memory location + ErrAsgZMem, -- 'Z' Assigning high impedence to memory location + ErrDefMemAct, -- No memory table match, using default action + ErrInitMem, -- Initialize memory contents + ErrMcpWrCont, -- Memory cross port to same port write contention + ErrMcpCpCont, -- Memory cross port read/write data/memory contention + ErrMcpCpRead, -- Memory cross port read to same port + ErrMcpRdWrCo, -- Memory cross port read/write data only contention + ErrMcpCpWrCont,-- Memory cross port to cross port write contention + ErrUnknMemDo, -- Unknown memory action + ErrUnknDatDo, -- Unknown data action + ErrUnknSymbol, -- Illegal memory symbol + ErrLdIlgArg, + ErrLdAddrRng, + ErrLdMemInfo, + ErrLdFileEmpty, + ErrPrintString +); + +TYPE VitalMemoryErrorSeverityType IS +ARRAY (VitalMemoryErrorType) OF SEVERITY_LEVEL; +CONSTANT VitalMemoryErrorSeverity : + VitalMemoryErrorSeverityType := ( + ErrGoodAddr => NOTE, + ErrUnknAddr => WARNING, + ErrInvaAddr => WARNING, + ErrGoodTrAddr => NOTE, + ErrUnknTrAddr => WARNING, + ErrInvaTrAddr => WARNING, + ErrWrDatMem => NOTE, + ErrNoChgMem => NOTE, + ErrCrAllMem => WARNING, + ErrCrWrdMem => WARNING, + ErrCrBitMem => WARNING, + ErrCrDatMem => WARNING, + ErrCrAllSubMem => WARNING, + ErrCrWrdSubMem => WARNING, + ErrCrBitSubMem => WARNING, + ErrCrDatSubMem => WARNING, + ErrCrWrdOut => WARNING, + ErrCrBitOut => WARNING, + ErrCrDatOut => WARNING, + ErrCrWrdSubOut => WARNING, + ErrCrBitSubOut => WARNING, + ErrCrDatSubOut => WARNING, + ErrImplOut => NOTE, + ErrReadOut => NOTE, + ErrAssgOut => NOTE, + ErrAsgXOut => NOTE, + ErrAsg0Out => NOTE, + ErrAsg1Out => NOTE, + ErrAsgZOut => NOTE, + ErrAsgSOut => NOTE, + ErrAsgXMem => NOTE, + ErrAsg0Mem => NOTE, + ErrAsg1Mem => NOTE, + ErrAsgZMem => NOTE, + ErrDefMemAct => NOTE, + ErrInitMem => NOTE, + ErrMcpWrCont => WARNING, + ErrMcpCpCont => WARNING, + ErrMcpCpRead => WARNING, + ErrMcpRdWrCo => WARNING, + ErrMcpCpWrCont => WARNING, + ErrUnknMemDo => ERROR, + ErrUnknDatDo => ERROR, + ErrUnknSymbol => ERROR, + ErrLdIlgArg => ERROR, + ErrLdAddrRng => WARNING, + ErrLdMemInfo => NOTE, + ErrLdFileEmpty => ERROR, + ErrPrintString => WARNING + ); + +-- ---------------------------------------------------------------------------- +CONSTANT MsgGoodAddr : STRING + := "Good address (no transition)"; +CONSTANT MsgUnknAddr : STRING + := "Unknown address (no transition)"; +CONSTANT MsgInvaAddr : STRING + := "Invalid address (no transition)"; +CONSTANT MsgGoodTrAddr : STRING + := "Good address (with transition)"; +CONSTANT MsgUnknTrAddr : STRING + := "Unknown address (with transition)"; +CONSTANT MsgInvaTrAddr : STRING + := "Invalid address (with transition)"; +CONSTANT MsgNoChgMem : STRING + := "Retaining previous memory contents"; +CONSTANT MsgWrDatMem : STRING + := "Writing data to memory"; +CONSTANT MsgCrAllMem : STRING + := "Corrupting entire memory with 'X'"; +CONSTANT MsgCrWrdMem : STRING + := "Corrupting a word in memory with 'X'"; +CONSTANT MsgCrBitMem : STRING + := "Corrupting a single bit in memory with 'X'"; +CONSTANT MsgCrDatMem : STRING + := "Corrupting a word with 'X' based on data in"; +CONSTANT MsgCrAllSubMem : STRING + := "Corrupting a sub-word entire memory with 'X'"; +CONSTANT MsgCrWrdSubMem : STRING + := "Corrupting a sub-word in memory with 'X'"; +CONSTANT MsgCrBitSubMem : STRING + := "Corrupting a single bit of a sub-word with 'X'"; +CONSTANT MsgCrDatSubMem : STRING + := "Corrupting a sub-word with 'X' based on data in"; +CONSTANT MsgCrWrdOut : STRING + := "Corrupting data out with 'X'"; +CONSTANT MsgCrBitOut : STRING + := "Corrupting a single bit of data out with 'X'"; +CONSTANT MsgCrDatOut : STRING + := "Corrupting data out with 'X' based on data in"; +CONSTANT MsgCrWrdSubOut : STRING + := "Corrupting data out sub-word with 'X'"; +CONSTANT MsgCrBitSubOut : STRING + := "Corrupting a single bit of data out sub-word with 'X'"; +CONSTANT MsgCrDatSubOut : STRING + := "Corrupting data out sub-word with 'X' based on data in"; +CONSTANT MsgImplOut : STRING + := "Implicit read from memory to data out"; +CONSTANT MsgReadOut : STRING + := "Reading data from memory to data out"; +CONSTANT MsgAssgOut : STRING + := "Transferring from data in to data out"; +CONSTANT MsgAsgXOut : STRING + := "Assigning unknown level to data out"; +CONSTANT MsgAsg0Out : STRING + := "Assigning low level to data out"; +CONSTANT MsgAsg1Out : STRING + := "Assigning high level to data out"; +CONSTANT MsgAsgZOut : STRING + := "Assigning high impedance to data out"; +CONSTANT MsgAsgSOut : STRING + := "Keeping data out at steady value"; +CONSTANT MsgAsgXMem : STRING + := "Assigning unknown level to memory location"; +CONSTANT MsgAsg0Mem : STRING + := "Assigning low level to memory location"; +CONSTANT MsgAsg1Mem : STRING + := "Assigning high level to memory location"; +CONSTANT MsgAsgZMem : STRING + := "Assigning high impedance to memory location"; +CONSTANT MsgDefMemAct : STRING + := "No memory table match, using default action"; +CONSTANT MsgInitMem : STRING + := "Initializing memory contents"; +CONSTANT MsgMcpWrCont : STRING + := "Same port write contention"; +CONSTANT MsgMcpCpCont : STRING + := "Cross port read/write data/memory contention"; +CONSTANT MsgMcpCpRead : STRING + := "Cross port read to same port"; +CONSTANT MsgMcpRdWrCo : STRING + := "Cross port read/write data only contention"; +CONSTANT MsgMcpCpWrCont : STRING + := "Cross port write contention"; +CONSTANT MsgUnknMemDo : STRING + := "Unknown memory action"; +CONSTANT MsgUnknDatDo : STRING + := "Unknown data action"; +CONSTANT MsgUnknSymbol : STRING + := "Illegal memory symbol"; + +CONSTANT MsgLdIlgArg : STRING + := "Illegal bit arguments while loading memory."; +CONSTANT MsgLdMemInfo : STRING + := "Loading data from the file into memory."; +CONSTANT MsgLdAddrRng : STRING + := "Address out of range while loading memory."; +CONSTANT MsgLdFileEmpty : STRING + := "Memory load file is empty."; +CONSTANT MsgPrintString : STRING + := ""; + +CONSTANT MsgUnknown : STRING + := "Unknown error message."; + +CONSTANT MsgVMT : STRING + := "VitalMemoryTable"; +CONSTANT MsgVMV : STRING + := "VitalMemoryViolation"; +CONSTANT MsgVDM : STRING + := "VitalDeclareMemory"; +CONSTANT MsgVMCP : STRING + := "VitalMemoryCrossPorts"; + +-- ---------------------------------------------------------------------------- +-- LOCAL Utilities +-- ---------------------------------------------------------------------------- + +-- ---------------------------------------------------------------------------- +-- Procedure: MemoryMessage +-- Parameters: ErrorId -- Input error code +-- Description: This function looks up the input error code and returns +-- the string value of the associated message. +-- ---------------------------------------------------------------------------- + +FUNCTION MemoryMessage ( + CONSTANT ErrorId : IN VitalMemoryErrorType +) RETURN STRING IS +BEGIN + CASE ErrorId IS + WHEN ErrGoodAddr => RETURN MsgGoodAddr ; + WHEN ErrUnknAddr => RETURN MsgUnknAddr ; + WHEN ErrInvaAddr => RETURN MsgInvaAddr ; + WHEN ErrGoodTrAddr => RETURN MsgGoodTrAddr ; + WHEN ErrUnknTrAddr => RETURN MsgUnknTrAddr ; + WHEN ErrInvaTrAddr => RETURN MsgInvaTrAddr ; + WHEN ErrWrDatMem => RETURN MsgWrDatMem ; + WHEN ErrNoChgMem => RETURN MsgNoChgMem ; + WHEN ErrCrAllMem => RETURN MsgCrAllMem ; + WHEN ErrCrWrdMem => RETURN MsgCrWrdMem ; + WHEN ErrCrBitMem => RETURN MsgCrBitMem ; + WHEN ErrCrDatMem => RETURN MsgCrDatMem ; + WHEN ErrCrAllSubMem => RETURN MsgCrAllSubMem; + WHEN ErrCrWrdSubMem => RETURN MsgCrWrdSubMem; + WHEN ErrCrBitSubMem => RETURN MsgCrBitSubMem; + WHEN ErrCrDatSubMem => RETURN MsgCrDatSubMem; + WHEN ErrCrWrdOut => RETURN MsgCrWrdOut ; + WHEN ErrCrBitOut => RETURN MsgCrBitOut ; + WHEN ErrCrDatOut => RETURN MsgCrDatOut ; + WHEN ErrCrWrdSubOut => RETURN MsgCrWrdSubOut; + WHEN ErrCrBitSubOut => RETURN MsgCrBitSubOut; + WHEN ErrCrDatSubOut => RETURN MsgCrDatSubOut; + WHEN ErrImplOut => RETURN MsgImplOut ; + WHEN ErrReadOut => RETURN MsgReadOut ; + WHEN ErrAssgOut => RETURN MsgAssgOut ; + WHEN ErrAsgXOut => RETURN MsgAsgXOut ; + WHEN ErrAsg0Out => RETURN MsgAsg0Out ; + WHEN ErrAsg1Out => RETURN MsgAsg1Out ; + WHEN ErrAsgZOut => RETURN MsgAsgZOut ; + WHEN ErrAsgSOut => RETURN MsgAsgSOut ; + WHEN ErrAsgXMem => RETURN MsgAsgXMem ; + WHEN ErrAsg0Mem => RETURN MsgAsg0Mem ; + WHEN ErrAsg1Mem => RETURN MsgAsg1Mem ; + WHEN ErrAsgZMem => RETURN MsgAsgZMem ; + WHEN ErrDefMemAct => RETURN MsgDefMemAct ; + WHEN ErrInitMem => RETURN MsgInitMem ; + WHEN ErrMcpWrCont => RETURN MsgMcpWrCont ; + WHEN ErrMcpCpCont => RETURN MsgMcpCpCont ; + WHEN ErrMcpCpRead => RETURN MsgMcpCpRead ; + WHEN ErrMcpRdWrCo => RETURN MsgMcpRdWrCo ; + WHEN ErrMcpCpWrCont => RETURN MsgMcpCpWrCont; + WHEN ErrUnknMemDo => RETURN MsgUnknMemDo ; + WHEN ErrUnknDatDo => RETURN MsgUnknDatDo ; + WHEN ErrUnknSymbol => RETURN MsgUnknSymbol ; + WHEN ErrLdIlgArg => RETURN MsgLdIlgArg ; + WHEN ErrLdAddrRng => RETURN MsgLdAddrRng ; + WHEN ErrLdMemInfo => RETURN MsgLdMemInfo ; + WHEN ErrLdFileEmpty => RETURN MsgLdFileEmpty; + WHEN ErrPrintString => RETURN MsgPrintString; + WHEN OTHERS => RETURN MsgUnknown ; + END CASE; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: PrintMemoryMessage +-- Parameters: Routine -- String identifying the calling routine +-- ErrorId -- Input error code for message lookup +-- Info -- Output string or character +-- InfoStr -- Additional output string +-- Info1 -- Additional output integer +-- Info2 -- Additional output integer +-- Info3 -- Additional output integer +-- Description: This procedure prints out a memory status message +-- given the input error id and other status information. +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalMemoryErrorType +) IS +BEGIN + ASSERT FALSE + REPORT Routine & ": " & MemoryMessage(ErrorId) + SEVERITY VitalMemoryErrorSeverity(ErrorId); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalMemoryErrorType; + CONSTANT Info : IN STRING +) IS +BEGIN + ASSERT FALSE + REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info + SEVERITY VitalMemoryErrorSeverity(ErrorId); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalMemoryErrorType; + CONSTANT Info1 : IN STRING; + CONSTANT Info2 : IN STRING +) IS +BEGIN + ASSERT FALSE + REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info1 & " " & Info2 + SEVERITY VitalMemoryErrorSeverity(ErrorId); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalMemoryErrorType; + CONSTANT Info : IN CHARACTER +) IS +BEGIN + ASSERT FALSE + REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info + SEVERITY VitalMemoryErrorSeverity(ErrorId); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalMemoryErrorType; + CONSTANT InfoStr : IN STRING; + CONSTANT Info1 : IN NATURAL +) IS + VARIABLE TmpStr : STRING ( 1 TO 256 ) ; + VARIABLE TmpInt : INTEGER := 1; +BEGIN + IntToStr(Info1,TmpStr,TmpInt); + ASSERT FALSE + REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr + SEVERITY VitalMemoryErrorSeverity(ErrorId); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalMemoryErrorType; + CONSTANT InfoStr : IN STRING; + CONSTANT Info1 : IN NATURAL; + CONSTANT Info2 : IN NATURAL +) IS + VARIABLE TmpStr : STRING ( 1 TO 256 ) ; + VARIABLE TmpInt : INTEGER := 1; +BEGIN + IntToStr(Info1,TmpStr,TmpInt); + IntToStr(Info2,TmpStr,TmpInt); + ASSERT FALSE + REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr + SEVERITY VitalMemoryErrorSeverity(ErrorId); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalMemoryErrorType; + CONSTANT InfoStr : IN STRING; + CONSTANT Info1 : IN NATURAL; + CONSTANT Info2 : IN NATURAL; + CONSTANT Info3 : IN NATURAL +) IS + VARIABLE TmpStr : STRING ( 1 TO 256 ) ; + VARIABLE TmpInt : INTEGER := 1; +BEGIN + IntToStr(Info1,TmpStr,TmpInt); + IntToStr(Info2,TmpStr,TmpInt); + IntToStr(Info3,TmpStr,TmpInt); + ASSERT FALSE + REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr + SEVERITY VitalMemoryErrorSeverity(ErrorId); +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE PrintMemoryMessage ( + CONSTANT Routine : IN STRING; + CONSTANT Table : IN VitalMemoryTableType; + CONSTANT Index : IN INTEGER; + CONSTANT InfoStr : IN STRING +) IS + CONSTANT TableEntries : INTEGER := Table'LENGTH(1); + CONSTANT TableWidth : INTEGER := Table'LENGTH(2); + VARIABLE TmpStr : STRING ( 1 TO 256 ) ; + VARIABLE TmpInt : INTEGER := 1; +BEGIN + IF (Index < 0 AND Index > TableEntries-1) THEN + ASSERT FALSE + REPORT Routine & ": Memory table search failure" + SEVERITY ERROR; + END IF; + ColLoop: + FOR i IN 0 TO TableWidth-1 LOOP + IF (i >= 64) THEN + TmpStr(TmpInt) := '.'; + TmpInt := TmpInt + 1; + TmpStr(TmpInt) := '.'; + TmpInt := TmpInt + 1; + TmpStr(TmpInt) := '.'; + TmpInt := TmpInt + 1; + EXIT ColLoop; + END IF; + TmpStr(TmpInt) := '''; + TmpInt := TmpInt + 1; + TmpStr(TmpInt) := To_MemoryChar(Table(Index,i)); + TmpInt := TmpInt + 1; + TmpStr(TmpInt) := '''; + TmpInt := TmpInt + 1; + IF (i < TableWidth-1) THEN + TmpStr(TmpInt) := ','; + TmpInt := TmpInt + 1; + END IF; + END LOOP; + ASSERT FALSE + REPORT Routine & ": Port=" & InfoStr & " TableRow=" & TmpStr + SEVERITY NOTE; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: DecodeAddress +-- Parameters: Address - Converted address. +-- AddrFlag - Flag to indicte address match +-- MemoryData - Information about memory characteristics +-- PrevAddressBus - Previous input address value +-- AddressBus - Input address value. +-- Description: This procedure is used for transforming a valid +-- address value to an integer in order to access memory. +-- It performs address bound checking as well. +-- Sets Address to -1 for unknowns +-- Sets Address to -2 for out of range +-- ---------------------------------------------------------------------------- + +PROCEDURE DecodeAddress ( + VARIABLE Address : INOUT INTEGER; + VARIABLE AddrFlag : INOUT VitalMemorySymbolType; + VARIABLE MemoryData : IN VitalMemoryDataType; + CONSTANT PrevAddressBus : IN std_logic_vector; + CONSTANT AddressBus : IN std_logic_vector +) IS + VARIABLE Power : NATURAL; + VARIABLE AddrUnkn : BOOLEAN; +BEGIN + Power := 0; + AddrUnkn := FALSE; + -- It is assumed that always Address'LEFT represents the Most significant bit. + FOR i IN AddressBus'RANGE LOOP + Power := Power * 2; + IF (AddressBus(i) /= '1' AND AddressBus(i) /= '0') THEN + AddrUnkn := TRUE; + Power := 0; + EXIT; + ELSIF (AddressBus(i) = '1') THEN + Power := Power + 1; + END IF; + END LOOP; + Address := Power; + AddrFlag := 'g'; + IF (AddrUnkn) THEN + AddrFlag := 'u'; -- unknown addr + Address := -1; + END IF; + IF ( Power > (MemoryData.NoOfWords - 1)) THEN + AddrFlag := 'i'; -- invalid addr + Address := -2; + END IF; + IF (PrevAddressBus /= AddressBus) THEN + CASE AddrFlag IS + WHEN 'g' => AddrFlag := 'G'; + WHEN 'u' => AddrFlag := 'U'; + WHEN 'i' => AddrFlag := 'I'; + WHEN OTHERS => + ASSERT FALSE REPORT + "DecodeAddress: Internal error. [AddrFlag]=" + & To_MemoryChar(AddrFlag) + SEVERITY ERROR; + END CASE; + END IF; +END DecodeAddress; + +-- ---------------------------------------------------------------------------- +-- Procedure: DecodeData +-- Parameters: DataFlag - Flag to indicte data match +-- PrevDataInBus - Previous input data value +-- DataInBus - Input data value. +-- HighBit - High bit offset value. +-- LowBit - Low bit offset value. +-- Description: This procedure is used for interpreting the input data +-- as a data flag for subsequent table matching. +-- ---------------------------------------------------------------------------- +PROCEDURE DecodeData ( + VARIABLE DataFlag : INOUT VitalMemorySymbolType; + CONSTANT PrevDataInBus : IN std_logic_vector; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT HighBit : IN NATURAL; + CONSTANT LowBit : IN NATURAL +) IS + VARIABLE DataUnkn : BOOLEAN := FALSE; +BEGIN + FOR i IN LowBit TO HighBit LOOP + IF DataInBus(i) /= '1' AND DataInBus(i) /= '0' THEN + DataUnkn := TRUE; + EXIT; + END IF; + END LOOP; + DataFlag := 'g'; + IF (DataUnkn) THEN + DataFlag := 'u'; -- unknown addr + END IF; + IF (PrevDataInBus(HighBit DOWNTO LowBit) /= + DataInBus(HighBit DOWNTO LowBit)) THEN + CASE DataFlag IS + WHEN 'g' => DataFlag := 'G'; + WHEN 'u' => DataFlag := 'U'; + WHEN OTHERS => + ASSERT FALSE REPORT + "DecodeData: Internal error. [DataFlag]=" + & To_MemoryChar(DataFlag) + SEVERITY ERROR; + END CASE; + END IF; +END DecodeData; + +-- ---------------------------------------------------------------------------- +-- Procedure: WriteMemory +-- Parameters: MemoryPtr - Pointer to the memory array. +-- DataInBus - Input Data to be written. +-- Address - Address of the memory location. +-- BitPosition - Position of bit in memory location. +-- HighBit - High bit offset value. +-- LowBit - Low bit offset value. +-- Description: This procedure is used to write to a memory location +-- on a bit/byte/word basis. +-- The high bit and low bit offset are used for byte write +-- operations.These parameters specify the data byte for write. +-- In the case of word write the complete memory word is used. +-- This procedure is overloaded for bit,byte and word write +-- memory operations.The number of parameters may vary. +-- ---------------------------------------------------------------------------- +PROCEDURE WriteMemory ( + VARIABLE MemoryPtr : INOUT VitalMemoryDataType; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT Address : IN INTEGER; + CONSTANT HighBit : IN NATURAL; + CONSTANT LowBit : IN NATURAL +) IS + VARIABLE TmpData : std_logic_vector(DataInBus'LENGTH - 1 DOWNTO 0); +BEGIN + -- Address bound checking. + IF ( Address < 0 OR Address > (MemoryPtr.NoOfWords - 1)) THEN + PrintMemoryMessage ( "WriteMemory", ErrPrintString, + "Aborting write operation as address is out of range.") ; + RETURN; + END IF; + TmpData := To_UX01(DataInBus); + FOR i in LowBit to HighBit LOOP + MemoryPtr.MemoryArrayPtr(Address).all(i) := TmpData(i); + END LOOP; +END WriteMemory; + +-- ---------------------------------------------------------------------------- +PROCEDURE WriteMemory ( + VARIABLE MemoryPtr : INOUT VitalMemoryDataType; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT Address : IN INTEGER; + CONSTANT BitPosition : IN NATURAL +) IS + VARIABLE HighBit : NATURAL; + VARIABLE LowBit : NATURAL; +BEGIN + HighBit := BitPosition; + LowBit := BitPosition; + WriteMemory (MemoryPtr, DataInBus, Address, HighBit, LowBit); +END WriteMemory; + +-- ---------------------------------------------------------------------------- +PROCEDURE WriteMemory ( + VARIABLE MemoryPtr : INOUT VitalMemoryDataType; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT Address : IN INTEGER +) IS + VARIABLE HighBit : NATURAL; + VARIABLE LowBit : NATURAL; +BEGIN + HighBit := MemoryPtr.NoOfBitsPerWord - 1; + LowBit := 0; + WriteMemory (MemoryPtr, DataInBus, Address, HighBit, LowBit); +END WriteMemory; + +-- ---------------------------------------------------------------------------- +-- Procedure: ReadMemory +-- Parameters: MemoryPtr - Pointer to the memory array. +-- DataOut - Output Data to be read in this. +-- Address - Address of the memory location. +-- BitPosition - Position of bit in memory location. +-- HighBit - High bit offset value. +-- LowBit - Low bit offset value. +-- Description: This procedure is used to read from a memory location +-- on a bit/byte/word basis. +-- The high bit and low bit offset are used for byte write +-- operations.These parameters specify the data byte for +-- read.In the case of word write the complete memory word +-- is used.This procedure is overloaded for bit,byte and +-- word write memory operations.The number of parameters +-- may vary. +-- ---------------------------------------------------------------------------- +PROCEDURE ReadMemory ( + VARIABLE MemoryPtr : INOUT VitalMemoryDataType; + VARIABLE DataOut : OUT std_logic_vector; + CONSTANT Address : IN INTEGER; + CONSTANT HighBit : IN NATURAL; + CONSTANT LowBit : IN NATURAL +) IS + VARIABLE DataOutTmp : std_logic_vector(MemoryPtr.NoOfBitsPerWord-1 DOWNTO 0); + VARIABLE length : NATURAL := (HighBit - LowBit + 1); +BEGIN + -- Address bound checking. + IF ( Address > (MemoryPtr.NoOfWords - 1)) THEN + PrintMemoryMessage ( + "ReadMemory",ErrInvaAddr, + "[Address,NoOfWords]=",Address,MemoryPtr.NoOfWords + ); + FOR i in LowBit to HighBit LOOP + DataOutTmp(i) := 'X'; + END LOOP; + ELSE + FOR i in LowBit to HighBit LOOP + DataOutTmp(i) := MemoryPtr.MemoryArrayPtr (Address).all(i); + END LOOP; + END IF; + DataOut := DataOutTmp; +END ReadMemory; + +-- ---------------------------------------------------------------------------- +PROCEDURE ReadMemory ( + VARIABLE MemoryPtr : INOUT VitalMemoryDataType; + VARIABLE DataOut : OUT std_logic_vector; + CONSTANT Address : IN INTEGER; + CONSTANT BitPosition : IN NATURAL +) IS + VARIABLE HighBit : NATURAL; + VARIABLE LowBit : NATURAL; +BEGIN + HighBit := BitPosition; + LowBit := BitPosition; + ReadMemory (MemoryPtr, DataOut, Address, HighBit, LowBit); +END ReadMemory; + +-- ---------------------------------------------------------------------------- +PROCEDURE ReadMemory ( + VARIABLE MemoryPtr : INOUT VitalMemoryDataType; + VARIABLE DataOut : OUT std_logic_vector; + CONSTANT Address : IN INTEGER +) IS + VARIABLE HighBit : NATURAL; + VARIABLE LowBit : NATURAL; +BEGIN + HighBit := MemoryPtr.NoOfBitsPerWord - 1; + LowBit := 0; + ReadMemory (MemoryPtr, DataOut, Address, HighBit, LowBit); +END ReadMemory; + + +-- ---------------------------------------------------------------------------- +-- Procedure: LoadMemory +-- Parameters: MemoryPtr - Pointer to the memory array. +-- FileName - Name of the output file. +-- HighBit - High bit offset value. +-- LowBit - Low bit offset value. +-- Description: This procedure is used to load the contents of the memory +-- from a specified input file. +-- The high bit and low bit offset are used so that same task +-- can be used for all bit/byte/word write operations. +-- In the case of a bit write RAM the HighBit and LowBit have +-- the same value. +-- This procedure is overloaded for word write operations. +-- ---------------------------------------------------------------------------- +PROCEDURE LoadMemory ( + VARIABLE MemoryPtr : INOUT VitalMemoryDataType; + CONSTANT FileName : IN STRING; + CONSTANT BinaryFile : IN BOOLEAN := FALSE +) IS + FILE Fptr : TEXT OPEN read_mode IS FileName; + VARIABLE OneLine : LINE; + VARIABLE Ignore : CHARACTER; + VARIABLE Index : NATURAL := 1; + VARIABLE LineNo : NATURAL := 0; + VARIABLE Address : INTEGER := 0; + VARIABLE DataInBus : std_logic_vector(MemoryPtr.NoOfBitsPerWord-1 DOWNTO 0); + VARIABLE AddrStr : STRING(1 TO 80) ; + VARIABLE DataInStr : STRING(1 TO 255) ; +BEGIN + IF (ENDFILE(fptr)) THEN + PrintMemoryMessage (MsgVDM, ErrLdFileEmpty, + "[FileName]="&FileName); + RETURN; + END IF ; + PrintMemoryMessage ( + MsgVDM,ErrLdMemInfo, "[FileName]="&FileName + ); + WHILE (NOT ENDFILE(fptr)) LOOP + ReadLine(Fptr, OneLine); + LineNo := LineNo + 1 ; + -- First ignoring leading spaces. + WHILE (OneLine'LENGTH /= 0 and IsSpace(OneLine(1))) LOOP + READ (OneLine, Ignore) ; -- Ignoring the space character. + END LOOP ; + -- Note that, by now oneline has been "stripped" of its leading spaces. + IF ( OneLine(1) = '@' ) THEN + READ (OneLine, Ignore); -- Ignore the '@' character and read the string. + -- Now strip off spaces, if any, between '@' and Address string. + WHILE (OneLine'LENGTH /= 0 and IsSpace(OneLine(1))) LOOP + READ (OneLine, Ignore) ; -- Ignoring the space character. + END LOOP ; + -- Now get the string which represents the address into string variable. + Index := 1; + WHILE (OneLine'LENGTH /= 0 AND (NOT(IsSpace(OneLine(1))))) LOOP + READ(OneLine, AddrStr(Index)); + Index := Index + 1; + END LOOP ; + AddrStr(Index) := NUL; + -- Now convert the hex string into a hex integer + Address := HexToInt(AddrStr) ; + ELSE + IF ( LineNo /= 1 ) THEN + Address := Address + 1; + END IF; + END IF ; + IF ( Address > (MemoryPtr.NoOfWords - 1) ) THEN + PrintMemoryMessage (MsgVDM, ErrLdAddrRng, + "[Address,lineno]=", Address, LineNo) ; + EXIT ; + END IF; + -- Now strip off spaces, between Address string and DataInBus string. + WHILE (OneLine'LENGTH /= 0 AND IsSpace(OneLine(1))) LOOP + READ (OneLine, Ignore) ; -- Ignoring the space character. + END LOOP ; + Index := 1; + WHILE (OneLine'LENGTH /= 0 AND (NOT(IsSpace(OneLine(1))))) LOOP + READ(OneLine, DataInStr(Index)); + Index := Index + 1; + END LOOP ; + DataInStr(Index) := NUL; + IF (BinaryFile) THEN + DataInBus := BinToBitv (DataInStr); + ELSE + DataInBus := HexToBitv (DataInStr); + END IF ; + WriteMemory (MemoryPtr, DataInBus, Address); + END LOOP ; +END LoadMemory; + +-- ---------------------------------------------------------------------------- +-- Procedure: MemoryMatch +-- Parameters: Symbol - Symbol from memory table +-- TestFlag - Interpreted data or address symbol +-- In2 - input from VitalMemoryTable procedure +-- to memory table +-- In2LastValue - Previous value of input +-- Err - TRUE if symbol is not a valid input symbol +-- ReturnValue - TRUE if match occurred +-- Description: This procedure sets ReturnValue to true if in2 matches +-- symbol (from the memory table). If symbol is an edge +-- value edge is set to true and in2 and in2LastValue are +-- checked against symbol. Err is set to true if symbol +-- is an invalid value for the input portion of the memory +-- table. +-- ---------------------------------------------------------------------------- +PROCEDURE MemoryMatch ( + CONSTANT Symbol : IN VitalMemorySymbolType; + CONSTANT In2 : IN std_ulogic; + CONSTANT In2LastValue : IN std_ulogic; + VARIABLE Err : OUT BOOLEAN; + VARIABLE ReturnValue : OUT BOOLEAN +) IS +BEGIN + IF (NOT ValidMemoryTableInput(Symbol) ) THEN + PrintMemoryMessage(MsgVMT,ErrUnknSymbol,To_MemoryChar(Symbol)); + Err := TRUE; + ReturnValue := FALSE; + ELSE + ReturnValue := MemoryTableMatch(To_X01(In2LastValue), To_X01(In2), Symbol); + Err := FALSE; + END IF; +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE MemoryMatch ( + CONSTANT Symbol : IN VitalMemorySymbolType; + CONSTANT TestFlag : IN VitalMemorySymbolType; + VARIABLE Err : OUT BOOLEAN; + VARIABLE ReturnValue : OUT BOOLEAN +) IS +BEGIN + Err := FALSE; + ReturnValue := FALSE; + CASE Symbol IS + WHEN 'g'|'u'|'i'|'G'|'U'|'I'|'-'|'*'|'S' => + IF (Symbol = TestFlag) THEN + ReturnValue := TRUE; + ELSE + CASE Symbol IS + WHEN '-' => + ReturnValue := TRUE; + Err := FALSE; + WHEN '*' => + IF (TestFlag = 'G' OR + TestFlag = 'U' OR + TestFlag = 'I') THEN + ReturnValue := TRUE; + Err := FALSE; + END IF; + WHEN 'S' => + IF (TestFlag = 'g' OR + TestFlag = 'u' OR + TestFlag = 'i') THEN + ReturnValue := TRUE; + Err := FALSE; + END IF; + WHEN OTHERS => + ReturnValue := FALSE; + END CASE; + END IF; + WHEN OTHERS => + Err := TRUE; + RETURN; + END CASE; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: MemoryTableCorruptMask +-- Description: Compute memory and data corruption masks for memory table +-- ---------------------------------------------------------------------------- +PROCEDURE MemoryTableCorruptMask ( + VARIABLE CorruptMask : OUT std_logic_vector; + CONSTANT Action : IN VitalMemorySymbolType; + CONSTANT EnableIndex : IN INTEGER; + CONSTANT BitsPerWord : IN INTEGER; + CONSTANT BitsPerSubWord : IN INTEGER; + CONSTANT BitsPerEnable : IN INTEGER +) IS + VARIABLE CorruptMaskTmp : std_logic_vector (CorruptMask'RANGE) + := (OTHERS => '0'); + VARIABLE ViolFlAryPosn : INTEGER; + VARIABLE HighBit : INTEGER; + VARIABLE LowBit : INTEGER; +BEGIN + CASE (Action) IS + WHEN 'c'|'l'|'e' => + -- Corrupt whole word + CorruptMaskTmp := (OTHERS => 'X'); + CorruptMask := CorruptMaskTmp; + RETURN; + WHEN 'd'|'C'|'L'|'D'|'E' => + -- Process corruption below + WHEN OTHERS => + -- No data or memory corruption + CorruptMaskTmp := (OTHERS => '0'); + CorruptMask := CorruptMaskTmp; + RETURN; + END CASE; + IF (Action = 'd') THEN + CorruptMaskTmp := (OTHERS => 'X'); + CorruptMask := CorruptMaskTmp; + RETURN; + END IF; + -- Remaining are subword cases 'C', 'L', 'D', 'E' + CorruptMaskTmp := (OTHERS => '0'); + LowBit := 0; + HighBit := BitsPerSubWord-1; + SubWordLoop: + FOR i IN 0 TO BitsPerEnable-1 LOOP + IF (i = EnableIndex) THEN + FOR j IN HighBit TO LowBit LOOP + CorruptMaskTmp(j) := 'X'; + END LOOP; + END IF; + -- Calculate HighBit and LowBit + LowBit := LowBit + BitsPerSubWord; + IF (LowBit > BitsPerWord) THEN + LowBit := BitsPerWord; + END IF; + HighBit := LowBit + BitsPerSubWord; + IF (HighBit > BitsPerWord) THEN + HighBit := BitsPerWord; + ELSE + HighBit := HighBit - 1; + END IF; + END LOOP; + CorruptMask := CorruptMaskTmp; + RETURN; +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE MemoryTableCorruptMask ( + VARIABLE CorruptMask : OUT std_logic_vector; + CONSTANT Action : IN VitalMemorySymbolType +) IS + VARIABLE CorruptMaskTmp : std_logic_vector (0 TO CorruptMask'LENGTH-1) + := (OTHERS => '0'); + VARIABLE ViolFlAryPosn : INTEGER; + VARIABLE HighBit : INTEGER; + VARIABLE LowBit : INTEGER; +BEGIN + CASE (Action) IS + WHEN 'c'|'l'|'d'|'e'|'C'|'L'|'D'|'E' => + -- Corrupt whole word + CorruptMaskTmp := (OTHERS => 'X'); + CorruptMask := CorruptMaskTmp; + RETURN; + WHEN OTHERS => + -- No data or memory corruption + CorruptMaskTmp := (OTHERS => '0'); + CorruptMask := CorruptMaskTmp; + RETURN; + END CASE; + RETURN; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: MemoryTableCorruptMask +-- Description: Compute memory and data corruption masks for violation table +-- ---------------------------------------------------------------------------- +PROCEDURE ViolationTableCorruptMask ( + VARIABLE CorruptMask : OUT std_logic_vector; + CONSTANT Action : IN VitalMemorySymbolType; + CONSTANT ViolationFlags : IN std_logic_vector; + CONSTANT ViolationFlagsArray : IN std_logic_vector; + CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType; + CONSTANT ViolationTable : IN VitalMemoryTableType; + CONSTANT TableIndex : IN INTEGER; + CONSTANT BitsPerWord : IN INTEGER; + CONSTANT BitsPerSubWord : IN INTEGER; + CONSTANT BitsPerEnable : IN INTEGER +) IS + VARIABLE CorruptMaskTmp : std_logic_vector (CorruptMask'RANGE) + := (OTHERS => '0'); + VARIABLE ViolMaskTmp : std_logic_vector (CorruptMask'RANGE) + := (OTHERS => '0'); + VARIABLE ViolFlAryPosn : INTEGER; + VARIABLE HighBit : INTEGER; + VARIABLE LowBit : INTEGER; + CONSTANT ViolFlagsSize : INTEGER := ViolationFlags'LENGTH; + CONSTANT ViolFlArySize : INTEGER := ViolationFlagsArray'LENGTH; + CONSTANT TableEntries : INTEGER := ViolationTable'LENGTH(1); + CONSTANT TableWidth : INTEGER := ViolationTable'LENGTH(2); + CONSTANT DatActionNdx : INTEGER := TableWidth - 1; + CONSTANT MemActionNdx : INTEGER := TableWidth - 2; +BEGIN + CASE (Action) IS + WHEN 'c'|'l'|'e' => + -- Corrupt whole word + CorruptMaskTmp := (OTHERS => 'X'); + CorruptMask := CorruptMaskTmp; + RETURN; + WHEN 'd'|'C'|'L'|'D'|'E' => + -- Process corruption below + WHEN OTHERS => + -- No data or memory corruption + CorruptMaskTmp := (OTHERS => '0'); + CorruptMask := CorruptMaskTmp; + RETURN; + END CASE; + RowLoop: -- Check each element of the ViolationFlags + FOR j IN 0 TO ViolFlagsSize LOOP + IF (j = ViolFlagsSize) THEN + ViolFlAryPosn := 0; + RowLoop2: -- Check relevant elements of the ViolationFlagsArray + FOR k IN 0 TO MemActionNdx - ViolFlagsSize - 1 LOOP + IF (ViolationTable(TableIndex, k + ViolFlagsSize) = 'X') THEN + MaskLoop: -- Set the 'X' bits in the violation mask + FOR m IN INTEGER RANGE 0 TO CorruptMask'LENGTH-1 LOOP + IF (m <= ViolationSizesArray(k)-1) THEN + ViolMaskTmp(m) := ViolMaskTmp(m) XOR + ViolationFlagsArray(ViolFlAryPosn+m); + ELSE + EXIT MaskLoop; + END IF; + END LOOP; + END IF; + ViolFlAryPosn := ViolFlAryPosn + ViolationSizesArray(k); + END LOOP; + ELSE + IF (ViolationTable(TableIndex, j) = 'X') THEN + ViolMaskTmp(0) := ViolMaskTmp(0) XOR ViolationFlags(j); + END IF; + END IF; + END LOOP; + IF (Action = 'd') THEN + CorruptMask := ViolMaskTmp; + RETURN; + END IF; + -- Remaining are subword cases 'C', 'L', 'D', 'E' + CorruptMaskTmp := (OTHERS => '0'); + LowBit := 0; + HighBit := BitsPerSubWord-1; + SubWordLoop: + FOR i IN 0 TO BitsPerEnable-1 LOOP + IF (ViolMaskTmp(i) = 'X') THEN + FOR j IN HighBit TO LowBit LOOP + CorruptMaskTmp(j) := 'X'; + END LOOP; + END IF; + -- Calculate HighBit and LowBit + LowBit := LowBit + BitsPerSubWord; + IF (LowBit > BitsPerWord) THEN + LowBit := BitsPerWord; + END IF; + HighBit := LowBit + BitsPerSubWord; + IF (HighBit > BitsPerWord) THEN + HighBit := BitsPerWord; + ELSE + HighBit := HighBit - 1; + END IF; + END LOOP; + CorruptMask := CorruptMaskTmp; + RETURN; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: MemoryTableLookUp +-- Parameters: MemoryAction - Output memory action to be performed +-- DataAction - Output data action to be performed +-- PrevControls - Previous data in for edge detection +-- PrevEnableBus - Previous enables for edge detection +-- Controls - Agregate of scalar control lines +-- EnableBus - Concatenation of vector control lines +-- EnableIndex - Current slice of vector control lines +-- AddrFlag - Matching symbol from address decoding +-- DataFlag - Matching symbol from data decoding +-- MemoryTable - Input memory action table +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control message output +-- +-- Description: This function is used to find the output of the +-- MemoryTable corresponding to a given set of inputs. +-- +-- ---------------------------------------------------------------------------- +PROCEDURE MemoryTableLookUp ( + VARIABLE MemoryAction : OUT VitalMemorySymbolType; + VARIABLE DataAction : OUT VitalMemorySymbolType; + VARIABLE MemoryCorruptMask : OUT std_logic_vector; + VARIABLE DataCorruptMask : OUT std_logic_vector; + CONSTANT PrevControls : IN std_logic_vector; + CONSTANT Controls : IN std_logic_vector; + CONSTANT AddrFlag : IN VitalMemorySymbolType; + CONSTANT DataFlag : IN VitalMemorySymbolType; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) IS + CONSTANT ControlsSize : INTEGER := Controls'LENGTH; + CONSTANT TableEntries : INTEGER := MemoryTable'LENGTH(1); + CONSTANT TableWidth : INTEGER := MemoryTable'LENGTH(2); + CONSTANT DatActionNdx : INTEGER := TableWidth - 1; + CONSTANT MemActionNdx : INTEGER := TableWidth - 2; + CONSTANT DataInBusNdx : INTEGER := TableWidth - 3; + CONSTANT AddressBusNdx : INTEGER := TableWidth - 4; + VARIABLE AddrFlagTable : VitalMemorySymbolType; + VARIABLE Match : BOOLEAN; + VARIABLE Err : BOOLEAN := FALSE; + VARIABLE TableAlias : VitalMemoryTableType( + 0 TO TableEntries - 1, + 0 TO TableWidth - 1) + := MemoryTable; +BEGIN + ColLoop: -- Compare each entry in the table + FOR i IN TableAlias'RANGE(1) LOOP + RowLoop: -- Check each element of the Controls + FOR j IN 0 TO ControlsSize LOOP + IF (j = ControlsSize) THEN + -- a match occurred, now check AddrFlag, DataFlag + MemoryMatch(TableAlias(i,AddressBusNdx),AddrFlag,Err,Match); + IF (Match) THEN + MemoryMatch(TableAlias(i,DataInBusNdx),DataFlag,Err,Match); + IF (Match) THEN + MemoryTableCorruptMask ( + CorruptMask => MemoryCorruptMask , + Action => TableAlias(i, MemActionNdx) + ); + MemoryTableCorruptMask ( + CorruptMask => DataCorruptMask , + Action => TableAlias(i, DatActionNdx) + ); + -- get the return memory and data actions + MemoryAction := TableAlias(i, MemActionNdx); + DataAction := TableAlias(i, DatActionNdx); + -- DEBUG: The lines below report table search + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMT,TableAlias,i,PortName); + END IF; + -- DEBUG: The lines above report table search + RETURN; + END IF; + END IF; + ELSE + -- Match memory table inputs + MemoryMatch ( TableAlias(i,j), + Controls(j), PrevControls(j), + Err, Match); + END IF; + EXIT RowLoop WHEN NOT(Match); + EXIT ColLoop WHEN Err; + END LOOP RowLoop; + END LOOP ColLoop; + -- no match found, return default action + MemoryAction := 's'; -- no change to memory + DataAction := 'S'; -- no change to dataout + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMT,ErrDefMemAct,HeaderMsg,PortName); + END IF; + RETURN; +END; + +-- ---------------------------------------------------------------------------- +PROCEDURE MemoryTableLookUp ( + VARIABLE MemoryAction : OUT VitalMemorySymbolType; + VARIABLE DataAction : OUT VitalMemorySymbolType; + VARIABLE MemoryCorruptMask : OUT std_logic_vector; + VARIABLE DataCorruptMask : OUT std_logic_vector; + CONSTANT PrevControls : IN std_logic_vector; + CONSTANT PrevEnableBus : IN std_logic_vector; + CONSTANT Controls : IN std_logic_vector; + CONSTANT EnableBus : IN std_logic_vector; + CONSTANT EnableIndex : IN INTEGER; + CONSTANT BitsPerWord : IN INTEGER; + CONSTANT BitsPerSubWord : IN INTEGER; + CONSTANT BitsPerEnable : IN INTEGER; + CONSTANT AddrFlag : IN VitalMemorySymbolType; + CONSTANT DataFlag : IN VitalMemorySymbolType; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) IS + CONSTANT ControlsSize : INTEGER := Controls'LENGTH; + CONSTANT TableEntries : INTEGER := MemoryTable'LENGTH(1); + CONSTANT TableWidth : INTEGER := MemoryTable'LENGTH(2); + CONSTANT DatActionNdx : INTEGER := TableWidth - 1; + CONSTANT MemActionNdx : INTEGER := TableWidth - 2; + CONSTANT DataInBusNdx : INTEGER := TableWidth - 3; + CONSTANT AddressBusNdx : INTEGER := TableWidth - 4; + VARIABLE AddrFlagTable : VitalMemorySymbolType; + VARIABLE Match : BOOLEAN; + VARIABLE Err : BOOLEAN := FALSE; + VARIABLE TableAlias : VitalMemoryTableType( + 0 TO TableEntries - 1, + 0 TO TableWidth - 1) + := MemoryTable; +BEGIN + ColLoop: -- Compare each entry in the table + FOR i IN TableAlias'RANGE(1) LOOP + RowLoop: -- Check each element of the Controls + FOR j IN 0 TO ControlsSize LOOP + IF (j = ControlsSize) THEN + -- a match occurred, now check EnableBus, AddrFlag, DataFlag + IF (EnableIndex >= 0) THEN + RowLoop2: -- Check relevant elements of the EnableBus + FOR k IN 0 TO AddressBusNdx - ControlsSize - 1 LOOP + MemoryMatch ( TableAlias(i,k + ControlsSize), + EnableBus(k * BitsPerEnable + EnableIndex), + PrevEnableBus(k * BitsPerEnable + EnableIndex), + Err, Match); + EXIT RowLoop2 WHEN NOT(Match); + END LOOP; + END IF; + IF (Match) THEN + MemoryMatch(TableAlias(i,AddressBusNdx),AddrFlag,Err,Match); + IF (Match) THEN + MemoryMatch(TableAlias(i,DataInBusNdx),DataFlag,Err,Match); + IF (Match) THEN + MemoryTableCorruptMask ( + CorruptMask => MemoryCorruptMask , + Action => TableAlias(i, MemActionNdx), + EnableIndex => EnableIndex , + BitsPerWord => BitsPerWord , + BitsPerSubWord => BitsPerSubWord , + BitsPerEnable => BitsPerEnable + ); + MemoryTableCorruptMask ( + CorruptMask => DataCorruptMask , + Action => TableAlias(i, DatActionNdx), + EnableIndex => EnableIndex , + BitsPerWord => BitsPerWord , + BitsPerSubWord => BitsPerSubWord , + BitsPerEnable => BitsPerEnable + ); + -- get the return memory and data actions + MemoryAction := TableAlias(i, MemActionNdx); + DataAction := TableAlias(i, DatActionNdx); + -- DEBUG: The lines below report table search + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMT,TableAlias,i,PortName); + END IF; + -- DEBUG: The lines above report table search + RETURN; + END IF; + END IF; + END IF; + ELSE + -- Match memory table inputs + MemoryMatch ( TableAlias(i,j), + Controls(j), PrevControls(j), + Err, Match); + END IF; + EXIT RowLoop WHEN NOT(Match); + EXIT ColLoop WHEN Err; + END LOOP RowLoop; + END LOOP ColLoop; + -- no match found, return default action + MemoryAction := 's'; -- no change to memory + DataAction := 'S'; -- no change to dataout + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMT,ErrDefMemAct,HeaderMsg,PortName); + END IF; + RETURN; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: ViolationTableLookUp +-- Parameters: MemoryAction - Output memory action to be performed +-- DataAction - Output data action to be performed +-- TimingDataArray - This is currently not used (comment out) +-- ViolationArray - Aggregation of violation variables +-- ViolationTable - Input memory violation table +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control message output +-- Description: This function is used to find the output of the +-- ViolationTable corresponding to a given set of inputs. +-- ---------------------------------------------------------------------------- +PROCEDURE ViolationTableLookUp ( + VARIABLE MemoryAction : OUT VitalMemorySymbolType; + VARIABLE DataAction : OUT VitalMemorySymbolType; + VARIABLE MemoryCorruptMask : OUT std_logic_vector; + VARIABLE DataCorruptMask : OUT std_logic_vector; + CONSTANT ViolationFlags : IN std_logic_vector; + CONSTANT ViolationFlagsArray : IN std_logic_vector; + CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType; + CONSTANT ViolationTable : IN VitalMemoryTableType; + CONSTANT BitsPerWord : IN INTEGER; + CONSTANT BitsPerSubWord : IN INTEGER; + CONSTANT BitsPerEnable : IN INTEGER; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) IS + CONSTANT ViolFlagsSize : INTEGER := ViolationFlags'LENGTH; + CONSTANT ViolFlArySize : INTEGER := ViolationFlagsArray'LENGTH; + VARIABLE ViolFlAryPosn : INTEGER; + VARIABLE ViolFlAryItem : std_ulogic; + CONSTANT ViolSzArySize : INTEGER := ViolationSizesArray'LENGTH; + CONSTANT TableEntries : INTEGER := ViolationTable'LENGTH(1); + CONSTANT TableWidth : INTEGER := ViolationTable'LENGTH(2); + CONSTANT DatActionNdx : INTEGER := TableWidth - 1; + CONSTANT MemActionNdx : INTEGER := TableWidth - 2; + VARIABLE HighBit : NATURAL := 0; + VARIABLE LowBit : NATURAL := 0; + VARIABLE Match : BOOLEAN; + VARIABLE Err : BOOLEAN := FALSE; + VARIABLE TableAlias : VitalMemoryTableType( + 0 TO TableEntries - 1, + 0 TO TableWidth - 1) + := ViolationTable; +BEGIN + ColLoop: -- Compare each entry in the table + FOR i IN TableAlias'RANGE(1) LOOP + RowLoop: -- Check each element of the ViolationFlags + FOR j IN 0 TO ViolFlagsSize LOOP + IF (j = ViolFlagsSize) THEN + ViolFlAryPosn := 0; + RowLoop2: -- Check relevant elements of the ViolationFlagsArray + FOR k IN 0 TO MemActionNdx - ViolFlagsSize - 1 LOOP + ViolFlAryItem := '0'; + SubwordLoop: -- Check for 'X' in ViolationFlagsArray chunk + FOR s IN ViolFlAryPosn TO ViolFlAryPosn+ViolationSizesArray(k)-1 LOOP + IF (ViolationFlagsArray(s) = 'X') THEN + ViolFlAryItem := 'X'; + EXIT SubwordLoop; + END IF; + END LOOP; + MemoryMatch ( TableAlias(i,k + ViolFlagsSize), + ViolFlAryItem,ViolFlAryItem, + Err, Match); + ViolFlAryPosn := ViolFlAryPosn + ViolationSizesArray(k); + EXIT RowLoop2 WHEN NOT(Match); + END LOOP; + IF (Match) THEN + -- Compute memory and data corruption masks + ViolationTableCorruptMask( + CorruptMask => MemoryCorruptMask , + Action => TableAlias(i, MemActionNdx), + ViolationFlags => ViolationFlags , + ViolationFlagsArray => ViolationFlagsArray , + ViolationSizesArray => ViolationSizesArray , + ViolationTable => ViolationTable , + TableIndex => i , + BitsPerWord => BitsPerWord , + BitsPerSubWord => BitsPerSubWord , + BitsPerEnable => BitsPerEnable + ); + ViolationTableCorruptMask( + CorruptMask => DataCorruptMask , + Action => TableAlias(i, DatActionNdx), + ViolationFlags => ViolationFlags , + ViolationFlagsArray => ViolationFlagsArray , + ViolationSizesArray => ViolationSizesArray , + ViolationTable => ViolationTable , + TableIndex => i , + BitsPerWord => BitsPerWord , + BitsPerSubWord => BitsPerSubWord , + BitsPerEnable => BitsPerEnable + ); + -- get the return memory and data actions + MemoryAction := TableAlias(i, MemActionNdx); + DataAction := TableAlias(i, DatActionNdx); + -- DEBUG: The lines below report table search + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMV,TableAlias,i,PortName); + END IF; + -- DEBUG: The lines above report table search + RETURN; + END IF; + ELSE + -- Match violation table inputs + Err := FALSE; + Match := FALSE; + IF (TableAlias(i,j) /= 'X' AND + TableAlias(i,j) /= '0' AND + TableAlias(i,j) /= '-') THEN + Err := TRUE; + ELSIF (TableAlias(i,j) = '-' OR + (TableAlias(i,j) = 'X' AND ViolationFlags(j) = 'X') OR + (TableAlias(i,j) = '0' AND ViolationFlags(j) = '0')) THEN + Match := TRUE; + END IF; + END IF; + EXIT RowLoop WHEN NOT(Match); + EXIT ColLoop WHEN Err; + END LOOP RowLoop; + END LOOP ColLoop; + -- no match found, return default action + MemoryAction := 's'; -- no change to memory + DataAction := 'S'; -- no change to dataout + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMV,ErrDefMemAct,HeaderMsg,PortName); + END IF; + RETURN; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: HandleMemoryAction +-- Parameters: MemoryData - Pointer to memory data structure +-- PortFlag - Indicates read/write mode of port +-- CorruptMask - XOR'ed with DataInBus when corrupting +-- DataInBus - Current data bus in +-- Address - Current address integer +-- HighBit - Current address high bit +-- LowBit - Current address low bit +-- MemoryTable - Input memory action table +-- MemoryAction - Memory action to be performed +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control message output +-- Description: This procedure performs the specified memory action on +-- the input memory data structure. +-- ---------------------------------------------------------------------------- +PROCEDURE HandleMemoryAction ( + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PortFlag : INOUT VitalPortFlagType; + CONSTANT CorruptMask : IN std_logic_vector; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT Address : IN INTEGER; + CONSTANT HighBit : IN NATURAL; + CONSTANT LowBit : IN NATURAL; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT MemoryAction : IN VitalMemorySymbolType; + CONSTANT CallerName : IN STRING; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) IS + VARIABLE DataInTmp : std_logic_vector(DataInBus'RANGE) + := DataInBus; + BEGIN + + -- Handle the memory action + CASE MemoryAction IS + + WHEN 'w' => + -- Writing data to memory + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrWrDatMem,HeaderMsg,PortName); + END IF; + WriteMemory(MemoryData,DataInBus,Address,HighBit,LowBit); + PortFlag.MemoryCurrent := WRITE; + + WHEN 's' => + -- Retaining previous memory contents + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrNoChgMem,HeaderMsg,PortName); + END IF; + -- Set memory current to quiet state + PortFlag.MemoryCurrent := READ; + + WHEN 'c' => + -- Corrupting entire memory with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrAllMem,HeaderMsg,PortName); + END IF; + DataInTmp := (OTHERS => 'X'); + -- No need to CorruptMask + FOR i IN 0 TO MemoryData.NoOfWords-1 LOOP + WriteMemory(MemoryData,DataInTmp,i); + END LOOP; + PortFlag.MemoryCurrent := CORRUPT; + + WHEN 'l' => + -- Corrupting a word in memory with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrWrdMem,HeaderMsg,PortName); + END IF; + DataInTmp := (OTHERS => 'X'); + -- No need to CorruptMask + WriteMemory(MemoryData,DataInTmp,Address); + PortFlag.MemoryCurrent := CORRUPT; + + WHEN 'd' => + -- Corrupting a single bit in memory with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrBitMem,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataInTmp,Address); + DataInTmp := DataInTmp XOR CorruptMask; + WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit); + PortFlag.MemoryCurrent := CORRUPT; + + WHEN 'e' => + -- Corrupting a word with 'X' based on data in + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrDatMem,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataInTmp,Address); + IF (DataInTmp /= DataInBus) THEN + DataInTmp := (OTHERS => 'X'); + -- No need to CorruptMask + WriteMemory(MemoryData,DataInTmp,Address); + END IF; + PortFlag.MemoryCurrent := CORRUPT; + + WHEN 'C' => + -- Corrupting a sub-word entire memory with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrAllSubMem,HeaderMsg,PortName); + END IF; + FOR i IN 0 TO MemoryData.NoOfWords-1 LOOP + ReadMemory(MemoryData,DataInTmp,i); + DataInTmp := DataInTmp XOR CorruptMask; + WriteMemory(MemoryData,DataInTmp,i,HighBit,LowBit); + END LOOP; + PortFlag.MemoryCurrent := CORRUPT; + + WHEN 'L' => + -- Corrupting a sub-word in memory with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrWrdSubMem,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataInTmp,Address); + DataInTmp := DataInTmp XOR CorruptMask; + WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit); + PortFlag.MemoryCurrent := CORRUPT; + + WHEN 'D' => + -- Corrupting a single bit of a memory sub-word with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrBitSubMem,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataInTmp,Address); + DataInTmp := DataInTmp XOR CorruptMask; + WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit); + PortFlag.MemoryCurrent := CORRUPT; + + WHEN 'E' => + -- Corrupting a sub-word with 'X' based on data in + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrDatSubMem,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataInTmp,Address); + IF (DataInBus(HighBit DOWNTO LowBit) /= + DataInTmp(HighBit DOWNTO LowBit)) THEN + DataInTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X'); + WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit); + END IF; + --PortFlag := WRITE; + PortFlag.MemoryCurrent := CORRUPT; + + WHEN '0' => + -- Assigning low level to memory location + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAsg0Mem,HeaderMsg,PortName); + END IF; + DataInTmp := (OTHERS => '0'); + WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit); + PortFlag.MemoryCurrent := WRITE; + + WHEN '1' => + -- Assigning high level to memory location + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAsg1Mem,HeaderMsg,PortName); + END IF; + DataInTmp := (OTHERS => '1'); + WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit); + PortFlag.MemoryCurrent := WRITE; + + WHEN 'Z' => + -- Assigning high impedence to memory location + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAsgZMem,HeaderMsg,PortName); + END IF; + DataInTmp := (OTHERS => 'Z'); + WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit); + PortFlag.MemoryCurrent := WRITE; + + WHEN OTHERS => + -- Unknown memory action + PortFlag.MemoryCurrent := UNDEF; + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrUnknMemDo,HeaderMsg,PortName); + END IF; + + END CASE; + + -- Note: HandleMemoryAction does not change the PortFlag.OutputDisable +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: HandleDataAction +-- Parameters: DataOutBus - Output result of the data action +-- MemoryData - Input pointer to memory data structure +-- PortFlag - Indicates read/write mode of port +-- CorruptMask - XOR'ed with DataInBus when corrupting +-- DataInBus - Current data bus in +-- Address - Current address integer +-- HighBit - Current address high bit +-- LowBit - Current address low bit +-- MemoryTable - Input memory action table +-- DataAction - Data action to be performed +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control message output +-- Description: This procedure performs the specified data action based +-- on the input memory data structure. Checks whether +-- the previous state is HighZ. If yes then portFlag +-- should be NOCHANGE for VMPD to ignore IORetain +-- corruption. The idea is that the first Z should be +-- propagated but later ones should be ignored. +-- ---------------------------------------------------------------------------- +PROCEDURE HandleDataAction ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PortFlag : INOUT VitalPortFlagType; + CONSTANT CorruptMask : IN std_logic_vector; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT Address : IN INTEGER; + CONSTANT HighBit : IN NATURAL; + CONSTANT LowBit : IN NATURAL; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT DataAction : IN VitalMemorySymbolType; + CONSTANT CallerName : IN STRING; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) IS + + VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE) + := DataOutBus; + +BEGIN + + -- Handle the data action + CASE DataAction IS + + WHEN 'l' => + -- Corrupting data out with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrWrdOut,HeaderMsg,PortName); + END IF; + DataOutTmp := (OTHERS => 'X'); + -- No need to CorruptMask + PortFlag.DataCurrent := CORRUPT; + + WHEN 'd' => + -- Corrupting a single bit of data out with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrBitOut,HeaderMsg,PortName); + END IF; + DataOutTmp(HighBit DOWNTO LowBit) := + DataOutTmp(HighBit DOWNTO LowBit) XOR + CorruptMask(HighBit DOWNTO LowBit); + PortFlag.DataCurrent := CORRUPT; + + WHEN 'e' => + -- Corrupting data out with 'X' based on data in + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrDatOut,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataOutTmp,Address); + IF (DataOutTmp /= DataInBus) THEN + DataOutTmp := (OTHERS => 'X'); + -- No need to CorruptMask + END IF; + PortFlag.DataCurrent := CORRUPT; + + WHEN 'L' => + -- Corrupting data out sub-word with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrWrdSubOut,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataOutTmp,Address); + DataOutTmp(HighBit DOWNTO LowBit) := + DataOutTmp(HighBit DOWNTO LowBit) XOR + CorruptMask(HighBit DOWNTO LowBit); + PortFlag.DataCurrent := CORRUPT; + + WHEN 'D' => + -- Corrupting a single bit of data out sub-word with 'X' + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrBitSubOut,HeaderMsg,PortName); + END IF; + DataOutTmp(HighBit DOWNTO LowBit) := + DataOutTmp(HighBit DOWNTO LowBit) XOR + CorruptMask(HighBit DOWNTO LowBit); + PortFlag.DataCurrent := CORRUPT; + + WHEN 'E' => + -- Corrupting data out sub-word with 'X' based on data in + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrCrDatSubOut,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataOutTmp,Address); + IF (DataInBus(HighBit DOWNTO LowBit) /= + DataOutTmp(HighBit DOWNTO LowBit)) THEN + DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X'); + -- No need to CorruptMask + END IF; + PortFlag.DataCurrent := CORRUPT; + + WHEN 'M' => + -- Implicit read from memory to data out + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrImplOut,HeaderMsg,PortName); + END IF; + PortFlag.DataCurrent := READ; + + WHEN 'm' => + -- Reading data from memory to data out + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrReadOut,HeaderMsg,PortName); + END IF; + ReadMemory(MemoryData,DataOutTmp,Address); + PortFlag.DataCurrent := READ; + + WHEN 't' => + -- Transferring from data in to data out + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAssgOut,HeaderMsg,PortName); + END IF; + DataOutTmp := DataInBus; + PortFlag.DataCurrent := READ; + + WHEN '0' => + -- Assigning low level to data out + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAsg0Out,HeaderMsg,PortName); + END IF; + DataOutTmp := (OTHERS => '0'); + PortFlag.DataCurrent := READ; + + WHEN '1' => + -- Assigning high level to data out + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAsg1Out,HeaderMsg,PortName); + END IF; + DataOutTmp := (OTHERS => '1'); + PortFlag.DataCurrent := READ; + + WHEN 'Z' => + -- Assigning high impedence to data out + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAsgZOut,HeaderMsg,PortName); + END IF; + DataOutTmp := (OTHERS => 'Z'); + PortFlag.DataCurrent := HIGHZ; + + WHEN 'S' => + -- Keeping data out at steady value + PortFlag.OutputDisable := TRUE; + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrAsgSOut,HeaderMsg,PortName); + END IF; + + WHEN OTHERS => + -- Unknown data action + PortFlag.DataCurrent := UNDEF; + IF (MsgOn) THEN + PrintMemoryMessage(CallerName,ErrUnknDatDo,HeaderMsg,PortName); + END IF; + + END CASE; + + DataOutBus(HighBit DOWNTO LowBit) := DataOutTmp(HighBit DOWNTO LowBit); + +END; + + +-- ---------------------------------------------------------------------------- +-- Memory Table Modeling Primitives +-- ---------------------------------------------------------------------------- + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalDeclareMemory +-- Parameters: NoOfWords - Number of words in the memory +-- NoOfBitsPerWord - Number of bits per word in memory +-- NoOfBitsPerSubWord - Number of bits per sub word +-- MemoryLoadFile - Name of data file to load +-- Description: This function is intended to be used to initialize +-- memory data declarations, i.e. to be executed duing +-- simulation elaboration time. Handles the allocation +-- and initialization of memory for the memory data. +-- Default NoOfBitsPerSubWord is NoOfBitsPerWord. +-- ---------------------------------------------------------------------------- +IMPURE FUNCTION VitalDeclareMemory ( + CONSTANT NoOfWords : IN POSITIVE; + CONSTANT NoOfBitsPerWord : IN POSITIVE; + CONSTANT MemoryLoadFile : IN string := ""; + CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE +) RETURN VitalMemoryDataType IS + VARIABLE MemoryPtr : VitalMemoryDataType; +BEGIN + MemoryPtr := VitalDeclareMemory( + NoOfWords => NoOfWords, + NoOfBitsPerWord => NoOfBitsPerWord, + NoOfBitsPerSubWord => NoOfBitsPerWord, + MemoryLoadFile => MemoryLoadFile, + BinaryLoadFile => BinaryLoadFile + ); + RETURN MemoryPtr; +END; + +-- ---------------------------------------------------------------------------- +IMPURE FUNCTION VitalDeclareMemory ( + CONSTANT NoOfWords : IN POSITIVE; + CONSTANT NoOfBitsPerWord : IN POSITIVE; + CONSTANT NoOfBitsPerSubWord : IN POSITIVE; + CONSTANT MemoryLoadFile : IN string := ""; + CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE +) RETURN VitalMemoryDataType IS + VARIABLE MemoryPtr : VitalMemoryDataType; + VARIABLE BitsPerEnable : NATURAL + := ((NoOfBitsPerWord-1) + /NoOfBitsPerSubWord)+1; +BEGIN + PrintMemoryMessage(MsgVDM,ErrInitMem); + MemoryPtr := new VitalMemoryArrayRecType '( + NoOfWords => NoOfWords, + NoOfBitsPerWord => NoOfBitsPerWord, + NoOfBitsPerSubWord => NoOfBitsPerSubWord, + NoOfBitsPerEnable => BitsPerEnable, + MemoryArrayPtr => NULL + ); + MemoryPtr.MemoryArrayPtr + := new MemoryArrayType (0 to MemoryPtr.NoOfWords - 1); + FOR i IN 0 TO MemoryPtr.NoOfWords - 1 LOOP + MemoryPtr.MemoryArrayPtr(i) + := new MemoryWordType (MemoryPtr.NoOfBitsPerWord - 1 DOWNTO 0); + END LOOP; + IF (MemoryLoadFile /= "") THEN + LoadMemory (MemoryPtr, MemoryLoadFile, BinaryLoadFile); + END IF; + RETURN MemoryPtr; +END; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryTable +-- Parameters: DataOutBus - Output candidate zero delay data bus out +-- MemoryData - Pointer to memory data structure +-- PrevControls - Previous data in for edge detection +-- PrevEnableBus - Previous enables for edge detection +-- PrevDataInBus - Previous data bus for edge detection +-- PrevAddressBus - Previous address bus for edge detection +-- PortFlag - Indicates port operating mode +-- PortFlagArray - Vector form of PortFlag for sub-word +-- Controls - Agregate of scalar control lines +-- EnableBus - Concatenation of vector control lines +-- DataInBus - Input value of data bus in +-- AddressBus - Input value of address bus in +-- AddressValue - Decoded value of the AddressBus +-- MemoryTable - Input memory action table +-- PortType - The type of port (currently not used) +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control the generation of messages +-- MsgSeverity - Control level of message generation +-- Description: This procedure implements the majority of the memory +-- modeling functionality via lookup of the memory action +-- tables and performing the specified actions if matches +-- are found, or the default actions otherwise. The +-- overloadings are provided for the word and sub-word +-- (using the EnableBus and PortFlagArray arguments) addressing +-- cases. +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryTable ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PrevControls : INOUT std_logic_vector; + VARIABLE PrevDataInBus : INOUT std_logic_vector; + VARIABLE PrevAddressBus : INOUT std_logic_vector; + VARIABLE PortFlag : INOUT VitalPortFlagVectorType; + CONSTANT Controls : IN std_logic_vector; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressBus : IN std_logic_vector; + VARIABLE AddressValue : INOUT VitalAddressValueType; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType := UNDEF; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) IS + + VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE) + := DataOutBus; + VARIABLE MemoryAction : VitalMemorySymbolType; + VARIABLE DataAction : VitalMemorySymbolType; + VARIABLE HighBit : NATURAL := MemoryData.NoOfBitsPerWord-1; + VARIABLE LowBit : NATURAL := 0; + VARIABLE Address : INTEGER := 0; + VARIABLE PortFlagTmp : VitalPortFlagType; + VARIABLE AddrFlag : VitalMemorySymbolType := 'g'; -- good addr + VARIABLE DataFlag : VitalMemorySymbolType := 'g'; -- good data + VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE); + VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE); + +BEGIN + + -- Optimize for case when all current inputs are same as previous + IF (PrevDataInBus = DataInBus + AND PrevAddressBus = AddressBus + AND PrevControls = Controls + AND PortFlag(0).MemoryCurrent = PortFlag(0).MemoryPrevious + AND PortFlag(0).DataCurrent = PortFlag(0).DataPrevious) THEN + PortFlag(0).OutputDisable := TRUE; + RETURN; + END IF; + + PortFlag(0).DataPrevious := PortFlag(0).DataCurrent; + PortFlag(0).MemoryPrevious := PortFlag(0).MemoryCurrent; + PortFlag(0).OutputDisable := FALSE; + PortFlagTmp := PortFlag(0); + + -- Convert address bus to integer value and table lookup flag + DecodeAddress( + Address => Address , + AddrFlag => AddrFlag , + MemoryData => MemoryData , + PrevAddressBus => PrevAddressBus , + AddressBus => AddressBus + ); + + -- Interpret data bus as a table lookup flag + DecodeData ( + DataFlag => DataFlag , + PrevDataInBus => PrevDataInBus , + DataInBus => DataInBus , + HighBit => HighBit , + LowBit => LowBit + ); + + -- Lookup memory and data actions + MemoryTableLookUp( + MemoryAction => MemoryAction , + DataAction => DataAction , + MemoryCorruptMask => MemCorruptMask , + DataCorruptMask => DatCorruptMask , + PrevControls => PrevControls , + Controls => Controls , + AddrFlag => AddrFlag , + DataFlag => DataFlag , + MemoryTable => MemoryTable , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + + -- Handle data action before memory action + -- This allows reading previous memory contents + HandleDataAction( + DataOutBus => DataOutTmp , + MemoryData => MemoryData , + PortFlag => PortFlagTmp , + CorruptMask => DatCorruptMask , + DataInBus => DataInBus , + Address => Address , + HighBit => HighBit , + LowBit => LowBit , + MemoryTable => MemoryTable , + DataAction => DataAction , + CallerName => MsgVMT , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + + HandleMemoryAction( + MemoryData => MemoryData , + PortFlag => PortFlagTmp , + CorruptMask => MemCorruptMask , + DataInBus => DataInBus , + Address => Address , + HighBit => HighBit , + LowBit => LowBit , + MemoryTable => MemoryTable , + MemoryAction => MemoryAction , + CallerName => MsgVMT , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + + -- Set the output PortFlag(0) value + IF (DataAction = 'S') THEN + PortFlagTmp.OutputDisable := TRUE; + END IF; + IF (PortFlagTmp.DataCurrent = PortFlagTmp.DataPrevious + AND PortFlagTmp.DataCurrent = HIGHZ) THEN + PortFlagTmp.OutputDisable := TRUE; + END IF; + PortFlag(0) := PortFlagTmp; + + -- Set previous values for subsequent edge detection + PrevControls := Controls; + PrevDataInBus := DataInBus; + PrevAddressBus := AddressBus; + + -- Set the candidate zero delay return value + DataOutBus := DataOutTmp; + + -- Set the output AddressValue for VitalMemoryCrossPorts + AddressValue := Address; + +END VitalMemoryTable; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryTable ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PrevControls : INOUT std_logic_vector; + VARIABLE PrevEnableBus : INOUT std_logic_vector; + VARIABLE PrevDataInBus : INOUT std_logic_vector; + VARIABLE PrevAddressBus : INOUT std_logic_vector; + VARIABLE PortFlagArray : INOUT VitalPortFlagVectorType; + CONSTANT Controls : IN std_logic_vector; + CONSTANT EnableBus : IN std_logic_vector; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressBus : IN std_logic_vector; + VARIABLE AddressValue : INOUT VitalAddressValueType; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType := UNDEF; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) IS + + VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord; + VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord; + VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable; + VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE) + := DataOutBus; + VARIABLE MemoryAction : VitalMemorySymbolType; + VARIABLE DataAction : VitalMemorySymbolType; + VARIABLE HighBit : NATURAL := BitsPerSubWord-1; + VARIABLE LowBit : NATURAL := 0; + VARIABLE Address : INTEGER := 0; + VARIABLE PortFlagTmp : VitalPortFlagType; + VARIABLE AddrFlag : VitalMemorySymbolType := 'g'; -- good addr + VARIABLE DataFlag : VitalMemorySymbolType := 'g'; -- good data + VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE); + VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE); + +BEGIN + + -- Optimize for case when all current inputs are same as previous + IF (PrevDataInBus = DataInBus + AND PrevAddressBus = AddressBus + AND PrevControls = Controls) THEN + CheckFlags: + FOR i IN 0 TO BitsPerEnable-1 LOOP + IF (PortFlagArray(i).MemoryCurrent /= PortFlagArray(i).MemoryPrevious + OR PortFlagArray(i).DataCurrent /= PortFlagArray(i).DataPrevious) THEN + EXIT CheckFlags; + END IF; + IF (i = BitsPerEnable-1) THEN + FOR j IN 0 TO BitsPerEnable-1 LOOP + PortFlagArray(j).OutputDisable := TRUE; + END LOOP; + RETURN; + END IF; + END LOOP; + END IF; + + -- Convert address bus to integer value and table lookup flag + DecodeAddress( + Address => Address, + AddrFlag => AddrFlag, + MemoryData => MemoryData, + PrevAddressBus => PrevAddressBus, + AddressBus => AddressBus + ); + + -- Perform independent operations for each sub-word + FOR i IN 0 TO BitsPerEnable-1 LOOP + + -- Set the output PortFlag(i) value + PortFlagArray(i).DataPrevious := PortFlagArray(i).DataCurrent; + PortFlagArray(i).MemoryPrevious := PortFlagArray(i).MemoryCurrent; + PortFlagArray(i).OutputDisable := FALSE; + PortFlagTmp := PortFlagArray(i); + + -- Interpret data bus as a table lookup flag + DecodeData ( + DataFlag => DataFlag , + PrevDataInBus => PrevDataInBus , + DataInBus => DataInBus , + HighBit => HighBit , + LowBit => LowBit + ); + + -- Lookup memory and data actions + MemoryTableLookUp( + MemoryAction => MemoryAction , + DataAction => DataAction , + MemoryCorruptMask => MemCorruptMask , + DataCorruptMask => DatCorruptMask , + PrevControls => PrevControls , + PrevEnableBus => PrevEnableBus , + Controls => Controls , + EnableBus => EnableBus , + EnableIndex => i , + BitsPerWord => BitsPerWord , + BitsPerSubWord => BitsPerSubWord , + BitsPerEnable => BitsPerEnable , + AddrFlag => AddrFlag , + DataFlag => DataFlag , + MemoryTable => MemoryTable , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + + -- Handle data action before memory action + -- This allows reading previous memory contents + HandleDataAction( + DataOutBus => DataOutTmp , + MemoryData => MemoryData , + PortFlag => PortFlagTmp , + CorruptMask => DatCorruptMask , + DataInBus => DataInBus , + Address => Address , + HighBit => HighBit , + LowBit => LowBit , + MemoryTable => MemoryTable , + DataAction => DataAction , + CallerName => MsgVMT , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + + HandleMemoryAction( + MemoryData => MemoryData , + PortFlag => PortFlagTmp , + CorruptMask => MemCorruptMask , + DataInBus => DataInBus , + Address => Address , + HighBit => HighBit , + LowBit => LowBit , + MemoryTable => MemoryTable , + MemoryAction => MemoryAction , + CallerName => MsgVMT , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + + -- Set the output PortFlag(i) value + IF (DataAction = 'S') THEN + PortFlagTmp.OutputDisable := TRUE; + END IF; + IF (PortFlagTmp.DataCurrent = PortFlagTmp.DataPrevious + AND PortFlagTmp.DataCurrent = HIGHZ) THEN + PortFlagTmp.OutputDisable := TRUE; + END IF; + PortFlagArray(i) := PortFlagTmp; + + IF (i < BitsPerEnable-1) THEN + -- Calculate HighBit and LowBit + LowBit := LowBit + BitsPerSubWord; + IF (LowBit > BitsPerWord) THEN + LowBit := BitsPerWord; + END IF; + HighBit := LowBit + BitsPerSubWord; + IF (HighBit > BitsPerWord) THEN + HighBit := BitsPerWord; + ELSE + HighBit := HighBit - 1; + END IF; + END IF; + + END LOOP; + + -- Set previous values for subsequent edge detection + PrevControls := Controls; + PrevEnableBus := EnableBus; + PrevDataInBus := DataInBus; + PrevAddressBus := AddressBus; + + -- Set the candidate zero delay return value + DataOutBus := DataOutTmp; + + -- Set the output AddressValue for VitalMemoryCrossPorts + AddressValue := Address; + +END VitalMemoryTable; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryCrossPorts +-- Parameters: DataOutBus - Output candidate zero delay data bus out +-- MemoryData - Pointer to memory data structure +-- SamePortFlag - Operating mode for same port +-- SamePortAddressValue - Operating modes for cross ports +-- CrossPortAddressArray - Decoded AddressBus for cross ports +-- CrossPortMode - Write contention and crossport read control +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control the generation of messages +-- Description: These procedures control the effect of memory operations +-- on a given port due to operations on other ports in a +-- multi-port memory. +-- This includes data write through when reading and writing +-- to the same address, as well as write contention when +-- there are multiple write to the same address. +-- If addresses do not match then data bus is unchanged. +-- The DataOutBus can be diabled with 'Z' value. +-- If the WritePortFlag is 'CORRUPT', that would mean +-- that the whole memory is corrupted. So, for corrupting +-- the Read port, the Addresses need not be compared. +-- +-- CrossPortMode Enum Description +-- 1. CpRead Allows Cross Port Read Only +-- No contention checking. +-- 2. WriteContention Allows for write contention checks +-- only between multiple write ports +-- 3. ReadWriteContention Allows contention between read and +-- write ports. The action is to corrupt +-- the memory and the output bus. +-- 4. CpReadAndWriteContention Is a combination of 1 & 2 +-- 5. CpReadAndReadContention Allows contention between read and +-- write ports. The action is to corrupt +-- the dataout bus only. The cp read is +-- performed if not contending. +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryCrossPorts ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE SamePortFlag : INOUT VitalPortFlagVectorType; + CONSTANT SamePortAddressValue : IN VitalAddressValueType; + CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType; + CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType; + CONSTANT CrossPortMode : IN VitalCrossPortModeType + := CpReadAndWriteContention; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) IS + + VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord; + VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord; + VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable; + VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE) := (OTHERS => 'Z'); + VARIABLE MemoryTmp : std_logic_vector(DataOutBus'RANGE); + VARIABLE CrossPorts : NATURAL := CrossPortAddressArray'LENGTH; + VARIABLE LowBit : NATURAL := 0; + VARIABLE HighBit : NATURAL := BitsPerSubWord-1; + VARIABLE Address : VitalAddressValueType := SamePortAddressValue; + VARIABLE AddressJ : VitalAddressValueType; + VARIABLE AddressK : VitalAddressValueType; + VARIABLE PortFlagI : VitalPortFlagType; + VARIABLE PortFlagIJ : VitalPortFlagType; + VARIABLE PortFlagIK : VitalPortFlagType; + VARIABLE DoCpRead : BOOLEAN := FALSE; + VARIABLE DoWrCont : BOOLEAN := FALSE; + VARIABLE DoCpCont : BOOLEAN := FALSE; + VARIABLE DoRdWrCont : BOOLEAN := FALSE; + VARIABLE CpWrCont : BOOLEAN := FALSE; + VARIABLE ModeWrCont : BOOLEAN := + (CrossPortMode=WriteContention) OR + (CrossPortMode=CpReadAndWriteContention); + VARIABLE ModeCpRead : BOOLEAN := + (CrossPortMode=CpRead) OR + (CrossPortMode=CpReadAndWriteContention); + VARIABLE ModeCpCont : BOOLEAN := (CrossPortMode=ReadWriteContention); + VARIABLE ModeRdWrCont : BOOLEAN := (CrossPortMode=CpReadAndReadContention); + +BEGIN + + -- Check for disabled port (i.e. OTHERS => 'Z') + IF (DataOutBus = DataOutTmp) THEN + RETURN; + ELSE + DataOutTmp := DataOutBus; + END IF; + + -- Check for error in address + IF (Address < 0) THEN + RETURN; + END IF; + + ReadMemory(MemoryData,MemoryTmp,Address); + + SubWordLoop: -- For each slice of the sub-word I + FOR i IN 0 TO BitsPerEnable-1 LOOP + PortFlagI := SamePortFlag(i); + + -- For each cross port J: check with same port address + FOR j IN 0 TO CrossPorts-1 LOOP + PortFlagIJ := CrossPortFlagArray(i+j*BitsPerEnable); + AddressJ := CrossPortAddressArray(j); + IF (AddressJ < 0) THEN + NEXT; + END IF; + DoWrCont := (Address = AddressJ) AND + (ModeWrCont = TRUE) AND + ((PortFlagI.MemoryCurrent = WRITE) OR + (PortFlagI.MemoryCurrent = CORRUPT)) AND + ((PortFlagIJ.MemoryCurrent = WRITE) OR + (PortFlagIJ.MemoryCurrent = CORRUPT)) ; + DoCpRead := (Address = AddressJ) AND + (ModeCpRead = TRUE) AND + ((PortFlagI.MemoryCurrent = READ) OR + (PortFlagI.OutputDisable = TRUE)) AND + ((PortFlagIJ.MemoryCurrent = WRITE) OR + (PortFlagIJ.MemoryCurrent = CORRUPT)) ; + DoCpCont := (Address = AddressJ) AND + (ModeCpCont = TRUE) AND + ((PortFlagI.MemoryCurrent = READ) OR + (PortFlagI.OutputDisable = TRUE)) AND + ((PortFlagIJ.MemoryCurrent = WRITE) OR + (PortFlagIJ.MemoryCurrent = CORRUPT)) ; + DoRdWrCont:= (Address = AddressJ) AND + (ModeRdWrCont = TRUE) AND + ((PortFlagI.MemoryCurrent = READ) OR + (PortFlagI.OutputDisable = TRUE)) AND + ((PortFlagIJ.MemoryCurrent = WRITE) OR + (PortFlagIJ.MemoryCurrent = CORRUPT)) ; + IF (DoWrCont OR DoCpCont) THEN + -- Corrupt dataout and memory + MemoryTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X'); + DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X'); + SamePortFlag(i).MemoryCurrent := CORRUPT; + SamePortFlag(i).DataCurrent := CORRUPT; + SamePortFlag(i).OutputDisable := FALSE; + EXIT; + END IF; + IF (DoCpRead) THEN + -- Update dataout with memory + DataOutTmp(HighBit DOWNTO LowBit) := + MemoryTmp(HighBit DOWNTO LowBit); + SamePortFlag(i).MemoryCurrent := READ; + SamePortFlag(i).DataCurrent := READ; + SamePortFlag(i).OutputDisable := FALSE; + EXIT; + END IF; + IF (DoRdWrCont) THEN + -- Corrupt dataout only + DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X'); + SamePortFlag(i).DataCurrent := CORRUPT; + SamePortFlag(i).OutputDisable := FALSE; + EXIT; + END IF; + END LOOP; + + IF (i < BitsPerEnable-1) THEN + -- Calculate HighBit and LowBit + LowBit := LowBit + BitsPerSubWord; + IF (LowBit > BitsPerWord) THEN + LowBit := BitsPerWord; + END IF; + HighBit := LowBit + BitsPerSubWord; + IF (HighBit > BitsPerWord) THEN + HighBit := BitsPerWord; + ELSE + HighBit := HighBit - 1; + END IF; + END IF; + + END LOOP; -- SubWordLoop + + DataOutBus := DataOutTmp; + + IF (DoWrCont) THEN + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMCP,ErrMcpWrCont,HeaderMsg,PortName); + END IF; + WriteMemory(MemoryData,MemoryTmp,Address); + END IF; + + IF (DoCpCont) THEN + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMCP,ErrMcpCpCont,HeaderMsg,PortName); + END IF; + WriteMemory(MemoryData,MemoryTmp,Address); + END IF; + + IF (DoCpRead) THEN + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMCP,ErrMcpCpRead,HeaderMsg,PortName); + END IF; + END IF; + + IF (DoRdWrCont) THEN + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMCP,ErrMcpRdWrCo,HeaderMsg,PortName); + END IF; + END IF; + +END VitalMemoryCrossPorts; + +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryCrossPorts ( + VARIABLE MemoryData : INOUT VitalMemoryDataType; + CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType; + CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) IS + + VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord; + VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord; + VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable; + VARIABLE MemoryTmp : std_logic_vector(BitsPerWord-1 DOWNTO 0); + VARIABLE CrossPorts : NATURAL := CrossPortAddressArray'LENGTH; + VARIABLE LowBit : NATURAL := 0; + VARIABLE HighBit : NATURAL := BitsPerSubWord-1; + VARIABLE AddressJ : VitalAddressValueType; + VARIABLE AddressK : VitalAddressValueType; + VARIABLE PortFlagIJ : VitalPortFlagType; + VARIABLE PortFlagIK : VitalPortFlagType; + VARIABLE CpWrCont : BOOLEAN := FALSE; + +BEGIN + + SubWordLoop: -- For each slice of the sub-word I + FOR i IN 0 TO BitsPerEnable-1 LOOP + + -- For each cross port J: check with each cross port K + FOR j IN 0 TO CrossPorts-1 LOOP + PortFlagIJ := CrossPortFlagArray(i+j*BitsPerEnable); + AddressJ := CrossPortAddressArray(j); + -- Check for error in address + IF (AddressJ < 0) THEN + NEXT; + END IF; + ReadMemory(MemoryData,MemoryTmp,AddressJ); + -- For each cross port K + FOR k IN 0 TO CrossPorts-1 LOOP + IF (k <= j) THEN + NEXT; + END IF; + PortFlagIK := CrossPortFlagArray(i+k*BitsPerEnable); + AddressK := CrossPortAddressArray(k); + -- Check for error in address + IF (AddressK < 0) THEN + NEXT; + END IF; + CpWrCont := ( (AddressJ = AddressK) AND + (PortFlagIJ.MemoryCurrent = WRITE) AND + (PortFlagIK.MemoryCurrent = WRITE) ) OR + ( (PortFlagIJ.MemoryCurrent = WRITE) AND + (PortFlagIK.MemoryCurrent = CORRUPT) ) OR + ( (PortFlagIJ.MemoryCurrent = CORRUPT) AND + (PortFlagIK.MemoryCurrent = WRITE) ) OR + ( (PortFlagIJ.MemoryCurrent = CORRUPT) AND + (PortFlagIK.MemoryCurrent = CORRUPT) ) ; + IF (CpWrCont) THEN + -- Corrupt memory only + MemoryTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X'); + EXIT; + END IF; + END LOOP; -- FOR k IN 0 TO CrossPorts-1 LOOP + IF (CpWrCont = TRUE) THEN + IF (MsgOn) THEN + PrintMemoryMessage(MsgVMCP,ErrMcpCpWrCont,HeaderMsg); + END IF; + WriteMemory(MemoryData,MemoryTmp,AddressJ); + END IF; + END LOOP; -- FOR j IN 0 TO CrossPorts-1 LOOP + + IF (i < BitsPerEnable-1) THEN + -- Calculate HighBit and LowBit + LowBit := LowBit + BitsPerSubWord; + IF (LowBit > BitsPerWord) THEN + LowBit := BitsPerWord; + END IF; + HighBit := LowBit + BitsPerSubWord; + IF (HighBit > BitsPerWord) THEN + HighBit := BitsPerWord; + ELSE + HighBit := HighBit - 1; + END IF; + END IF; + END LOOP; -- SubWordLoop + +END VitalMemoryCrossPorts; + + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryViolation +-- Parameters: DataOutBus - Output zero delay data bus out +-- MemoryData - Pointer to memory data structure +-- PortFlag - Indicates port operating mode +-- TimingDataArray - This is currently not used (comment out) +-- ViolationArray - Aggregation of violation variables +-- DataInBus - Input value of data bus in +-- AddressBus - Input value of address bus in +-- AddressValue - Decoded value of the AddressBus +-- ViolationTable - Input memory violation table +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control the generation of messages +-- MsgSeverity - Control level of message generation +-- Description: This procedure is intended to implement all actions on the +-- memory contents and data out bus as a result of timing viols. +-- It uses the memory action table to perform various corruption +-- policies specified by the user. +-- ---------------------------------------------------------------------------- + +PROCEDURE VitalMemoryViolation ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PortFlag : INOUT VitalPortFlagVectorType; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressValue : IN VitalAddressValueType; + CONSTANT ViolationFlags : IN std_logic_vector; + CONSTANT ViolationFlagsArray : IN X01ArrayT; + CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType; + CONSTANT ViolationTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) IS + + VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord; + VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord; + VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable; + VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE) + := DataOutBus; + VARIABLE MemoryAction : VitalMemorySymbolType; + VARIABLE DataAction : VitalMemorySymbolType; + -- VMT relies on the corrupt masks so HighBit/LowBit are full word + VARIABLE HighBit : NATURAL := BitsPerWord-1; + VARIABLE LowBit : NATURAL := 0; + VARIABLE PortFlagTmp : VitalPortFlagType; + VARIABLE VFlagArrayTmp : std_logic_vector + (0 TO ViolationFlagsArray'LENGTH-1); + VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE); + VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE); + +BEGIN + + -- Don't do anything if given an error address + IF (AddressValue < 0) THEN + RETURN; + END IF; + + FOR i IN ViolationFlagsArray'RANGE LOOP + VFlagArrayTmp(i) := ViolationFlagsArray(i); + END LOOP; + + -- Lookup memory and data actions + ViolationTableLookUp( + MemoryAction => MemoryAction , + DataAction => DataAction , + MemoryCorruptMask => MemCorruptMask , + DataCorruptMask => DatCorruptMask , + ViolationFlags => ViolationFlags , + ViolationFlagsArray => VFlagArrayTmp , + ViolationSizesArray => ViolationSizesArray , + ViolationTable => ViolationTable , + BitsPerWord => BitsPerWord , + BitsPerSubWord => BitsPerSubWord , + BitsPerEnable => BitsPerEnable , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + + -- Need to read incoming PF value (was not before) + PortFlagTmp := PortFlag(0); + + IF (PortType = READ OR PortType = RDNWR) THEN + -- Handle data action before memory action + -- This allows reading previous memory contents + HandleDataAction( + DataOutBus => DataOutTmp , + MemoryData => MemoryData , + PortFlag => PortFlagTmp , + CorruptMask => DatCorruptMask , + DataInBus => DataInBus , + Address => AddressValue , + HighBit => HighBit , + LowBit => LowBit , + MemoryTable => ViolationTable , + DataAction => DataAction , + CallerName => MsgVMV , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + END IF; + + IF (PortType = WRITE OR PortType = RDNWR) THEN + HandleMemoryAction( + MemoryData => MemoryData , + PortFlag => PortFlagTmp , + CorruptMask => MemCorruptMask , + DataInBus => DataInBus , + Address => AddressValue , + HighBit => HighBit , + LowBit => LowBit , + MemoryTable => ViolationTable , + MemoryAction => MemoryAction , + CallerName => MsgVMV , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn + ); + END IF; + + -- Check if we need to turn off PF.OutputDisable + IF (DataAction /= 'S') THEN + PortFlagTmp.OutputDisable := FALSE; + -- Set the output PortFlag(0) value + -- Note that all bits of PortFlag get PortFlagTmp + FOR i IN PortFlag'RANGE LOOP + PortFlag(i) := PortFlagTmp; + END LOOP; + END IF; + + -- Set the candidate zero delay return value + DataOutBus := DataOutTmp; + +END; + +PROCEDURE VitalMemoryViolation ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PortFlag : INOUT VitalPortFlagVectorType; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressValue : IN VitalAddressValueType; + CONSTANT ViolationFlags : IN std_logic_vector; + CONSTANT ViolationTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) IS + + VARIABLE VFlagArrayTmp : X01ArrayT (0 TO 0); + +BEGIN + + VitalMemoryViolation ( + DataOutBus => DataOutBus , + MemoryData => MemoryData , + PortFlag => PortFlag , + DataInBus => DataInBus , + AddressValue => AddressValue , + ViolationFlags => ViolationFlags , + ViolationFlagsArray => VFlagArrayTmp , + ViolationSizesArray => ( 0 => 0 ) , + ViolationTable => ViolationTable , + PortType => PortType , + PortName => PortName , + HeaderMsg => HeaderMsg , + MsgOn => MsgOn , + MsgSeverity => MsgSeverity + ); + +END; + +END Vital_Memory ; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/memory_p.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/memory_p.vhdl new file mode 100644 index 00000000..83874f45 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/memory_p.vhdl @@ -0,0 +1,1729 @@ +-- ---------------------------------------------------------------------------- +-- Title : Standard VITAL Memory Package +-- : +-- Library : Vital_Memory +-- : +-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4 +-- : Ekambaram Balaji, LSI Logic Corporation +-- : Jose De Castro, Consultant +-- : Prakash Bare, GDA Technologies +-- : William Yam, LSI Logic Corporation +-- : Dennis Brophy, Model Technology +-- : +-- Purpose : This packages defines standard types, constants, functions +-- : and procedures for use in developing ASIC memory models. +-- : +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Modification History : +-- ---------------------------------------------------------------------------- +-- Ver:|Auth:| Date:| Changes Made: +-- 0.1 | eb |071796| First prototye as part of VITAL memory proposal +-- 0.2 | jdc |012897| Initial prototyping with proposed MTM scheme +-- 0.3 | jdc |090297| Extensive updates for TAG review (functional) +-- 0.4 | eb |091597| Changed naming conventions for VitalMemoryTable +-- | | | Added interface of VitalMemoryCrossPorts() & +-- | | | VitalMemoryViolation(). +-- 0.5 | jdc |092997| Completed naming changes thoughout package body. +-- | | | Testing with simgle port test model looks ok. +-- 0.6 | jdc |121797| Major updates to the packages: +-- | | | - Implement VitalMemoryCrossPorts() +-- | | | - Use new VitalAddressValueType +-- | | | - Use new VitalCrossPortModeType enum +-- | | | - Overloading without SamePort args +-- | | | - Honor erroneous address values +-- | | | - Honor ports disabled with 'Z' +-- | | | - Implement implicit read 'M' table symbol +-- | | | - Cleanup buses to use (H DOWNTO L) +-- | | | - Message control via MsgOn,HeaderMsg,PortName +-- | | | - Tested with 1P1RW,2P2RW,4P2R2W,4P4RW cases +-- 0.7 | jdc |052698| Bug fixes to the packages: +-- | | | - Fix failure with negative Address values +-- | | | - Added debug messages for VMT table search +-- | | | - Remove 'S' for action column (only 's') +-- | | | - Remove 's' for response column (only 'S') +-- | | | - Remove 'X' for action and response columns +-- 0.8 | jdc |061298| Implemented VitalMemoryViolation() +-- | | | - Minimal functionality violation tables +-- | | | - Missing: +-- | | | - Cannot handle wide violation variables +-- | | | - Cannot handle sub-word cases +-- | | | Fixed IIC version of MemoryMatch +-- | | | Fixed 'M' vs 'm' switched on debug output +-- | | | TO BE DONE: +-- | | | - Implement 'd' corrupting a single bit +-- | | | - Implement 'D' corrupting a single bit +-- 0.9 |eb/sc|080498| Added UNDEF value for VitalPortFlagType +-- 0.10|eb/sc|080798| Added CORRUPT value for VitalPortFlagType +-- 0.11|eb/sc|081798| Added overloaded function interface for +-- | | | VitalDeclareMemory +-- 0.14| jdc |113198| Merging of memory functionality and version +-- | | | 1.4 9/17/98 of timing package from Prakash +-- 0.15| jdc |120198| Major development of VMV functionality +-- 0.16| jdc |120298| Complete VMV functionlality for initial testing +-- | | | - New ViolationTableCorruptMask() procedure +-- | | | - New MemoryTableCorruptMask() procedure +-- | | | - HandleMemoryAction(): +-- | | | - Removed DataOutBus bogus output +-- | | | - Replaced DataOutTmp with DataInTmp +-- | | | - Added CorruptMask input handling +-- | | | - Implemented 'd','D' using CorruptMask +-- | | | - CorruptMask on 'd','C','L','D','E' +-- | | | - CorruptMask ignored on 'c','l','e' +-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT +-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT +-- | | | - Changed 'c','l','d','e' to ignore HighBit, LowBit +-- | | | - Changed 'C','L','D','E' to use HighBit, LowBit +-- | | | - HandleDataAction(): +-- | | | - Added CorruptMask input handling +-- | | | - Implemented 'd','D' using CorruptMask +-- | | | - CorruptMask on 'd','C','L','D','E' +-- | | | - CorruptMask ignored on 'l','e' +-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT +-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT +-- | | | - Changed 'l','d','e' to ignore HighBit, LowBit +-- | | | - Changed 'L','D','E' to use HighBit, LowBit +-- | | | - MemoryTableLookUp(): +-- | | | - Added MsgOn table debug output +-- | | | - Uses new MemoryTableCorruptMask() +-- | | | - ViolationTableLookUp(): +-- | | | - Uses new ViolationTableCorruptMask() +-- 0.17| jdc |120898| - Added VitalMemoryViolationSymbolType, +-- | | | VitalMemoryViolationTableType data +-- | | | types but not used yet (need to discuss) +-- | | | - Added overload for VitalMemoryViolation() +-- | | | which does not have array flags +-- | | | - Bug fixes for VMV functionality: +-- | | | - ViolationTableLookUp() not handling '-' in +-- | | | scalar violation matching +-- | | | - VitalMemoryViolation() now normalizes +-- | | | VFlagArrayTmp'LEFT as LSB before calling +-- | | | ViolationTableLookUp() for proper scanning +-- | | | - ViolationTableCorruptMask() had to remove +-- | | | normalization of CorruptMaskTmp and +-- | | | ViolMaskTmp for proper MSB:LSB corruption +-- | | | - HandleMemoryAction(), HandleDataAction() +-- | | | - Removed 'D','E' since not being used +-- | | | - Use XOR instead of OR for corrupt masks +-- | | | - Now 'd' is sensitive to HighBit, LowBit +-- | | | - Fixed LowBit overflow in bit writeable case +-- | | | - MemoryTableCorruptMask() +-- | | | - ViolationTableCorruptMask() +-- | | | - VitalMemoryTable() +-- | | | - VitalMemoryCrossPorts() +-- | | | - Fixed VitalMemoryViolation() failing on +-- | | | error AddressValue from earlier VMT() +-- | | | - Minor cleanup of code formatting +-- 0.18| jdc |032599| - In VitalDeclareMemory() +-- | | | - Added BinaryLoadFile formal arg and +-- | | | modified LoadMemory() to handle bin +-- | | | - Added NOCHANGE to VitalPortFlagType +-- | | | - For VitalCrossPortModeType +-- | | | - Added CpContention enum +-- | | | - In HandleDataAction() +-- | | | - Set PortFlag := NOCHANGE for 'S' +-- | | | - In HandleMemoryAction() +-- | | | - Set PortFlag := NOCHANGE for 's' +-- | | | - In VitalMemoryTable() and +-- | | | VitalMemoryViolation() +-- | | | - Honor PortFlag = NOCHANGE returned +-- | | | from HandleMemoryAction() +-- | | | - In VitalMemoryCrossPorts() +-- | | | - Fixed Address = AddressJ for all +-- | | | conditions of DoWrCont & DoCpRead +-- | | | - Handle CpContention like WrContOnly +-- | | | under CpReadOnly conditions, with +-- | | | associated memory message changes +-- | | | - Handle PortFlag = NOCHANGE like +-- | | | PortFlag = READ for actions +-- | | | - Modeling change: +-- | | | - Need to init PortFlag every delta +-- | | | PortFlag_A := (OTHES => UNDEF); +-- | | | - Updated InternalTimingCheck code +-- 0.19| jdc |042599| - Fixes for bit-writeable cases +-- | | | - Check PortFlag after HandleDataAction +-- | | | in VitalMemoryViolation() +-- 0.20| jdc |042599| - Merge PortFlag changes from Prakash +-- | | | and Willian: +-- | | | VitalMemorySchedulePathDelay() +-- | | | VitalMemoryExpandPortFlag() +-- 0.21| jdc |072199| - Changed VitalCrossPortModeType enums, +-- | | | added new CpReadAndReadContention. +-- | | | - Fixed VitalMemoryCrossPorts() parameter +-- | | | SamePortFlag to INOUT so that it can +-- | | | set CORRUPT or READ value. +-- | | | - Fixed VitalMemoryTable() where PortFlag +-- | | | setting by HandleDataAction() is being +-- | | | ignored when HandleMemoryAction() sets +-- | | | PortFlagTmp to NOCHANGE. +-- | | | - Fixed VitalMemoryViolation() to set +-- | | | all bits of PortFlag when violating. +-- 0.22| jdc |072399| - Added HIGHZ to PortFlagType. HandleData +-- | | | checks whether the previous state is HIGHZ. +-- | | | If yes then portFlag should be NOCHANGE +-- | | | for VMPD to ignore IORetain corruption. +-- | | | The idea is that the first Z should be +-- | | | propagated but later ones should be ignored. +-- | | | +-- 0.23| jdc |100499| - Took code checked in by Dennis 09/28/99 +-- | | | - Changed VitalPortFlagType to record of +-- | | | new VitalPortStateType to hold current, +-- | | | previous values and separate disable. +-- | | | Also created VitalDefaultPortFlag const. +-- | | | Removed usage of PortFlag NOCHANGE +-- | | | - VitalMemoryTable() changes: +-- | | | Optimized return when all curr = prev +-- | | | AddressValue is now INOUT to optimize +-- | | | Transfer PF.MemoryCurrent to MemoryPrevious +-- | | | Transfer PF.DataCurrent to DataPrevious +-- | | | Reset PF.OutputDisable to FALSE +-- | | | Expects PortFlag init in declaration +-- | | | No need to init PortFlag every delta +-- | | | - VitalMemorySchedulePathDelay() changes: +-- | | | Initialize with VitalDefaultPortFlag +-- | | | Check PortFlag.OutputDisable +-- | | | - HandleMemoryAction() changes: +-- | | | Set value of PortFlag.MemoryCurrent +-- | | | Never set PortFlag.OutputDisable +-- | | | - HandleDataAction() changes: +-- | | | Set value of PortFlag.DataCurrent +-- | | | Set PortFlag.DataCurrent for HIGHZ +-- | | | - VitalMemoryCrossPorts() changes: +-- | | | Check/set value of PF.MemoryCurrent +-- | | | Check value of PF.OutputDisable +-- | | | - VitalMemoryViolation() changes: +-- | | | Fixed bug - not reading inout PF value +-- | | | Clean up setting of PortFlag +-- 0.24| jdc |100899| - Modified update of PF.OutputDisable +-- | | | to correctly accomodate 2P1W1R case: +-- | | | the read port should not exhibit +-- | | | IO retain corrupt when reading +-- | | | addr unrelated to addr being written. +-- 0.25| jdc |100999| - VitalMemoryViolation() change: +-- | | | Fixed bug with RDNWR mode incorrectly +-- | | | updating the PF.OutputDisable +-- 0.26| jdc |100999| - VitalMemoryCrossPorts() change: +-- | | | Fixed bugs with update of PF +-- 0.27| jdc |101499| - VitalMemoryCrossPorts() change: +-- | | | Added DoRdWrCont message (ErrMcpRdWrCo, +-- | | | Memory cross port read/write data only +-- | | | contention) +-- | | | - VitalMemoryTable() change: +-- | | | Set PF.OutputDisable := TRUE for the +-- | | | optimized cases. +-- 0.28| pb |112399| - Added 8 VMPD procedures for vector +-- | | | PathCondition support. Now the total +-- | | | number of overloadings for VMPD is 24. +-- | | | - Number of overloadings for SetupHold +-- | | | procedures increased to 5. Scalar violations +-- | | | are not supported anymore. Vector checkEnabled +-- | | | support is provided through the new overloading +-- 0.29| jdc |120999| - HandleMemoryAction() HandleDataAction() +-- | | | Reinstated 'D' and 'E' actions but +-- | | | with new PortFlagType +-- | | | - Updated file handling syntax, must compile +-- | | | with -93 syntax now. +-- 0.30| jdc |022300| - Formated for 80 column max width +-- ---------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.Vital_Timing.ALL; +USE IEEE.Vital_Primitives.ALL; + +LIBRARY STD; +USE STD.TEXTIO.ALL; + +PACKAGE Vital_Memory IS + +-- ---------------------------------------------------------------------------- +-- Timing Section +-- ---------------------------------------------------------------------------- + +-- ---------------------------------------------------------------------------- +-- Types and constants for Memory timing procedures +-- ---------------------------------------------------------------------------- +TYPE VitalMemoryArcType IS (ParallelArc, CrossArc, SubwordArc); +TYPE OutputRetainBehaviorType IS (BitCorrupt, WordCorrupt); +TYPE VitalMemoryMsgFormatType IS (Vector, Scalar, VectorEnum); +TYPE X01ArrayT IS ARRAY (NATURAL RANGE <> ) OF X01; +TYPE X01ArrayPT IS ACCESS X01ArrayT; +TYPE VitalMemoryViolationType IS ACCESS X01ArrayT; +CONSTANT DefaultNumBitsPerSubword : INTEGER := -1; + + +-- Data type storing path delay and schedule information for output bits +TYPE VitalMemoryScheduleDataType IS RECORD + OutputData : std_ulogic; + NumBitsPerSubWord : INTEGER; + ScheduleTime : TIME; + ScheduleValue : std_ulogic; + LastOutputValue : std_ulogic; + PropDelay : TIME; + OutputRetainDelay : TIME; + InputAge : TIME; +END RECORD; + +TYPE VitalMemoryTimingDataType IS RECORD + NotFirstFlag : BOOLEAN; + RefLast : X01; + RefTime : TIME; + HoldEn : BOOLEAN; + TestLast : std_ulogic; + TestTime : TIME; + SetupEn : BOOLEAN; + TestLastA : VitalLogicArrayPT; + TestTimeA : VitalTimeArrayPT; + RefLastA : X01ArrayPT; + RefTimeA : VitalTimeArrayPT; + HoldEnA : VitalBoolArrayPT; + SetupEnA : VitalBoolArrayPT; +END RECORD; + +TYPE VitalPeriodDataArrayType IS ARRAY (NATURAL RANGE <>) OF + VitalPeriodDataType; + +-- Data type storing path delay and schedule information for output +-- vectors +TYPE VitalMemoryScheduleDataVectorType IS ARRAY (NATURAL RANGE <> ) OF + VitalMemoryScheduleDataType; + +-- VitalPortFlagType records runtime mode of port sub-word slices +-- TYPE VitalPortFlagType IS ( +-- UNDEF, +-- READ, +-- WRITE, +-- CORRUPT, +-- HIGHZ, +-- NOCHANGE +-- ); + +-- VitalPortFlagType records runtime mode of port sub-word slices +TYPE VitalPortStateType IS ( + UNDEF, + READ, + WRITE, + CORRUPT, + HIGHZ +); + +TYPE VitalPortFlagType IS RECORD + MemoryCurrent : VitalPortStateType; + MemoryPrevious : VitalPortStateType; + DataCurrent : VitalPortStateType; + DataPrevious : VitalPortStateType; + OutputDisable : BOOLEAN; +END RECORD; + +CONSTANT VitalDefaultPortFlag : VitalPortFlagType := ( + MemoryCurrent => READ, + MemoryPrevious => UNDEF, + DataCurrent => READ, + DataPrevious => UNDEF, + OutputDisable => FALSE +); + +-- VitalPortFlagVectorType to be same width i as enables of a port +-- or j multiples thereof, where j is the number of cross ports +TYPE VitalPortFlagVectorType IS + ARRAY (NATURAL RANGE <>) OF VitalPortFlagType; + +-- ---------------------------------------------------------------------------- +-- Functions : VitalMemory path delay procedures +-- - VitalMemoryInitPathDelay +-- - VitalMemoryAddPathDelay +-- - VitalMemorySchedulePathDelay +-- +-- Description: VitalMemoryInitPathDelay, VitalMemoryAddPathDelay and +-- VitalMemorySchedulePathDelay are Level 1 routines used +-- for selecting the propagation delay paths based on +-- path condition, transition type and delay values and +-- schedule a new output value. +-- +-- Following features are implemented in these procedures: +-- o condition dependent path selection +-- o Transition dependent delay selection +-- o shortest delay path selection from multiple +-- candidate paths +-- o Scheduling of the computed values on the specified +-- signal. +-- o output retain behavior if outputRetain flag is set +-- o output mapping to alternate strengths to model +-- pull-up, pull-down etc. +-- +-- +-- +-- Following is information on overloading of the procedures. +-- +-- VitalMemoryInitPathDelay is overloaded for ScheduleDataArray and +-- OutputDataArray +-- +-- ---------------------------------------------------------------------------- +-- ScheduleDataArray OutputDataArray +-- ---------------------------------------------------------------------------- +-- Scalar Scalar +-- Vector Vector +-- ---------------------------------------------------------------------------- +-- +-- +-- VitalMemoryAddPathDelay is overloaded for ScheduleDataArray, +-- PathDelayArray, InputSignal and delaytype. +-- +-- ---------------------------------------------------------------------------- +-- DelayType InputSignal ScheduleData PathDelay +-- Array Array +-- ---------------------------------------------------------------------------- +-- VitalDelayType Scalar Scalar Scalar +-- VitalDelayType Scalar Vector Vector +-- VitalDelayType Vector Scalar Vector +-- VitalDelayType Vector Vector Vector +-- VitalDelayType01 Scalar Scalar Scalar +-- VitalDelayType01 Scalar Vector Vector +-- VitalDelayType01 Vector Scalar Vector +-- VitalDelayType01 Vector Vector Vector +-- VitalDelayType01Z Scalar Scalar Scalar +-- VitalDelayType01Z Scalar Vector Vector +-- VitalDelayType01Z Vector Scalar Vector +-- VitalDelayType01Z Vector Vector Vector +-- VitalDelayType01XZ Scalar Scalar Scalar +-- VitalDelayType01XZ Scalar Vector Vector +-- VitalDelayType01XZ Vector Scalar Vector +-- VitalDelayType01XZ Vector Vector Vector +-- ---------------------------------------------------------------------------- +-- +-- +-- VitalMemorySchedulePathDelay is overloaded for ScheduleDataArray, +-- and OutSignal +-- +-- ---------------------------------------------------------------------------- +-- OutSignal ScheduleDataArray +-- ---------------------------------------------------------------------------- +-- Scalar Scalar +-- Vector Vector +-- ---------------------------------------------------------------------------- +-- +-- Procedure Declarations: +-- +-- +-- Function : VitalMemoryInitPathDelay +-- +-- Arguments: +-- +-- INOUT Type Description +-- +-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/ +-- ScheduleData VitalMemoryScheduleDataType +-- Internal data variable for +-- storing delay and schedule +-- information for each output bit +-- +-- +-- IN +-- +-- OutputDataArray/ STD_LOGIC_VECTOR/Array containing current output +-- OutputData STD_ULOGIC value +-- +-- +-- NumBitsPerSubWord INTEGER Number of bits per subword. +-- Default value of this argument +-- is DefaultNumBitsPerSubword +-- which is interpreted as no +-- subwords +-- +-- ---------------------------------------------------------------------------- +-- +-- +-- ScheduleDataArray - Vector +-- OutputDataArray - Vector +-- +PROCEDURE VitalMemoryInitPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + VARIABLE OutputDataArray : IN STD_LOGIC_VECTOR; + CONSTANT NumBitsPerSubWord : IN INTEGER := DefaultNumBitsPerSubword +); +-- +-- ScheduleDataArray - Scalar +-- OutputDataArray - Scalar +-- +PROCEDURE VitalMemoryInitPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + VARIABLE OutputData : IN STD_ULOGIC +); + +-- ---------------------------------------------------------------------------- +-- +-- Function : VitalMemoryAddPathDelay +-- +-- Arguments +-- +-- INOUT Type Description +-- +-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/ +-- ScheduleData VitalMemoryScheduleDataType +-- Internal data variable for +-- storing delay and schedule +-- information for each output bit +-- +-- InputChangeTimeArray/ VitaltimeArrayT/Time +-- InputChangeTime Holds the time since the last +-- input change +-- +-- IN +-- +-- InputSignal STD_LOGIC_VECTOR +-- STD_ULOGIC/ Array holding the input value +-- +-- OutputSignalName STRING The output signal name +-- +-- PathDelayArray/ VitalDelayArrayType01ZX, +-- PathDelay VitalDelayArrayType01Z, +-- VitalDelayArrayType01, +-- VitalDelayArrayType/ +-- VitalDelayType01ZX, +-- VitalDelayType01Z, +-- VitalDelayType01, +-- VitalDelayType Array of delay values +-- +-- ArcType VitalMemoryArcType +-- Indicates the Path type. This +-- can be SubwordArc, CrossArc or +-- ParallelArc +-- +-- PathCondition BOOLEAN If True, the transition in +-- the corresponding input signal +-- is considered while +-- caluculating the prop. delay +-- else the transition is ignored. +-- +-- OutputRetainFlag BOOLEAN If specified TRUE,output retain +-- (hold) behavior is implemented. +-- +-- ---------------------------------------------------------------------------- +-- +-- #1 +-- DelayType - VitalDelayType +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelay : IN VitalDelayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #2 +-- DelayType - VitalDelayType +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #3 +-- DelayType - VitalDelayType +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray: IN VitalBoolArrayT +); + +-- #4 +-- DelayType - VitalDelayType +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #5 +-- DelayType - VitalDelayType +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #6 +-- DelayType - VitalDelayType +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT +); + +-- #7 +-- DelayType - VitalDelayType01 +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelay : IN VitalDelayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #8 +-- DelayType - VitalDelayType01 +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #9 +-- DelayType - VitalDelayType01 +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray: IN VitalBoolArrayT +); + +-- #10 +-- DelayType - VitalDelayType01 +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #11 +-- DelayType - VitalDelayType01 +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE +); + +-- #12 +-- DelayType - VitalDelayType01 +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT +); + +-- #13 +-- DelayType - VitalDelayType01Z +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelay : IN VitalDelayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +); + +-- #14 +-- DelayType - VitalDelayType01Z +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +); + +-- #15 +-- DelayType - VitalDelayType01Z +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray: IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +); + +-- #16 +-- DelayType - VitalDelayType01Z +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +); + +-- #17 +-- DelayType - VitalDelayType01Z +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +); + +-- #18 +-- DelayType - VitalDelayType01Z +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01Z; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +); + +-- #19 +-- DelayType - VitalDelayType01ZX +-- Input - Scalar +-- Output - Scalar +-- Delay - Scalar +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelay : IN VitalDelayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +); + +-- #20 +-- DelayType - VitalDelayType01ZX +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +); + +-- #21 +-- DelayType - VitalDelayType01ZX +-- Input - Scalar +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_ULOGIC; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTime : INOUT Time; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray: IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE +); + +-- #22 +-- DelayType - VitalDelayType01ZX +-- Input - Vector +-- Output - Scalar +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +); + +-- #23 +-- DelayType - VitalDelayType01ZX +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Scalar + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathCondition : IN BOOLEAN := TRUE; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +); + +-- #24 +-- DelayType - VitalDelayType01ZX +-- Input - Vector +-- Output - Vector +-- Delay - Vector +-- Condition - Vector + +PROCEDURE VitalMemoryAddPathDelay ( + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType; + SIGNAL InputSignal : IN STD_LOGIC_VECTOR; + CONSTANT OutputSignalName : IN STRING := ""; + VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT; + CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT PathConditionArray : IN VitalBoolArrayT; + CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE; + CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt +); + +-- ---------------------------------------------------------------------------- +-- +-- Function : VitalMemorySchedulePathDelay +-- +-- Arguments: +-- +-- OUT Type Description +-- OutSignal STD_LOGIC_VECTOR/ The output signal for +-- STD_ULOGIC scheduling +-- +-- IN +-- OutputSignalName STRING The name of the output signal +-- +-- IN +-- PortFlag VitalPortFlagType Port flag variable from +-- functional procedures +-- +-- IN +-- OutputMap VitalOutputMapType For VitalPathDelay01Z, the +-- output can be mapped to +-- alternate strengths to model +-- tri-state devices, pull-ups +-- and pull-downs. +-- +-- INOUT +-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/ +-- ScheduleData VitalMemoryScheduleDataType +-- Internal data variable for +-- storing delay and schedule +-- information for each +-- output bit +-- +-- ---------------------------------------------------------------------------- +-- +-- ScheduleDataArray - Vector +-- OutputSignal - Vector +-- +PROCEDURE VitalMemorySchedulePathDelay ( + SIGNAL OutSignal : OUT std_logic_vector; + CONSTANT OutputSignalName : IN STRING := ""; + CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag; + CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap; + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType +); +-- +-- ScheduleDataArray - Vector +-- OutputSignal - Vector +-- +PROCEDURE VitalMemorySchedulePathDelay ( + SIGNAL OutSignal : OUT std_logic_vector; + CONSTANT OutputSignalName : IN STRING := ""; + CONSTANT PortFlag : IN VitalPortFlagVectorType; + CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap; + VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType +); +-- +-- ScheduleDataArray - Scalar +-- OutputSignal - Scalar +-- +PROCEDURE VitalMemorySchedulePathDelay ( + SIGNAL OutSignal : OUT std_ulogic; + CONSTANT OutputSignalName : IN STRING := ""; + CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag; + CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap; + VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType +); + +-- ---------------------------------------------------------------------------- +FUNCTION VitalMemoryTimingDataInit RETURN VitalMemoryTimingDataType; + +-- ---------------------------------------------------------------------------- +-- +-- Function Name: VitalMemorySetupHoldCheck +-- +-- Description: The VitalMemorySetupHoldCheck procedure detects a setup or a +-- hold violation on the input test signal with respect +-- to the corresponding input reference signal. The timing +-- constraints are specified through parameters +-- representing the high and low values for the setup and +-- hold values for the setup and hold times. This +-- procedure assumes non-negative values for setup and hold +-- timing constraints. +-- +-- It is assumed that negative timing constraints +-- are handled by internally delaying the test or +-- reference signals. Negative setup times result in +-- a delayed reference signal. Negative hold times +-- result in a delayed test signal. Furthermore, the +-- delays and constraints associated with these and +-- other signals may need to be appropriately +-- adjusted so that all constraint intervals overlap +-- the delayed reference signals and all constraint +-- values (with respect to the delayed signals) are +-- non-negative. +-- +-- This function is overloaded based on the input +-- TestSignal and reference signals. Parallel, Subword and +-- Cross Arc relationships between test and reference +-- signals are supported. +-- +-- TestSignal XXXXXXXXXXXX____________________________XXXXXXXXXXXXXXXXXXXXXX +-- : +-- : -->| error region |<-- +-- : +-- _______________________________ +-- RefSignal \______________________________ +-- : | | | +-- : | -->| |<-- thold +-- : -->| tsetup |<-- +-- +-- Arguments: +-- +-- IN Type Description +-- TestSignal std_logic_vector Value of test signal +-- TestSignalName STRING Name of test signal +-- TestDelay VitalDelayArrayType Model's internal delay associated +-- with TestSignal +-- RefSignal std_ulogic Value of reference signal +-- std_logic_vector +-- RefSignalName STRING Name of reference signal +-- RefDelay TIME Model's internal delay associated +-- VitalDelayArrayType with RefSignal +-- SetupHigh VitalDelayArrayType Absolute minimum time duration +-- before the transition of RefSignal +-- for which transitions of +-- TestSignal are allowed to proceed +-- to the "1" state without causing +-- a setup violation. +-- SetupLow VitalDelayArrayType Absolute minimum time duration +-- before the transition of RefSignal +-- for which transitions of +-- TestSignal are allowed to proceed +-- to the "0" state without causing +-- a setup violation. +-- HoldHigh VitalDelayArrayType Absolute minimum time duration +-- after the transition of RefSignal +-- for which transitions of +-- TestSignal are allowed to +-- proceed to the "1" state without +-- causing a hold violation. +-- HoldLow VitalDelayArrayType Absolute minimum time duration +-- after the transition of RefSignal +-- for which transitions of +-- TestSignal are allowed to +-- proceed to the "0" state without +-- causing a hold violation. +-- CheckEnabled BOOLEAN Check performed if TRUE. +-- RefTransition VitalEdgeSymbolType +-- Reference edge specified. Events +-- on the RefSignal which match the +-- edge spec. are used as reference +-- edges. +-- ArcType VitalMemoryArcType +-- NumBitsPerSubWord INTEGER +-- HeaderMsg STRING String that will accompany any +-- assertion messages produced. +-- XOn BOOLEAN If TRUE, Violation output +-- parameter is set to "X". +-- Otherwise, Violation is always +-- set to "0." +-- MsgOn BOOLEAN If TRUE, set and hold violation +-- message will be generated. +-- Otherwise, no messages are +-- generated, even upon violations. +-- MsgSeverity SEVERITY_LEVEL Severity level for the assertion. +-- MsgFormat VitalMemoryMsgFormatType +-- Format of the Test/Reference +-- signals in violation messages. +-- +-- INOUT +-- TimingData VitalMemoryTimingDataType +-- VitalMemorySetupHoldCheck information +-- storage area. This is used +-- internally to detect reference +-- edges and record the time of the +-- last edge. +-- +-- OUT +-- Violation X01 This is the violation flag returned. +-- X01ArrayT Overloaded for array type. +-- +-- +-- ---------------------------------------------------------------------------- + +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayType; + CONSTANT SetupLow : IN VitalDelayType; + CONSTANT HoldHigh : IN VitalDelayType; + CONSTANT HoldLow : IN VitalDelayType; + CONSTANT CheckEnabled : IN VitalBoolArrayT; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +); + +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayArrayType; + CONSTANT SetupLow : IN VitalDelayArrayType; + CONSTANT HoldHigh : IN VitalDelayArrayType; + CONSTANT HoldLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +); + +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayArrayType; + CONSTANT SetupLow : IN VitalDelayArrayType; + CONSTANT HoldHigh : IN VitalDelayArrayType; + CONSTANT HoldLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN VitalBoolArrayT; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +); + +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + SIGNAL RefSignal : IN std_logic_vector; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN VitalDelayArrayType; + CONSTANT SetupHigh : IN VitalDelayArrayType; + CONSTANT SetupLow : IN VitalDelayArrayType; + CONSTANT HoldHigh : IN VitalDelayArrayType; + CONSTANT HoldLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +); + +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + SIGNAL RefSignal : IN std_logic_vector; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN VitalDelayArrayType; + CONSTANT SetupHigh : IN VitalDelayArrayType; + CONSTANT SetupLow : IN VitalDelayArrayType; + CONSTANT HoldHigh : IN VitalDelayArrayType; + CONSTANT HoldLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN VitalBoolArrayT; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +); + +--------------- following are not needed -------------------------- + +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN VitalDelayArrayType; + CONSTANT SetupLow : IN VitalDelayArrayType; + CONSTANT HoldHigh : IN VitalDelayArrayType; + CONSTANT HoldLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +); + +PROCEDURE VitalMemorySetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalMemoryTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + SIGNAL RefSignal : IN std_logic_vector; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN VitalDelayArrayType; + CONSTANT SetupHigh : IN VitalDelayArrayType; + CONSTANT SetupLow : IN VitalDelayArrayType; + CONSTANT HoldHigh : IN VitalDelayArrayType; + CONSTANT HoldLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT ArcType : IN VitalMemoryArcType := CrossArc; + CONSTANT NumBitsPerSubWord : IN INTEGER := 1; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE +); + + +-- ---------------------------------------------------------------------------- +-- +-- Function Name: VitalPeriodPulseCheck +-- +-- Description: VitalPeriodPulseCheck checks for minimum and maximum +-- periodicity and pulse width for "1" and "0" values of +-- the input test signal. The timing constraint is +-- specified through parameters representing the minimal +-- period between successive rising and falling edges of +-- the input test signal and the minimum pulse widths +-- associated with high and low values. +-- +-- VitalPeriodCheck's accepts rising and falling edges +-- from 1 and 0 as well as transitions to and from 'X.' +-- +-- _______________ __________ +-- ____________| |_______| +-- +-- |<--- pw_hi --->| +-- |<-------- period ----->| +-- -->| pw_lo |<-- +-- +-- Arguments: +-- IN Type Description +-- TestSignal std_logic_vector Value of test signal +-- TestSignalName STRING Name of the test signal +-- TestDelay VitalDelayArrayType +-- Model's internal delay associated +-- with TestSignal +-- Period VitalDelayArrayType +-- Minimum period allowed between +-- consecutive rising ('P') or +-- falling ('F') transitions. +-- PulseWidthHigh VitalDelayArrayType +-- Minimum time allowed for a high +-- pulse ('1' or 'H') +-- PulseWidthLow VitalDelayArrayType +-- Minimum time allowed for a low +-- pulse ('0' or 'L') +-- CheckEnabled BOOLEAN Check performed if TRUE. +-- HeaderMsg STRING String that will accompany any +-- assertion messages produced. +-- XOn BOOLEAN If TRUE, Violation output parameter +-- is set to "X". Otherwise, Violation +-- is always set to "0." +-- MsgOn BOOLEAN If TRUE, period/pulse violation +-- message will be generated. +-- Otherwise, no messages are generated, +-- even though a violation is detected. +-- MsgSeverity SEVERITY_LEVEL Severity level for the assertion. +-- MsgFormat VitalMemoryMsgFormatType +-- Format of the Test/Reference signals +-- in violation messages. +-- +-- INOUT +-- PeriodData VitalPeriodDataArrayType +-- VitalPeriodPulseCheck information +-- storage area. This is used +-- internally to detect reference edges +-- and record the pulse and period +-- times. +-- OUT +-- Violation X01 This is the violation flag returned. +-- X01ArrayT Overloaded for array type. +-- +-- ---------------------------------------------------------------------------- +PROCEDURE VitalMemoryPeriodPulseCheck ( + VARIABLE Violation : OUT X01ArrayT; + VARIABLE PeriodData : INOUT VitalPeriodDataArrayType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + CONSTANT Period : IN VitalDelayArrayType; + CONSTANT PulseWidthHigh : IN VitalDelayArrayType; + CONSTANT PulseWidthLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType +); + +PROCEDURE VitalMemoryPeriodPulseCheck ( + VARIABLE Violation : OUT X01; + VARIABLE PeriodData : INOUT VitalPeriodDataArrayType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN VitalDelayArrayType; + CONSTANT Period : IN VitalDelayArrayType; + CONSTANT PulseWidthHigh : IN VitalDelayArrayType; + CONSTANT PulseWidthLow : IN VitalDelayArrayType; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT MsgFormat : IN VitalMemoryMsgFormatType +); + +-- ---------------------------------------------------------------------------- +-- Functionality Section +-- ---------------------------------------------------------------------------- + +-- ---------------------------------------------------------------------------- +-- All Memory Types and Record definitions. +-- ---------------------------------------------------------------------------- +TYPE MemoryWordType IS ARRAY (NATURAL RANGE <>) OF UX01; +TYPE MemoryWordPtr IS ACCESS MemoryWordType; + +TYPE MemoryArrayType IS ARRAY (NATURAL RANGE <>) OF MemoryWordPtr; +TYPE MemoryArrayPtrType IS ACCESS MemoryArrayType; + +TYPE VitalMemoryArrayRecType IS +RECORD +NoOfWords : POSITIVE; +NoOfBitsPerWord : POSITIVE; +NoOfBitsPerSubWord : POSITIVE; +NoOfBitsPerEnable : POSITIVE; +MemoryArrayPtr : MemoryArrayPtrType; +END RECORD; + +TYPE VitalMemoryDataType IS ACCESS VitalMemoryArrayRecType; + +TYPE VitalTimingDataVectorType IS +ARRAY (NATURAL RANGE <>) OF VitalTimingDataType; + +TYPE VitalMemoryViolFlagSizeType IS ARRAY (NATURAL RANGE <>) OF INTEGER; + +-- ---------------------------------------------------------------------------- +-- Symbol Literals used for Memory Table Modeling +-- ---------------------------------------------------------------------------- + +-- Symbol literals from '/' to 'S' are closely related to MemoryTableMatch +-- lookup matching and the order cannot be arbitrarily changed. +-- The remaining symbol literals are interpreted directly and matchting is +-- handled in the MemoryMatch procedure itself. + +TYPE VitalMemorySymbolType IS ( + '/', -- 0 -> 1 + '\', -- 1 -> 0 + 'P', -- Union of '/' and '^' (any edge to 1) + 'N', -- Union of '\' and 'v' (any edge to 0) + 'r', -- 0 -> X + 'f', -- 1 -> X + 'p', -- Union of '/' and 'r' (any edge from 0) + 'n', -- Union of '\' and 'f' (any edge from 1) + 'R', -- Union of '^' and 'p' (any possible rising edge) + 'F', -- Union of 'v' and 'n' (any possible falling edge) + '^', -- X -> 1 + 'v', -- X -> 0 + 'E', -- Union of 'v' and '^' (any edge from X) + 'A', -- Union of 'r' and '^' (rising edge to or from 'X') + + 'D', -- Union of 'f' and 'v' (falling edge to or from 'X') + + '*', -- Union of 'R' and 'F' (any edge) + 'X', -- Unknown level + '0', -- low level + '1', -- high level + '-', -- don't care + 'B', -- 0 or 1 + 'Z', -- High Impedance + 'S', -- steady value + + 'g', -- Good address (no transition) + 'u', -- Unknown address (no transition) + 'i', -- Invalid address (no transition) + 'G', -- Good address (with transition) + 'U', -- Unknown address (with transition) + 'I', -- Invalid address (with transition) + + 'w', -- Write data to memory + 's', -- Retain previous memory contents + + 'c', -- Corrupt entire memory with 'X' + 'l', -- Corrupt a word in memory with 'X' + 'd', -- Corrupt a single bit in memory with 'X' + 'e', -- Corrupt a word with 'X' based on data in + 'C', -- Corrupt a sub-word entire memory with 'X' + 'L', -- Corrupt a sub-word in memory with 'X' + + -- The following entries are commented since their + -- interpretation overlap with existing definitions. + + -- 'D', -- Corrupt a single bit of a sub-word with 'X' + -- 'E', -- Corrupt a sub-word with 'X' based on datain + + 'M', -- Implicit read data from memory + 'm', -- Read data from memory + 't' -- Immediate assign/transfer data in + +); + +TYPE VitalMemoryTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> ) + OF VitalMemorySymbolType; + +TYPE VitalMemoryViolationSymbolType IS ( + 'X', -- Unknown level + '0', -- low level + '-' -- don't care +); + +TYPE VitalMemoryViolationTableType IS + ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> ) + OF VitalMemoryViolationSymbolType; + +TYPE VitalPortType IS ( + UNDEF, + READ, + WRITE, + RDNWR +); + +TYPE VitalCrossPortModeType IS ( + CpRead, -- CpReadOnly, + WriteContention, -- WrContOnly, + ReadWriteContention, -- CpContention + CpReadAndWriteContention, -- WrContAndCpRead, + CpReadAndReadContention +); + +SUBTYPE VitalAddressValueType IS INTEGER; +TYPE VitalAddressValueVectorType IS + ARRAY (NATURAL RANGE <>) OF VitalAddressValueType; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalDeclareMemory +-- Parameters: NoOfWords - Number of words in the memory +-- NoOfBitsPerWord - Number of bits per word in memory +-- NoOfBitsPerSubWord - Number of bits per sub word +-- MemoryLoadFile - Name of data file to load +-- Description: This function is intended to be used to initialize +-- memory data declarations, i.e. to be executed duing +-- simulation elaboration time. Handles the allocation +-- and initialization of memory for the memory data. +-- Default NoOfBitsPerSubWord is NoOfBits. +-- ---------------------------------------------------------------------------- + +IMPURE FUNCTION VitalDeclareMemory ( + CONSTANT NoOfWords : IN POSITIVE; + CONSTANT NoOfBitsPerWord : IN POSITIVE; + CONSTANT NoOfBitsPerSubWord : IN POSITIVE; + CONSTANT MemoryLoadFile : IN string := ""; + CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE +) RETURN VitalMemoryDataType; + +IMPURE FUNCTION VitalDeclareMemory ( + CONSTANT NoOfWords : IN POSITIVE; + CONSTANT NoOfBitsPerWord : IN POSITIVE; + CONSTANT MemoryLoadFile : IN string := ""; + CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE +) RETURN VitalMemoryDataType; + + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryTable +-- Parameters: DataOutBus - Output candidate zero delay data bus out +-- MemoryData - Pointer to memory data structure +-- PrevControls - Previous data in for edge detection +-- PrevEnableBus - Previous enables for edge detection +-- PrevDataInBus - Previous data bus for edge detection +-- PrevAddressBus - Previous address bus for edge detection +-- PortFlag - Indicates port operating mode +-- PortFlagArray - Vector form of PortFlag for sub-word +-- Controls - Agregate of scalar control lines +-- EnableBus - Concatenation of vector control lines +-- DataInBus - Input value of data bus in +-- AddressBus - Input value of address bus in +-- AddressValue - Decoded value of the AddressBus +-- MemoryTable - Input memory action table +-- PortType - The type of port (currently not used) +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control the generation of messages +-- MsgSeverity - Control level of message generation +-- Description: This procedure implements the majority of the memory +-- modeling functionality via lookup of the memory action +-- tables and performing the specified actions if matches +-- are found, or the default actions otherwise. The +-- overloadings are provided for the word and sub-word +-- (using the EnableBus and PortFlagArray arguments) addressing +-- cases. +-- ---------------------------------------------------------------------------- + +PROCEDURE VitalMemoryTable ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PrevControls : INOUT std_logic_vector; + VARIABLE PrevDataInBus : INOUT std_logic_vector; + VARIABLE PrevAddressBus : INOUT std_logic_vector; + VARIABLE PortFlag : INOUT VitalPortFlagVectorType; + CONSTANT Controls : IN std_logic_vector; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressBus : IN std_logic_vector; + VARIABLE AddressValue : INOUT VitalAddressValueType; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType := UNDEF; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +); + +PROCEDURE VitalMemoryTable ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PrevControls : INOUT std_logic_vector; + VARIABLE PrevEnableBus : INOUT std_logic_vector; + VARIABLE PrevDataInBus : INOUT std_logic_vector; + VARIABLE PrevAddressBus : INOUT std_logic_vector; + VARIABLE PortFlagArray : INOUT VitalPortFlagVectorType; + CONSTANT Controls : IN std_logic_vector; + CONSTANT EnableBus : IN std_logic_vector; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressBus : IN std_logic_vector; + VARIABLE AddressValue : INOUT VitalAddressValueType; + CONSTANT MemoryTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType := UNDEF; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +); + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryCrossPorts +-- Parameters: DataOutBus - Output candidate zero delay data bus out +-- MemoryData - Pointer to memory data structure +-- SamePortFlag - Operating mode for same port +-- SamePortAddressValue - Decoded AddressBus for same port +-- CrossPortFlagArray - Operating modes for cross ports +-- CrossPortAddressArray - Decoded AddressBus for cross ports +-- CrossPortMode - Write contention and crossport read control +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control the generation of messages +-- +-- Description: These procedures control the effect of memory operations +-- on a given port due to operations on other ports in a +-- multi-port memory. +-- This includes data write through when reading and writing +-- to the same address, as well as write contention when +-- there are multiple write to the same address. +-- If addresses do not match then data bus is unchanged. +-- The DataOutBus can be diabled with 'Z' value. +-- ---------------------------------------------------------------------------- + +PROCEDURE VitalMemoryCrossPorts ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE SamePortFlag : INOUT VitalPortFlagVectorType; + CONSTANT SamePortAddressValue : IN VitalAddressValueType; + CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType; + CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType; + CONSTANT CrossPortMode : IN VitalCrossPortModeType + := CpReadAndWriteContention; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) ; + +PROCEDURE VitalMemoryCrossPorts ( + VARIABLE MemoryData : INOUT VitalMemoryDataType; + CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType; + CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE +) ; + +-- ---------------------------------------------------------------------------- +-- Procedure: VitalMemoryViolation +-- Parameters: DataOutBus - Output zero delay data bus out +-- MemoryData - Pointer to memory data structure +-- PortFlag - Indicates port operating mode +-- DataInBus - Input value of data bus in +-- AddressValue - Decoded value of the AddressBus +-- ViolationFlags - Aggregate of scalar violation vars +-- ViolationFlagsArray - Concatenation of vector violation vars +-- ViolationTable - Input memory violation table +-- PortType - The type of port (currently not used) +-- PortName - Port name string for messages +-- HeaderMsg - Header string for messages +-- MsgOn - Control the generation of messages +-- MsgSeverity - Control level of message generation +-- Description: This procedure is intended to implement all actions on the +-- memory contents and data out bus as a result of timing viols. +-- It uses the memory action table to perform various corruption +-- policies specified by the user. +-- ---------------------------------------------------------------------------- + +PROCEDURE VitalMemoryViolation ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PortFlag : INOUT VitalPortFlagVectorType; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressValue : IN VitalAddressValueType; + CONSTANT ViolationFlags : IN std_logic_vector; + CONSTANT ViolationFlagsArray : IN X01ArrayT; + CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType; + CONSTANT ViolationTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) ; + +PROCEDURE VitalMemoryViolation ( + VARIABLE DataOutBus : INOUT std_logic_vector; + VARIABLE MemoryData : INOUT VitalMemoryDataType; + VARIABLE PortFlag : INOUT VitalPortFlagVectorType; + CONSTANT DataInBus : IN std_logic_vector; + CONSTANT AddressValue : IN VitalAddressValueType; + CONSTANT ViolationFlags : IN std_logic_vector; + CONSTANT ViolationTable : IN VitalMemoryTableType; + CONSTANT PortType : IN VitalPortType; + CONSTANT PortName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := ""; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING +) ; + +END Vital_Memory; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/prmtvs_b.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/prmtvs_b.vhdl new file mode 100644 index 00000000..dcfc92b2 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/prmtvs_b.vhdl @@ -0,0 +1,5622 @@ +------------------------------------------------------------------------------- +-- Title : Standard VITAL_Primitives Package +-- : $Revision$ +-- : +-- Library : VITAL +-- : +-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4 +-- : +-- Purpose : This packages defines standard types, constants, functions +-- : and procedures for use in developing ASIC models. +-- : Specifically a set of logic primitives are defined. +-- : +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Modification History : +-- ---------------------------------------------------------------------------- +-- Version No:|Auth:| Mod.Date:| Changes Made: +-- v95.0 A | | 06/02/95 | Initial ballot draft 1995 +-- v95.1 | | 08/31/95 | #204 - glitch detection prior to OutputMap +-- ---------------------------------------------------------------------------- +-- v95.2 | ddl | 09/14/96 | #223 - single input prmtvs use on-detect +-- | | | instead of glitch-on-event behavior +-- v95.3 | ddl | 09/24/96 | #236 - VitalTruthTable DataIn should be of +-- | | | of class SIGNAL +-- v95.4 | ddl | 01/16/97 | #243 - index constraint error in nbit xor/xnor +-- v99.1 | dbb | 03/31/99 | Updated for VHDL 93 +-- ---------------------------------------------------------------------------- + +LIBRARY STD; +USE STD.TEXTIO.ALL; + +PACKAGE BODY VITAL_Primitives IS + -- ------------------------------------------------------------------------ + -- Default values for Primitives + -- ------------------------------------------------------------------------ + -- default values for delay parameters + CONSTANT VitalDefDelay01 : VitalDelayType01 := VitalZeroDelay01; + CONSTANT VitalDefDelay01Z : VitalDelayType01Z := VitalZeroDelay01Z; + + TYPE VitalTimeArray IS ARRAY (NATURAL RANGE <>) OF TIME; + + -- default primitive model operation parameters + -- Glitch detection/reporting + TYPE VitalGlitchModeType IS ( MessagePlusX, MessageOnly, XOnly, NoGlitch); + CONSTANT PrimGlitchMode : VitalGlitchModeType := XOnly; + + -- ------------------------------------------------------------------------ + -- Local Type and Subtype Declarations + -- ------------------------------------------------------------------------ + --------------------------------------------------------------------------- + -- enumeration value representing the transition or level of the signal. + -- See function 'GetEdge' + --------------------------------------------------------------------------- + TYPE EdgeType IS ( 'U', -- Uninitialized level + 'X', -- Unknown level + '0', -- low level + '1', -- high level + '\', -- 1 to 0 falling edge + '/', -- 0 to 1 rising edge + 'F', -- * to 0 falling edge + 'R', -- * to 1 rising edge + 'f', -- rising to X edge + 'r', -- falling to X edge + 'x', -- Unknown edge (ie U->X) + 'V' -- Timing violation edge + ); + TYPE EdgeArray IS ARRAY ( NATURAL RANGE <> ) OF EdgeType; + + TYPE EdgeX1Table IS ARRAY ( EdgeType ) OF EdgeType; + TYPE EdgeX2Table IS ARRAY ( EdgeType, EdgeType ) OF EdgeType; + TYPE EdgeX3Table IS ARRAY ( EdgeType, EdgeType, EdgeType ) OF EdgeType; + TYPE EdgeX4Table IS ARRAY (EdgeType,EdgeType,EdgeType,EdgeType) OF EdgeType; + + TYPE LogicToEdgeT IS ARRAY(std_ulogic, std_ulogic) OF EdgeType; + TYPE LogicToLevelT IS ARRAY(std_ulogic ) OF EdgeType; + + TYPE GlitchDataType IS + RECORD + SchedTime : TIME; + GlitchTime : TIME; + SchedValue : std_ulogic; + CurrentValue : std_ulogic; + END RECORD; + TYPE GlitchDataArrayType IS ARRAY (NATURAL RANGE <>) + OF GlitchDataType; + + -- Enumerated type used in selection of output path delays + TYPE SchedType IS + RECORD + inp0 : TIME; -- time (abs) of output change due to input change to 0 + inp1 : TIME; -- time (abs) of output change due to input change to 1 + InpX : TIME; -- time (abs) of output change due to input change to X + Glch0 : TIME; -- time (abs) of output glitch due to input change to 0 + Glch1 : TIME; -- time (abs) of output glitch due to input change to 0 + END RECORD; + + TYPE SchedArray IS ARRAY ( NATURAL RANGE <> ) OF SchedType; + CONSTANT DefSchedType : SchedType := (TIME'HIGH, TIME'HIGH, 0 ns,0 ns,0 ns); + CONSTANT DefSchedAnd : SchedType := (TIME'HIGH, 0 ns,0 ns, TIME'HIGH,0 ns); + + -- Constrained array declarations (common sizes used by primitives) + SUBTYPE SchedArray2 IS SchedArray(1 DOWNTO 0); + SUBTYPE SchedArray3 IS SchedArray(2 DOWNTO 0); + SUBTYPE SchedArray4 IS SchedArray(3 DOWNTO 0); + SUBTYPE SchedArray8 IS SchedArray(7 DOWNTO 0); + + SUBTYPE TimeArray2 IS VitalTimeArray(1 DOWNTO 0); + SUBTYPE TimeArray3 IS VitalTimeArray(2 DOWNTO 0); + SUBTYPE TimeArray4 IS VitalTimeArray(3 DOWNTO 0); + SUBTYPE TimeArray8 IS VitalTimeArray(7 DOWNTO 0); + + SUBTYPE GlitchArray2 IS GlitchDataArrayType(1 DOWNTO 0); + SUBTYPE GlitchArray3 IS GlitchDataArrayType(2 DOWNTO 0); + SUBTYPE GlitchArray4 IS GlitchDataArrayType(3 DOWNTO 0); + SUBTYPE GlitchArray8 IS GlitchDataArrayType(7 DOWNTO 0); + + SUBTYPE EdgeArray2 IS EdgeArray(1 DOWNTO 0); + SUBTYPE EdgeArray3 IS EdgeArray(2 DOWNTO 0); + SUBTYPE EdgeArray4 IS EdgeArray(3 DOWNTO 0); + SUBTYPE EdgeArray8 IS EdgeArray(7 DOWNTO 0); + + CONSTANT DefSchedArray2 : SchedArray2 := + (OTHERS=> (0 ns, 0 ns, 0 ns, 0 ns, 0 ns)); + + TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic; + + CONSTANT InitialEdge : LogicToLevelT := ( + '1'|'H' => 'R', + '0'|'L' => 'F', + OTHERS => 'x' + ); + + CONSTANT LogicToEdge : LogicToEdgeT := ( -- previous, current + -- old \ new: U X 0 1 Z W L H - + 'U' => ( 'U', 'x', 'F', 'R', 'x', 'x', 'F', 'R', 'x' ), + 'X' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ), + '0' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ), + '1' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ), + 'Z' => ( 'x', 'X', 'F', 'R', 'X', 'x', 'F', 'R', 'x' ), + 'W' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ), + 'L' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ), + 'H' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ), + '-' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ) + ); + CONSTANT LogicToLevel : LogicToLevelT := ( + '1'|'H' => '1', + '0'|'L' => '0', + 'U' => 'U', + OTHERS => 'X' + ); + + -- ----------------------------------- + -- 3-state logic tables + -- ----------------------------------- + CONSTANT BufIf0_Table : stdlogic_table := + -- enable data value + ( '1'|'H' => ( OTHERS => 'Z' ), + '0'|'L' => ( '1'|'H' => '1', + '0'|'L' => '0', + 'U' => 'U', + OTHERS => 'X' ), + 'U' => ( OTHERS => 'U' ), + OTHERS => ( OTHERS => 'X' ) ); + CONSTANT BufIf1_Table : stdlogic_table := + -- enable data value + ( '0'|'L' => ( OTHERS => 'Z' ), + '1'|'H' => ( '1'|'H' => '1', + '0'|'L' => '0', + 'U' => 'U', + OTHERS => 'X' ), + 'U' => ( OTHERS => 'U' ), + OTHERS => ( OTHERS => 'X' ) ); + CONSTANT InvIf0_Table : stdlogic_table := + -- enable data value + ( '1'|'H' => ( OTHERS => 'Z' ), + '0'|'L' => ( '1'|'H' => '0', + '0'|'L' => '1', + 'U' => 'U', + OTHERS => 'X' ), + 'U' => ( OTHERS => 'U' ), + OTHERS => ( OTHERS => 'X' ) ); + CONSTANT InvIf1_Table : stdlogic_table := + -- enable data value + ( '0'|'L' => ( OTHERS => 'Z' ), + '1'|'H' => ( '1'|'H' => '0', + '0'|'L' => '1', + 'U' => 'U', + OTHERS => 'X' ), + 'U' => ( OTHERS => 'U' ), + OTHERS => ( OTHERS => 'X' ) ); + + + TYPE To_StateCharType IS ARRAY (VitalStateSymbolType) OF CHARACTER; + CONSTANT To_StateChar : To_StateCharType := + ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v', + 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S' ); + TYPE To_TruthCharType IS ARRAY (VitalTruthSymbolType) OF CHARACTER; + CONSTANT To_TruthChar : To_TruthCharType := + ( 'X', '0', '1', '-', 'B', 'Z' ); + + TYPE TruthTableOutMapType IS ARRAY (VitalTruthSymbolType) OF std_ulogic; + CONSTANT TruthTableOutMap : TruthTableOutMapType := + -- 'X', '0', '1', '-', 'B', 'Z' + ( 'X', '0', '1', 'X', '-', 'Z' ); + + TYPE StateTableOutMapType IS ARRAY (VitalStateSymbolType) OF std_ulogic; + -- does conversion to X01Z or '-' if invalid + CONSTANT StateTableOutMap : StateTableOutMapType := + -- '/' '\' 'P' 'N' 'r' 'f' 'p' 'n' 'R' 'F' '^' 'v' + -- 'E' 'A' 'D' '*' 'X' '0' '1' '-' 'B' 'Z' 'S' + ( '-','-','-','-','-','-','-','-','-','-','-','-', + '-','-','-','-','X','0','1','X','-','Z','W'); + + -- ------------------------------------------------------------------------ + TYPE ValidTruthTableInputType IS ARRAY (VitalTruthSymbolType) OF BOOLEAN; + -- checks if a symbol IS valid for the stimulus portion of a truth table + CONSTANT ValidTruthTableInput : ValidTruthTableInputType := + -- 'X' '0' '1' '-' 'B' 'Z' + ( TRUE, TRUE, TRUE, TRUE, TRUE, FALSE ); + + TYPE TruthTableMatchType IS ARRAY (X01, VitalTruthSymbolType) OF BOOLEAN; + -- checks if an input matches th corresponding truth table symbol + -- use: TruthTableMatch(input_converted_to_X01, truth_table_stimulus_symbol) + CONSTANT TruthTableMatch : TruthTableMatchType := ( + -- X, 0, 1, - B Z + ( TRUE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- X + ( FALSE, TRUE, FALSE, TRUE, TRUE, FALSE ), -- 0 + ( FALSE, FALSE, TRUE, TRUE, TRUE, FALSE ) -- 1 + ); + + -- ------------------------------------------------------------------------ + TYPE ValidStateTableInputType IS ARRAY (VitalStateSymbolType) OF BOOLEAN; + CONSTANT ValidStateTableInput : ValidStateTableInputType := + -- '/', '\', 'P', 'N', 'r', 'f', + ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, + -- 'p', 'n', 'R', 'F', '^', 'v', + TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, + -- 'E', 'A', 'D', '*', + TRUE, TRUE, TRUE, TRUE, + -- 'X', '0', '1', '-', 'B', 'Z', + TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, + -- 'S' + TRUE ); + + CONSTANT ValidStateTableState : ValidStateTableInputType := + -- '/', '\', 'P', 'N', 'r', 'f', + ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + -- 'p', 'n', 'R', 'F', '^', 'v', + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + -- 'E', 'A', 'D', '*', + FALSE, FALSE, FALSE, FALSE, + -- 'X', '0', '1', '-', 'B', 'Z', + TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, + -- 'S' + FALSE ); + + TYPE StateTableMatchType IS ARRAY (X01,X01,VitalStateSymbolType) OF BOOLEAN; + -- last value, present value, table symbol + CONSTANT StateTableMatch : StateTableMatchType := ( + ( -- X (lastvalue) + -- / \ P N r f + -- p n R F ^ v + -- E A D * + -- X 0 1 - B Z S + (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE, + TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE), + (FALSE,FALSE,FALSE,TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,TRUE, FALSE,TRUE, + TRUE, FALSE,TRUE, TRUE, + FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE), + (FALSE,FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,FALSE,TRUE, FALSE,TRUE, FALSE, + TRUE, TRUE, FALSE,TRUE, + FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE) + ), + + (-- 0 (lastvalue) + -- / \ P N r f + -- p n R F ^ v + -- E A D * + -- X 0 1 - B Z S + (FALSE,FALSE,FALSE,FALSE,TRUE, FALSE, + TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,TRUE, FALSE,TRUE, + TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE), + (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE, + FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE ), + (TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, + TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,TRUE, + FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE) + ), + + (-- 1 (lastvalue) + -- / \ P N r f + -- p n R F ^ v + -- E A D * + -- X 0 1 - B Z S + (FALSE,FALSE,FALSE,FALSE,FALSE,TRUE , + FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, + FALSE,FALSE,TRUE, TRUE, + TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE), + (FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, + FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, + FALSE,FALSE,FALSE,TRUE, + FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE), + (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE ) + ) + ); + + TYPE Logic_UX01Z_Table IS ARRAY (std_ulogic) OF UX01Z; + ---------------------------------------------------------- + -- table name : cvt_to_x01z + -- parameters : std_ulogic -- some logic value + -- returns : UX01Z -- state value of logic value + -- purpose : to convert state-strength to state only + ---------------------------------------------------------- + CONSTANT cvt_to_ux01z : Logic_UX01Z_Table := + ('U','X','0','1','Z','X','0','1','X' ); + + TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER; + CONSTANT LogicCvtTable : LogicCvtTableType + := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); + + -------------------------------------------------------------------- + -- LOCAL Utilities + -------------------------------------------------------------------- + -- ------------------------------------------------------------------------ + -- FUNCTION NAME : MINIMUM + -- + -- PARAMETERS : in1, in2 - integer, time + -- + -- DESCRIPTION : return smaller of in1 and in2 + -- ------------------------------------------------------------------------ + FUNCTION Minimum ( + CONSTANT in1, in2 : INTEGER + ) RETURN INTEGER IS + BEGIN + IF (in1 < in2) THEN + RETURN in1; + END IF; + RETURN in2; + END; + -- ------------------------------------------------------------------------ + FUNCTION Minimum ( + CONSTANT t1,t2 : IN TIME + ) RETURN TIME IS + BEGIN + IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF; + END Minimum; + + -- ------------------------------------------------------------------------ + -- FUNCTION NAME : MAXIMUM + -- + -- PARAMETERS : in1, in2 - integer, time + -- + -- DESCRIPTION : return larger of in1 and in2 + -- ------------------------------------------------------------------------ + FUNCTION Maximum ( + CONSTANT in1, in2 : INTEGER + ) RETURN INTEGER IS + BEGIN + IF (in1 > in2) THEN + RETURN in1; + END IF; + RETURN in2; + END; + ----------------------------------------------------------------------- + FUNCTION Maximum ( + CONSTANT t1,t2 : IN TIME + ) RETURN TIME IS + BEGIN + IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF; + END Maximum; + + ----------------------------------------------------------------------- + FUNCTION GlitchMinTime ( + CONSTANT Time1, Time2 : IN TIME + ) RETURN TIME IS + BEGIN + IF ( Time1 >= NOW ) THEN + IF ( Time2 >= NOW ) THEN + RETURN Minimum ( Time1, Time2); + ELSE + RETURN Time1; + END IF; + ELSE + IF ( Time2 >= NOW ) THEN + RETURN Time2; + ELSE + RETURN 0 ns; + END IF; + END IF; + END; + + -------------------------------------------------------------------- + -- Error Message Types and Tables + -------------------------------------------------------------------- + TYPE VitalErrorType IS ( + ErrNegDel, + ErrInpSym, + ErrOutSym, + ErrStaSym, + ErrVctLng, + ErrTabWidSml, + ErrTabWidLrg, + ErrTabResSml, + ErrTabResLrg + ); + + TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL; + CONSTANT VitalErrorSeverity : VitalErrorSeverityType := ( + ErrNegDel => WARNING, + ErrInpSym => ERROR, + ErrOutSym => ERROR, + ErrStaSym => ERROR, + ErrVctLng => ERROR, + ErrTabWidSml => ERROR, + ErrTabWidLrg => WARNING, + ErrTabResSml => WARNING, + ErrTabResLrg => WARNING + ); + + CONSTANT MsgNegDel : STRING := + "Negative delay. New output value not scheduled. Output signal is: "; + CONSTANT MsgInpSym : STRING := + "Illegal symbol in the input portion of a Truth/State table."; + CONSTANT MsgOutSym : STRING := + "Illegal symbol in the output portion of a Truth/State table."; + CONSTANT MsgStaSym : STRING := + "Illegal symbol in the state portion of a State table."; + CONSTANT MsgVctLng : STRING := + "Vector (array) lengths not equal. "; + CONSTANT MsgTabWidSml : STRING := + "Width of the Truth/State table is too small."; + CONSTANT MsgTabWidLrg : STRING := + "Width of Truth/State table is too large. Extra elements are ignored."; + CONSTANT MsgTabResSml : STRING := + "Result of Truth/State table has too many elements."; + CONSTANT MsgTabResLrg : STRING := + "Result of Truth/State table has too few elements."; + + CONSTANT MsgUnknown : STRING := + "Unknown error message."; + + -------------------------------------------------------------------- + -- LOCAL Utilities + -------------------------------------------------------------------- + FUNCTION VitalMessage ( + CONSTANT ErrorId : IN VitalErrorType + ) RETURN STRING IS + BEGIN + CASE ErrorId IS + WHEN ErrNegDel => RETURN MsgNegDel; + WHEN ErrInpSym => RETURN MsgInpSym; + WHEN ErrOutSym => RETURN MsgOutSym; + WHEN ErrStaSym => RETURN MsgStaSym; + WHEN ErrVctLng => RETURN MsgVctLng; + WHEN ErrTabWidSml => RETURN MsgTabWidSml; + WHEN ErrTabWidLrg => RETURN MsgTabWidLrg; + WHEN ErrTabResSml => RETURN MsgTabResSml; + WHEN ErrTabResLrg => RETURN MsgTabResLrg; + WHEN OTHERS => RETURN MsgUnknown; + END CASE; + END; + + PROCEDURE VitalError ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalErrorType + ) IS + BEGIN + ASSERT FALSE + REPORT Routine & ": " & VitalMessage(ErrorId) + SEVERITY VitalErrorSeverity(ErrorId); + END; + + PROCEDURE VitalError ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalErrorType; + CONSTANT Info : IN STRING + ) IS + BEGIN + ASSERT FALSE + REPORT Routine & ": " & VitalMessage(ErrorId) & Info + SEVERITY VitalErrorSeverity(ErrorId); + END; + + PROCEDURE VitalError ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalErrorType; + CONSTANT Info : IN CHARACTER + ) IS + BEGIN + ASSERT FALSE + REPORT Routine & ": " & VitalMessage(ErrorId) & Info + SEVERITY VitalErrorSeverity(ErrorId); + END; + + --------------------------------------------------------------------------- + PROCEDURE ReportGlitch ( + CONSTANT GlitchRoutine : IN STRING; + CONSTANT OutSignalName : IN STRING; + CONSTANT PreemptedTime : IN TIME; + CONSTANT PreemptedValue : IN std_ulogic; + CONSTANT NewTime : IN TIME; + CONSTANT NewValue : IN std_ulogic; + CONSTANT Index : IN INTEGER := 0; + CONSTANT IsArraySignal : IN BOOLEAN := FALSE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ) IS + + VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE; + BEGIN + + Write (StrPtr1, PreemptedTime ); + Write (StrPtr2, NewTime); + Write (StrPtr3, LogicCvtTable(PreemptedValue)); + Write (StrPtr4, LogicCvtTable(NewValue)); + IF IsArraySignal THEN + Write (StrPtr5, STRING'( "(" ) ); + Write (StrPtr5, Index); + Write (StrPtr5, STRING'( ")" ) ); + ELSE + Write (StrPtr5, STRING'( " " ) ); + END IF; + + -- Issue Report only if Preemted value has not been + -- removed from event queue + ASSERT PreemptedTime > NewTime + REPORT GlitchRoutine & ": GLITCH Detected on port " & + OutSignalName & StrPtr5.ALL & + "; Preempted Future Value := " & StrPtr3.ALL & + " @ " & StrPtr1.ALL & + "; Newly Scheduled Value := " & StrPtr4.ALL & + " @ " & StrPtr2.ALL & + ";" + SEVERITY MsgSeverity; + + DEALLOCATE(StrPtr1); + DEALLOCATE(StrPtr2); + DEALLOCATE(StrPtr3); + DEALLOCATE(StrPtr4); + DEALLOCATE(StrPtr5); + RETURN; + END ReportGlitch; + + --------------------------------------------------------------------------- + -- Procedure : VitalGlitchOnEvent + -- : + -- Parameters : OutSignal ........ signal being driven + -- : OutSignalName..... name of the driven signal + -- : GlitchData........ internal data required by the procedure + -- : NewValue.......... new value being assigned + -- : NewDelay.......... Delay accompanying the assignment + -- : (Note: for vectors, this is an array) + -- : GlitchMode........ Glitch generation mode + -- : MessagePlusX, MessageOnly, + -- : XOnly, NoGlitch ) + -- : GlitchDelay....... if <= 0 ns , then there will be no Glitch + -- : if > NewDelay, then there is no Glitch, + -- : otherwise, this is the time when a FORCED + -- : generation of a glitch will occur. + ---------------------------------------------------------------------------- + PROCEDURE VitalGlitchOnEvent ( + SIGNAL OutSignal : OUT std_logic; + CONSTANT OutSignalName : IN STRING; + VARIABLE GlitchData : INOUT GlitchDataType; + CONSTANT NewValue : IN std_logic; + CONSTANT NewDelay : IN TIME := 0 ns; + CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX; + CONSTANT GlitchDelay : IN TIME := -1 ns; -- IR#223 + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ) IS + -- ------------------------------------------------------------------------ + VARIABLE NoGlitchDet : BOOLEAN := FALSE; + VARIABLE OldGlitch : BOOLEAN := FALSE; + VARIABLE Dly : TIME := NewDelay; + + BEGIN + -- If nothing to schedule, just return + IF NewDelay < 0 ns THEN + IF (NewValue /= GlitchData.SchedValue) THEN + VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName ); + END IF; + + ELSE + -- If nothing currently scheduled + IF GlitchData.SchedTime <= NOW THEN + GlitchData.CurrentValue := GlitchData.SchedValue; + IF (GlitchDelay <= 0 ns) THEN + IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF; + NoGlitchDet := TRUE; + END IF; + + -- Transaction currently scheduled - if glitch already happened + ELSIF GlitchData.GlitchTime <= NOW THEN + GlitchData.CurrentValue := 'X'; + OldGlitch := TRUE; + IF (GlitchData.SchedValue = NewValue) THEN + dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); + END IF; + + -- Transaction currently scheduled (no glitch if same value) + ELSIF (GlitchData.SchedValue = NewValue) AND + (GlitchData.SchedTime = GlitchData.GlitchTime) AND + (GlitchDelay <= 0 ns) THEN + NoGlitchDet := TRUE; + Dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); + + END IF; + + GlitchData.SchedTime := NOW+Dly; + IF OldGlitch THEN + OutSignal <= NewValue AFTER Dly; + + ELSIF NoGlitchDet THEN + GlitchData.GlitchTime := NOW+Dly; + OutSignal <= NewValue AFTER Dly; + + ELSE -- new glitch + GlitchData.GlitchTime := GlitchMinTime ( GlitchData.GlitchTime, + NOW+GlitchDelay ); + + IF (GlitchMode = MessagePlusX) OR + (GlitchMode = MessageOnly) THEN + ReportGlitch ( "VitalGlitchOnEvent", OutSignalName, + GlitchData.GlitchTime, GlitchData.SchedValue, + (Dly + NOW), NewValue, + MsgSeverity=>MsgSeverity ); + END IF; + + IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN + OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW; + OutSignal <= TRANSPORT NewValue AFTER Dly; + ELSE + OutSignal <= NewValue AFTER Dly; + END IF; + END IF; + + GlitchData.SchedValue := NewValue; + END IF; + + RETURN; + END; + + ---------------------------------------------------------------------------- + PROCEDURE VitalGlitchOnEvent ( + SIGNAL OutSignal : OUT std_logic_vector; + CONSTANT OutSignalName : IN STRING; + VARIABLE GlitchData : INOUT GlitchDataArrayType; + CONSTANT NewValue : IN std_logic_vector; + CONSTANT NewDelay : IN VitalTimeArray; + CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX; + CONSTANT GlitchDelay : IN VitalTimeArray; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ) IS + + ALIAS GlDataAlias : GlitchDataArrayType(1 TO GlitchData'LENGTH) + IS GlitchData; + ALIAS NewValAlias : std_logic_vector(1 TO NewValue'LENGTH) IS NewValue; + ALIAS GlDelayAlias : VitalTimeArray(1 TO GlitchDelay'LENGTH) + IS GlitchDelay; + ALIAS NewDelAlias : VitalTimeArray(1 TO NewDelay'LENGTH) IS NewDelay; + + VARIABLE Index : INTEGER := OutSignal'LEFT; + VARIABLE Direction : INTEGER; + VARIABLE NoGlitchDet : BOOLEAN; + VARIABLE OldGlitch : BOOLEAN; + VARIABLE Dly, GlDly : TIME; + + BEGIN + IF (OutSignal'LEFT > OutSignal'RIGHT) THEN + Direction := -1; + ELSE + Direction := 1; + END IF; + + IF ( (OutSignal'LENGTH /= GlitchData'LENGTH) OR + (OutSignal'LENGTH /= NewValue'LENGTH) OR + (OutSignal'LENGTH /= NewDelay'LENGTH) OR + (OutSignal'LENGTH /= GlitchDelay'LENGTH) ) THEN + VitalError ( "VitalGlitchOnEvent", ErrVctLng, OutSignalName ); + RETURN; + END IF; + + -- a call to the scalar function cannot be made since the actual + -- name associated with a signal parameter must be locally static + FOR n IN 1 TO OutSignal'LENGTH LOOP + + NoGlitchDet := FALSE; + OldGlitch := FALSE; + Dly := NewDelAlias(n); + + -- If nothing to schedule, just skip to next loop iteration + IF NewDelAlias(n) < 0 ns THEN + IF (NewValAlias(n) /= GlDataAlias(n).SchedValue) THEN + VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName ); + END IF; + ELSE + -- If nothing currently scheduled (i.e. last scheduled + -- transaction already occurred) + IF GlDataAlias(n).SchedTime <= NOW THEN + GlDataAlias(n).CurrentValue := GlDataAlias(n).SchedValue; + IF (GlDelayAlias(n) <= 0 ns) THEN + -- Next iteration if no change in value + IF (NewValAlias(n) = GlDataAlias(n).SchedValue) THEN + Index := Index + Direction; + NEXT; + END IF; + -- since last transaction already occurred there is no glitch + NoGlitchDet := TRUE; + END IF; + + -- Transaction currently scheduled - if glitch already happened + ELSIF GlDataAlias(n).GlitchTime <= NOW THEN + GlDataAlias(n).CurrentValue := 'X'; + OldGlitch := TRUE; + IF (GlDataAlias(n).SchedValue = NewValAlias(n)) THEN + dly := Minimum( GlDataAlias(n).SchedTime-NOW, + NewDelAlias(n) ); + END IF; + + -- Transaction currently scheduled + ELSIF (GlDataAlias(n).SchedValue = NewValAlias(n)) AND + (GlDataAlias(n).SchedTime = GlDataAlias(n).GlitchTime) AND + (GlDelayAlias(n) <= 0 ns) THEN + NoGlitchDet := TRUE; + Dly := Minimum( GlDataAlias(n).SchedTime-NOW, + NewDelAlias(n) ); + END IF; + + -- update last scheduled transaction + GlDataAlias(n).SchedTime := NOW+Dly; + + IF OldGlitch THEN + OutSignal(Index) <= NewValAlias(n) AFTER Dly; + ELSIF NoGlitchDet THEN + -- if no glitch then update last glitch time + -- and OutSignal(actual_index) + GlDataAlias(n).GlitchTime := NOW+Dly; + OutSignal(Index) <= NewValAlias(n) AFTER Dly; + ELSE -- new glitch + GlDataAlias(n).GlitchTime := GlitchMinTime ( + GlDataAlias(n).GlitchTime, + NOW+GlDelayAlias(n) ); + + IF (GlitchMode = MessagePlusX) OR + (GlitchMode = MessageOnly) THEN + ReportGlitch ( "VitalGlitchOnEvent", OutSignalName, + GlDataAlias(n).GlitchTime, + GlDataAlias(n).SchedValue, + (Dly + NOW), NewValAlias(n), + Index, TRUE, MsgSeverity ); + END IF; + + IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN + GlDly := GlDataAlias(n).GlitchTime - NOW; + OutSignal(Index) <= 'X' AFTER GlDly; + OutSignal(Index) <= TRANSPORT NewValAlias(n) AFTER Dly; + ELSE + OutSignal(Index) <= NewValAlias(n) AFTER Dly; + END IF; + + END IF; -- glitch / no-glitch + GlDataAlias(n).SchedValue := NewValAlias(n); + + END IF; -- NewDelAlias(n) < 0 ns + Index := Index + Direction; + END LOOP; + + RETURN; + END; + + --------------------------------------------------------------------------- + -- ------------------------------------------------------------------------ + -- PROCEDURE NAME : TruthOutputX01Z + -- + -- PARAMETERS : table_out - output of table + -- X01Zout - output converted to X01Z + -- err - true if illegal character is encountered + -- + -- + -- DESCRIPTION : converts the output of a truth table to a valid + -- std_ulogic + -- ------------------------------------------------------------------------ + PROCEDURE TruthOutputX01Z ( + CONSTANT TableOut : IN VitalTruthSymbolType; + VARIABLE X01Zout : OUT std_ulogic; + VARIABLE Err : OUT BOOLEAN + ) IS + VARIABLE TempOut : std_ulogic; + BEGIN + Err := FALSE; + TempOut := TruthTableOutMap(TableOut); + IF (TempOut = '-') THEN + Err := TRUE; + TempOut := 'X'; + VitalError ( "VitalTruthTable", ErrOutSym, To_TruthChar(TableOut)); + END IF; + X01Zout := TempOut; + END; + + -- ------------------------------------------------------------------------ + -- PROCEDURE NAME : StateOutputX01Z + -- + -- PARAMETERS : table_out - output of table + -- prev_out - previous output value + -- X01Zout - output cojnverted to X01Z + -- err - true if illegal character is encountered + -- + -- DESCRIPTION : converts the output of a state table to a + -- valid std_ulogic + -- ------------------------------------------------------------------------ + PROCEDURE StateOutputX01Z ( + CONSTANT TableOut : IN VitalStateSymbolType; + CONSTANT PrevOut : IN std_ulogic; + VARIABLE X01Zout : OUT std_ulogic; + VARIABLE Err : OUT BOOLEAN + ) IS + VARIABLE TempOut : std_ulogic; + BEGIN + Err := FALSE; + TempOut := StateTableOutMap(TableOut); + IF (TempOut = '-') THEN + Err := TRUE; + TempOut := 'X'; + VitalError ( "VitalStateTable", ErrOutSym, To_StateChar(TableOut)); + ELSIF (TempOut = 'W') THEN + TempOut := To_X01Z(PrevOut); + END IF; + X01Zout := TempOut; + END; + + -- ------------------------------------------------------------------------ + -- PROCEDURE NAME: StateMatch + -- + -- PARAMETERS : symbol - symbol from state table + -- in2 - input from VitalStateTble procedure + -- to state table + -- in2LastValue - previous value of input + -- state - false if the symbol is from the input + -- portion of the table, + -- true if the symbol is from the state + -- portion of the table + -- Err - true if symbol is not a valid input symbol + -- ReturnValue - true if match occurred + -- + -- DESCRIPTION : This procedure sets ReturnValue to true if in2 matches + -- symbol (from the state table). If symbol is an edge + -- value edge is set to true and in2 and in2LastValue are + -- checked against symbol. Err is set to true if symbol + -- is an invalid value for the input portion of the state + -- table. + -- + -- ------------------------------------------------------------------------ + PROCEDURE StateMatch ( + CONSTANT Symbol : IN VitalStateSymbolType; + CONSTANT in2 : IN std_ulogic; + CONSTANT in2LastValue : IN std_ulogic; + CONSTANT State : IN BOOLEAN; + VARIABLE Err : OUT BOOLEAN; + VARIABLE ReturnValue : OUT BOOLEAN + ) IS + BEGIN + IF (State) THEN + IF (NOT ValidStateTableState(Symbol)) THEN + VitalError ( "VitalStateTable", ErrStaSym, To_StateChar(Symbol)); + Err := TRUE; + ReturnValue := FALSE; + ELSE + Err := FALSE; + ReturnValue := StateTableMatch(in2LastValue, in2, Symbol); + END IF; + ELSE + IF (NOT ValidStateTableInput(Symbol) ) THEN + VitalError ( "VitalStateTable", ErrInpSym, To_StateChar(Symbol)); + Err := TRUE; + ReturnValue := FALSE; + ELSE + ReturnValue := StateTableMatch(in2LastValue, in2, Symbol); + Err := FALSE; + END IF; + END IF; + END; + + -- ----------------------------------------------------------------------- + -- FUNCTION NAME: StateTableLookUp + -- + -- PARAMETERS : StateTable - state table + -- PresentDataIn - current inputs + -- PreviousDataIn - previous inputs and states + -- NumStates - number of state variables + -- PresentOutputs - current state and current outputs + -- + -- DESCRIPTION : This function is used to find the output of the + -- StateTable corresponding to a given set of inputs. + -- + -- ------------------------------------------------------------------------ + FUNCTION StateTableLookUp ( + CONSTANT StateTable : VitalStateTableType; + CONSTANT PresentDataIn : std_logic_vector; + CONSTANT PreviousDataIn : std_logic_vector; + CONSTANT NumStates : NATURAL; + CONSTANT PresentOutputs : std_logic_vector + ) RETURN std_logic_vector IS + + CONSTANT InputSize : INTEGER := PresentDataIn'LENGTH; + CONSTANT NumInputs : INTEGER := InputSize + NumStates - 1; + CONSTANT TableEntries : INTEGER := StateTable'LENGTH(1); + CONSTANT TableWidth : INTEGER := StateTable'LENGTH(2); + CONSTANT OutSize : INTEGER := TableWidth - InputSize - NumStates; + VARIABLE Inputs : std_logic_vector(0 TO NumInputs); + VARIABLE PrevInputs : std_logic_vector(0 TO NumInputs) + := (OTHERS => 'X'); + VARIABLE ReturnValue : std_logic_vector(0 TO (OutSize-1)) + := (OTHERS => 'X'); + VARIABLE Temp : std_ulogic; + VARIABLE Match : BOOLEAN; + VARIABLE Err : BOOLEAN := FALSE; + + -- This needs to be done since the TableLookup arrays must be + -- ascending starting with 0 + VARIABLE TableAlias : VitalStateTableType(0 TO TableEntries - 1, + 0 TO TableWidth - 1) + := StateTable; + + BEGIN + Inputs(0 TO InputSize-1) := PresentDataIn; + Inputs(InputSize TO NumInputs) := PresentOutputs(0 TO NumStates - 1); + PrevInputs(0 TO InputSize - 1) := PreviousDataIn(0 TO InputSize - 1); + + ColLoop: -- Compare each entry in the table + FOR i IN TableAlias'RANGE(1) LOOP + + RowLoop: -- Check each element of the entry + FOR j IN 0 TO InputSize + NumStates LOOP + + IF (j = InputSize + NumStates) THEN -- a match occurred + FOR k IN 0 TO Minimum(OutSize, PresentOutputs'LENGTH)-1 LOOP + StateOutputX01Z ( + TableAlias(i, TableWidth - k - 1), + PresentOutputs(PresentOutputs'LENGTH - k - 1), + Temp, Err); + ReturnValue(OutSize - k - 1) := Temp; + IF (Err) THEN + ReturnValue := (OTHERS => 'X'); + RETURN ReturnValue; + END IF; + END LOOP; + RETURN ReturnValue; + END IF; + + StateMatch ( TableAlias(i,j), + Inputs(j), PrevInputs(j), + j >= InputSize, Err, Match); + EXIT RowLoop WHEN NOT(Match); + EXIT ColLoop WHEN Err; + END LOOP RowLoop; + END LOOP ColLoop; + + ReturnValue := (OTHERS => 'X'); + RETURN ReturnValue; + END; + + -------------------------------------------------------------------- + -- to_ux01z + ------------------------------------------------------------------- + FUNCTION To_UX01Z ( s : std_ulogic + ) RETURN UX01Z IS + BEGIN + RETURN cvt_to_ux01z (s); + END; + + --------------------------------------------------------------------------- + -- Function : GetEdge + -- Purpose : Converts transitions on a given input signal into a + -- enumeration value representing the transition or level + -- of the signal. + -- + -- previous "value" current "value" := "edge" + -- --------------------------------------------------------- + -- '1' | 'H' '1' | 'H' '1' level, no edge + -- '0' | 'L' '1' | 'H' '/' rising edge + -- others '1' | 'H' 'R' rising from X + -- + -- '1' | 'H' '0' | 'L' '\' falling egde + -- '0' | 'L' '0' | 'L' '0' level, no edge + -- others '0' | 'L' 'F' falling from X + -- + -- 'X' | 'W' | '-' 'X' | 'W' | '-' 'X' unknown (X) level + -- 'Z' 'Z' 'X' unknown (X) level + -- 'U' 'U' 'U' 'U' level + -- + -- '1' | 'H' others 'f' falling to X + -- '0' | 'L' others 'r' rising to X + -- 'X' | 'W' | '-' 'U' | 'Z' 'x' unknown (X) edge + -- 'Z' 'X' | 'W' | '-' | 'U' 'x' unknown (X) edge + -- 'U' 'X' | 'W' | '-' | 'Z' 'x' unknown (X) edge + -- + --------------------------------------------------------------------------- + FUNCTION GetEdge ( + SIGNAL s : IN std_logic + ) RETURN EdgeType IS + BEGIN + IF (s'EVENT) + THEN RETURN LogicToEdge ( s'LAST_VALUE, s ); + ELSE RETURN LogicToLevel ( s ); + END IF; + END; + + --------------------------------------------------------------------------- + PROCEDURE GetEdge ( + SIGNAL s : IN std_logic_vector; + VARIABLE LastS : INOUT std_logic_vector; + VARIABLE Edge : OUT EdgeArray ) IS + + ALIAS sAlias : std_logic_vector ( 1 TO s'LENGTH ) IS s; + ALIAS LastSAlias : std_logic_vector ( 1 TO LastS'LENGTH ) IS LastS; + ALIAS EdgeAlias : EdgeArray ( 1 TO Edge'LENGTH ) IS Edge; + BEGIN + IF s'LENGTH /= LastS'LENGTH OR + s'LENGTH /= Edge'LENGTH THEN + VitalError ( "GetEdge", ErrVctLng, "s, LastS, Edge" ); + END IF; + + FOR n IN 1 TO s'LENGTH LOOP + EdgeAlias(n) := LogicToEdge( LastSAlias(n), sAlias(n) ); + LastSAlias(n) := sAlias(n); + END LOOP; + END; + + --------------------------------------------------------------------------- + FUNCTION ToEdge ( Value : IN std_logic + ) RETURN EdgeType IS + BEGIN + RETURN LogicToLevel( Value ); + END; + + -- Note: This function will likely be replaced by S'DRIVING_VALUE in VHDL'92 + ---------------------------------------------------------------------------- + IMPURE FUNCTION CurValue ( + CONSTANT GlitchData : IN GlitchDataType + ) RETURN std_logic IS + BEGIN + IF NOW >= GlitchData.SchedTime THEN + RETURN GlitchData.SchedValue; + ELSIF NOW >= GlitchData.GlitchTime THEN + RETURN 'X'; + ELSE + RETURN GlitchData.CurrentValue; + END IF; + END; + --------------------------------------------------------------------------- + IMPURE FUNCTION CurValue ( + CONSTANT GlitchData : IN GlitchDataArrayType + ) RETURN std_logic_vector IS + VARIABLE Result : std_logic_vector(GlitchData'RANGE); + BEGIN + FOR n IN GlitchData'RANGE LOOP + IF NOW >= GlitchData(n).SchedTime THEN + Result(n) := GlitchData(n).SchedValue; + ELSIF NOW >= GlitchData(n).GlitchTime THEN + Result(n) := 'X'; + ELSE + Result(n) := GlitchData(n).CurrentValue; + END IF; + END LOOP; + RETURN Result; + END; + + --------------------------------------------------------------------------- + -- function calculation utilities + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + -- Function : VitalSame + -- Returns : VitalSame compares the state (UX01) of two logic value. A + -- value of 'X' is returned if the values are different. The + -- common value is returned if the values are equal. + -- Purpose : When the result of a logic model may be either of two + -- separate input values (eg. when the select on a MUX is 'X'), + -- VitalSame may be used to determine if the result needs to + -- be 'X'. + -- Arguments : See the declarations below... + --------------------------------------------------------------------------- + FUNCTION VitalSame ( + CONSTANT a, b : IN std_ulogic + ) RETURN std_ulogic IS + BEGIN + IF To_UX01(a) = To_UX01(b) + THEN RETURN To_UX01(a); + ELSE RETURN 'X'; + END IF; + END; + + --------------------------------------------------------------------------- + -- delay selection utilities + --------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + -- Procedure : BufPath, InvPath + -- + -- Purpose : BufPath and InvPath compute output change times, based on + -- a change on an input port. The computed output change times + -- returned in the composite parameter 'schd'. + -- + -- BufPath and InpPath are used together with the delay path + -- selection functions (GetSchedDelay, VitalAND, VitalOR... ) + -- The 'schd' value from each of the input ports of a model are + -- combined by the delay selection functions (VitalAND, + -- VitalOR, ...). The GetSchedDelay procedure converts the + -- combined output changes times to the single delay (delta + -- time) value for scheduling the output change (passed to + -- VitalGlitchOnEvent). + -- + -- The values in 'schd' are: (absolute times) + -- inp0 : time of output change due to input change to 0 + -- inp1 : time of output change due to input change to 1 + -- inpX : time of output change due to input change to X + -- glch0 : time of output glitch due to input change to 0 + -- glch1 : time of output glitch due to input change to 1 + -- + -- The output times are computed from the model INPUT value + -- and not the final value. For this reason, 'BufPath' should + -- be used to compute the output times for a non-inverting + -- delay paths and 'InvPath' should be used to compute the + -- ouput times for inverting delay paths. Delay paths which + -- include both non-inverting and paths require usage of both + -- 'BufPath' and 'InvPath'. (IE this is needed for the + -- select->output path of a MUX -- See the VitalMUX model). + -- + -- + -- Parameters : schd....... Computed output result times. (INOUT parameter + -- modified only on input edges) + -- Iedg....... Input port edge/level value. + -- tpd....... Propagation delays from this input + -- + --------------------------------------------------------------------------- + + PROCEDURE BufPath ( + VARIABLE Schd : INOUT SchedType; + CONSTANT Iedg : IN EdgeType; + CONSTANT tpd : IN VitalDelayType01 + ) IS + BEGIN + CASE Iedg IS + WHEN '0'|'1' => NULL; -- no edge: no timing update + WHEN '/'|'R' => Schd.inp0 := TIME'HIGH; + Schd.inp1 := NOW + tpd(tr01); Schd.Glch1 := Schd.inp1; + Schd.InpX := Schd.inp1; + WHEN '\'|'F' => Schd.inp1 := TIME'HIGH; + Schd.inp0 := NOW + tpd(tr10); Schd.Glch0 := Schd.inp0; + Schd.InpX := Schd.inp0; + WHEN 'r' => Schd.inp1 := TIME'HIGH; + Schd.inp0 := TIME'HIGH; + Schd.InpX := NOW + tpd(tr01); + WHEN 'f' => Schd.inp0 := TIME'HIGH; + Schd.inp1 := TIME'HIGH; + Schd.InpX := NOW + tpd(tr10); + WHEN 'x' => Schd.inp1 := TIME'HIGH; + Schd.inp0 := TIME'HIGH; + -- update for X->X change + Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); + WHEN OTHERS => NULL; -- no timing change + END CASE; + END; + + PROCEDURE BufPath ( + VARIABLE Schd : INOUT SchedArray; + CONSTANT Iedg : IN EdgeArray; + CONSTANT tpd : IN VitalDelayArrayType01 + ) IS + BEGIN + FOR n IN Schd'RANGE LOOP + CASE Iedg(n) IS + WHEN '0'|'1' => NULL; -- no edge: no timing update + WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH; + Schd(n).inp1 := NOW + tpd(n)(tr01); + Schd(n).Glch1 := Schd(n).inp1; + Schd(n).InpX := Schd(n).inp1; + WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH; + Schd(n).inp0 := NOW + tpd(n)(tr10); + Schd(n).Glch0 := Schd(n).inp0; + Schd(n).InpX := Schd(n).inp0; + WHEN 'r' => Schd(n).inp1 := TIME'HIGH; + Schd(n).inp0 := TIME'HIGH; + Schd(n).InpX := NOW + tpd(n)(tr01); + WHEN 'f' => Schd(n).inp0 := TIME'HIGH; + Schd(n).inp1 := TIME'HIGH; + Schd(n).InpX := NOW + tpd(n)(tr10); + WHEN 'x' => Schd(n).inp1 := TIME'HIGH; + Schd(n).inp0 := TIME'HIGH; + -- update for X->X change + Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10), + tpd(n)(tr01) ); + WHEN OTHERS => NULL; -- no timing change + END CASE; + END LOOP; + END; + + PROCEDURE InvPath ( + VARIABLE Schd : INOUT SchedType; + CONSTANT Iedg : IN EdgeType; + CONSTANT tpd : IN VitalDelayType01 + ) IS + BEGIN + CASE Iedg IS + WHEN '0'|'1' => NULL; -- no edge: no timing update + WHEN '/'|'R' => Schd.inp0 := TIME'HIGH; + Schd.inp1 := NOW + tpd(tr10); Schd.Glch1 := Schd.inp1; + Schd.InpX := Schd.inp1; + WHEN '\'|'F' => Schd.inp1 := TIME'HIGH; + Schd.inp0 := NOW + tpd(tr01); Schd.Glch0 := Schd.inp0; + Schd.InpX := Schd.inp0; + WHEN 'r' => Schd.inp1 := TIME'HIGH; + Schd.inp0 := TIME'HIGH; + Schd.InpX := NOW + tpd(tr10); + WHEN 'f' => Schd.inp0 := TIME'HIGH; + Schd.inp1 := TIME'HIGH; + Schd.InpX := NOW + tpd(tr01); + WHEN 'x' => Schd.inp1 := TIME'HIGH; + Schd.inp0 := TIME'HIGH; + -- update for X->X change + Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); + WHEN OTHERS => NULL; -- no timing change + END CASE; + END; + + PROCEDURE InvPath ( + VARIABLE Schd : INOUT SchedArray; + CONSTANT Iedg : IN EdgeArray; + CONSTANT tpd : IN VitalDelayArrayType01 + ) IS + BEGIN + FOR n IN Schd'RANGE LOOP + CASE Iedg(n) IS + WHEN '0'|'1' => NULL; -- no edge: no timing update + WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH; + Schd(n).inp1 := NOW + tpd(n)(tr10); + Schd(n).Glch1 := Schd(n).inp1; + Schd(n).InpX := Schd(n).inp1; + WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH; + Schd(n).inp0 := NOW + tpd(n)(tr01); + Schd(n).Glch0 := Schd(n).inp0; + Schd(n).InpX := Schd(n).inp0; + WHEN 'r' => Schd(n).inp1 := TIME'HIGH; + Schd(n).inp0 := TIME'HIGH; + Schd(n).InpX := NOW + tpd(n)(tr10); + WHEN 'f' => Schd(n).inp0 := TIME'HIGH; + Schd(n).inp1 := TIME'HIGH; + Schd(n).InpX := NOW + tpd(n)(tr01); + WHEN 'x' => Schd(n).inp1 := TIME'HIGH; + Schd(n).inp0 := TIME'HIGH; + -- update for X->X change + Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10), + tpd(n)(tr01) ); + WHEN OTHERS => NULL; -- no timing change + END CASE; + END LOOP; + END; + + --------------------------------------------------------------------------- + -- Procedure : BufEnab, InvEnab + -- + -- Purpose : BufEnab and InvEnab compute output change times, from a + -- change on an input enable port for a 3-state driver. The + -- computed output change times are returned in the composite + -- parameters 'schd1', 'schd0'. + -- + -- BufEnab and InpEnab are used together with the delay path + -- selection functions (GetSchedDelay, VitalAND, VitalOR... ) + -- The 'schd' value from each of the non-enable input ports of + -- a model (See BufPath, InvPath) are combined using the delay + -- selection functions (VitalAND, VitalOR, ...). The + -- GetSchedDelay procedure combines the output times on the + -- enable path with the output times from the data path(s) and + -- computes the single delay (delta time) value for scheduling + -- the output change (passed to VitalGlitchOnEvent) + -- + -- The values in 'schd*' are: (absolute times) + -- inp0 : time of output change due to input change to 0 + -- inp1 : time of output change due to input change to 1 + -- inpX : time of output change due to input change to X + -- glch0 : time of output glitch due to input change to 0 + -- glch1 : time of output glitch due to input change to 1 + -- + -- 'schd1' contains output times for 1->Z, Z->1 transitions. + -- 'schd0' contains output times for 0->Z, Z->0 transitions. + -- + -- 'BufEnab' is used for computing the output times for an + -- high asserted enable (output 'Z' for enable='0'). + -- 'InvEnab' is used for computing the output times for an + -- low asserted enable (output 'Z' for enable='1'). + -- + -- Note: separate 'schd1', 'schd0' parameters are generated + -- so that the combination of the delay paths from + -- multiple enable signals may be combined using the + -- same functions/operators used in combining separate + -- data paths. (See exampe 2 below) + -- + -- + -- Parameters : schd1...... Computed output result times for 1->Z, Z->1 + -- transitions. This parameter is modified only on + -- input edge values (events). + -- schd0...... Computed output result times for 0->Z, 0->1 + -- transitions. This parameter is modified only on + -- input edge values (events). + -- Iedg....... Input port edge/level value. + -- tpd....... Propagation delays for the enable -> output path. + -- + --------------------------------------------------------------------------- + PROCEDURE BufEnab ( + VARIABLE Schd1 : INOUT SchedType; + VARIABLE Schd0 : INOUT SchedType; + CONSTANT Iedg : IN EdgeType; + CONSTANT tpd : IN VitalDelayType01Z + ) IS + BEGIN + CASE Iedg IS + WHEN '0'|'1' => NULL; -- no edge: no timing update + WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH; + Schd1.inp1 := NOW + tpd(trz1); + Schd1.Glch1 := Schd1.inp1; + Schd1.InpX := Schd1.inp1; + Schd0.inp0 := TIME'HIGH; + Schd0.inp1 := NOW + tpd(trz0); + Schd0.Glch1 := Schd0.inp1; + Schd0.InpX := Schd0.inp1; + WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH; + Schd1.inp0 := NOW + tpd(tr1z); + Schd1.Glch0 := Schd1.inp0; + Schd1.InpX := Schd1.inp0; + Schd0.inp1 := TIME'HIGH; + Schd0.inp0 := NOW + tpd(tr0z); + Schd0.Glch0 := Schd0.inp0; + Schd0.InpX := Schd0.inp0; + WHEN 'r' => Schd1.inp1 := TIME'HIGH; + Schd1.inp0 := TIME'HIGH; + Schd1.InpX := NOW + tpd(trz1); + Schd0.inp1 := TIME'HIGH; + Schd0.inp0 := TIME'HIGH; + Schd0.InpX := NOW + tpd(trz0); + WHEN 'f' => Schd1.inp0 := TIME'HIGH; + Schd1.inp1 := TIME'HIGH; + Schd1.InpX := NOW + tpd(tr1z); + Schd0.inp0 := TIME'HIGH; + Schd0.inp1 := TIME'HIGH; + Schd0.InpX := NOW + tpd(tr0z); + WHEN 'x' => Schd1.inp0 := TIME'HIGH; + Schd1.inp1 := TIME'HIGH; + Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); + Schd0.inp0 := TIME'HIGH; + Schd0.inp1 := TIME'HIGH; + Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); + WHEN OTHERS => NULL; -- no timing change + END CASE; + END; + + PROCEDURE InvEnab ( + VARIABLE Schd1 : INOUT SchedType; + VARIABLE Schd0 : INOUT SchedType; + CONSTANT Iedg : IN EdgeType; + CONSTANT tpd : IN VitalDelayType01Z + ) IS + BEGIN + CASE Iedg IS + WHEN '0'|'1' => NULL; -- no edge: no timing update + WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH; + Schd1.inp1 := NOW + tpd(tr1z); + Schd1.Glch1 := Schd1.inp1; + Schd1.InpX := Schd1.inp1; + Schd0.inp0 := TIME'HIGH; + Schd0.inp1 := NOW + tpd(tr0z); + Schd0.Glch1 := Schd0.inp1; + Schd0.InpX := Schd0.inp1; + WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH; + Schd1.inp0 := NOW + tpd(trz1); + Schd1.Glch0 := Schd1.inp0; + Schd1.InpX := Schd1.inp0; + Schd0.inp1 := TIME'HIGH; + Schd0.inp0 := NOW + tpd(trz0); + Schd0.Glch0 := Schd0.inp0; + Schd0.InpX := Schd0.inp0; + WHEN 'r' => Schd1.inp1 := TIME'HIGH; + Schd1.inp0 := TIME'HIGH; + Schd1.InpX := NOW + tpd(tr1z); + Schd0.inp1 := TIME'HIGH; + Schd0.inp0 := TIME'HIGH; + Schd0.InpX := NOW + tpd(tr0z); + WHEN 'f' => Schd1.inp0 := TIME'HIGH; + Schd1.inp1 := TIME'HIGH; + Schd1.InpX := NOW + tpd(trz1); + Schd0.inp0 := TIME'HIGH; + Schd0.inp1 := TIME'HIGH; + Schd0.InpX := NOW + tpd(trz0); + WHEN 'x' => Schd1.inp0 := TIME'HIGH; + Schd1.inp1 := TIME'HIGH; + Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); + Schd0.inp0 := TIME'HIGH; + Schd0.inp1 := TIME'HIGH; + Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); + WHEN OTHERS => NULL; -- no timing change + END CASE; + END; + + --------------------------------------------------------------------------- + -- Procedure : GetSchedDelay + -- + -- Purpose : GetSchedDelay computes the final delay (incremental) for + -- for scheduling an output signal. The delay is computed + -- from the absolute output times in the 'NewSched' parameter. + -- (See BufPath, InvPath). + -- + -- Computation of the output delay for non-3_state outputs + -- consists of selection the appropriate output time based + -- on the new output value 'NewValue' and subtracting 'NOW' + -- to convert to an incremental delay value. + -- + -- The Computation of the output delay for 3_state output + -- also includes combination of the enable path delay with + -- the date path delay. + -- + -- Parameters : NewDelay... Returned output delay value. + -- GlchDelay.. Returned output delay for the start of a glitch. + -- NewValue... New output value. + -- CurValue... Current value of the output. + -- NewSched... Composite containing the combined absolute + -- output times from the data inputs. + -- EnSched1... Composite containing the combined absolute + -- output times from the enable input(s). + -- (for a 3_state output transitions 1->Z, Z->1) + -- EnSched0... Composite containing the combined absolute + -- output times from the enable input(s). + -- (for a 3_state output transitions 0->Z, Z->0) + -- + --------------------------------------------------------------------------- + PROCEDURE GetSchedDelay ( + VARIABLE NewDelay : OUT TIME; + VARIABLE GlchDelay : OUT TIME; + CONSTANT NewValue : IN std_ulogic; + CONSTANT CurValue : IN std_ulogic; + CONSTANT NewSched : IN SchedType + ) IS + VARIABLE Tim, Glch : TIME; + BEGIN + + CASE To_UX01(NewValue) IS + WHEN '0' => Tim := NewSched.inp0; + Glch := NewSched.Glch1; + WHEN '1' => Tim := NewSched.inp1; + Glch := NewSched.Glch0; + WHEN OTHERS => Tim := NewSched.InpX; + Glch := -1 ns; + END CASE; + IF (CurValue /= NewValue) + THEN Glch := -1 ns; + END IF; + + NewDelay := Tim - NOW; + IF Glch < 0 ns + THEN GlchDelay := Glch; + ELSE GlchDelay := Glch - NOW; + END IF; -- glch < 0 ns + END; + + PROCEDURE GetSchedDelay ( + VARIABLE NewDelay : OUT VitalTimeArray; + VARIABLE GlchDelay : OUT VitalTimeArray; + CONSTANT NewValue : IN std_logic_vector; + CONSTANT CurValue : IN std_logic_vector; + CONSTANT NewSched : IN SchedArray + ) IS + VARIABLE Tim, Glch : TIME; + ALIAS NewDelayAlias : VitalTimeArray( NewDelay'LENGTH DOWNTO 1) + IS NewDelay; + ALIAS GlchDelayAlias : VitalTimeArray(GlchDelay'LENGTH DOWNTO 1) + IS GlchDelay; + ALIAS NewSchedAlias : SchedArray( NewSched'LENGTH DOWNTO 1) + IS NewSched; + ALIAS NewValueAlias : std_logic_vector ( NewValue'LENGTH DOWNTO 1 ) + IS NewValue; + ALIAS CurValueAlias : std_logic_vector ( CurValue'LENGTH DOWNTO 1 ) + IS CurValue; + BEGIN + FOR n IN NewDelay'LENGTH DOWNTO 1 LOOP + CASE To_UX01(NewValueAlias(n)) IS + WHEN '0' => Tim := NewSchedAlias(n).inp0; + Glch := NewSchedAlias(n).Glch1; + WHEN '1' => Tim := NewSchedAlias(n).inp1; + Glch := NewSchedAlias(n).Glch0; + WHEN OTHERS => Tim := NewSchedAlias(n).InpX; + Glch := -1 ns; + END CASE; + IF (CurValueAlias(n) /= NewValueAlias(n)) + THEN Glch := -1 ns; + END IF; + + NewDelayAlias(n) := Tim - NOW; + IF Glch < 0 ns + THEN GlchDelayAlias(n) := Glch; + ELSE GlchDelayAlias(n) := Glch - NOW; + END IF; -- glch < 0 ns + END LOOP; + RETURN; + END; + + PROCEDURE GetSchedDelay ( + VARIABLE NewDelay : OUT TIME; + VARIABLE GlchDelay : OUT TIME; + CONSTANT NewValue : IN std_ulogic; + CONSTANT CurValue : IN std_ulogic; + CONSTANT NewSched : IN SchedType; + CONSTANT EnSched1 : IN SchedType; + CONSTANT EnSched0 : IN SchedType + ) IS + SUBTYPE v2 IS std_logic_vector(0 TO 1); + VARIABLE Tim, Glch : TIME; + BEGIN + + CASE v2'(To_X01Z(CurValue) & To_X01Z(NewValue)) IS + WHEN "00" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); + Glch := GlitchMinTime(NewSched.Glch1,EnSched0.Glch0); + WHEN "01" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); + Glch := EnSched1.Glch0; + WHEN "0Z" => Tim := EnSched0.inp0; + Glch := NewSched.Glch1; + WHEN "0X" => Tim := Maximum (NewSched.InpX, EnSched1.InpX); + Glch := 0 ns; + WHEN "10" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); + Glch := EnSched0.Glch0; + WHEN "11" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); + Glch := GlitchMinTime(NewSched.Glch0,EnSched1.Glch0); + WHEN "1Z" => Tim := EnSched1.inp0; + Glch := NewSched.Glch0; + WHEN "1X" => Tim := Maximum (NewSched.InpX, EnSched0.InpX); + Glch := 0 ns; + WHEN "Z0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); + IF NewSched.Glch0 > NOW + THEN Glch := Maximum(NewSched.Glch1,EnSched1.inp1); + ELSE Glch := 0 ns; + END IF; + WHEN "Z1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); + IF NewSched.Glch1 > NOW + THEN Glch := Maximum(NewSched.Glch0,EnSched0.inp1); + ELSE Glch := 0 ns; + END IF; + WHEN "ZX" => Tim := Maximum (NewSched.InpX, EnSched1.InpX); + Glch := 0 ns; + WHEN "ZZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX); + Glch := 0 ns; + WHEN "X0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); + Glch := 0 ns; + WHEN "X1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); + Glch := 0 ns; + WHEN "XZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX); + Glch := 0 ns; + WHEN OTHERS => Tim := Maximum (NewSched.InpX, EnSched1.InpX); + Glch := 0 ns; + + END CASE; + NewDelay := Tim - NOW; + IF Glch < 0 ns + THEN GlchDelay := Glch; + ELSE GlchDelay := Glch - NOW; + END IF; -- glch < 0 ns + END; + + --------------------------------------------------------------------------- + -- Operators and Functions for combination (selection) of path delays + -- > These functions support selection of the "appripriate" path delay + -- dependent on the logic function. + -- > These functions only "select" from the possable output times. No + -- calculation (addition) of delays is performed. + -- > See description of 'BufPath', 'InvPath' and 'GetSchedDelay' + -- > See primitive PROCEDURE models for examples. + --------------------------------------------------------------------------- + + FUNCTION "not" ( + CONSTANT a : IN SchedType + ) RETURN SchedType IS + VARIABLE z : SchedType; + BEGIN + z.inp1 := a.inp0 ; + z.inp0 := a.inp1 ; + z.InpX := a.InpX ; + z.Glch1 := a.Glch0; + z.Glch0 := a.Glch1; + RETURN (z); + END; + + FUNCTION "and" ( + CONSTANT a, b : IN SchedType + ) RETURN SchedType IS + VARIABLE z : SchedType; + BEGIN + z.inp1 := Maximum ( a.inp1 , b.inp1 ); + z.inp0 := Minimum ( a.inp0 , b.inp0 ); + z.InpX := GlitchMinTime ( a.InpX , b.InpX ); + z.Glch1 := Maximum ( a.Glch1, b.Glch1 ); + z.Glch0 := GlitchMinTime ( a.Glch0, b.Glch0 ); + RETURN (z); + END; + + FUNCTION "or" ( + CONSTANT a, b : IN SchedType + ) RETURN SchedType IS + VARIABLE z : SchedType; + BEGIN + z.inp0 := Maximum ( a.inp0 , b.inp0 ); + z.inp1 := Minimum ( a.inp1 , b.inp1 ); + z.InpX := GlitchMinTime ( a.InpX , b.InpX ); + z.Glch0 := Maximum ( a.Glch0, b.Glch0 ); + z.Glch1 := GlitchMinTime ( a.Glch1, b.Glch1 ); + RETURN (z); + END; + + IMPURE FUNCTION "nand" ( + CONSTANT a, b : IN SchedType + ) RETURN SchedType IS + VARIABLE z : SchedType; + BEGIN + z.inp0 := Maximum ( a.inp1 , b.inp1 ); + z.inp1 := Minimum ( a.inp0 , b.inp0 ); + z.InpX := GlitchMinTime ( a.InpX , b.InpX ); + z.Glch0 := Maximum ( a.Glch1, b.Glch1 ); + z.Glch1 := GlitchMinTime ( a.Glch0, b.Glch0 ); + RETURN (z); + END; + + IMPURE FUNCTION "nor" ( + CONSTANT a, b : IN SchedType + ) RETURN SchedType IS + VARIABLE z : SchedType; + BEGIN + z.inp1 := Maximum ( a.inp0 , b.inp0 ); + z.inp0 := Minimum ( a.inp1 , b.inp1 ); + z.InpX := GlitchMinTime ( a.InpX , b.InpX ); + z.Glch1 := Maximum ( a.Glch0, b.Glch0 ); + z.Glch0 := GlitchMinTime ( a.Glch1, b.Glch1 ); + RETURN (z); + END; + + -- ------------------------------------------------------------------------ + -- Delay Calculation for 2-bit Logical gates. + -- ------------------------------------------------------------------------ + IMPURE FUNCTION VitalXOR2 ( + CONSTANT ab,ai, bb,bi : IN SchedType + ) RETURN SchedType IS + VARIABLE z : SchedType; + BEGIN + -- z = (a AND b) NOR (a NOR b) + z.inp1 := Maximum ( Minimum (ai.inp0 , bi.inp0 ), + Minimum (ab.inp1 , bb.inp1 ) ); + z.inp0 := Minimum ( Maximum (ai.inp1 , bi.inp1 ), + Maximum (ab.inp0 , bb.inp0 ) ); + z.InpX := Maximum ( Maximum (ai.InpX , bi.InpX ), + Maximum (ab.InpX , bb.InpX ) ); + z.Glch1 := Maximum (GlitchMinTime (ai.Glch0, bi.Glch0), + GlitchMinTime (ab.Glch1, bb.Glch1) ); + z.Glch0 := GlitchMinTime ( Maximum (ai.Glch1, bi.Glch1), + Maximum (ab.Glch0, bb.Glch0) ); + RETURN (z); + END; + + IMPURE FUNCTION VitalXNOR2 ( + CONSTANT ab,ai, bb,bi : IN SchedType + ) RETURN SchedType IS + VARIABLE z : SchedType; + BEGIN + -- z = (a AND b) OR (a NOR b) + z.inp0 := Maximum ( Minimum (ab.inp0 , bb.inp0 ), + Minimum (ai.inp1 , bi.inp1 ) ); + z.inp1 := Minimum ( Maximum (ab.inp1 , bb.inp1 ), + Maximum (ai.inp0 , bi.inp0 ) ); + z.InpX := Maximum ( Maximum (ab.InpX , bb.InpX ), + Maximum (ai.InpX , bi.InpX ) ); + z.Glch0 := Maximum (GlitchMinTime (ab.Glch0, bb.Glch0), + GlitchMinTime (ai.Glch1, bi.Glch1) ); + z.Glch1 := GlitchMinTime ( Maximum (ab.Glch1, bb.Glch1), + Maximum (ai.Glch0, bi.Glch0) ); + RETURN (z); + END; + + -- ------------------------------------------------------------------------ + -- Delay Calculation for 3-bit Logical gates. + -- ------------------------------------------------------------------------ + IMPURE FUNCTION VitalXOR3 ( + CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType ) + RETURN SchedType IS + BEGIN + RETURN VitalXOR2 ( VitalXOR2 (ab,ai, bb,bi), + VitalXOR2 (ai,ab, bi,bb), + cb, ci ); + END; + + IMPURE FUNCTION VitalXNOR3 ( + CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType ) + RETURN SchedType IS + BEGIN + RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ), + VitalXOR2 ( ai,ab, bi,bb ), + cb, ci ); + END; + + -- ------------------------------------------------------------------------ + -- Delay Calculation for 4-bit Logical gates. + -- ------------------------------------------------------------------------ + IMPURE FUNCTION VitalXOR4 ( + CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType ) + RETURN SchedType IS + BEGIN + RETURN VitalXOR2 ( VitalXOR2 ( ab,ai, bb,bi ), + VitalXOR2 ( ai,ab, bi,bb ), + VitalXOR2 ( cb,ci, db,di ), + VitalXOR2 ( ci,cb, di,db ) ); + END; + + IMPURE FUNCTION VitalXNOR4 ( + CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType ) + RETURN SchedType IS + BEGIN + RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ), + VitalXOR2 ( ai,ab, bi,bb ), + VitalXOR2 ( cb,ci, db,di ), + VitalXOR2 ( ci,cb, di,db ) ); + END; + + -- ------------------------------------------------------------------------ + -- Delay Calculation for N-bit Logical gates. + -- ------------------------------------------------------------------------ + -- Note: index range on datab,datai assumed to be 1 TO length. + -- This is enforced by internal only usage of this Function + IMPURE FUNCTION VitalXOR ( + CONSTANT DataB, DataI : IN SchedArray + ) RETURN SchedType IS + CONSTANT Leng : INTEGER := DataB'LENGTH; + BEGIN + IF Leng = 2 THEN + RETURN VitalXOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) ); + ELSE + RETURN VitalXOR2 ( VitalXOR ( DataB(1 TO Leng-1), + DataI(1 TO Leng-1) ), + VitalXOR ( DataI(1 TO Leng-1), + DataB(1 TO Leng-1) ), + DataB(Leng),DataI(Leng) ); + END IF; + END; + + -- Note: index range on datab,datai assumed to be 1 TO length. + -- This is enforced by internal only usage of this Function + IMPURE FUNCTION VitalXNOR ( + CONSTANT DataB, DataI : IN SchedArray + ) RETURN SchedType IS + CONSTANT Leng : INTEGER := DataB'LENGTH; + BEGIN + IF Leng = 2 THEN + RETURN VitalXNOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) ); + ELSE + RETURN VitalXNOR2 ( VitalXOR ( DataB(1 TO Leng-1), + DataI(1 TO Leng-1) ), + VitalXOR ( DataI(1 TO Leng-1), + DataB(1 TO Leng-1) ), + DataB(Leng),DataI(Leng) ); + END IF; + END; + + -- ------------------------------------------------------------------------ + -- Multiplexor + -- MUX .......... result := data(dselect) + -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'), + -- data1 when (dselect = '1'), + -- 'X' when (dselect = 'X') and (data0 /= data1) + -- MUX4 .......... 4-input mux; result := data(dselect) + -- MUX8 .......... 8-input mux; result := data(dselect) + -- ------------------------------------------------------------------------ + FUNCTION VitalMUX2 ( + CONSTANT d1, d0 : IN SchedType; + CONSTANT sb, SI : IN SchedType + ) RETURN SchedType IS + BEGIN + RETURN (d1 AND sb) OR (d0 AND (NOT SI) ); + END; +-- + FUNCTION VitalMUX4 ( + CONSTANT Data : IN SchedArray4; + CONSTANT sb : IN SchedArray2; + CONSTANT SI : IN SchedArray2 + ) RETURN SchedType IS + BEGIN + RETURN ( sb(1) AND VitalMUX2(Data(3),Data(2), sb(0), SI(0)) ) + OR ( (NOT SI(1)) AND VitalMUX2(Data(1),Data(0), sb(0), SI(0)) ); + END; + + FUNCTION VitalMUX8 ( + CONSTANT Data : IN SchedArray8; + CONSTANT sb : IN SchedArray3; + CONSTANT SI : IN SchedArray3 + ) RETURN SchedType IS + BEGIN + RETURN ( ( sb(2)) AND VitalMUX4 (Data(7 DOWNTO 4), + sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) ) + OR ( (NOT SI(2)) AND VitalMUX4 (Data(3 DOWNTO 0), + sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) ); + END; +-- + FUNCTION VInterMux ( + CONSTANT Data : IN SchedArray; + CONSTANT sb : IN SchedArray; + CONSTANT SI : IN SchedArray + ) RETURN SchedType IS + CONSTANT sMsb : INTEGER := sb'LENGTH; + CONSTANT dMsbHigh : INTEGER := Data'LENGTH; + CONSTANT dMsbLow : INTEGER := Data'LENGTH/2; + BEGIN + IF sb'LENGTH = 1 THEN + RETURN VitalMUX2( Data(2), Data(1), sb(1), SI(1) ); + ELSIF sb'LENGTH = 2 THEN + RETURN VitalMUX4( Data, sb, SI ); + ELSIF sb'LENGTH = 3 THEN + RETURN VitalMUX8( Data, sb, SI ); + ELSIF sb'LENGTH > 3 THEN + RETURN (( sb(sMsb)) AND VInterMux( Data(dMsbLow DOWNTO 1), + sb(sMsb-1 DOWNTO 1), + SI(sMsb-1 DOWNTO 1) )) + OR ((NOT SI(sMsb)) AND VInterMux( Data(dMsbHigh DOWNTO dMsbLow+1), + sb(sMsb-1 DOWNTO 1), + SI(sMsb-1 DOWNTO 1) )); + ELSE + RETURN (0 ns, 0 ns, 0 ns, 0 ns, 0 ns); -- dselect'LENGTH < 1 + END IF; + END; +-- + FUNCTION VitalMUX ( + CONSTANT Data : IN SchedArray; + CONSTANT sb : IN SchedArray; + CONSTANT SI : IN SchedArray + ) RETURN SchedType IS + CONSTANT msb : INTEGER := 2**sb'LENGTH; + VARIABLE lDat : SchedArray(msb DOWNTO 1); + ALIAS DataAlias : SchedArray ( Data'LENGTH DOWNTO 1 ) IS Data; + ALIAS sbAlias : SchedArray ( sb'LENGTH DOWNTO 1 ) IS sb; + ALIAS siAlias : SchedArray ( SI'LENGTH DOWNTO 1 ) IS SI; + BEGIN + IF Data'LENGTH <= msb THEN + FOR i IN Data'LENGTH DOWNTO 1 LOOP + lDat(i) := DataAlias(i); + END LOOP; + FOR i IN msb DOWNTO Data'LENGTH+1 LOOP + lDat(i) := DefSchedAnd; + END LOOP; + ELSE + FOR i IN msb DOWNTO 1 LOOP + lDat(i) := DataAlias(i); + END LOOP; + END IF; + RETURN VInterMux( lDat, sbAlias, siAlias ); + END; + + -- ------------------------------------------------------------------------ + -- Decoder + -- General Algorithm : + -- (a) Result(...) := '0' when (enable = '0') + -- (b) Result(data) := '1'; all other subelements = '0' + -- ... Result array is decending (n-1 downto 0) + -- + -- DECODERn .......... n:2**n decoder + -- ------------------------------------------------------------------------ + FUNCTION VitalDECODER2 ( + CONSTANT DataB : IN SchedType; + CONSTANT DataI : IN SchedType; + CONSTANT Enable : IN SchedType + ) RETURN SchedArray IS + VARIABLE Result : SchedArray2; + BEGIN + Result(1) := Enable AND ( DataB); + Result(0) := Enable AND (NOT DataI); + RETURN Result; + END; + + FUNCTION VitalDECODER4 ( + CONSTANT DataB : IN SchedArray2; + CONSTANT DataI : IN SchedArray2; + CONSTANT Enable : IN SchedType + ) RETURN SchedArray IS + VARIABLE Result : SchedArray4; + BEGIN + Result(3) := Enable AND ( DataB(1)) AND ( DataB(0)); + Result(2) := Enable AND ( DataB(1)) AND (NOT DataI(0)); + Result(1) := Enable AND (NOT DataI(1)) AND ( DataB(0)); + Result(0) := Enable AND (NOT DataI(1)) AND (NOT DataI(0)); + RETURN Result; + END; + + FUNCTION VitalDECODER8 ( + CONSTANT DataB : IN SchedArray3; + CONSTANT DataI : IN SchedArray3; + CONSTANT Enable : IN SchedType + ) RETURN SchedArray IS + VARIABLE Result : SchedArray8; + BEGIN + Result(7):= Enable AND ( DataB(2))AND( DataB(1))AND( DataB(0)); + Result(6):= Enable AND ( DataB(2))AND( DataB(1))AND(NOT DataI(0)); + Result(5):= Enable AND ( DataB(2))AND(NOT DataI(1))AND( DataB(0)); + Result(4):= Enable AND ( DataB(2))AND(NOT DataI(1))AND(NOT DataI(0)); + Result(3):= Enable AND (NOT DataI(2))AND( DataB(1))AND( DataB(0)); + Result(2):= Enable AND (NOT DataI(2))AND( DataB(1))AND(NOT DataI(0)); + Result(1):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND( DataB(0)); + Result(0):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND(NOT DataI(0)); + RETURN Result; + END; + + + FUNCTION VitalDECODER ( + CONSTANT DataB : IN SchedArray; + CONSTANT DataI : IN SchedArray; + CONSTANT Enable : IN SchedType + ) RETURN SchedArray IS + CONSTANT DMsb : INTEGER := DataB'LENGTH - 1; + ALIAS DataBAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataB; + ALIAS DataIAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataI; + BEGIN + IF DataB'LENGTH = 1 THEN + RETURN VitalDECODER2 ( DataBAlias( 0 ), + DataIAlias( 0 ), Enable ); + ELSIF DataB'LENGTH = 2 THEN + RETURN VitalDECODER4 ( DataBAlias(1 DOWNTO 0), + DataIAlias(1 DOWNTO 0), Enable ); + ELSIF DataB'LENGTH = 3 THEN + RETURN VitalDECODER8 ( DataBAlias(2 DOWNTO 0), + DataIAlias(2 DOWNTO 0), Enable ); + ELSIF DataB'LENGTH > 3 THEN + RETURN VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0), + DataIAlias(DMsb-1 DOWNTO 0), + Enable AND ( DataBAlias(DMsb)) ) + & VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0), + DataIAlias(DMsb-1 DOWNTO 0), + Enable AND (NOT DataIAlias(DMsb)) ); + ELSE + RETURN DefSchedArray2; + END IF; + END; + + +------------------------------------------------------------------------------- +-- PRIMITIVES +------------------------------------------------------------------------------- + -- ------------------------------------------------------------------------ + -- N-bit wide Logical gates. + -- ------------------------------------------------------------------------ + FUNCTION VitalAND ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + Result := '1'; + FOR i IN Data'RANGE LOOP + Result := Result AND Data(i); + END LOOP; + RETURN ResultMap(Result); + END; +-- + FUNCTION VitalOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + Result := '0'; + FOR i IN Data'RANGE LOOP + Result := Result OR Data(i); + END LOOP; + RETURN ResultMap(Result); + END; +-- + FUNCTION VitalXOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + Result := '0'; + FOR i IN Data'RANGE LOOP + Result := Result XOR Data(i); + END LOOP; + RETURN ResultMap(Result); + END; +-- + FUNCTION VitalNAND ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + Result := '1'; + FOR i IN Data'RANGE LOOP + Result := Result AND Data(i); + END LOOP; + RETURN ResultMap(NOT Result); + END; +-- + FUNCTION VitalNOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + Result := '0'; + FOR i IN Data'RANGE LOOP + Result := Result OR Data(i); + END LOOP; + RETURN ResultMap(NOT Result); + END; +-- + FUNCTION VitalXNOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + Result := '0'; + FOR i IN Data'RANGE LOOP + Result := Result XOR Data(i); + END LOOP; + RETURN ResultMap(NOT Result); + END; + + -- ------------------------------------------------------------------------ + -- Commonly used 2-bit Logical gates. + -- ------------------------------------------------------------------------ + FUNCTION VitalAND2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a AND b); + END; +-- + FUNCTION VitalOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a OR b); + END; +-- + FUNCTION VitalXOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a XOR b); + END; +-- + FUNCTION VitalNAND2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a NAND b); + END; +-- + FUNCTION VitalNOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a NOR b); + END; +-- + FUNCTION VitalXNOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT (a XOR b)); + END; +-- + -- ------------------------------------------------------------------------ + -- Commonly used 3-bit Logical gates. + -- ------------------------------------------------------------------------ + FUNCTION VitalAND3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a AND b AND c); + END; +-- + FUNCTION VitalOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a OR b OR c); + END; +-- + FUNCTION VitalXOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a XOR b XOR c); + END; +-- + FUNCTION VitalNAND3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT (a AND b AND c)); + END; +-- + FUNCTION VitalNOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT (a OR b OR c)); + END; +-- + FUNCTION VitalXNOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT (a XOR b XOR c)); + END; + + -- --------------------------------------------------------------------------- + -- Commonly used 4-bit Logical gates. + -- --------------------------------------------------------------------------- + FUNCTION VitalAND4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a AND b AND c AND d); + END; +-- + FUNCTION VitalOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a OR b OR c OR d); + END; +-- + FUNCTION VitalXOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(a XOR b XOR c XOR d); + END; +-- + FUNCTION VitalNAND4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT (a AND b AND c AND d)); + END; +-- + FUNCTION VitalNOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT (a OR b OR c OR d)); + END; +-- + FUNCTION VitalXNOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT (a XOR b XOR c XOR d)); + END; + + -- ------------------------------------------------------------------------ + -- Buffers + -- BUF ....... standard non-inverting buffer + -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0') + -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1') + -- ------------------------------------------------------------------------ + FUNCTION VitalBUF ( + CONSTANT Data : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(To_UX01(Data)); + END; +-- + FUNCTION VitalBUFIF0 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(BufIf0_Table(Enable,Data)); + END; +-- + FUNCTION VitalBUFIF1 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(BufIf1_Table(Enable,Data)); + END; + FUNCTION VitalIDENT ( + CONSTANT Data : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(To_UX01Z(Data)); + END; + + -- ------------------------------------------------------------------------ + -- Invertors + -- INV ......... standard inverting buffer + -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0') + -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1') + -- ------------------------------------------------------------------------ + FUNCTION VitalINV ( + CONSTANT Data : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(NOT Data); + END; +-- + FUNCTION VitalINVIF0 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(InvIf0_Table(Enable,Data)); + END; +-- + FUNCTION VitalINVIF1 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic IS + BEGIN + RETURN ResultMap(InvIf1_Table(Enable,Data)); + END; + + -- ------------------------------------------------------------------------ + -- Multiplexor + -- MUX .......... result := data(dselect) + -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'), + -- data1 when (dselect = '1'), + -- 'X' when (dselect = 'X') and (data0 /= data1) + -- MUX4 .......... 4-input mux; result := data(dselect) + -- MUX8 .......... 8-input mux; result := data(dselect) + -- ------------------------------------------------------------------------ + FUNCTION VitalMUX2 ( + CONSTANT Data1, Data0 : IN std_ulogic; + CONSTANT dSelect : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + CASE To_X01(dSelect) IS + WHEN '0' => Result := To_UX01(Data0); + WHEN '1' => Result := To_UX01(Data1); + WHEN OTHERS => Result := VitalSame( Data1, Data0 ); + END CASE; + RETURN ResultMap(Result); + END; +-- + FUNCTION VitalMUX4 ( + CONSTANT Data : IN std_logic_vector4; + CONSTANT dSelect : IN std_logic_vector2; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Slct : std_logic_vector2; + VARIABLE Result : UX01; + BEGIN + Slct := To_X01(dSelect); + CASE Slct IS + WHEN "00" => Result := To_UX01(Data(0)); + WHEN "01" => Result := To_UX01(Data(1)); + WHEN "10" => Result := To_UX01(Data(2)); + WHEN "11" => Result := To_UX01(Data(3)); + WHEN "0X" => Result := VitalSame( Data(1), Data(0) ); + WHEN "1X" => Result := VitalSame( Data(2), Data(3) ); + WHEN "X0" => Result := VitalSame( Data(2), Data(0) ); + WHEN "X1" => Result := VitalSame( Data(3), Data(1) ); + WHEN OTHERS => Result := VitalSame( VitalSame(Data(3),Data(2)), + VitalSame(Data(1),Data(0))); + END CASE; + RETURN ResultMap(Result); + END; +-- + FUNCTION VitalMUX8 ( + CONSTANT Data : IN std_logic_vector8; + CONSTANT dSelect : IN std_logic_vector3; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + VARIABLE Result : UX01; + BEGIN + CASE To_X01(dSelect(2)) IS + WHEN '0' => Result := VitalMUX4( Data(3 DOWNTO 0), + dSelect(1 DOWNTO 0)); + WHEN '1' => Result := VitalMUX4( Data(7 DOWNTO 4), + dSelect(1 DOWNTO 0)); + WHEN OTHERS => Result := VitalSame( VitalMUX4( Data(3 DOWNTO 0), + dSelect(1 DOWNTO 0)), + VitalMUX4( Data(7 DOWNTO 4), + dSelect(1 DOWNTO 0))); + END CASE; + RETURN ResultMap(Result); + END; +-- + FUNCTION VInterMux ( + CONSTANT Data : IN std_logic_vector; + CONSTANT dSelect : IN std_logic_vector + ) RETURN std_ulogic IS + + CONSTANT sMsb : INTEGER := dSelect'LENGTH; + CONSTANT dMsbHigh : INTEGER := Data'LENGTH; + CONSTANT dMsbLow : INTEGER := Data'LENGTH/2; + ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data; + ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect; + + VARIABLE Result : UX01; + BEGIN + IF dSelect'LENGTH = 1 THEN + Result := VitalMUX2( DataAlias(2), DataAlias(1), dSelAlias(1) ); + ELSIF dSelect'LENGTH = 2 THEN + Result := VitalMUX4( DataAlias, dSelAlias ); + ELSIF dSelect'LENGTH > 2 THEN + CASE To_X01(dSelect(sMsb)) IS + WHEN '0' => + Result := VInterMux( DataAlias(dMsbLow DOWNTO 1), + dSelAlias(sMsb-1 DOWNTO 1) ); + WHEN '1' => + Result := VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1), + dSelAlias(sMsb-1 DOWNTO 1) ); + WHEN OTHERS => + Result := VitalSame( + VInterMux( DataAlias(dMsbLow DOWNTO 1), + dSelAlias(sMsb-1 DOWNTO 1) ), + VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1), + dSelAlias(sMsb-1 DOWNTO 1) ) + ); + END CASE; + ELSE + Result := 'X'; -- dselect'LENGTH < 1 + END IF; + RETURN Result; + END; +-- + FUNCTION VitalMUX ( + CONSTANT Data : IN std_logic_vector; + CONSTANT dSelect : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic IS + CONSTANT msb : INTEGER := 2**dSelect'LENGTH; + ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data; + ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect; + VARIABLE lDat : std_logic_vector(msb DOWNTO 1) := (OTHERS=>'X'); + VARIABLE Result : UX01; + BEGIN + IF Data'LENGTH <= msb THEN + FOR i IN Data'LENGTH DOWNTO 1 LOOP + lDat(i) := DataAlias(i); + END LOOP; + ELSE + FOR i IN msb DOWNTO 1 LOOP + lDat(i) := DataAlias(i); + END LOOP; + END IF; + Result := VInterMux( lDat, dSelAlias ); + RETURN ResultMap(Result); + END; + + -- ------------------------------------------------------------------------ + -- Decoder + -- General Algorithm : + -- (a) Result(...) := '0' when (enable = '0') + -- (b) Result(data) := '1'; all other subelements = '0' + -- ... Result array is decending (n-1 downto 0) + -- + -- DECODERn .......... n:2**n decoder + -- ------------------------------------------------------------------------ + FUNCTION VitalDECODER2 ( + CONSTANT Data : IN std_ulogic; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector2 IS + VARIABLE Result : std_logic_vector2; + BEGIN + Result(1) := ResultMap(Enable AND ( Data)); + Result(0) := ResultMap(Enable AND (NOT Data)); + RETURN Result; + END; +-- + FUNCTION VitalDECODER4 ( + CONSTANT Data : IN std_logic_vector2; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector4 IS + VARIABLE Result : std_logic_vector4; + BEGIN + Result(3) := ResultMap(Enable AND ( Data(1)) AND ( Data(0))); + Result(2) := ResultMap(Enable AND ( Data(1)) AND (NOT Data(0))); + Result(1) := ResultMap(Enable AND (NOT Data(1)) AND ( Data(0))); + Result(0) := ResultMap(Enable AND (NOT Data(1)) AND (NOT Data(0))); + RETURN Result; + END; +-- + FUNCTION VitalDECODER8 ( + CONSTANT Data : IN std_logic_vector3; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector8 IS + VARIABLE Result : std_logic_vector8; + BEGIN + Result(7) := ( Data(2)) AND ( Data(1)) AND ( Data(0)); + Result(6) := ( Data(2)) AND ( Data(1)) AND (NOT Data(0)); + Result(5) := ( Data(2)) AND (NOT Data(1)) AND ( Data(0)); + Result(4) := ( Data(2)) AND (NOT Data(1)) AND (NOT Data(0)); + Result(3) := (NOT Data(2)) AND ( Data(1)) AND ( Data(0)); + Result(2) := (NOT Data(2)) AND ( Data(1)) AND (NOT Data(0)); + Result(1) := (NOT Data(2)) AND (NOT Data(1)) AND ( Data(0)); + Result(0) := (NOT Data(2)) AND (NOT Data(1)) AND (NOT Data(0)); + + Result(0) := ResultMap ( Enable AND Result(0) ); + Result(1) := ResultMap ( Enable AND Result(1) ); + Result(2) := ResultMap ( Enable AND Result(2) ); + Result(3) := ResultMap ( Enable AND Result(3) ); + Result(4) := ResultMap ( Enable AND Result(4) ); + Result(5) := ResultMap ( Enable AND Result(5) ); + Result(6) := ResultMap ( Enable AND Result(6) ); + Result(7) := ResultMap ( Enable AND Result(7) ); + + RETURN Result; + END; +-- + FUNCTION VitalDECODER ( + CONSTANT Data : IN std_logic_vector; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector IS + + CONSTANT DMsb : INTEGER := Data'LENGTH - 1; + ALIAS DataAlias : std_logic_vector ( DMsb DOWNTO 0 ) IS Data; + BEGIN + IF Data'LENGTH = 1 THEN + RETURN VitalDECODER2 (DataAlias( 0 ), Enable, ResultMap ); + ELSIF Data'LENGTH = 2 THEN + RETURN VitalDECODER4 (DataAlias(1 DOWNTO 0), Enable, ResultMap ); + ELSIF Data'LENGTH = 3 THEN + RETURN VitalDECODER8 (DataAlias(2 DOWNTO 0), Enable, ResultMap ); + ELSIF Data'LENGTH > 3 THEN + RETURN VitalDECODER (DataAlias(DMsb-1 DOWNTO 0), + Enable AND ( DataAlias(DMsb)), ResultMap ) + & VitalDECODER (DataAlias(DMsb-1 DOWNTO 0), + Enable AND (NOT DataAlias(DMsb)), ResultMap ); + ELSE RETURN "X"; + END IF; + END; + + -- ------------------------------------------------------------------------ + -- N-bit wide Logical gates. + -- ------------------------------------------------------------------------ + PROCEDURE VitalAND ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE Data_Schd : SchedArray(Data'RANGE); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN LOOP + q <= VitalAND(Data, ResultMap); + WAIT ON Data; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := '1'; + new_schd := Data_Schd(Data_Schd'LEFT); + FOR i IN Data'RANGE LOOP + NewValue := NewValue AND Data(i); + new_schd := new_schd AND Data_Schd(i); + END LOOP; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data; + END LOOP; + END IF; --SN + END; +-- + PROCEDURE VitalOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE Data_Schd : SchedArray(Data'RANGE); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN LOOP + q <= VitalOR(Data, ResultMap); + WAIT ON Data; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := '0'; + new_schd := Data_Schd(Data_Schd'LEFT); + FOR i IN Data'RANGE LOOP + NewValue := NewValue OR Data(i); + new_schd := new_schd OR Data_Schd(i); + END LOOP; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data; + END LOOP; + END IF; --SN + END; +-- + PROCEDURE VitalXOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH); + VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd; + ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN LOOP + q <= VitalXOR(Data, ResultMap); + WAIT ON Data; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q ); + InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := VitalXOR ( Data ); + new_schd := VitalXOR ( DataB_Schd, DataI_Schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data; + END LOOP; + END IF; --SN + END; +-- + PROCEDURE VitalNAND ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE Data_Schd : SchedArray(Data'RANGE); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN LOOP + q <= VitalNAND(Data, ResultMap); + WAIT ON Data; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + InvPath ( Data_Schd, Data_Edge, Atpd_data_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := '1'; + new_schd := Data_Schd(Data_Schd'LEFT); + FOR i IN Data'RANGE LOOP + NewValue := NewValue AND Data(i); + new_schd := new_schd AND Data_Schd(i); + END LOOP; + NewValue := NOT NewValue; + new_schd := NOT new_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalNOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE Data_Schd : SchedArray(Data'RANGE); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN LOOP + q <= VitalNOR(Data, ResultMap); + WAIT ON Data; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + InvPath ( Data_Schd, Data_Edge, Atpd_data_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := '0'; + new_schd := Data_Schd(Data_Schd'LEFT); + FOR i IN Data'RANGE LOOP + NewValue := NewValue OR Data(i); + new_schd := new_schd OR Data_Schd(i); + END LOOP; + NewValue := NOT NewValue; + new_schd := NOT new_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data; + END LOOP; + END IF; --SN + END; +-- + PROCEDURE VitalXNOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH); + VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd; + ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN LOOP + q <= VitalXNOR(Data, ResultMap); + WAIT ON Data; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q ); + InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := VitalXNOR ( Data ); + new_schd := VitalXNOR ( DataB_Schd, DataI_Schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data; + END LOOP; + END IF; --SN + END; +-- + + -- ------------------------------------------------------------------------ + -- Commonly used 2-bit Logical gates. + -- ------------------------------------------------------------------------ + PROCEDURE VitalAND2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalAND2 ( a, b, ResultMap ); + WAIT ON a, b; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( a_schd, InitialEdge(a), tpd_a_q ); + BufPath ( b_schd, InitialEdge(b), tpd_b_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( a_schd, GetEdge(a), tpd_a_q ); + BufPath ( b_schd, GetEdge(b), tpd_b_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a AND b; + new_schd := a_schd AND b_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalOR2 ( a, b, ResultMap ); + WAIT ON a, b; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( a_schd, InitialEdge(a), tpd_a_q ); + BufPath ( b_schd, InitialEdge(b), tpd_b_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( a_schd, GetEdge(a), tpd_a_q ); + BufPath ( b_schd, GetEdge(b), tpd_b_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a OR b; + new_schd := a_schd OR b_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalNAND2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalNAND2 ( a, b, ResultMap ); + WAIT ON a, b; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( a_schd, InitialEdge(a), tpd_a_q ); + InvPath ( b_schd, InitialEdge(b), tpd_b_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( a_schd, GetEdge(a), tpd_a_q ); + InvPath ( b_schd, GetEdge(b), tpd_b_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a NAND b; + new_schd := a_schd NAND b_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalNOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalNOR2 ( a, b, ResultMap ); + WAIT ON a, b; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( a_schd, InitialEdge(a), tpd_a_q ); + InvPath ( b_schd, InitialEdge(b), tpd_b_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( a_schd, GetEdge(a), tpd_a_q ); + InvPath ( b_schd, GetEdge(b), tpd_b_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a NOR b; + new_schd := a_schd NOR b_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalXOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE ab_schd, bb_schd : SchedType; + VARIABLE ai_schd, bi_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalXOR2 ( a, b, ResultMap ); + WAIT ON a, b; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); + InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); + BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); + InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( ab_schd, GetEdge(a), tpd_a_q ); + InvPath ( ai_schd, GetEdge(a), tpd_a_q ); + + BufPath ( bb_schd, GetEdge(b), tpd_b_q ); + InvPath ( bi_schd, GetEdge(b), tpd_b_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a XOR b; + new_schd := VitalXOR2 ( ab_schd,ai_schd, bb_schd,bi_schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalXNOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE ab_schd, bb_schd : SchedType; + VARIABLE ai_schd, bi_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalXNOR2 ( a, b, ResultMap ); + WAIT ON a, b; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); + InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); + BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); + InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( ab_schd, GetEdge(a), tpd_a_q ); + InvPath ( ai_schd, GetEdge(a), tpd_a_q ); + + BufPath ( bb_schd, GetEdge(b), tpd_b_q ); + InvPath ( bi_schd, GetEdge(b), tpd_b_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := NOT (a XOR b); + new_schd := VitalXNOR2 ( ab_schd,ai_schd, bb_schd,bi_schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b; + END LOOP; + END IF; + END; + + -- ------------------------------------------------------------------------ + -- Commonly used 3-bit Logical gates. + -- ------------------------------------------------------------------------ + PROCEDURE VitalAND3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN +-- + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalAND3 ( a, b, c, ResultMap ); + WAIT ON a, b, c; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( a_schd, InitialEdge(a), tpd_a_q ); + BufPath ( b_schd, InitialEdge(b), tpd_b_q ); + BufPath ( c_schd, InitialEdge(c), tpd_c_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( a_schd, GetEdge(a), tpd_a_q ); + BufPath ( b_schd, GetEdge(b), tpd_b_q ); + BufPath ( c_schd, GetEdge(c), tpd_c_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a AND b AND c; + new_schd := a_schd AND b_schd AND c_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalOR3 ( a, b, c, ResultMap ); + WAIT ON a, b, c; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( a_schd, InitialEdge(a), tpd_a_q ); + BufPath ( b_schd, InitialEdge(b), tpd_b_q ); + BufPath ( c_schd, InitialEdge(c), tpd_c_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( a_schd, GetEdge(a), tpd_a_q ); + BufPath ( b_schd, GetEdge(b), tpd_b_q ); + BufPath ( c_schd, GetEdge(c), tpd_c_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a OR b OR c; + new_schd := a_schd OR b_schd OR c_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalNAND3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalNAND3 ( a, b, c, ResultMap ); + WAIT ON a, b, c; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( a_schd, InitialEdge(a), tpd_a_q ); + InvPath ( b_schd, InitialEdge(b), tpd_b_q ); + InvPath ( c_schd, InitialEdge(c), tpd_c_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( a_schd, GetEdge(a), tpd_a_q ); + InvPath ( b_schd, GetEdge(b), tpd_b_q ); + InvPath ( c_schd, GetEdge(c), tpd_c_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := (a AND b) NAND c; + new_schd := (a_schd AND b_schd) NAND c_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalNOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalNOR3 ( a, b, c, ResultMap ); + WAIT ON a, b, c; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( a_schd, InitialEdge(a), tpd_a_q ); + InvPath ( b_schd, InitialEdge(b), tpd_b_q ); + InvPath ( c_schd, InitialEdge(c), tpd_c_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( a_schd, GetEdge(a), tpd_a_q ); + InvPath ( b_schd, GetEdge(b), tpd_b_q ); + InvPath ( c_schd, GetEdge(c), tpd_c_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := (a OR b) NOR c; + new_schd := (a_schd OR b_schd) NOR c_schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalXOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE ab_schd, bb_schd, cb_schd : SchedType; + VARIABLE ai_schd, bi_schd, ci_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalXOR3 ( a, b, c, ResultMap ); + WAIT ON a, b, c; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); + InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); + BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); + InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); + BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); + InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( ab_schd, GetEdge(a), tpd_a_q ); + InvPath ( ai_schd, GetEdge(a), tpd_a_q ); + + BufPath ( bb_schd, GetEdge(b), tpd_b_q ); + InvPath ( bi_schd, GetEdge(b), tpd_b_q ); + + BufPath ( cb_schd, GetEdge(c), tpd_c_q ); + InvPath ( ci_schd, GetEdge(c), tpd_c_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a XOR b XOR c; + new_schd := VitalXOR3 ( ab_schd,ai_schd, + bb_schd,bi_schd, + cb_schd,ci_schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalXNOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE ab_schd, bb_schd, cb_schd : SchedType; + VARIABLE ai_schd, bi_schd, ci_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalXNOR3 ( a, b, c, ResultMap ); + WAIT ON a, b, c; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); + InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); + BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); + InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); + BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); + InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( ab_schd, GetEdge(a), tpd_a_q ); + InvPath ( ai_schd, GetEdge(a), tpd_a_q ); + + BufPath ( bb_schd, GetEdge(b), tpd_b_q ); + InvPath ( bi_schd, GetEdge(b), tpd_b_q ); + + BufPath ( cb_schd, GetEdge(c), tpd_c_q ); + InvPath ( ci_schd, GetEdge(c), tpd_c_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := NOT (a XOR b XOR c); + new_schd := VitalXNOR3 ( ab_schd, ai_schd, + bb_schd, bi_schd, + cb_schd, ci_schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c; + END LOOP; + END IF; + END; + + -- ------------------------------------------------------------------------ + -- Commonly used 4-bit Logical gates. + -- ------------------------------------------------------------------------ + PROCEDURE VitalAND4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01) + AND (tpd_d_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalAND4 ( a, b, c, d, ResultMap ); + WAIT ON a, b, c, d; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( a_schd, InitialEdge(a), tpd_a_q ); + BufPath ( b_schd, InitialEdge(b), tpd_b_q ); + BufPath ( c_schd, InitialEdge(c), tpd_c_q ); + BufPath ( d_Schd, InitialEdge(d), tpd_d_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( a_schd, GetEdge(a), tpd_a_q ); + BufPath ( b_schd, GetEdge(b), tpd_b_q ); + BufPath ( c_schd, GetEdge(c), tpd_c_q ); + BufPath ( d_Schd, GetEdge(d), tpd_d_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a AND b AND c AND d; + new_schd := a_schd AND b_schd AND c_schd AND d_Schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c, d; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01) + AND (tpd_d_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalOR4 ( a, b, c, d, ResultMap ); + WAIT ON a, b, c, d; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( a_schd, InitialEdge(a), tpd_a_q ); + BufPath ( b_schd, InitialEdge(b), tpd_b_q ); + BufPath ( c_schd, InitialEdge(c), tpd_c_q ); + BufPath ( d_Schd, InitialEdge(d), tpd_d_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( a_schd, GetEdge(a), tpd_a_q ); + BufPath ( b_schd, GetEdge(b), tpd_b_q ); + BufPath ( c_schd, GetEdge(c), tpd_c_q ); + BufPath ( d_Schd, GetEdge(d), tpd_d_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a OR b OR c OR d; + new_schd := a_schd OR b_schd OR c_schd OR d_Schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c, d; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalNAND4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01) + AND (tpd_d_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalNAND4 ( a, b, c, d, ResultMap ); + WAIT ON a, b, c, d; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( a_schd, InitialEdge(a), tpd_a_q ); + InvPath ( b_schd, InitialEdge(b), tpd_b_q ); + InvPath ( c_schd, InitialEdge(c), tpd_c_q ); + InvPath ( d_Schd, InitialEdge(d), tpd_d_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( a_schd, GetEdge(a), tpd_a_q ); + InvPath ( b_schd, GetEdge(b), tpd_b_q ); + InvPath ( c_schd, GetEdge(c), tpd_c_q ); + InvPath ( d_Schd, GetEdge(d), tpd_d_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := (a AND b) NAND (c AND d); + new_schd := (a_schd AND b_schd) NAND (c_schd AND d_Schd); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c, d; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalNOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01) + AND (tpd_d_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalNOR4 ( a, b, c, d, ResultMap ); + WAIT ON a, b, c, d; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( a_schd, InitialEdge(a), tpd_a_q ); + InvPath ( b_schd, InitialEdge(b), tpd_b_q ); + InvPath ( c_schd, InitialEdge(c), tpd_c_q ); + InvPath ( d_Schd, InitialEdge(d), tpd_d_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( a_schd, GetEdge(a), tpd_a_q ); + InvPath ( b_schd, GetEdge(b), tpd_b_q ); + InvPath ( c_schd, GetEdge(c), tpd_c_q ); + InvPath ( d_Schd, GetEdge(d), tpd_d_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := (a OR b) NOR (c OR d); + new_schd := (a_schd OR b_schd) NOR (c_schd OR d_Schd); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c, d; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalXOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType; + VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01) + AND (tpd_d_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalXOR4 ( a, b, c, d, ResultMap ); + WAIT ON a, b, c, d; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); + InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); + + BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); + InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); + + BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); + InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); + + BufPath ( DB_Schd, InitialEdge(d), tpd_d_q ); + InvPath ( di_schd, InitialEdge(d), tpd_d_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( ab_schd, GetEdge(a), tpd_a_q ); + InvPath ( ai_schd, GetEdge(a), tpd_a_q ); + + BufPath ( bb_schd, GetEdge(b), tpd_b_q ); + InvPath ( bi_schd, GetEdge(b), tpd_b_q ); + + BufPath ( cb_schd, GetEdge(c), tpd_c_q ); + InvPath ( ci_schd, GetEdge(c), tpd_c_q ); + + BufPath ( DB_Schd, GetEdge(d), tpd_d_q ); + InvPath ( di_schd, GetEdge(d), tpd_d_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := a XOR b XOR c XOR d; + new_schd := VitalXOR4 ( ab_schd,ai_schd, bb_schd,bi_schd, + cb_schd,ci_schd, DB_Schd,di_schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c, d; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalXNOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType; + VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType; + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_a_q = VitalZeroDelay01) + AND (tpd_b_q = VitalZeroDelay01) + AND (tpd_c_q = VitalZeroDelay01) + AND (tpd_d_q = VitalZeroDelay01)) THEN + LOOP + q <= VitalXNOR4 ( a, b, c, d, ResultMap ); + WAIT ON a, b, c, d; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); + InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); + + BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); + InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); + + BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); + InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); + + BufPath ( DB_Schd, InitialEdge(d), tpd_d_q ); + InvPath ( di_schd, InitialEdge(d), tpd_d_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( ab_schd, GetEdge(a), tpd_a_q ); + InvPath ( ai_schd, GetEdge(a), tpd_a_q ); + + BufPath ( bb_schd, GetEdge(b), tpd_b_q ); + InvPath ( bi_schd, GetEdge(b), tpd_b_q ); + + BufPath ( cb_schd, GetEdge(c), tpd_c_q ); + InvPath ( ci_schd, GetEdge(c), tpd_c_q ); + + BufPath ( DB_Schd, GetEdge(d), tpd_d_q ); + InvPath ( di_schd, GetEdge(d), tpd_d_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := NOT (a XOR b XOR c XOR d); + new_schd := VitalXNOR4 ( ab_schd,ai_schd, bb_schd,bi_schd, + cb_schd,ci_schd, DB_Schd,di_schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON a, b, c, d; + END LOOP; + END IF; + END; + + -- ------------------------------------------------------------------------ + -- Buffers + -- BUF ....... standard non-inverting buffer + -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0') + -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1') + -- ------------------------------------------------------------------------ + PROCEDURE VitalBUF ( + SIGNAL q : OUT std_ulogic; + SIGNAL a : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF (tpd_a_q = VitalZeroDelay01) THEN + LOOP + q <= ResultMap(To_UX01(a)); + WAIT ON a; + END LOOP; + + ELSE + LOOP + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := To_UX01(a); -- convert to forcing strengths + CASE EdgeType'(GetEdge(a)) IS + WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr01); + WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr10); + WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10)); + END CASE; + + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode ); + + WAIT ON a; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalBUFIF1 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) IS + VARIABLE NewValue : UX01Z; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_data_q = VitalZeroDelay01 ) + AND (tpd_enable_q = VitalZeroDelay01Z)) THEN + LOOP + q <= VitalBUFIF1( Data, Enable, ResultMap ); + WAIT ON Data, Enable; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( d_Schd, InitialEdge(Data), tpd_data_q ); + BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( d_Schd, GetEdge(Data), tpd_data_q ); + BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := VitalBUFIF1( Data, Enable ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), + d_Schd, e1_Schd, e0_Schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalBUFIF0 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) IS + VARIABLE NewValue : UX01Z; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; + VARIABLE ne1_schd, ne0_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_data_q = VitalZeroDelay01 ) + AND (tpd_enable_q = VitalZeroDelay01Z)) THEN + LOOP + q <= VitalBUFIF0( Data, Enable, ResultMap ); + WAIT ON Data, Enable; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( d_Schd, InitialEdge(Data), tpd_data_q ); + InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( d_Schd, GetEdge(Data), tpd_data_q ); + InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := VitalBUFIF0( Data, Enable ); + ne1_schd := NOT e1_Schd; + ne0_schd := NOT e0_Schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), + d_Schd, ne1_schd, ne0_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; + END; + + PROCEDURE VitalIDENT ( + SIGNAL q : OUT std_ulogic; + SIGNAL a : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) IS + SUBTYPE v2 IS std_logic_vector(0 TO 1); + VARIABLE NewValue : UX01Z; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF (tpd_a_q = VitalZeroDelay01Z) THEN + LOOP + q <= ResultMap(To_UX01Z(a)); + WAIT ON a; + END LOOP; + + ELSE + LOOP + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + CASE v2'(To_X01Z(NewValue) & To_X01Z(a)) IS + WHEN "00" => Dly := tpd_a_q(tr10); + WHEN "01" => Dly := tpd_a_q(tr01); + WHEN "0Z" => Dly := tpd_a_q(tr0z); + WHEN "0X" => Dly := tpd_a_q(tr01); + WHEN "10" => Dly := tpd_a_q(tr10); + WHEN "11" => Dly := tpd_a_q(tr01); + WHEN "1Z" => Dly := tpd_a_q(tr1z); + WHEN "1X" => Dly := tpd_a_q(tr10); + WHEN "Z0" => Dly := tpd_a_q(trz0); + WHEN "Z1" => Dly := tpd_a_q(trz1); + WHEN "ZZ" => Dly := 0 ns; + WHEN "ZX" => Dly := Minimum (tpd_a_q(trz1), tpd_a_q(trz0)); + WHEN "X0" => Dly := tpd_a_q(tr10); + WHEN "X1" => Dly := tpd_a_q(tr01); + WHEN "XZ" => Dly := Minimum (tpd_a_q(tr0z), tpd_a_q(tr1z)); + WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10)); + END CASE; + NewValue := To_UX01Z(a); + + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode ); + + WAIT ON a; + END LOOP; + END IF; + END; + + -- ------------------------------------------------------------------------ + -- Invertors + -- INV ......... standard inverting buffer + -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0') + -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1') + -- ------------------------------------------------------------------------ + PROCEDURE VitalINV ( + SIGNAL q : OUT std_ulogic; + SIGNAL a : IN std_ulogic ; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + IF (tpd_a_q = VitalZeroDelay01) THEN + LOOP + q <= ResultMap(NOT a); + WAIT ON a; + END LOOP; + + ELSE + LOOP + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := NOT a; + CASE EdgeType'(GetEdge(a)) IS + WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr10); + WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr01); + WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10)); + END CASE; + + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode ); + + WAIT ON a; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalINVIF1 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) IS + VARIABLE NewValue : UX01Z; + VARIABLE new_schd : SchedType; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_data_q = VitalZeroDelay01 ) + AND (tpd_enable_q = VitalZeroDelay01Z)) THEN + LOOP + q <= VitalINVIF1( Data, Enable, ResultMap ); + WAIT ON Data, Enable; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( d_Schd, InitialEdge(Data), tpd_data_q ); + BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( d_Schd, GetEdge(Data), tpd_data_q ); + BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := VitalINVIF1( Data, Enable ); + new_schd := NOT d_Schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), + new_schd, e1_Schd, e0_Schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalINVIF0 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) IS + VARIABLE NewValue : UX01Z; + VARIABLE new_schd : SchedType; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; + VARIABLE ne1_schd, ne0_schd : SchedType := DefSchedType; + VARIABLE Dly, Glch : TIME; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_data_q = VitalZeroDelay01 ) + AND (tpd_enable_q = VitalZeroDelay01Z)) THEN + LOOP + q <= VitalINVIF0( Data, Enable, ResultMap ); + WAIT ON Data, Enable; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + InvPath ( d_Schd, InitialEdge(Data), tpd_data_q ); + InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + InvPath ( d_Schd, GetEdge(Data), tpd_data_q ); + InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delay + -- ------------------------------------ + NewValue := VitalINVIF0( Data, Enable ); + ne1_schd := NOT e1_Schd; + ne0_schd := NOT e0_Schd; + new_schd := NOT d_Schd; + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), + new_schd, ne1_schd, ne0_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; + END; + + -- ------------------------------------------------------------------------ + -- Multiplexor + -- MUX .......... result := data(dselect) + -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'), + -- data1 when (dselect = '1'), + -- 'X' when (dselect = 'X') and (data0 /= data1) + -- MUX4 .......... 4-input mux; result := data(dselect) + -- MUX8 .......... 8-input mux; result := data(dselect) + -- ------------------------------------------------------------------------ + PROCEDURE VitalMUX2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL d1, d0 : IN std_ulogic; + SIGNAL dSel : IN std_ulogic; + CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + VARIABLE d1_Schd, d0_Schd : SchedType; + VARIABLE dSel_bSchd, dSel_iSchd : SchedType; + VARIABLE d1_Edge, d0_Edge, dSel_Edge : EdgeType; + BEGIN + + -- ------------------------------------------------------------------------ + -- For ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF ( (tpd_d1_q = VitalZeroDelay01) + AND (tpd_d0_q = VitalZeroDelay01) + AND (tpd_dsel_q = VitalZeroDelay01) ) THEN + LOOP + q <= VitalMUX2 ( d1, d0, dSel, ResultMap ); + WAIT ON d1, d0, dSel; + END LOOP; + + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( d1_Schd, InitialEdge(d1), tpd_d1_q ); + BufPath ( d0_Schd, InitialEdge(d0), tpd_d0_q ); + BufPath ( dSel_bSchd, InitialEdge(dSel), tpd_dsel_q ); + InvPath ( dSel_iSchd, InitialEdge(dSel), tpd_dsel_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( d1_Schd, GetEdge(d1), tpd_d1_q ); + BufPath ( d0_Schd, GetEdge(d0), tpd_d0_q ); + BufPath ( dSel_bSchd, GetEdge(dSel), tpd_dsel_q ); + InvPath ( dSel_iSchd, GetEdge(dSel), tpd_dsel_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalMUX2 ( d1, d0, dSel ); + new_schd := VitalMUX2 ( d1_Schd, d0_Schd, dSel_bSchd, dSel_iSchd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON d1, d0, dSel; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalMUX4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector4; + SIGNAL dSel : IN std_logic_vector2; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U'); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + VARIABLE Data_Schd : SchedArray4; + VARIABLE Data_Edge : EdgeArray4; + VARIABLE dSel_Edge : EdgeArray2; + VARIABLE dSel_bSchd : SchedArray2; + VARIABLE dSel_iSchd : SchedArray2; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN dSel'RANGE LOOP + IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + + IF (AllZeroDelay) THEN LOOP + q <= VitalMUX(Data, dSel, ResultMap); + WAIT ON Data, dSel; + END LOOP; + END IF; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + FOR n IN dSel'RANGE LOOP + BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); + InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); + + GetEdge ( dSel, LastdSel, dSel_Edge ); + BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q ); + InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalMUX4 ( Data, dSel ); + new_schd := VitalMUX4 ( Data_Schd, dSel_bSchd, dSel_iSchd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, dSel; + END LOOP; + END IF; --SN + END; + + PROCEDURE VitalMUX8 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector8; + SIGNAL dSel : IN std_logic_vector3; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U'); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + VARIABLE Data_Schd : SchedArray8; + VARIABLE Data_Edge : EdgeArray8; + VARIABLE dSel_Edge : EdgeArray3; + VARIABLE dSel_bSchd : SchedArray3; + VARIABLE dSel_iSchd : SchedArray3; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN dSel'RANGE LOOP + IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + + IF (AllZeroDelay) THEN LOOP + q <= VitalMUX(Data, dSel, ResultMap); + WAIT ON Data, dSel; + END LOOP; + END IF; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + FOR n IN dSel'RANGE LOOP + BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); + InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); + + GetEdge ( dSel, LastdSel, dSel_Edge ); + BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q ); + InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalMUX8 ( Data, dSel ); + new_schd := VitalMUX8 ( Data_Schd, dSel_bSchd, dSel_iSchd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, dSel; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalMUX ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + SIGNAL dSel : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U'); + VARIABLE NewValue : UX01; + VARIABLE Glitch_Data : GlitchDataType; + VARIABLE new_schd : SchedType; + VARIABLE Dly, Glch : TIME; + VARIABLE Data_Schd : SchedArray(Data'RANGE); + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE dSel_Edge : EdgeArray(dSel'RANGE); + VARIABLE dSel_bSchd : SchedArray(dSel'RANGE); + VARIABLE dSel_iSchd : SchedArray(dSel'RANGE); + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + FOR i IN dSel'RANGE LOOP + IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + IF (AllZeroDelay) THEN + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + + IF (AllZeroDelay) THEN LOOP + q <= VitalMUX(Data, dSel, ResultMap); + WAIT ON Data, dSel; + END LOOP; + END IF; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + FOR n IN dSel'RANGE LOOP + BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); + InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); + END LOOP; + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); + + GetEdge ( dSel, LastdSel, dSel_Edge ); + BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q ); + InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalMUX ( Data, dSel ); + new_schd := VitalMUX ( Data_Schd, dSel_bSchd, dSel_iSchd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, dSel; + END LOOP; + END IF; --SN + END; + + -- ------------------------------------------------------------------------ + -- Decoder + -- General Algorithm : + -- (a) Result(...) := '0' when (enable = '0') + -- (b) Result(data) := '1'; all other subelements = '0' + -- ... Result array is decending (n-1 downto 0) + -- + -- DECODERn .......... n:2**n decoder + -- Caution: If 'ResultMap' defines other than strength mapping, the + -- delay selection is not defined. + -- ------------------------------------------------------------------------ + PROCEDURE VitalDECODER2 ( + SIGNAL q : OUT std_logic_vector2; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE NewValue : std_logic_vector2; + VARIABLE Glitch_Data : GlitchArray2; + VARIABLE new_schd : SchedArray2; + VARIABLE Dly, Glch : TimeArray2; + VARIABLE Enable_Schd : SchedType := DefSchedType; + VARIABLE Data_BSchd, Data_ISchd : SchedType; + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF (tpd_enable_q = VitalZeroDelay01) AND (tpd_data_q = VitalZeroDelay01) THEN + LOOP + q <= VitalDECODER2(Data, Enable, ResultMap); + WAIT ON Data, Enable; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + BufPath ( Data_BSchd, InitialEdge(Data), tpd_data_q ); + InvPath ( Data_ISchd, InitialEdge(Data), tpd_data_q ); + BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + BufPath ( Data_BSchd, GetEdge(Data), tpd_data_q ); + InvPath ( Data_ISchd, GetEdge(Data), tpd_data_q ); + + BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalDECODER2 ( Data, Enable, ResultMap ); + new_schd := VitalDECODER2 ( Data_BSchd, Data_ISchd, Enable_Schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; -- SN + END; +-- + PROCEDURE VitalDECODER4 ( + SIGNAL q : OUT std_logic_vector4; + SIGNAL Data : IN std_logic_vector2; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE NewValue : std_logic_vector4; + VARIABLE Glitch_Data : GlitchArray4; + VARIABLE new_schd : SchedArray4; + VARIABLE Dly, Glch : TimeArray4; + VARIABLE Enable_Schd : SchedType; + VARIABLE Enable_Edge : EdgeType; + VARIABLE Data_Edge : EdgeArray2; + VARIABLE Data_BSchd, Data_ISchd : SchedArray2; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF (tpd_enable_q /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + ELSE + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + END IF; + IF (AllZeroDelay) THEN LOOP + q <= VitalDECODER4(Data, Enable, ResultMap); + WAIT ON Data, Enable; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_BSchd, Data_Edge, Atpd_data_q ); + InvPath ( Data_ISchd, Data_Edge, Atpd_data_q ); + + BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalDECODER4 ( Data, Enable, ResultMap ); + new_schd := VitalDECODER4 ( Data_BSchd, Data_ISchd, Enable_Schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; + END; +-- + PROCEDURE VitalDECODER8 ( + SIGNAL q : OUT std_logic_vector8; + SIGNAL Data : IN std_logic_vector3; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE NewValue : std_logic_vector8; + VARIABLE Glitch_Data : GlitchArray8; + VARIABLE new_schd : SchedArray8; + VARIABLE Dly, Glch : TimeArray8; + VARIABLE Enable_Schd : SchedType; + VARIABLE Enable_Edge : EdgeType; + VARIABLE Data_Edge : EdgeArray3; + VARIABLE Data_BSchd, Data_ISchd : SchedArray3; + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF (tpd_enable_q /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + ELSE + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + END IF; + IF (AllZeroDelay) THEN LOOP + q <= VitalDECODER(Data, Enable, ResultMap); + WAIT ON Data, Enable; + END LOOP; + ELSE + + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_BSchd, Data_Edge, Atpd_data_q ); + InvPath ( Data_ISchd, Data_Edge, Atpd_data_q ); + + BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalDECODER8 ( Data, Enable, ResultMap ); + new_schd := VitalDECODER8 ( Data_BSchd, Data_ISchd, Enable_Schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; --SN + END; +-- + PROCEDURE VitalDECODER ( + SIGNAL q : OUT std_logic_vector; + SIGNAL Data : IN std_logic_vector; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) IS + VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); + VARIABLE NewValue : std_logic_vector(q'RANGE); + VARIABLE Glitch_Data : GlitchDataArrayType(q'RANGE); + VARIABLE new_schd : SchedArray(q'RANGE); + VARIABLE Dly, Glch : VitalTimeArray(q'RANGE); + VARIABLE Enable_Schd : SchedType; + VARIABLE Enable_Edge : EdgeType; + VARIABLE Data_Edge : EdgeArray(Data'RANGE); + VARIABLE Data_BSchd, Data_ISchd : SchedArray(Data'RANGE); + ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; + VARIABLE AllZeroDelay : BOOLEAN := TRUE; + BEGIN + -- ------------------------------------------------------------------------ + -- Check if ALL zero delay paths, use simple model + -- ( No delay selection, glitch detection required ) + -- ------------------------------------------------------------------------ + IF (tpd_enable_q /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + ELSE + FOR i IN Data'RANGE LOOP + IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN + AllZeroDelay := FALSE; + EXIT; + END IF; + END LOOP; + END IF; + IF (AllZeroDelay) THEN LOOP + q <= VitalDECODER(Data, Enable, ResultMap); + WAIT ON Data, Enable; + END LOOP; + ELSE + -- -------------------------------------- + -- Initialize delay schedules + -- -------------------------------------- + FOR n IN Data'RANGE LOOP + BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); + END LOOP; + BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); + + LOOP + -- -------------------------------------- + -- Process input signals + -- get edge values + -- re-evaluate output schedules + -- -------------------------------------- + GetEdge ( Data, LastData, Data_Edge ); + BufPath ( Data_BSchd, Data_Edge, Atpd_data_q ); + InvPath ( Data_ISchd, Data_Edge, Atpd_data_q ); + + BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); + + -- ------------------------------------ + -- Compute function and propation delaq + -- ------------------------------------ + NewValue := VitalDECODER ( Data, Enable, ResultMap ); + new_schd := VitalDECODER ( Data_BSchd, Data_ISchd, Enable_Schd ); + + -- ------------------------------------------------------ + -- Assign Outputs + -- get delays to new value and possable glitch + -- schedule output change with On Event glitch detection + -- ------------------------------------------------------ + GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); + VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, + PrimGlitchMode, GlitchDelay=>Glch ); + + WAIT ON Data, Enable; + END LOOP; + END IF; + END; + + -- ------------------------------------------------------------------------ + FUNCTION VitalTruthTable ( + CONSTANT TruthTable : IN VitalTruthTableType; + CONSTANT DataIn : IN std_logic_vector + ) RETURN std_logic_vector IS + + CONSTANT InputSize : INTEGER := DataIn'LENGTH; + CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize; + VARIABLE ReturnValue : std_logic_vector(OutSize - 1 DOWNTO 0) + := (OTHERS => 'X'); + VARIABLE DataInAlias : std_logic_vector(0 TO InputSize - 1) + := To_X01(DataIn); + VARIABLE Index : INTEGER; + VARIABLE Err : BOOLEAN := FALSE; + + -- This needs to be done since the TableLookup arrays must be + -- ascending starting with 0 + VARIABLE TableAlias : VitalTruthTableType(0 TO (TruthTable'LENGTH(1)-1), + 0 TO (TruthTable'LENGTH(2)-1)) + := TruthTable; + + BEGIN + -- search through each row of the truth table + IF OutSize > 0 THEN + ColLoop: + FOR i IN TableAlias'RANGE(1) LOOP + + RowLoop: -- Check each input element of the entry + FOR j IN 0 TO InputSize LOOP + + IF (j = InputSize) THEN -- This entry matches + -- Return the Result + Index := 0; + FOR k IN TruthTable'LENGTH(2) - 1 DOWNTO InputSize LOOP + TruthOutputX01Z ( TableAlias(i,k), + ReturnValue(Index), Err); + EXIT WHEN Err; + Index := Index + 1; + END LOOP; + + IF Err THEN + ReturnValue := (OTHERS => 'X'); + END IF; + RETURN ReturnValue; + END IF; + IF NOT ValidTruthTableInput(TableAlias(i,j)) THEN + VitalError ( "VitalTruthTable", ErrInpSym, + To_TruthChar(TableAlias(i,j)) ); + EXIT ColLoop; + END IF; + EXIT RowLoop WHEN NOT ( TruthTableMatch( DataInAlias(j), + TableAlias(i, j))); + END LOOP RowLoop; + END LOOP ColLoop; + + ELSE + VitalError ( "VitalTruthTable", ErrTabWidSml ); + END IF; + RETURN ReturnValue; + END VitalTruthTable; + + FUNCTION VitalTruthTable ( + CONSTANT TruthTable : IN VitalTruthTableType; + CONSTANT DataIn : IN std_logic_vector + ) RETURN std_logic IS + + CONSTANT InputSize : INTEGER := DataIn'LENGTH; + CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize; + VARIABLE TempResult : std_logic_vector(OutSize - 1 DOWNTO 0) + := (OTHERS => 'X'); + BEGIN + IF (OutSize > 0) THEN + TempResult := VitalTruthTable(TruthTable, DataIn); + IF ( 1 > OutSize) THEN + VitalError ( "VitalTruthTable", ErrTabResSml ); + ELSIF ( 1 < OutSize) THEN + VitalError ( "VitalTruthTable", ErrTabResLrg ); + END IF; + RETURN (TempResult(0)); + ELSE + VitalError ( "VitalTruthTable", ErrTabWidSml ); + RETURN 'X'; + END IF; + END VitalTruthTable; + + PROCEDURE VitalTruthTable ( + SIGNAL Result : OUT std_logic_vector; + CONSTANT TruthTable : IN VitalTruthTableType; + SIGNAL DataIn : IN std_logic_vector -- IR#236 + ) IS + CONSTANT ResLeng : INTEGER := Result'LENGTH; + CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH; + CONSTANT FinalResLen : INTEGER := Minimum(ActResLen, ResLeng); + VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0) + := (OTHERS => 'X'); + + BEGIN + TempResult := VitalTruthTable(TruthTable, DataIn); + + IF (ResLeng > ActResLen) THEN + VitalError ( "VitalTruthTable", ErrTabResSml ); + ELSIF (ResLeng < ActResLen) THEN + VitalError ( "VitalTruthTable", ErrTabResLrg ); + END IF; + TempResult(FinalResLen-1 DOWNTO 0) := TempResult(FinalResLen-1 DOWNTO 0); + Result <= TempResult; + + END VitalTruthTable; + + PROCEDURE VitalTruthTable ( + SIGNAL Result : OUT std_logic; + CONSTANT TruthTable : IN VitalTruthTableType; + SIGNAL DataIn : IN std_logic_vector -- IR#236 + ) IS + + CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH; + VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0) + := (OTHERS => 'X'); + + BEGIN + TempResult := VitalTruthTable(TruthTable, DataIn); + + IF ( 1 > ActResLen) THEN + VitalError ( "VitalTruthTable", ErrTabResSml ); + ELSIF ( 1 < ActResLen) THEN + VitalError ( "VitalTruthTable", ErrTabResLrg ); + END IF; + IF (ActResLen > 0) THEN + Result <= TempResult(0); + END IF; + + END VitalTruthTable; + + -- ------------------------------------------------------------------------ + PROCEDURE VitalStateTable ( + VARIABLE Result : INOUT std_logic_vector; + VARIABLE PreviousDataIn : INOUT std_logic_vector; + CONSTANT StateTable : IN VitalStateTableType; + CONSTANT DataIn : IN std_logic_vector; + CONSTANT NumStates : IN NATURAL + ) IS + + CONSTANT InputSize : INTEGER := DataIn'LENGTH; + CONSTANT OutSize : INTEGER + := StateTable'LENGTH(2) - InputSize - NumStates; + CONSTANT ResLeng : INTEGER := Result'LENGTH; + VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1) + := To_X01(DataIn); + VARIABLE PrevDataAlias : std_logic_vector(0 TO PreviousDataIn'LENGTH-1) + := To_X01(PreviousDataIn); + VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1) + := To_X01(Result); + VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1); + + BEGIN + IF (PreviousDataIn'LENGTH < DataIn'LENGTH) THEN + VitalError ( "VitalStateTable", ErrVctLng, "PreviousDataIn 'X'); + Result := ResultAlias; + + ELSIF (OutSize <= 0) THEN + VitalError ( "VitalStateTable", ErrTabWidSml ); + + ResultAlias := (OTHERS => 'X'); + Result := ResultAlias; + + ELSE + IF (ResLeng > OutSize) THEN + VitalError ( "VitalStateTable", ErrTabResSml ); + ELSIF (ResLeng < OutSize) THEN + VitalError ( "VitalStateTable", ErrTabResLrg ); + END IF; + + ExpResult := StateTableLookUp ( StateTable, DataInAlias, + PrevDataAlias, NumStates, + ResultAlias); + ResultAlias := (OTHERS => 'X'); + ResultAlias ( Maximum(0, ResLeng - OutSize) TO ResLeng - 1) + := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1); + + Result := ResultAlias; + PrevDataAlias(0 TO InputSize - 1) := DataInAlias; + PreviousDataIn := PrevDataAlias; + + END IF; + END VitalStateTable; + + + PROCEDURE VitalStateTable ( + VARIABLE Result : INOUT std_logic; -- states + VARIABLE PreviousDataIn : INOUT std_logic_vector; -- previous inputs and states + CONSTANT StateTable : IN VitalStateTableType; -- User's StateTable data + CONSTANT DataIn : IN std_logic_vector -- Inputs + ) IS + + VARIABLE ResultAlias : std_logic_vector(0 TO 0); + BEGIN + ResultAlias(0) := Result; + VitalStateTable ( StateTable => StateTable, + DataIn => DataIn, + NumStates => 1, + Result => ResultAlias, + PreviousDataIn => PreviousDataIn + ); + Result := ResultAlias(0); + + END VitalStateTable; + + PROCEDURE VitalStateTable ( + SIGNAL Result : INOUT std_logic_vector; + CONSTANT StateTable : IN VitalStateTableType; + SIGNAL DataIn : IN std_logic_vector; + CONSTANT NumStates : IN NATURAL + ) IS + + CONSTANT InputSize : INTEGER := DataIn'LENGTH; + CONSTANT OutSize : INTEGER + := StateTable'LENGTH(2) - InputSize - NumStates; + CONSTANT ResLeng : INTEGER := Result'LENGTH; + + VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1) + := (OTHERS => 'X'); + VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1); + VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1); + VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1); + + BEGIN + IF (OutSize <= 0) THEN + VitalError ( "VitalStateTable", ErrTabWidSml ); + + ResultAlias := (OTHERS => 'X'); + Result <= ResultAlias; + + ELSE + IF (ResLeng > OutSize) THEN + VitalError ( "VitalStateTable", ErrTabResSml ); + ELSIF (ResLeng < OutSize) THEN + VitalError ( "VitalStateTable", ErrTabResLrg ); + END IF; + + LOOP + DataInAlias := To_X01(DataIn); + ResultAlias := To_X01(Result); + ExpResult := StateTableLookUp ( StateTable, DataInAlias, + PrevData, NumStates, + ResultAlias); + ResultAlias := (OTHERS => 'X'); + ResultAlias(Maximum(0, ResLeng - OutSize) TO ResLeng-1) + := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1); + + Result <= ResultAlias; + PrevData := DataInAlias; + + WAIT ON DataIn; + END LOOP; + + END IF; + + END VitalStateTable; + + PROCEDURE VitalStateTable ( + SIGNAL Result : INOUT std_logic; + CONSTANT StateTable : IN VitalStateTableType; + SIGNAL DataIn : IN std_logic_vector + ) IS + + CONSTANT InputSize : INTEGER := DataIn'LENGTH; + CONSTANT OutSize : INTEGER := StateTable'LENGTH(2) - InputSize-1; + + VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1) + := (OTHERS => 'X'); + VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1); + VARIABLE ResultAlias : std_logic_vector(0 TO 0); + VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1); + + BEGIN + IF (OutSize <= 0) THEN + VitalError ( "VitalStateTable", ErrTabWidSml ); + + Result <= 'X'; + + ELSE + IF ( 1 > OutSize) THEN + VitalError ( "VitalStateTable", ErrTabResSml ); + ELSIF ( 1 < OutSize) THEN + VitalError ( "VitalStateTable", ErrTabResLrg ); + END IF; + + LOOP + ResultAlias(0) := To_X01(Result); + DataInAlias := To_X01(DataIn); + ExpResult := StateTableLookUp ( StateTable, DataInAlias, + PrevData, 1, ResultAlias); + + Result <= ExpResult(OutSize-1); + PrevData := DataInAlias; + + WAIT ON DataIn; + END LOOP; + END IF; + + END VitalStateTable; + + -- ------------------------------------------------------------------------ + -- std_logic resolution primitive + -- ------------------------------------------------------------------------ + PROCEDURE VitalResolve ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector --IR236 4/2/98 + ) IS + VARIABLE uData : std_ulogic_vector(Data'RANGE); + BEGIN + FOR i IN Data'RANGE LOOP + uData(i) := Data(i); + END LOOP; + q <= resolved(uData); + END; + +END VITAL_Primitives; + diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/prmtvs_p.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/prmtvs_p.vhdl new file mode 100644 index 00000000..857899e3 --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/prmtvs_p.vhdl @@ -0,0 +1,1413 @@ +-- ----------------------------------------------------------------------------- +-- Title : Standard VITAL_Primitives Package +-- : $Revision$ +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4 +-- : +-- Purpose : This packages defines standard types, constants, functions +-- : and procedures for use in developing ASIC models. +-- : Specifically a set of logic primitives are defined. +-- : +-- Known Errors : +-- : +-- Note : No declarations or definitions shall be included in, +-- : or excluded from this package. The "package declaration" +-- : defines the objects (types, subtypes, constants, functions, +-- : procedures ... etc.) that can be used by a user. The package +-- : body shall be considered the formal definition of the +-- : semantics of this package. Tool developers may choose to +-- : implement the package body in the most efficient manner +-- : available to them. +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Acknowledgments: +-- This code was originally developed under the "VHDL Initiative Toward ASIC +-- Libraries" (VITAL), an industry sponsored initiative. Technical +-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator: +-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design +-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek, +-- Texas Instruments; Victor Martin, Hewlett-Packard Company. +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Modification History : +-- ---------------------------------------------------------------------------- +-- Version No:|Auth:| Mod.Date:| Changes Made: +-- v95.0 A | | 06/02/95 | Initial ballot draft 1995 +-- ---------------------------------------------------------------------------- +-- v95.3 | ddl | 09/24/96 | #236 - VitalTruthTable DataIn should be of +-- | | | of class SIGNAL (PROPOSED) +-- ---------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.Std_Logic_1164.ALL; +USE IEEE.VITAL_Timing.ALL; + +PACKAGE VITAL_Primitives IS + -- ------------------------------------------------------------------------ + -- Type and Subtype Declarations + -- ------------------------------------------------------------------------ + + -- For Truth and State Tables + SUBTYPE VitalTruthSymbolType IS VitalTableSymbolType RANGE 'X' TO 'Z'; + SUBTYPE VitalStateSymbolType IS VitalTableSymbolType RANGE '/' TO 'S'; + + TYPE VitalTruthTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> ) + OF VitalTruthSymbolType; + TYPE VitalStateTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> ) + OF VitalStateSymbolType; + + -- --------------------------------- + -- Default values used by primitives + -- --------------------------------- + CONSTANT VitalDefDelay01 : VitalDelayType01; -- Propagation delays + CONSTANT VitalDefDelay01Z : VitalDelayType01Z; + + -- ------------------------------------------------------------------------ + -- VITAL Primitives + -- + -- The primitives packages contains a collections of common gates, + -- including AND, OR, XOR, NAND, NOR, XNOR, BUF, INV, MUX and DECODER + -- functions. In addition, for sequential devices, a STATE TABLE construct + -- is provided. For complex functions a modeler may wish to use either + -- a collection of connected VITAL primitives, or a TRUTH TABLE construct. + -- + -- For each primitive a Function and Procedure is provided. The primitive + -- functions are provided to support behavioral modeling styles. The + -- primitive procedures are provided to support structural modeling styles. + -- + -- The procedures wait internally for an event on an input signal, compute + -- the new result, perform glitch handling, schedule transaction on the + -- output signals, and wait for future input events. All of the functional + -- (logic) input or output parameters of the primitive procedures are + -- signals. All the other parameters are constants. + -- + -- The procedure primitives are parameterized for separate path delays + -- from each input signal. All path delays default to 0 ns. + -- + -- The sequential primitive functions compute the defined function and + -- return a value of type std_ulogic or std_logic_vector. All parameters + -- of the primitive functions are constants of mode IN. + -- + -- The primitives are based on 1164 operators. The user may also elect to + -- express functions using the 1164 operators as well. These styles are + -- all equally acceptable methods for device modeling. + -- + -- ------------------------------------------------------------------------ + -- + -- Sequential + -- Primitive + -- Function Name: N-input logic device function calls: + -- VitalAND VitalOR VitalXOR + -- VitalNAND VitalNOR VitalXNOR + -- + -- Description: The function calls return the evaluated logic function + -- corresponding to the function name. + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_logic_vector The input signals for the n-bit + -- wide logic functions. + -- ResultMap VitalResultMapType The output signal strength + -- result map to modify default + -- result mapping. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- std_ulogic The evaluated logic function of + -- the n-bit wide primitives. + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalAND ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNAND ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXNOR ( + CONSTANT Data : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap + ) RETURN std_ulogic; + + -- ------------------------------------------------------------------------- + -- + -- Concurrent + -- Primitive + -- Procedure Name: N-input logic device concurrent procedure calls. + -- VitalAND VitalOR VitalXOR + -- VitalNAND VitalNOR VitalXNOR + -- + -- Description: The procedure calls return the evaluated logic function + -- corresponding to the function name as a parameter to the + -- procedure. Propagation delay form data to q is a + -- a parameter to the procedure. A vector of delay values + -- for inputs to output are provided. It is noted that + -- limitations in SDF make the back annotation of the delay + -- array difficult. + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_logic_vector The input signals for the n- + -- bit wide logic functions. + -- tpd_data_q VitalDelayArrayType01 The propagation delay from + -- the data inputs to the output + -- q. + -- + -- INOUT + -- none + -- + -- OUT + -- q std_ulogic The output signal of the + -- evaluated logic function. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalAND ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNAND ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXNOR ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + -- ------------------------------------------------------------------------- + -- + -- Sequential + -- Primitive + -- Function Name: 2,3 and 4 input logic device function calls. + -- + -- VitalAND2 VitalOR2 VitalXOR2 + -- VitalAND3 VitalOR3 VitalXOR3 + -- VitalAND4 VitalOR4 VitalXOR4 + -- + -- VitalNAND2 VitalNOR2 VitalXNOR2 + -- VitalNAND3 VitalNOR3 VitalXNOR3 + -- VitalNAND4 VitalNOR4 VitalXNOR4 + -- + -- Description: The function calls return the evaluated 2, 3 or 4 input + -- logic function corresponding to the function name. + -- + -- Arguments: + -- + -- IN Type Description + -- a, b, c, d std_ulogic 2 input devices have a and b as + -- inputs. 3 input devices have a, b + -- and c as inputs. 4 input devices + -- have a, b, c and d as inputs. + -- ResultMap VitalResultMapType The output signal strength result map + -- to modify default result mapping. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- std_ulogic The result of the evaluated logic + -- function. + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalAND2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNAND2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXNOR2 ( + CONSTANT a, b : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalAND3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNAND3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXNOR3 ( + CONSTANT a, b, c : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalAND4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNAND4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalNOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalXNOR4 ( + CONSTANT a, b, c, d : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + -- ------------------------------------------------------------------------- + -- + -- Concurrent + -- Primitive + -- Procedure Name: 2, 3 and 4 input logic device concurrent procedure + -- calls. + -- + -- VitalAND2 VitalOR2 VitalXOR2 + -- VitalAND3 VitalOR3 VitalXOR3 + -- VitalAND4 VitalOR4 VitalXOR4 + -- + -- VitalNAND2 VitalNOR2 VitalXNOR2 + -- VitalNAND3 VitalNOR3 VitalXNOR3 + -- VitalNAND4 VitalNOR4 VitalXNOR4 + -- + -- Description: The procedure calls return the evaluated logic function + -- corresponding to the function name as a parameter to the + -- procedure. Propagation delays from a and b to q are + -- a parameter to the procedure. The default propagation + -- delay is 0 ns. + -- + -- Arguments: + -- + -- IN Type Description + -- a, b, c, d std_ulogic 2 input devices have a and b as + -- inputs. 3 input devices have a, b + -- and c as inputs. 4 input devices + -- have a, b, c and d as inputs. + -- tpd_a_q VitalDelayType01 The propagation delay from the a + -- input to output q for 2, 3 and 4 + -- input devices. + -- tpd_b_q VitalDelayType01 The propagation delay from the b + -- input to output q for 2, 3 and 4 + -- input devices. + -- tpd_c_q VitalDelayType01 The propagation delay from the c + -- input to output q for 3 and 4 input + -- devices. + -- tpd_d_q VitalDelayType01 The propagation delay from the d + -- input to output q for 4 input + -- devices. + -- ResultMap VitalResultMapType The output signal strength result map + -- to modify default result mapping. + -- + -- INOUT + -- none + -- + -- OUT + -- q std_ulogic The output signal of the evaluated + -- logic function. + -- + -- Returns + -- none + -- ------------------------------------------------------------------------- + PROCEDURE VitalAND2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNAND2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXNOR2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalAND3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNAND3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXNOR3 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalAND4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNAND4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalNOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalXNOR4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL a, b, c, d : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + -- ------------------------------------------------------------------------ + -- + -- Sequential + -- Primitive + -- Function Name: Buffer logic device concurrent procedure calls. + -- + -- Description: Four buffer sequential primitive function calls are + -- provided. One is a simple buffer and the others + -- offer high and low enables and the four permits + -- propagation of Z as shown below: + -- + -- VitalBUF Standard non-inverting buffer + -- VitalBUFIF0 Non-inverting buffer with Enable low + -- VitalBUFIF1 Non-inverting buffer with Enable high + -- VitalIDENT Pass buffer capable of propagating Z + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_ulogic Input to the buffers + -- Enable std_ulogic Enable for the enable high and low + -- buffers. + -- ResultMap VitalResultMapType The output signal strength result map + -- to modify default result mapping for + -- simple buffer. + -- VitalResultZMapType The output signal strength result map + -- to modify default result mapping + -- which has high impedance capability + -- for the enable high, enable low and + -- identity buffers. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- std_ulogic The output signal of the evaluated + -- buffer function. + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalBUF ( + CONSTANT Data : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + FUNCTION VitalBUFIF0 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic; + FUNCTION VitalBUFIF1 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic; + FUNCTION VitalIDENT ( + CONSTANT Data : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic; + + -- ------------------------------------------------------------------------- + -- + -- Concurrent + -- Primitive + -- Procedure Name: Buffer device procedure calls. + -- + -- Description: Four buffer concurrent primitive procedure calls are + -- provided. One is a simple buffer and the others + -- offer high and low enables and the fourth permits + -- propagation of Z as shown below: + -- + -- VitalBUF Standard non-inverting buffer + -- VitalBUFIF0 Non-inverting buffer with Enable low + -- VitalBUFIF1 Non-inverting buffer with Enable high + -- VitalIDENT Pass buffer capable of propagating Z + -- + -- Arguments: + -- + -- IN Type Description + -- a std_ulogic Input signal to the buffers + -- Enable std_ulogic Enable signal for the enable high and + -- low buffers. + -- tpd_a_q VitalDelayType01 Propagation delay from input to + -- output for the simple buffer. + -- VitalDelayType01Z Propagation delay from input to + -- to output for the enable high and low + -- and identity buffers. + -- tpd_enable_q VitalDelayType01Z Propagation delay from enable to + -- output for the enable high and low + -- buffers. + -- ResultMap VitalResultMapType The output signal strength result map + -- to modify default result mapping for + -- simple buffer. + -- VitalResultZMapType The output signal strength result map + -- to modify default result mapping + -- which has high impedance capability + -- for the enable high, enable low and + -- identity buffers. + -- + -- INOUT + -- none + -- + -- OUT + -- q std_ulogic Output of the buffers. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalBUF ( + SIGNAL q : OUT std_ulogic; + SIGNAL a : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalBUFIF0 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap); + + + PROCEDURE VitalBUFIF1 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap); + + PROCEDURE VitalIDENT ( + SIGNAL q : OUT std_ulogic; + SIGNAL a : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap ); + + -- ------------------------------------------------------------------------ + -- + -- Sequential + -- Primitive + -- Function Name: VitalINV, VitalINVIF0, VitalINVIF1 + -- + -- Description: Inverter functions which return the inverted signal + -- value. Inverters with enable low and high are provided + -- which can drive high impedance when inactive. + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_ulogic Input to the inverter + -- Enable std_ulogic Enable to the enable high and low + -- inverters. + -- ResultMap VitalResultMap The output signal strength result map + -- to modify default result mapping for + -- simple inverter. + -- VitalResultZMapType The output signal strength result map + -- to modify default result mapping + -- which has high impedance capability + -- for the enable high, enable low + -- inverters. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- std_ulogic Output of the inverter + -- + -- ------------------------------------------------------------------------- + + FUNCTION VitalINV ( + CONSTANT Data : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalINVIF0 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic; + + FUNCTION VitalINVIF1 ( + CONSTANT Data, Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap + ) RETURN std_ulogic; + + -- ------------------------------------------------------------------------- + -- + -- Concurrent + -- Primitive + -- Procedure Name: VitalINV, VitalINVIF0, VitalINVIF1 + -- + -- Description: The concurrent primitive procedure calls implement a + -- signal inversion function. The output is a parameter to + -- the procedure. The path delay information is passed as + -- a parameter to the call. + -- + -- Arguments: + -- + -- IN Type Description + -- a std_ulogic Input signal for the simple inverter + -- Data std_ulogic Input signal for the enable high and + -- low inverters. + -- Enable std_ulogic Enable signal for the enable high and + -- low inverters. + -- tpd_a_q VitalDelayType01 Propagation delay from input a to + -- output q for the simple inverter. + -- tpd_data_q VitalDelayType01 Propagation delay from input data to + -- output q for the enable high and low + -- inverters. + -- tpd_enable_q VitalDelayType01Z Propagation delay from input enable + -- to output q for the enable high and + -- low inverters. + -- ResultMap VitalResultMapType The output signal strength result map + -- to modify default result mapping for + -- simple inverter. + -- VitalResultZMapType The output signal strength result map + -- to modify default result mapping + -- which has high impedance capability + -- for the enable high, enable low + -- inverters. + -- + -- INOUT + -- none + -- + -- OUT + -- q std_ulogic Output signal of the inverter. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalINV ( + SIGNAL q : OUT std_ulogic; + SIGNAL a : IN std_ulogic; + CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + PROCEDURE VitalINVIF0 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap); + + PROCEDURE VitalINVIF1 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; + CONSTANT ResultMap : IN VitalResultZMapType + := VitalDefaultResultZMap); + + -- ------------------------------------------------------------------------ + -- + -- Sequential + -- Primitive + -- Function Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8 + -- + -- Description: The VitalMUX functions return the selected data bit + -- based on the value of dSelect. For MUX2, the function + -- returns data0 when dselect is 0 and returns data1 when + -- dselect is 1. When dselect is X, result is X for MUX2 + -- when data0 /= data1. X propagation is reduced when the + -- dselect signal is X and both data signals are identical. + -- When this is the case, the result returned is the value + -- of the data signals. + -- + -- For the N input device: + -- + -- N must equal 2**(bits of dSelect) + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_logic_vector Input signal for the N-bit, 4-bit and + -- 8-bit mux. + -- Data1,Data0 std_ulogic Input signals for the 2-bit mux. + -- dSelect std_ulogic Select signal for 2-bit mux + -- std_logic_vector2 Select signal for 4-bit mux + -- std_logic_vector3 Select signal for 8-bit mux + -- std_logic_vector Select signal for N-Bit mux + -- ResultMap VitalResultMapType The output signal strength result map + -- to modify default result mapping for + -- all muxes. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- std_ulogic The value of the selected bit is + -- returned. + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalMUX ( + CONSTANT Data : IN std_logic_vector; + CONSTANT dSelect : IN std_logic_vector; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalMUX2 ( + CONSTANT Data1, Data0 : IN std_ulogic; + CONSTANT dSelect : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalMUX4 ( + CONSTANT Data : IN std_logic_vector4; + CONSTANT dSelect : IN std_logic_vector2; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + FUNCTION VitalMUX8 ( + CONSTANT Data : IN std_logic_vector8; + CONSTANT dSelect : IN std_logic_vector3; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_ulogic; + + -- ------------------------------------------------------------------------- + -- + -- Concurrent + -- Primitive + -- Procedure Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8 + -- + -- Description: The VitalMUX concurrent primitive procedures calls + -- return in the output q the value of the selected data + -- bit based on the value of dsel. For the two bit mux, + -- the data returned is either d0 or d1, the data input. + -- For 4, 8 and N-bit functions, data is the input and is + -- of type std_logic_vector. For the 2-bit mux, if d0 or + -- d1 are X, the output is X only when d0 do not equal d1. + -- When d0 and d1 are equal, the return value is this value + -- to reduce X propagation. + -- + -- Propagation delay information is passed as a parameter + -- to the procedure call for delays from data to output and + -- select to output. For 2-bit muxes, the propagation + -- delays from data are provided for d0 and d1 to output. + -- + -- + -- Arguments: + -- + -- IN Type Description + -- d1,d0 std_ulogic Input signals for the 2-bit mux. + -- Data std_logic_vector4 Input signals for the 4-bit mux. + -- std_logic_vector8 Input signals for the 8-bit mux. + -- std_logic_vector Input signals for the N-bit mux. + -- dsel std_ulogic Select signal for the 2-bit mux. + -- std_logic_vector2 Select signals for the 4-bit mux. + -- std_logic_vector3 Select signals for the 8-bit mux. + -- std_logic_vector Select signals for the N-bit mux. + -- tpd_d1_q VitalDelayType01 Propagation delay from input d1 to + -- output q for 2-bit mux. + -- tpd_d0_q VitalDelayType01 Propagation delay from input d0 to + -- output q for 2-bit mux. + -- tpd_data_q VitalDelayArrayType01 Propagation delay from input data + -- to output q for 4-bit, 8-bit and + -- N-bit muxes. + -- tpd_dsel_q VitalDelayType01 Propagation delay from input dsel + -- to output q for 2-bit mux. + -- VitalDelayArrayType01 Propagation delay from input dsel + -- to output q for 4-bit, 8-bit and + -- N-bit muxes. + -- ResultMap VitalResultMapType The output signal strength result + -- map to modify default result + -- mapping for all muxes. + -- + -- INOUT + -- none + -- + -- OUT + -- q std_ulogic The value of the selected signal. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalMUX ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector; + SIGNAL dSel : IN std_logic_vector; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalMUX2 ( + SIGNAL q : OUT std_ulogic; + SIGNAL d1, d0 : IN std_ulogic; + SIGNAL dSel : IN std_ulogic; + CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalMUX4 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector4; + SIGNAL dSel : IN std_logic_vector2; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalMUX8 ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector8; + SIGNAL dSel : IN std_logic_vector3; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + -- ------------------------------------------------------------------------ + -- + -- Sequential + -- Primitive + -- Function Name: VitalDECODER, VitalDECODER2, VitalDECODER4, + -- VitalDECODER8 + -- + -- Description: The VitalDECODER functions are the sequential primitive + -- calls for decoder logic. The functions are provided + -- for N, 2, 4 and 8-bit outputs. + -- + -- The N-bit decoder is (2**(bits of data)) wide. + -- + -- The VitalDECODER returns 0 if enable is 0. + -- The VitalDECODER returns the result bit set to 1 if + -- enable is 1. All other bits of returned result are + -- set to 0. + -- + -- The returned array is in descending order: + -- (n-1 downto 0). + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_ulogic Input signal for 2-bit decoder. + -- std_logic_vector2 Input signals for 4-bit decoder. + -- std_logic_vector3 Input signals for 8-bit decoder. + -- std_logic_vector Input signals for N-bit decoder. + -- Enable std_ulogic Enable input signal. The result is + -- output when enable is high. + -- ResultMap VitalResultMapType The output signal strength result map + -- to modify default result mapping for + -- all output signals of the decoders. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- std_logic_vector2 The output of the 2-bit decoder. + -- std_logic_vector4 The output of the 4-bit decoder. + -- std_logic_vector8 The output of the 8-bit decoder. + -- std_logic_vector The output of the n-bit decoder. + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalDECODER ( + CONSTANT Data : IN std_logic_vector; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector; + + FUNCTION VitalDECODER2 ( + CONSTANT Data : IN std_ulogic; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector2; + + FUNCTION VitalDECODER4 ( + CONSTANT Data : IN std_logic_vector2; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector4; + + FUNCTION VitalDECODER8 ( + CONSTANT Data : IN std_logic_vector3; + CONSTANT Enable : IN std_ulogic; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap + ) RETURN std_logic_vector8; + + -- ------------------------------------------------------------------------- + -- + -- Concurrent + -- Primitive + -- Procedure Name: VitalDECODER, VitalDECODER2, VitalDECODER4, + -- VitalDECODER8 + -- + -- Description: The VitalDECODER procedures are the concurrent primitive + -- procedure calls for decoder functions. The procedures + -- are provided for N, 2, 4 and 8 outputs. + -- + -- The N-bit decoder is (2**(bits of data)) wide. + -- + -- The procedural form of the decoder is used for + -- distributed delay modeling. The delay information for + -- each path is passed as an argument to the procedure. + -- + -- Result is set to 0 if enable is 0. + -- The result bit represented by data is set to 1 if + -- enable is 1. All other bits of result are set to 0. + -- + -- The result array is in descending order: (n-1 downto 0). + -- + -- For the N-bit decoder, the delay path is a vector of + -- delays from inputs to outputs. + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_ulogic Input signal for 2-bit decoder. + -- std_logic_vector2 Input signals for 4-bit decoder. + -- std_logic_vector3 Input signals for 8-bit decoder. + -- std_logic_vector Input signals for N-bit decoder. + -- enable std_ulogic Enable input signal. The result is + -- output when enable is high. + -- tpd_data_q VitalDelayType01 Propagation delay from input data + -- to output q for 2-bit decoder. + -- VitalDelayArrayType01 Propagation delay from input data + -- to output q for 4, 8 and n-bit + -- decoders. + -- tpd_enable_q VitalDelayType01 Propagation delay from input enable + -- to output q for 2, 4, 8 and n-bit + -- decoders. + -- + -- INOUT + -- none + -- + -- OUT + -- q std_logic_vector2 Output signals for 2-bit decoder. + -- std_logic_vector4 Output signals for 4-bit decoder. + -- std_logic_vector8 Output signals for 8-bit decoder. + -- std_logic_vector Output signals for n-bit decoder. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalDECODER ( + SIGNAL q : OUT std_logic_vector; + SIGNAL Data : IN std_logic_vector; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + PROCEDURE VitalDECODER2 ( + SIGNAL q : OUT std_logic_vector2; + SIGNAL Data : IN std_ulogic; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + PROCEDURE VitalDECODER4 ( + SIGNAL q : OUT std_logic_vector4; + SIGNAL Data : IN std_logic_vector2; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + PROCEDURE VitalDECODER8 ( + SIGNAL q : OUT std_logic_vector8; + SIGNAL Data : IN std_logic_vector3; + SIGNAL Enable : IN std_ulogic; + CONSTANT tpd_data_q : IN VitalDelayArrayType01; + CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; + CONSTANT ResultMap : IN VitalResultMapType + := VitalDefaultResultMap ); + + -- ------------------------------------------------------------------------- + -- Function Name: VitalTruthTable + -- + -- Description: VitalTruthTable implements a truth table. Given + -- a set of inputs, a sequential search is performed + -- to match the input. If a match is found, the output + -- is set based on the contents of the CONSTANT TruthTable. + -- If there is no match, all X's are returned. There is + -- no limit to the size of the table. + -- + -- There is a procedure and function for VitalTruthTable. + -- For each of these, a single value output (std_logic) and + -- a multi-value output (std_logic_vector) are provided. + -- + -- The first dimension of the table is for number of + -- entries in the truth table and second dimension is for + -- the number of elements in a row. The number of inputs + -- in the row should be Data'LENGTH plus result'LENGTH. + -- + -- Elements is a row will be interpreted as + -- Input(NumInputs - 1),.., Input(0), + -- Result(NumOutputs - 1),.., Result(0) + -- + -- All inputs will be mapped to the X01 subtype + -- + -- If the value of Result is not in the range 'X' to 'Z' + -- then an error will be reported. Also, the Result is + -- always given either as a 0, 1, X or Z value. + -- + -- Arguments: + -- + -- IN Type Description + -- TruthTable The input constant which defines the + -- behavior in truth table form. + -- DataIn The inputs to the truth table used to + -- perform input match to select + -- output(s) to value(s) to drive. + -- + -- INOUT + -- none + -- + -- OUT + -- Result std_logic Concurrent procedure version scalar + -- output. + -- std_logic_vector Concurrent procedure version vector + -- output. + -- + -- Returns + -- Result std_logic Function version scalar output. + -- std_logic_vector Function version vector output. + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalTruthTable ( + CONSTANT TruthTable : IN VitalTruthTableType; + CONSTANT DataIn : IN std_logic_vector + ) RETURN std_logic_vector; + + FUNCTION VitalTruthTable ( + CONSTANT TruthTable : IN VitalTruthTableType; + CONSTANT DataIn : IN std_logic_vector + ) RETURN std_logic; + + PROCEDURE VitalTruthTable ( + SIGNAL Result : OUT std_logic_vector; + CONSTANT TruthTable : IN VitalTruthTableType; + SIGNAL DataIn : IN std_logic_vector -- IR#236 + ); + PROCEDURE VitalTruthTable ( + SIGNAL Result : OUT std_logic; + CONSTANT TruthTable : IN VitalTruthTableType; + SIGNAL DataIn : IN std_logic_vector -- IR#236 + ); + -- ------------------------------------------------------------------------- + -- + -- Function Name: VitalStateTable + -- + -- Description: VitalStateTable is a non-concurrent implementation of a + -- state machine (Moore Machine). It is used to model + -- sequential devices and devices with internal states. + -- + -- The procedure takes the value of the state table + -- data set and performs a sequential search of the + -- CONSTANT StateTable until a match is found. Once a + -- match is found, the result of that match is applied + -- to Result. If there is no match, all X's are returned. + -- The resultant output becomes the input for the next + -- state. + -- + -- The first dimension of the table is the number of + -- entries in the state table and second dimension is the + -- number of elements in a row of the table. The number of + -- inputs in the row should be DataIn'LENGTH. Result should + -- contain the current state (which will become the next + -- state) as well as the outputs + -- + -- Elements is a row of the table will be interpreted as + -- Input(NumInputs-1),.., Input(0), State(NumStates-1), + -- ..., State(0),Output(NumOutputs-1),.., Output(0) + -- + -- where State(numStates-1) DOWNTO State(0) represent the + -- present state and Output(NumOutputs - 1) DOWNTO + -- Outputs(NumOutputs - NumStates) represent the new + -- values of the state variables (i.e. the next state). + -- Also, Output(NumOutputs - NumStates - 1) + -- + -- This procedure returns the next state and the new + -- outputs when a match is made between the present state + -- and present inputs and the state table. A search is + -- made starting at the top of the state table and + -- terminates with the first match. If no match is found + -- then the next state and new outputs are set to all 'X's. + -- + -- (Asynchronous inputs (i.e. resets and clears) must be + -- handled by placing the corresponding entries at the top + -- of the table. ) + -- + -- All inputs will be mapped to the X01 subtype. + -- + -- NOTE: Edge transitions should not be used as values + -- for the state variables in the present state + -- portion of the state table. The only valid + -- values that can be used for the present state + -- portion of the state table are: + -- 'X', '0', '1', 'B', '-' + -- + -- Arguments: + -- + -- IN Type Description + -- StateTable VitalStateTableType The input constant which defines + -- the behavior in state table form. + -- DataIn std_logic_vector The current state inputs to the + -- state table used to perform input + -- matches and transition + -- calculations. + -- NumStates NATURAL Number of state variables + -- + -- INOUT + -- Result std_logic Output signal for scalar version of + -- the concurrent procedure call. + -- std_logic_vector Output signals for vector version + -- of the concurrent procedure call. + -- PreviousDataIn std_logic_vector The previous inputs and states used + -- in transition calculations and to + -- set outputs for steady state cases. + -- + -- OUT + -- none + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalStateTable ( + VARIABLE Result : INOUT std_logic_vector; + VARIABLE PreviousDataIn : INOUT std_logic_vector; + CONSTANT StateTable : IN VitalStateTableType; + CONSTANT DataIn : IN std_logic_vector; + CONSTANT NumStates : IN NATURAL + ); + + PROCEDURE VitalStateTable ( + VARIABLE Result : INOUT std_logic; + VARIABLE PreviousDataIn : INOUT std_logic_vector; + CONSTANT StateTable : IN VitalStateTableType; + CONSTANT DataIn : IN std_logic_vector + ); + + PROCEDURE VitalStateTable ( + SIGNAL Result : INOUT std_logic_vector; + CONSTANT StateTable : IN VitalStateTableType; + SIGNAL DataIn : IN std_logic_vector; + CONSTANT NumStates : IN NATURAL + ); + + PROCEDURE VitalStateTable ( + SIGNAL Result : INOUT std_logic; + CONSTANT StateTable : IN VitalStateTableType; + SIGNAL DataIn : IN std_logic_vector + ); + + -- ------------------------------------------------------------------------- + -- + -- Function Name: VitalResolve + -- + -- Description: VitalResolve takes a vector of signals and resolves + -- them to a std_ulogic value. This procedure can be used + -- to resolve multiple drivers in a single model. + -- + -- Arguments: + -- + -- IN Type Description + -- Data std_logic_vector Set of input signals which drive a + -- common signal. + -- + -- INOUT + -- none + -- + -- OUT + -- q std_ulogic Output signal which is the resolved + -- value being driven by the collection of + -- input signals. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalResolve ( + SIGNAL q : OUT std_ulogic; + SIGNAL Data : IN std_logic_vector); --IR236 4/2/98 + +END VITAL_Primitives; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/timing_b.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/timing_b.vhdl new file mode 100644 index 00000000..cf6f6f5b --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/timing_b.vhdl @@ -0,0 +1,2187 @@ +------------------------------------------------------------------------------- +-- Title : Standard VITAL TIMING Package +-- : $Revision$ +-- Library : VITAL +-- : +-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4 +-- : +-- Purpose : This packages defines standard types, attributes, constants, +-- : functions and procedures for use in developing ASIC models. +-- : This file contains the Package Body. +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Modification History : +-- ---------------------------------------------------------------------------- +-- Version No:|Auth:| Mod.Date:| Changes Made: +-- v95.0 A | | 06/08/95 | Initial ballot draft 1995 +-- v95.1 | | 08/31/95 | #IR203 - Timing violations at time 0 +-- #IR204 - Output mapping prior to glitch detection +-- v98.0 |TAG | 03/27/98 | Initial ballot draft 1998 +-- | #IR225 - Negative Premptive Glitch +-- **Code_effected=ReportGlitch,VitalGlitch, +-- VitalPathDelay,VitalPathDelay01, +-- VitalPathDelay01z. +-- #IR105 - Skew timing check needed +-- **Code_effected=NONE, New code added!! +-- #IR245,IR246,IR251 ITC code to fix false boundry cases +-- **Code_effected=InternalTimingCheck. +-- #IR248 - Allows VPD to use a default timing delay +-- **Code_effected=VitalPathDelay, +-- VitalPathDelay01,VitalPathDelay01z, +-- VitalSelectPathDelay,VitalSelectPathDelay01, +-- VitalSelectPathDelay01z. +-- #IR250 - Corrects fastpath condition in VPD +-- **Code_effected=VitalPathDelay01, +-- VitalPathDelay01z, +-- #IR252 - Corrects cancelled timing check call if +-- condition expires. +-- **Code_effected=VitalSetupHoldCheck, +-- VitalRecoveryRemovalCheck. +-- v98.1 | jdc | 03/25/99 | Changed UseDefaultDelay to IgnoreDefaultDelay +-- and set default to FALSE in VitalPathDelay() +-- +-- ---------------------------------------------------------------------------- + +LIBRARY STD; +USE STD.TEXTIO.ALL; + +PACKAGE BODY VITAL_Timing IS + + -- -------------------------------------------------------------------- + -- Package Local Declarations + -- -------------------------------------------------------------------- + + TYPE CheckType IS ( SetupCheck, HoldCheck, RecoveryCheck, RemovalCheck, + PulseWidCheck, PeriodCheck ); + + TYPE CheckInfoType IS RECORD + Violation : BOOLEAN; + CheckKind : CheckType; + ObsTime : TIME; + ExpTime : TIME; + DetTime : TIME; + State : X01; + END RECORD; + + TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER; + TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4); + + CONSTANT LogicCvtTable : LogicCvtTableType + := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); + CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" ); + + TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN; + -- last value, present value, edge symbol + CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType := ( + 'X'=>('X'=>( OTHERS => FALSE), + '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ), + '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE ) ), + '0'=>('X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ), + '0'=>( OTHERS => FALSE ), + '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE ) ), + '1'=>('X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ), + '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ), + '1'=>( OTHERS => FALSE ) ) ); + + + + + --------------------------------------------------------------------------- + -- Tables used to implement 'posedge' and 'negedge' in path delays + -- These are new tables for Skewcheck routines. IR105 + --------------------------------------------------------------------------- + + TYPE EdgeRable IS ARRAY(std_ulogic, std_ulogic) OF boolean; + + CONSTANT Posedge : EdgeRable := ( + -- ------------------------------------------------------------------------ + -- | U X 0 1 Z W L H - + -- ------------------------------------------------------------------------ + ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- U + ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- X + ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- 0 + ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 1 + ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- Z + ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- W + ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- L + ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- H + ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ) -- - + + ); --IR105 + + + CONSTANT Negedge : EdgeRable := ( + -- ----------------------------------------------------------------------- + -- | U X 0 1 Z W L H - + -- ----------------------------------------------------------------------- + ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- U + ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- X + ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 0 + ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- 1 + ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- Z + ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- W + ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- L + ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- H + ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ) -- - + + ); --IR105 + + TYPE SkewType IS (Inphase, Outphase); --IR105 + + CONSTANT noTrigger : TIME := -1 ns; --IR105 + --------------------------------------------------------------------------- + -- End of Skew (IR105 additions) + --------------------------------------------------------------------------- + + + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + -- Misc Utilities Local Utilities + --------------------------------------------------------------------------- + ----------------------------------------------------------------------- + FUNCTION Minimum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS + BEGIN + IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF; + END Minimum; + ----------------------------------------------------------------------- + FUNCTION Maximum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS + BEGIN + IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF; + END Maximum; + + -------------------------------------------------------------------- + -- Error Message Types and Tables + -------------------------------------------------------------------- + TYPE VitalErrorType IS ( + ErrVctLng , + ErrNoPath , + ErrNegPath , + ErrNegDel + ); + + TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL; + CONSTANT VitalErrorSeverity : VitalErrorSeverityType := ( + ErrVctLng => ERROR, + ErrNoPath => WARNING, + ErrNegPath => WARNING, + ErrNegDel => WARNING + ); + + CONSTANT MsgNoPath : STRING := + "No Delay Path Condition TRUE. 0-delay used. Output signal is: "; + CONSTANT MsgNegPath : STRING := + "Path Delay less than time since input. 0 delay used. Output signal is: "; + CONSTANT MsgNegDel : STRING := + "Negative delay. New output value not scheduled. Output signal is: "; + CONSTANT MsgVctLng : STRING := + "Vector (array) lengths not equal. "; + + CONSTANT MsgUnknown : STRING := + "Unknown error message."; + + FUNCTION VitalMessage ( + CONSTANT ErrorId : IN VitalErrorType + ) RETURN STRING IS + BEGIN + CASE ErrorId IS + WHEN ErrVctLng => RETURN MsgVctLng; + WHEN ErrNoPath => RETURN MsgNoPath; + WHEN ErrNegPath => RETURN MsgNegPath; + WHEN ErrNegDel => RETURN MsgNegDel; + WHEN OTHERS => RETURN MsgUnknown; + END CASE; + END; + + PROCEDURE VitalError ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalErrorType + ) IS + BEGIN + ASSERT FALSE + REPORT Routine & ": " & VitalMessage(ErrorId) + SEVERITY VitalErrorSeverity(ErrorId); + END; + + PROCEDURE VitalError ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalErrorType; + CONSTANT Info : IN STRING + ) IS + BEGIN + ASSERT FALSE + REPORT Routine & ": " & VitalMessage(ErrorId) & Info + SEVERITY VitalErrorSeverity(ErrorId); + END; + + PROCEDURE VitalError ( + CONSTANT Routine : IN STRING; + CONSTANT ErrorId : IN VitalErrorType; + CONSTANT Info : IN CHARACTER + ) IS + BEGIN + ASSERT FALSE + REPORT Routine & ": " & VitalMessage(ErrorId) & Info + SEVERITY VitalErrorSeverity(ErrorId); + END; + + --------------------------------------------------------------------------- + -- Time Delay Assignment Subprograms + --------------------------------------------------------------------------- + FUNCTION VitalExtendToFillDelay ( + CONSTANT Delay : IN VitalDelayType + ) RETURN VitalDelayType01Z IS + BEGIN + RETURN (OTHERS => Delay); + END VitalExtendToFillDelay; + + FUNCTION VitalExtendToFillDelay ( + CONSTANT Delay : IN VitalDelayType01 + ) RETURN VitalDelayType01Z IS + VARIABLE Delay01Z : VitalDelayType01Z; + BEGIN + Delay01Z(tr01) := Delay(tr01); + Delay01Z(tr0z) := Delay(tr01); + Delay01Z(trz1) := Delay(tr01); + Delay01Z(tr10) := Delay(tr10); + Delay01Z(tr1z) := Delay(tr10); + Delay01Z(trz0) := Delay(tr10); + RETURN (Delay01Z); + END VitalExtendToFillDelay; + + FUNCTION VitalExtendToFillDelay ( + CONSTANT Delay : IN VitalDelayType01Z + ) RETURN VitalDelayType01Z IS + BEGIN + RETURN Delay; + END VitalExtendToFillDelay; + + --------------------------------------------------------------------------- + FUNCTION VitalCalcDelay ( + CONSTANT NewVal : IN std_ulogic := 'X'; + CONSTANT OldVal : IN std_ulogic := 'X'; + CONSTANT Delay : IN VitalDelayType + ) RETURN TIME IS + BEGIN + RETURN delay; + END VitalCalcDelay; + + FUNCTION VitalCalcDelay ( + CONSTANT NewVal : IN std_ulogic := 'X'; + CONSTANT OldVal : IN std_ulogic := 'X'; + CONSTANT Delay : IN VitalDelayType01 + ) RETURN TIME IS + VARIABLE Result : TIME; + BEGIN + CASE Newval IS + WHEN '0' | 'L' => Result := Delay(tr10); + WHEN '1' | 'H' => Result := Delay(tr01); + WHEN 'Z' => + CASE Oldval IS + WHEN '0' | 'L' => Result := Delay(tr01); + WHEN '1' | 'H' => Result := Delay(tr10); + WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01)); + END CASE; + WHEN OTHERS => + CASE Oldval IS + WHEN '0' | 'L' => Result := Delay(tr01); + WHEN '1' | 'H' => Result := Delay(tr10); + WHEN 'Z' => Result := MINIMUM(Delay(tr10), Delay(tr01)); + WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01)); + END CASE; + END CASE; + RETURN Result; + END VitalCalcDelay; + + FUNCTION VitalCalcDelay ( + CONSTANT NewVal : IN std_ulogic := 'X'; + CONSTANT OldVal : IN std_ulogic := 'X'; + CONSTANT Delay : IN VitalDelayType01Z + ) RETURN TIME IS + VARIABLE Result : TIME; + BEGIN + CASE Oldval IS + WHEN '0' | 'L' => + CASE Newval IS + WHEN '0' | 'L' => Result := Delay(tr10); + WHEN '1' | 'H' => Result := Delay(tr01); + WHEN 'Z' => Result := Delay(tr0z); + WHEN OTHERS => Result := MINIMUM(Delay(tr01), Delay(tr0z)); + END CASE; + WHEN '1' | 'H' => + CASE Newval IS + WHEN '0' | 'L' => Result := Delay(tr10); + WHEN '1' | 'H' => Result := Delay(tr01); + WHEN 'Z' => Result := Delay(tr1z); + WHEN OTHERS => Result := MINIMUM(Delay(tr10), Delay(tr1z)); + END CASE; + WHEN 'Z' => + CASE Newval IS + WHEN '0' | 'L' => Result := Delay(trz0); + WHEN '1' | 'H' => Result := Delay(trz1); + WHEN 'Z' => Result := MAXIMUM (Delay(tr0z), Delay(tr1z)); + WHEN OTHERS => Result := MINIMUM (Delay(trz1), Delay(trz0)); + END CASE; + WHEN 'U' | 'X' | 'W' | '-' => + CASE Newval IS + WHEN '0' | 'L' => Result := MAXIMUM(Delay(tr10), Delay(trz0)); + WHEN '1' | 'H' => Result := MAXIMUM(Delay(tr01), Delay(trz1)); + WHEN 'Z' => Result := MAXIMUM(Delay(tr1z), Delay(tr0z)); + WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01)); + END CASE; + END CASE; + RETURN Result; + END VitalCalcDelay; + + --------------------------------------------------------------------------- + -- + -- VitalSelectPathDelay returns the path delay selected by the Paths array. + -- If no paths are selected, it returns either the appropriate default + -- delay or TIME'HIGH, depending upon the value of IgnoreDefaultDelay. + -- + + FUNCTION VitalSelectPathDelay ( + CONSTANT NewValue : IN std_logic; + CONSTANT OldValue : IN std_logic; + CONSTANT OutSignalName : IN string; + CONSTANT Paths : IN VitalPathArrayType; + CONSTANT DefaultDelay : IN VitalDelayType; + CONSTANT IgnoreDefaultDelay : IN BOOLEAN + ) RETURN TIME IS + + VARIABLE TmpDelay : TIME; + VARIABLE InputAge : TIME := TIME'HIGH; + VARIABLE PropDelay : TIME := TIME'HIGH; + BEGIN + -- for each delay path + FOR i IN Paths'RANGE LOOP + -- ignore the delay path if it is not enabled + NEXT WHEN NOT Paths(i).PathCondition; + -- ignore the delay path if a more recent input event has been seen + NEXT WHEN Paths(i).InputChangeTime > InputAge; + + -- This is the most recent input change (so far) + -- Get the transition dependent delay + TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay); + + -- If other inputs changed at the same time, + -- then use the minimum of their propagation delays, + -- else use the propagation delay from this input. + IF Paths(i).InputChangeTime < InputAge THEN + PropDelay := TmpDelay; + ELSE -- Simultaneous inputs change + IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF; + end if; + + InputAge := Paths(i).InputChangeTime; + END LOOP; + + -- If there were no paths (with an enabled condition), + -- use the default delay, if so indicated, otherwise return TIME'HIGH + IF (PropDelay = TIME'HIGH) THEN + IF (IgnoreDefaultDelay) THEN + PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); + END IF; + + -- If the time since the most recent selected input event is + -- greater than the propagation delay from that input, + -- then use the default delay (won't happen if no paths are selected) + ELSIF (InputAge > PropDelay) THEN + PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); + + -- Adjust the propagation delay by the time since the + -- the input event occurred (Usually 0 ns). + ELSE + PropDelay := PropDelay - InputAge; + END IF; + + RETURN PropDelay; + END; + + FUNCTION VitalSelectPathDelay ( + CONSTANT NewValue : IN std_logic; + CONSTANT OldValue : IN std_logic; + CONSTANT OutSignalName : IN string; + CONSTANT Paths : IN VitalPathArray01Type; + CONSTANT DefaultDelay : IN VitalDelayType01; + CONSTANT IgnoreDefaultDelay : IN BOOLEAN + ) RETURN TIME IS + + VARIABLE TmpDelay : TIME; + VARIABLE InputAge : TIME := TIME'HIGH; + VARIABLE PropDelay : TIME := TIME'HIGH; + BEGIN + -- for each delay path + FOR i IN Paths'RANGE LOOP + -- ignore the delay path if it is not enabled + NEXT WHEN NOT Paths(i).PathCondition; + -- ignore the delay path if a more recent input event has been seen + NEXT WHEN Paths(i).InputChangeTime > InputAge; + + -- This is the most recent input change (so far) + -- Get the transition dependent delay + TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay); + + -- If other inputs changed at the same time, + -- then use the minimum of their propagation delays, + -- else use the propagation delay from this input. + IF Paths(i).InputChangeTime < InputAge THEN + PropDelay := TmpDelay; + ELSE -- Simultaneous inputs change + IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF; + end if; + + InputAge := Paths(i).InputChangeTime; + END LOOP; + + -- If there were no paths (with an enabled condition), + -- use the default delay, if so indicated, otherwise return TIME'HIGH + IF (PropDelay = TIME'HIGH) THEN + IF (IgnoreDefaultDelay) THEN + PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); + END IF; + + -- If the time since the most recent selected input event is + -- greater than the propagation delay from that input, + -- then use the default delay (won't happen if no paths are selected) + ELSIF (InputAge > PropDelay) THEN + PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); + + -- Adjust the propagation delay by the time since the + -- the input event occurred (Usually 0 ns). + ELSE + PropDelay := PropDelay - InputAge; + END IF; + + RETURN PropDelay; + END; + + FUNCTION VitalSelectPathDelay ( + CONSTANT NewValue : IN std_logic; + CONSTANT OldValue : IN std_logic; + CONSTANT OutSignalName : IN string; + CONSTANT Paths : IN VitalPathArray01ZType; + CONSTANT DefaultDelay : IN VitalDelayType01Z; + CONSTANT IgnoreDefaultDelay : IN BOOLEAN + ) RETURN TIME IS + + VARIABLE TmpDelay : TIME; + VARIABLE InputAge : TIME := TIME'HIGH; + VARIABLE PropDelay : TIME := TIME'HIGH; + BEGIN + -- for each delay path + FOR i IN Paths'RANGE LOOP + -- ignore the delay path if it is not enabled + NEXT WHEN NOT Paths(i).PathCondition; + -- ignore the delay path if a more recent input event has been seen + NEXT WHEN Paths(i).InputChangeTime > InputAge; + + -- This is the most recent input change (so far) + -- Get the transition dependent delay + TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay); + + -- If other inputs changed at the same time, + -- then use the minimum of their propagation delays, + -- else use the propagation delay from this input. + IF Paths(i).InputChangeTime < InputAge THEN + PropDelay := TmpDelay; + ELSE -- Simultaneous inputs change + IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF; + end if; + + InputAge := Paths(i).InputChangeTime; + END LOOP; + + -- If there were no paths (with an enabled condition), + -- use the default delay, if so indicated, otherwise return TIME'HIGH + IF (PropDelay = TIME'HIGH) THEN + IF (IgnoreDefaultDelay) THEN + PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); + END IF; + + -- If the time since the most recent selected input event is + -- greater than the propagation delay from that input, + -- then use the default delay (won't happen if no paths are selected) + ELSIF (InputAge > PropDelay) THEN + PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); + + -- Adjust the propagation delay by the time since the + -- the input event occurred (Usually 0 ns). + ELSE + PropDelay := PropDelay - InputAge; + END IF; + + RETURN PropDelay; + END; + + + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + -- Glitch Handlers + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + PROCEDURE ReportGlitch ( + CONSTANT GlitchRoutine : IN STRING; + CONSTANT OutSignalName : IN STRING; + CONSTANT PreemptedTime : IN TIME; + CONSTANT PreemptedValue : IN std_ulogic; + CONSTANT NewTime : IN TIME; + CONSTANT NewValue : IN std_ulogic; + CONSTANT Index : IN INTEGER := 0; + CONSTANT IsArraySignal : IN BOOLEAN := FALSE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ) IS + + VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE; + BEGIN + + Write (StrPtr1, PreemptedTime ); + Write (StrPtr2, NewTime); + Write (StrPtr3, LogicCvtTable(PreemptedValue)); + Write (StrPtr4, LogicCvtTable(NewValue)); + IF IsArraySignal THEN + Write (StrPtr5, STRING'( "(" ) ); + Write (StrPtr5, Index); + Write (StrPtr5, STRING'( ")" ) ); + ELSE + Write (StrPtr5, STRING'( " " ) ); + END IF; + + -- Issue Report only if Preempted value has not been + -- removed from event queue + ASSERT PreemptedTime > NewTime + REPORT GlitchRoutine & ": GLITCH Detected on port " & + OutSignalName & StrPtr5.ALL & + "; Preempted Future Value := " & StrPtr3.ALL & + " @ " & StrPtr1.ALL & + "; Newly Scheduled Value := " & StrPtr4.ALL & + " @ " & StrPtr2.ALL & + ";" + SEVERITY MsgSeverity; + + + ASSERT PreemptedTime <= NewTime + REPORT GlitchRoutine & ": GLITCH Detected on port " & + OutSignalName & StrPtr5.ALL & + "; Negative Preempted Value := " & StrPtr3.ALL & + " @ " & StrPtr1.ALL & + "; Newly Scheduled Value := " & StrPtr4.ALL & + " @ " & StrPtr2.ALL & + ";" + SEVERITY MsgSeverity; + + + DEALLOCATE(StrPtr1); + DEALLOCATE(StrPtr2); + DEALLOCATE(StrPtr3); + DEALLOCATE(StrPtr4); + DEALLOCATE(StrPtr5); + RETURN; + END ReportGlitch; + + --------------------------------------------------------------------------- + PROCEDURE VitalGlitch ( + SIGNAL OutSignal : OUT std_logic; + VARIABLE GlitchData : INOUT VitalGlitchDataType; + CONSTANT OutSignalName : IN string; + CONSTANT NewValue : IN std_logic; + CONSTANT NewDelay : IN TIME := 0 ns; + CONSTANT Mode : IN VitalGlitchKindType := OnEvent; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 + CONSTANT MsgOn : IN BOOLEAN := FALSE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ) IS + --------------------------------------------------------------------------- + VARIABLE NewGlitch : BOOLEAN := TRUE; + VARIABLE dly : TIME := NewDelay; + VARIABLE NOW_TIME : TIME := NOW; + VARIABLE NegPreemptGlitch : BOOLEAN := FALSE; + + BEGIN + NegPreemptGlitch:=FALSE;--reset Preempt-Glitch + + -- If nothing to schedule, just return + IF NewDelay < 0 ns THEN + IF (NewValue /= GlitchData.SchedValue) THEN + VitalError ( "VitalGlitch", ErrNegDel, OutSignalName ); + END IF; + RETURN; + END IF; + + -- If simple signal assignment + -- perform the signal assignment + IF ( Mode = VitalInertial) THEN + OutSignal <= NewValue AFTER dly; + ELSIF ( Mode = VitalTransport ) THEN + OutSignal <= TRANSPORT NewValue AFTER dly; + ELSE + -- Glitch Processing --- + -- If nothing currently scheduled + IF GlitchData.SchedTime <= NOW THEN -- NOW >= last event + -- Note: NewValue is always /= OldValue when called from VPPD + IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF; + NewGlitch := FALSE; + GlitchData.GlitchTime := NOW+dly; + + -- New value earlier than the earliest previous value scheduled + -- (negative preemptive) + ELSIF (NOW+dly <= GlitchData.GlitchTime) + AND (NOW+dly <= GlitchData.SchedTime) THEN + + -- Glitch is negative preemptive - check if same value and + -- NegPreempt is on IR225 + IF (GlitchData.SchedValue /= NewValue) AND (NegPreemptOn) AND + (NOW > 0 NS) THEN + NewGlitch := TRUE; + NegPreemptGlitch :=TRUE; -- Set preempt Glitch condition + ELSE + NewGlitch := FALSE; -- No new glitch, save time for + -- possible future glitch + END IF; + GlitchData.GlitchTime := NOW+dly; + + -- Transaction currently scheduled - if glitch already happened + ELSIF GlitchData.GlitchTime <= NOW THEN + IF (GlitchData.SchedValue = NewValue) THEN + dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); + END IF; + NewGlitch := FALSE; + + -- Transaction currently scheduled (no glitch if same value) + ELSIF (GlitchData.SchedValue = NewValue) + AND (GlitchData.SchedTime = GlitchData.GlitchTime) THEN + -- revise scheduled output time if new delay is sooner + dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); + -- No new glitch, save time for possable future glitch + NewGlitch := FALSE; + GlitchData.GlitchTime := NOW+dly; + + -- Transaction currently scheduled represents a glitch + ELSE + NewGlitch := TRUE; -- A new glitch has been detected + END IF; + + IF NewGlitch THEN + -- If messages requested, report the glitch + IF MsgOn THEN + IF NegPreemptGlitch THEN --IR225 + ReportGlitch ("VitalGlitch-Neg", OutSignalName, + GlitchData.GlitchTime, GlitchData.SchedValue, + (dly + NOW), NewValue, + MsgSeverity=>MsgSeverity ); + ELSE + ReportGlitch ("VitalGlitch", OutSignalName, + GlitchData.GlitchTime, GlitchData.SchedValue, + (dly + NOW), NewValue, + MsgSeverity=>MsgSeverity ); + END IF; + END IF; + + -- If 'X' generation is requested, schedule the new value + -- preceeded by a glitch pulse. + -- Otherwise just schedule the new value (inertial mode). + IF XOn THEN + IF (Mode = OnDetect) THEN + OutSignal <= 'X'; + ELSE + OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW; + END IF; + + IF NegPreemptGlitch THEN -- IR225 + OutSignal <= TRANSPORT NewValue AFTER GlitchData.SchedTime-NOW; + ELSE + OutSignal <= TRANSPORT NewValue AFTER dly; + END IF; + ELSE + OutSignal <= NewValue AFTER dly; -- no glitch regular prop delay + END IF; + + -- If there no new glitch was detected, just schedule the new value. + ELSE + OutSignal <= NewValue AFTER dly; + END IF; + END IF; + + -- Record the new value and time depending on glitch type just scheduled. + IF NOT NegPreemptGlitch THEN -- 5/2/96 for "x-pulse" IR225 + GlitchData.SchedValue := NewValue; + GlitchData.SchedTime := NOW+dly; -- pulse timing. + ELSE + GlitchData.SchedValue := 'X'; + -- leave GlitchData.SchedTime to old value since glitch is negative + END IF; + RETURN; + END; + + --------------------------------------------------------------------------- + PROCEDURE VitalPathDelay ( + SIGNAL OutSignal : OUT std_logic; + VARIABLE GlitchData : INOUT VitalGlitchDataType; + CONSTANT OutSignalName : IN string; + CONSTANT OutTemp : IN std_logic; + CONSTANT Paths : IN VitalPathArrayType; + CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay; + CONSTANT Mode : IN VitalGlitchKindType := OnEvent; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98 + CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE --IR248 3/14/98 + ) IS + + VARIABLE PropDelay : TIME; + + BEGIN + -- Check if the new value to be scheduled is different than the + -- previously scheduled value + IF (GlitchData.SchedTime <= NOW) AND + (GlitchData.SchedValue = OutTemp) + THEN RETURN; + END IF; + + -- Evaluate propagation delay paths + PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue, + OutSignalName, Paths, DefaultDelay, + IgnoreDefaultDelay); + + GlitchData.LastValue := OutTemp; + + -- Schedule the output transactions - including glitch handling + VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp, + PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity ); + + END VitalPathDelay; + + --------------------------------------------------------------------------- + + PROCEDURE VitalPathDelay01 ( + SIGNAL OutSignal : OUT std_logic; + VARIABLE GlitchData : INOUT VitalGlitchDataType; + CONSTANT OutSignalName : IN string; + CONSTANT OutTemp : IN std_logic; + CONSTANT Paths : IN VitalPathArray01Type; + CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01; + CONSTANT Mode : IN VitalGlitchKindType := OnEvent; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98 + CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98 + CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250 + + + ) IS + + VARIABLE PropDelay : TIME; + BEGIN + + -- Check if the new value to be scheduled is different than the + -- previously scheduled value + IF (GlitchData.SchedTime <= NOW) AND + (GlitchData.SchedValue = OutTemp) + THEN RETURN; + -- Check if the new value to be Scheduled is the same as the + -- previously scheduled output transactions. If this condition + -- exists and the new scheduled time is < the current GlitchData. + -- schedTime then a fast path condition exists (IR250). If the + -- modeler wants this condition rejected by setting the + -- RejectFastPath actual to true then exit out. + ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath) + THEN RETURN; + END IF; + + -- Evaluate propagation delay paths + PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue, + OutSignalName, Paths, DefaultDelay, + IgnoreDefaultDelay); + + GlitchData.LastValue := OutTemp; + + + VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp, + PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity ); + END VitalPathDelay01; + + --------------------------------------------------------------------------- + PROCEDURE VitalPathDelay01Z ( + SIGNAL OutSignal : OUT std_logic; + VARIABLE GlitchData : INOUT VitalGlitchDataType; + CONSTANT OutSignalName : IN string; + CONSTANT OutTemp : IN std_logic; + CONSTANT Paths : IN VitalPathArray01ZType; + CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z; + CONSTANT Mode : IN VitalGlitchKindType := OnEvent; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap; + CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98 + CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98 + CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250 + ) IS + + VARIABLE PropDelay : TIME; + + BEGIN + -- Check if the new value to be scheduled is different than the + -- previously scheduled value + IF (GlitchData.SchedTime <= NOW) AND + (GlitchData.SchedValue = OutTemp) + THEN RETURN; + -- Check if the new value to be Scheduled is the same as the + -- previously scheduled output transactions. If this condition + -- exists and the new scheduled time is < the current GlitchData. + -- schedTime then a fast path condition exists (IR250). If the + -- modeler wants this condition rejected by setting the + -- RejectFastPath actual to true then exit out. + ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath) + THEN RETURN; + END IF; + + -- Evaluate propagation delay paths + PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue, + OutSignalName, Paths, DefaultDelay, + IgnoreDefaultDelay); + + GlitchData.LastValue := OutTemp; + + + -- Schedule the output transactions - including glitch handling + VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp, + PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity ); + END VitalPathDelay01Z; + + + ---------------------------------------------------------------------------- + PROCEDURE VitalWireDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT twire : IN VitalDelayType + ) IS + BEGIN + OutSig <= TRANSPORT InSig AFTER twire; + END VitalWireDelay; + + PROCEDURE VitalWireDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT twire : IN VitalDelayType01 + ) IS + VARIABLE Delay : TIME; + BEGIN + Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire ); + OutSig <= TRANSPORT InSig AFTER Delay; + END VitalWireDelay; + + PROCEDURE VitalWireDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT twire : IN VitalDelayType01Z + ) IS + VARIABLE Delay : TIME; + BEGIN + Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire ); + OutSig <= TRANSPORT InSig AFTER Delay; + END VitalWireDelay; + + ---------------------------------------------------------------------------- + PROCEDURE VitalSignalDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT dly : IN TIME + ) IS + BEGIN + OutSig <= TRANSPORT InSig AFTER dly; + END; + + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + -- Setup and Hold Time Check Routine + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + PROCEDURE ReportViolation ( + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT CheckInfo : IN CheckInfoType; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ) IS + VARIABLE Message : LINE; + BEGIN + IF NOT CheckInfo.Violation THEN RETURN; END IF; + + Write ( Message, HeaderMsg ); + Case CheckInfo.CheckKind IS + WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") ); + WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") ); + WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") ); + WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") ); + WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH ")); + WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") ); + END CASE; + Write ( Message, HiLoStr(CheckInfo.State) ); + Write ( Message, STRING'(" VIOLATION ON ") ); + Write ( Message, TestSignalName ); + IF (RefSignalName'LENGTH > 0) THEN + Write ( Message, STRING'(" WITH RESPECT TO ") ); + Write ( Message, RefSignalName ); + END IF; + Write ( Message, ';' & LF ); + Write ( Message, STRING'(" Expected := ") ); + Write ( Message, CheckInfo.ExpTime); + Write ( Message, STRING'("; Observed := ") ); + Write ( Message, CheckInfo.ObsTime); + Write ( Message, STRING'("; At : ") ); + Write ( Message, CheckInfo.DetTime); + + ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity; + + DEALLOCATE (Message); + END ReportViolation; + + + --------------------------------------------------------------------------- + -- Procedure : InternalTimingCheck + --------------------------------------------------------------------------- + PROCEDURE InternalTimingCheck ( + CONSTANT TestSignal : IN std_ulogic; + CONSTANT RefSignal : IN std_ulogic; + CONSTANT TestDelay : IN TIME := 0 ns; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN TIME := 0 ns; + CONSTANT SetupLow : IN TIME := 0 ns; + CONSTANT HoldHigh : IN TIME := 0 ns; + CONSTANT HoldLow : IN TIME := 0 ns; + VARIABLE RefTime : IN TIME; + VARIABLE RefEdge : IN BOOLEAN; + VARIABLE TestTime : IN TIME; + VARIABLE TestEvent : IN BOOLEAN; + VARIABLE SetupEn : INOUT BOOLEAN; + VARIABLE HoldEn : INOUT BOOLEAN; + VARIABLE CheckInfo : INOUT CheckInfoType; + CONSTANT MsgOn : IN BOOLEAN + ) IS + VARIABLE bias : TIME; + VARIABLE actualObsTime : TIME; + VARIABLE BC : TIME; + VARIABLE Message:LINE; + BEGIN + -- Check SETUP constraint + IF RefEdge THEN + IF SetupEn THEN + CheckInfo.ObsTime := RefTime - TestTime; + CheckInfo.State := To_X01(TestSignal); + CASE CheckInfo.State IS + WHEN '0' => CheckInfo.ExpTime := SetupLow; + -- start of new code IR245-246 + BC := HoldHigh; + -- end of new code IR245-246 + WHEN '1' => CheckInfo.ExpTime := SetupHigh; + -- start of new code IR245-246 + BC := HoldLow; + -- end of new code IR245-246 + WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow); + -- start of new code IR245-246 + BC := Maximum(HoldHigh,HoldLow); + -- end of new code IR245-246 + END CASE; + -- added the second condition for IR 245-246 + CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime) + AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) ); + -- start of new code IR245-246 + IF(CheckInfo.ExpTime = 0 ns) THEN + CheckInfo.CheckKind := HoldCheck; + ELSE + CheckInfo.CheckKind := SetupCheck; + END IF; + -- end of new code IR245-246 + SetupEn := FALSE; + ELSE + CheckInfo.Violation := FALSE; + END IF; + + -- Check HOLD constraint + ELSIF TestEvent THEN + IF HoldEn THEN + CheckInfo.ObsTime := TestTime - RefTime; + CheckInfo.State := To_X01(TestSignal); + CASE CheckInfo.State IS + WHEN '0' => CheckInfo.ExpTime := HoldHigh; + + -- new code for unnamed IR + CheckInfo.State := '1'; + + -- start of new code IR245-246 + BC := SetupLow; + -- end of new code IR245-246 + WHEN '1' => CheckInfo.ExpTime := HoldLow; + + -- new code for unnamed IR + CheckInfo.State := '0'; + + -- start of new code IR245-246 + BC := SetupHigh; + -- end of new code IR245-246 + WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow); + -- start of new code IR245-246 + BC := Maximum(SetupHigh,SetupLow); + -- end of new code IR245-246 + END CASE; + -- added the second condition for IR 245-246 + CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime) + AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) ); + + -- start of new code IR245-246 + IF(CheckInfo.ExpTime = 0 ns) THEN + CheckInfo.CheckKind := SetupCheck; + ELSE + CheckInfo.CheckKind := HoldCheck; + END IF; + -- end of new code IR245-246 + HoldEn := NOT CheckInfo.Violation; + ELSE + CheckInfo.Violation := FALSE; + END IF; + ELSE + CheckInfo.Violation := FALSE; + END IF; + + -- Adjust report values to account for internal model delays + -- Note: TestDelay, RefDelay, TestTime, RefTime are non-negative + -- Note: bias may be negative or positive + IF MsgOn AND CheckInfo.Violation THEN + -- modified the code for correct reporting of violation in case of + -- order of signals being reversed because of internal delays + -- new variable + actualObsTime := (TestTime-TestDelay)-(RefTime-RefDelay); + bias := TestDelay - RefDelay; + IF (actualObsTime < 0 ns) THEN -- It should be a setup check + IF ( CheckInfo.CheckKind = HoldCheck) then + CheckInfo.CheckKind := SetupCheck; + CASE CheckInfo.State IS + WHEN '0' => CheckInfo.ExpTime := SetupLow; + WHEN '1' => CheckInfo.ExpTime := SetupHigh; + WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow); + END CASE; + END IF; + + CheckInfo.ObsTime := -actualObsTime; + CheckInfo.ExpTime := CheckInfo.ExpTime + bias; + CheckInfo.DetTime := RefTime - RefDelay; + ELSE -- It should be a hold check + IF ( CheckInfo.CheckKind = SetupCheck) then + CheckInfo.CheckKind := HoldCheck; + CASE CheckInfo.State IS + WHEN '0' => CheckInfo.ExpTime := HoldHigh; + CheckInfo.State := '1'; + WHEN '1' => CheckInfo.ExpTime := HoldLow; + CheckInfo.State := '0'; + WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow); + END CASE; + END IF; + + CheckInfo.ObsTime := actualObsTime; + CheckInfo.ExpTime := CheckInfo.ExpTime - bias; + CheckInfo.DetTime := TestTime - TestDelay; + END IF; + + END IF; + END InternalTimingCheck; + + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + FUNCTION VitalTimingDataInit + RETURN VitalTimingDataType IS + BEGIN + RETURN (FALSE,'X', 0 ns, FALSE, 'X', 0 ns, FALSE, NULL, NULL, NULL, NULL); + END; + + --------------------------------------------------------------------------- + -- Procedure : VitalSetupHoldCheck + --------------------------------------------------------------------------- + PROCEDURE VitalSetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalTimingDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN TIME := 0 ns; + CONSTANT SetupLow : IN TIME := 0 ns; + CONSTANT HoldHigh : IN TIME := 0 ns; + CONSTANT HoldLow : IN TIME := 0 ns; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98 + ) IS + + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge, TestEvent : BOOLEAN; + VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay); + VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); + VARIABLE bias : TIME; + BEGIN + + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLast := To_X01(TestSignal); + TimingData.RefLast := To_X01(RefSignal); + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), + RefTransition); + TimingData.RefLast := To_X01(RefSignal); + IF RefEdge THEN + TimingData.RefTime := NOW; + TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98 + TimingData.HoldEn := EnableHoldOnRef; --IR252 3/23/98 + END IF; + + -- Detect test (data) changes and record the time of the last change + TestEvent := TimingData.TestLast /= To_X01Z(TestSignal); + TimingData.TestLast := To_X01Z(TestSignal); + IF TestEvent THEN + TimingData.TestTime := NOW; + TimingData.SetupEn := EnableSetupOnTest; --IR252 3/23/98 + TimingData.HoldEn := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98 + END IF; + + -- Perform timing checks (if enabled) + Violation := '0'; + IF (CheckEnabled) THEN + InternalTimingCheck ( + TestSignal => TestSignal, + RefSignal => RefSignal, + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHigh, + SetupLow => SetupLow, + HoldHigh => HoldHigh, + HoldLow => HoldLow, + RefTime => TimingData.RefTime, + RefEdge => RefEdge, + TestTime => TimingData.TestTime, + TestEvent => TestEvent, + SetupEn => TimingData.SetupEn, + HoldEn => TimingData.HoldEn, + CheckInfo => CheckInfo, + MsgOn => MsgOn ); + + -- Report any detected violations and set return violation flag + IF CheckInfo.Violation THEN + IF (MsgOn) THEN + ReportViolation (TestSignalName, RefSignalName, + HeaderMsg, CheckInfo, MsgSeverity ); + END IF; + IF (XOn) THEN Violation := 'X'; END IF; + END IF; + END IF; + + END VitalSetupHoldCheck; + + --------------------------------------------------------------------------- + PROCEDURE VitalSetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN TIME := 0 ns; + CONSTANT SetupLow : IN TIME := 0 ns; + CONSTANT HoldHigh : IN TIME := 0 ns; + CONSTANT HoldLow : IN TIME := 0 ns; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98 + + ) IS + + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge : BOOLEAN; + VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE); + VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay); + VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); + VARIABLE bias : TIME; + VARIABLE ChangedAllAtOnce : BOOLEAN := TRUE; + VARIABLE StrPtr1 : LINE; + + BEGIN + -- Initialization of working area. + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE); + TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE); + TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE); + FOR i IN TestSignal'RANGE LOOP + TimingData.TestLastA(i) := To_X01(TestSignal(i)); + END LOOP; + TimingData.RefLast := To_X01(RefSignal); + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), + RefTransition); + TimingData.RefLast := To_X01(RefSignal); + IF RefEdge THEN + TimingData.RefTime := NOW; + TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98 + TimingData.HoldEnA.all := (TestSignal'RANGE => EnableHoldOnRef); --IR252 3/23/98 + END IF; + + -- Detect test (data) changes and record the time of the last change + FOR i IN TestSignal'RANGE LOOP + TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i)); + TimingData.TestLastA(i) := To_X01Z(TestSignal(i)); + IF TestEvent(i) THEN + TimingData.TestTimeA(i) := NOW; + TimingData.SetupEnA(i) := EnableSetupOnTest; --IR252 3/23/98 + TimingData.HoldEnA(i) := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98 + TimingData.TestTime := NOW; --IR252 3/23/98 + END IF; + END LOOP; + + -- Check to see if the Bus subelements changed all at the same time. + -- If so, then we can reduce the volume of error messages since we no + -- longer have to report every subelement individually + FOR i IN TestSignal'RANGE LOOP + IF TimingData.TestTimeA(i) /= TimingData.TestTime THEN + ChangedAllAtOnce := FALSE; + EXIT; + END IF; + END LOOP; + + -- Perform timing checks (if enabled) + Violation := '0'; + IF (CheckEnabled) THEN + FOR i IN TestSignal'RANGE LOOP + InternalTimingCheck ( + TestSignal => TestSignal(i), + RefSignal => RefSignal, + TestDelay => TestDly, + RefDelay => RefDly, + SetupHigh => SetupHigh, + SetupLow => SetupLow, + HoldHigh => HoldHigh, + HoldLow => HoldLow, + RefTime => TimingData.RefTime, + RefEdge => RefEdge, + TestTime => TimingData.TestTimeA(i), + TestEvent => TestEvent(i), + SetupEn => TimingData.SetupEnA(i), + HoldEn => TimingData.HoldEnA(i), + CheckInfo => CheckInfo, + MsgOn => MsgOn ); + + -- Report any detected violations and set return violation flag + IF CheckInfo.Violation THEN + IF (MsgOn) THEN + IF ( ChangedAllAtOnce AND (i = TestSignal'LEFT) ) THEN + ReportViolation (TestSignalName&"(...)", RefSignalName, + HeaderMsg, CheckInfo, MsgSeverity ); + ELSIF (NOT ChangedAllAtOnce) THEN + Write (StrPtr1, i); + ReportViolation (TestSignalName & "(" & StrPtr1.ALL & ")", + RefSignalName, + HeaderMsg, CheckInfo, MsgSeverity ); + DEALLOCATE (StrPtr1); + END IF; + END IF; + IF (XOn) THEN + Violation := 'X'; + END IF; + END IF; + END LOOP; + END IF; + + DEALLOCATE (StrPtr1); + + END VitalSetupHoldCheck; + + --------------------------------------------------------------------------- + -- Function : VitalRecoveryRemovalCheck + --------------------------------------------------------------------------- + PROCEDURE VitalRecoveryRemovalCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalTimingDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT Recovery : IN TIME := 0 ns; + CONSTANT Removal : IN TIME := 0 ns; + CONSTANT ActiveLow : IN BOOLEAN := TRUE; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98 + ) IS + VARIABLE CheckInfo : CheckInfoType; + VARIABLE RefEdge, TestEvent : BOOLEAN; + VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay); + VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); + VARIABLE bias : TIME; + BEGIN + + IF (TimingData.NotFirstFlag = FALSE) THEN + TimingData.TestLast := To_X01(TestSignal); + TimingData.RefLast := To_X01(RefSignal); + TimingData.NotFirstFlag := TRUE; + END IF; + + -- Detect reference edges and record the time of the last edge + RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), + RefTransition); + TimingData.RefLast := To_X01(RefSignal); + IF RefEdge THEN + TimingData.RefTime := NOW; + TimingData.SetupEn := TimingData.SetupEn AND EnableRecOnRef; --IR252 3/23/98 + TimingData.HoldEn := EnableRemOnRef; --IR252 3/23/98 + END IF; + + -- Detect test (data) changes and record the time of the last change + TestEvent := TimingData.TestLast /= To_X01Z(TestSignal); + TimingData.TestLast := To_X01Z(TestSignal); + IF TestEvent THEN + TimingData.TestTime := NOW; + TimingData.SetupEn := EnableRecOnTest; --IR252 3/23/98 + TimingData.HoldEn := TimingData.HoldEn AND EnableRemOnTest; --IR252 3/23/98 + END IF; + + -- Perform timing checks (if enabled) + Violation := '0'; + IF (CheckEnabled) THEN + + IF ActiveLow THEN + InternalTimingCheck ( + TestSignal, RefSignal, TestDly, RefDly, + Recovery, 0 ns, 0 ns, Removal, + TimingData.RefTime, RefEdge, + TimingData.TestTime, TestEvent, + TimingData.SetupEn, TimingData.HoldEn, + CheckInfo, MsgOn ); + ELSE + InternalTimingCheck ( + TestSignal, RefSignal, TestDly, RefDly, + 0 ns, Recovery, Removal, 0 ns, + TimingData.RefTime, RefEdge, + TimingData.TestTime, TestEvent, + TimingData.SetupEn, TimingData.HoldEn, + CheckInfo, MsgOn ); + END IF; + + + -- Report any detected violations and set return violation flag + IF CheckInfo.Violation THEN + IF CheckInfo.CheckKind = SetupCheck THEN + CheckInfo.CheckKind := RecoveryCheck; + ELSE + CheckInfo.CheckKind := RemovalCheck; + END IF; + IF (MsgOn) THEN + ReportViolation (TestSignalName, RefSignalName, + HeaderMsg, CheckInfo, MsgSeverity ); + END IF; + IF (XOn) THEN Violation := 'X'; END IF; + END IF; + END IF; + + END VitalRecoveryRemovalCheck; + + --------------------------------------------------------------------------- + PROCEDURE VitalPeriodPulseCheck ( + VARIABLE Violation : OUT X01; + VARIABLE PeriodData : INOUT VitalPeriodDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + CONSTANT Period : IN TIME := 0 ns; + CONSTANT PulseWidthHigh : IN TIME := 0 ns; + CONSTANT PulseWidthLow : IN TIME := 0 ns; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ) IS + + VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay); + VARIABLE CheckInfo : CheckInfoType; + VARIABLE PeriodObs : TIME; + VARIABLE PulseTest, PeriodTest : BOOLEAN; + VARIABLE TestValue : X01 := To_X01(TestSignal); + BEGIN + + IF (PeriodData.NotFirstFlag = FALSE) THEN + PeriodData.Rise := + -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow)); + PeriodData.Fall := + -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow)); + PeriodData.Last := To_X01(TestSignal); + PeriodData.NotFirstFlag := TRUE; + END IF; + + -- Initialize for no violation + -- No violation possible if no test signal change + Violation := '0'; + IF (PeriodData.Last = TestValue) THEN + RETURN; + END IF; + + -- record starting pulse times + IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'P') THEN + -- Compute period times, then record the High Rise Time + PeriodObs := NOW - PeriodData.Rise; + PeriodData.Rise := NOW; + PeriodTest := TRUE; + ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'N') THEN + -- Compute period times, then record the Low Fall Time + PeriodObs := NOW - PeriodData.Fall; + PeriodData.Fall := NOW; + PeriodTest := TRUE; + ELSE + PeriodTest := FALSE; + END IF; + + -- do checks on pulse ends + IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'p') THEN + -- Compute pulse times + CheckInfo.ObsTime := NOW - PeriodData.Fall; + CheckInfo.ExpTime := PulseWidthLow; + PulseTest := TRUE; + ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'n') THEN + -- Compute pulse times + CheckInfo.ObsTime := NOW - PeriodData.Rise; + CheckInfo.ExpTime := PulseWidthHigh; + PulseTest := TRUE; + ELSE + PulseTest := FALSE; + END IF; + + IF PulseTest AND CheckEnabled THEN + -- Verify Pulse Width [ignore 1st edge] + IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN + IF (XOn) THEN Violation := 'X'; END IF; + IF (MsgOn) THEN + CheckInfo.Violation := TRUE; + CheckInfo.CheckKind := PulseWidCheck; + CheckInfo.DetTime := NOW - TestDly; + CheckInfo.State := PeriodData.Last; + ReportViolation (TestSignalName, "", + HeaderMsg, CheckInfo, MsgSeverity ); + END IF; -- MsgOn + END IF; + END IF; + + IF PeriodTest AND CheckEnabled THEN + -- Verify the Period [ignore 1st edge] + CheckInfo.ObsTime := PeriodObs; + CheckInfo.ExpTime := Period; + IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN + IF (XOn) THEN Violation := 'X'; END IF; + IF (MsgOn) THEN + CheckInfo.Violation := TRUE; + CheckInfo.CheckKind := PeriodCheck; + CheckInfo.DetTime := NOW - TestDly; + CheckInfo.State := TestValue; + ReportViolation (TestSignalName, "", + HeaderMsg, CheckInfo, MsgSeverity ); + END IF; -- MsgOn + END IF; + END IF; + + PeriodData.Last := TestValue; + + END VitalPeriodPulseCheck; + + + + PROCEDURE ReportSkewViolation ( + CONSTANT Signal1Name : IN STRING := ""; + CONSTANT Signal2Name : IN STRING := ""; + CONSTANT ExpectedTime : IN TIME; + CONSTANT OccuranceTime : IN TIME; + CONSTANT HeaderMsg : IN STRING; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT SkewPhase : IN SkewType; + CONSTANT ViolationFlag : IN BOOLEAN := TRUE + ) IS + VARIABLE Message : LINE; + BEGIN + Write ( Message, HeaderMsg ); + IF (ViolationFlag /= TRUE) THEN + Write ( Message, STRING'(" POSSIBLE") ); + END IF; + IF (SkewPhase = Inphase) THEN + Write ( Message, STRING'(" IN PHASE ") ); + ELSE + Write ( Message, STRING'(" OUT OF PHASE ") ); + END IF; + Write ( Message, STRING'("SKEW VIOLATION ON ") ); + Write ( Message, Signal2Name ); + IF (Signal1Name'LENGTH > 0) THEN + Write ( Message, STRING'(" WITH RESPECT TO ") ); + Write ( Message, Signal1Name ); + END IF; + Write ( Message, ';' & LF ); + Write ( Message, STRING'(" At : ") ); + Write ( Message, OccuranceTime); + Write ( Message, STRING'("; Skew Limit : ") ); + Write ( Message, ExpectedTime); + + ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity; + + DEALLOCATE (Message); + END ReportSkewViolation; + + + PROCEDURE VitalInPhaseSkewCheck ( + VARIABLE Violation : OUT X01; + VARIABLE SkewData : INOUT VitalSkewDataType; + SIGNAL Signal1 : IN std_ulogic; + CONSTANT Signal1Name : IN STRING := ""; + CONSTANT Signal1Delay : IN TIME := 0 ns; + SIGNAL Signal2 : IN std_ulogic; + CONSTANT Signal2Name : IN STRING := ""; + CONSTANT Signal2Delay : IN TIME := 0 ns; + CONSTANT SkewS1S2RiseRise : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1RiseRise : IN TIME := TIME'HIGH; + CONSTANT SkewS1S2FallFall : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1FallFall : IN TIME := TIME'HIGH; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT HeaderMsg : IN STRING := ""; + SIGNAL Trigger : INOUT std_ulogic + ) IS + VARIABLE ReportType : VitalSkewExpectedType := none; + VARIABLE ExpectedType : VitalSkewExpectedType := none; + VARIABLE ReportTime : TIME; + VARIABLE TriggerDelay : TIME; + VARIABLE ViolationCertain : Boolean := TRUE; + BEGIN + Violation := '0'; + ReportType := none; + TriggerDelay := noTrigger; + + IF (CheckEnabled) THEN + IF (SkewData.ExpectedType /= none) THEN + IF (trigger'Event) THEN + CASE SkewData.ExpectedType IS + WHEN s1r => ReportType := s1r; + ReportTime := NOW - Signal1Delay; + WHEN s1f => ReportType := s1f; + ReportTime := NOW - Signal1Delay; + WHEN s2r => ReportType := s2r; + ReportTime := NOW - Signal2Delay; + WHEN s2f => ReportType := s2f; + ReportTime := NOW - Signal2Delay; + WHEN OTHERS => + END CASE; + SkewData.ExpectedType := none; + ELSIF ( Signal1'Event OR Signal2'Event ) THEN + IF ( Signal1 /= 'X' AND Signal2 /= 'X' ) THEN + TriggerDelay := 0 ns; + ExpectedType := none; + END IF; + END IF; + END IF; + + IF (Signal1'EVENT and Signal2'EVENT) THEN + IF (Signal1 = Signal2) THEN + IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay - Signal2Delay) >= + SkewS1S2RiseRise) THEN + ReportType := s2r; + ReportTime := NOW - Signal1Delay + + SkewS1S2RiseRise; + ELSIF ((Signal2Delay -Signal1Delay) >= + SkewS2S1RiseRise) THEN + ReportType := s1r; + ReportTime := NOW - Signal2Delay + + SkewS2S1RiseRise; + END IF; + ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay - Signal2Delay) >= + SkewS1S2FallFall) THEN + ReportType := s2f; + ReportTime := NOW - Signal1Delay + + SkewS1S2FallFall; + ELSIF ((Signal2Delay - Signal1Delay) >= + SkewS2S1FallFall) THEN + ReportType := s1f; + ReportTime := NOW - Signal2Delay + + SkewS2S1FallFall; + END IF; + END IF; + ELSIF (Posedge(Signal1'LAST_VALUE , Signal1)) THEN + IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay > + SkewS2S1FallFall)) THEN + ReportType := s1f; + ReportTime := NOW - Signal2Delay + + SkewS2S1FallFall; + ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay > + SkewS1S2RiseRise)) THEN + ReportType := s2r; + ReportTime := NOW - Signal1Delay + + SkewS1S2RiseRise; + ELSIF (Signal2Delay > Signal1Delay) THEN + SkewData.ExpectedType := s2r; + TriggerDelay := SkewS1S2RiseRise + + Signal2Delay - Signal1Delay; + ELSIF (Signal1Delay > Signal2Delay) THEN + SkewData.ExpectedType := s1r; + TriggerDelay := SkewS2S1RiseRise + + Signal1Delay - Signal2Delay; + ELSIF (SkewS1S2RiseRise < SkewS2S1RiseRise) THEN + SkewData.ExpectedType := s2r; + TriggerDelay := SkewS1S2RiseRise; + ELSE + SkewData.ExpectedType := s1r; + TriggerDelay := SkewS2S1RiseRise; + END IF; + ELSIF (Negedge(Signal1'LAST_VALUE , Signal1)) THEN + IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay > + SkewS2S1RiseRise)) THEN + ReportType := s1r; + ReportTime := NOW - Signal2Delay + + SkewS2S1RiseRise; + ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay > + SkewS1S2FallFall)) THEN + ReportType := s2f; + ReportTime := NOW - Signal1Delay + + SkewS1S2FallFall; + ELSIF (Signal2Delay > Signal1Delay) THEN + SkewData.ExpectedType := s2f; + TriggerDelay := SkewS1S2FallFall + + Signal2Delay - Signal1Delay; + ELSIF (Signal1Delay > Signal2Delay) THEN + SkewData.ExpectedType := s1f; + TriggerDelay := SkewS2S1FallFall + + Signal1Delay - Signal2Delay; + ELSIF (SkewS1S2FallFall < SkewS2S1FallFall) THEN + SkewData.ExpectedType := s2f; + TriggerDelay := SkewS1S2FallFall; + ELSE + SkewData.ExpectedType := s1f; + TriggerDelay := SkewS2S1FallFall; + END IF; + END IF; + ELSIF (Signal1'EVENT) THEN + IF ( Signal1 /= Signal2) THEN + IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN + IF (SkewS1S2RiseRise > (Signal1Delay - + Signal2Delay)) THEN + SkewData.ExpectedType := s2r; + TriggerDelay := SkewS1S2RiseRise + + Signal2Delay - + Signal1Delay; + ELSE + ReportType := s2r; + ReportTime := NOW + SkewS1S2RiseRise - + Signal1Delay; + END IF; + ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN + IF (SkewS1S2FallFall > (Signal1Delay - + Signal2Delay)) THEN + SkewData.ExpectedType := s2f; + TriggerDelay := SkewS1S2FallFall + + Signal2Delay - + Signal1Delay; + ELSE + ReportType := s2f; + ReportTime := NOW + SkewS1S2FallFall - + Signal1Delay; + END IF; + END IF; + ELSE + IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay - SkewS1S2RiseRise) > + (Signal2'LAST_EVENT + Signal2Delay)) THEN + IF ((SkewData.Signal2Old2 - Signal2Delay) > + (NOW - Signal1Delay + + SkewS1S2RiseRise)) THEN + ViolationCertain := FALSE; + ReportType := s2r; + ReportTime := NOW + SkewS1S2RiseRise - + Signal1Delay; + END IF; + END IF; + ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay - SkewS1S2FallFall) > + (Signal2'LAST_EVENT + Signal2Delay)) THEN + IF (( SkewData.Signal2Old2 - Signal2Delay) > + (NOW - Signal1Delay + + SkewS1S2FallFall )) THEN + ViolationCertain := FALSE; + ReportType := s2f; + ReportTime := NOW + SkewS1S2FallFall - + Signal1Delay; + END IF; + END IF; + END IF; + END IF; + ELSIF (Signal2'EVENT) THEN + IF (Signal1 /= Signal2) THEN + IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN + IF ( SkewS2S1RiseRise > (Signal2Delay - + Signal1Delay)) THEN + SkewData.ExpectedType := s1r; + TriggerDelay := SkewS2S1RiseRise + + Signal1Delay - + Signal2Delay; + ELSE + ReportType := s2r; + ReportTime := NOW + SkewS2S1RiseRise - + Signal2Delay; + END IF; + ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN + IF ( SkewS2S1FallFall > (Signal2Delay - + Signal1Delay)) THEN + SkewData.ExpectedType := s1f; + TriggerDelay := SkewS2S1FallFall + + Signal1Delay - + Signal2Delay; + ELSE + ReportType := s1f; + ReportTime := NOW + SkewS2S1FallFall - + Signal2Delay; + END IF; + END IF; + ELSE + IF (Posedge(Signal2'LAST_VALUE, Signal2)) THEN + IF ((Signal2Delay - SkewS2S1RiseRise) > + (Signal1'LAST_EVENT + Signal1Delay)) THEN + IF (( SkewData.Signal1Old2 - Signal1Delay) > + (NOW - Signal2Delay + + SkewS2S1RiseRise )) THEN + ViolationCertain := FALSE; + ReportType := s1r; + ReportTime := NOW + SkewS2S1RiseRise - + Signal2Delay; + END IF; + END IF; + ELSIF (Negedge(Signal2'LAST_VALUE, Signal2)) THEN + IF ((Signal2Delay - SkewS2S1FallFall) > + (Signal1'LAST_EVENT + Signal1Delay)) THEN + IF (( SkewData.Signal1Old2 - Signal1Delay) > + (NOW - Signal2Delay + + SkewS2S1FallFall )) THEN + ViolationCertain := FALSE; + ReportType := s1f; + ReportTime := NOW + SkewS2S1FallFall - + Signal2Delay; + END IF; + END IF; + END IF; + END IF; + END IF; + + IF (ReportType /= none) THEN + IF (MsgOn) THEN + CASE ReportType IS + WHEN s1r => + ReportSkewViolation( + Signal2Name, + Signal1Name, + SkewS2S1RiseRise, + ReportTime, + HeaderMsg, + MsgSeverity, + Inphase, + ViolationCertain); + WHEN s1f => + ReportSkewViolation( + Signal2Name, + Signal1Name, + SkewS2S1FallFall, + ReportTime, + HeaderMsg, + MsgSeverity, + Inphase, + ViolationCertain); + WHEN s2r => + ReportSkewViolation( + Signal1Name, + Signal2Name, + SkewS1S2RiseRise, + ReportTime, + HeaderMsg, + MsgSeverity, + Inphase, + ViolationCertain); + WHEN s2f => + ReportSkewViolation( + Signal1Name, + Signal2Name, + SkewS1S2FallFall, + ReportTime, + HeaderMsg, + MsgSeverity, + Inphase, + ViolationCertain); + WHEN OTHERS => + END CASE; + END IF; + IF (XOn) THEN + Violation := 'X'; + END IF; + SkewData.ExpectedType := none; + END IF; + IF (TriggerDelay /= noTrigger) THEN + IF (TriggerDelay = 0 ns) THEN + trigger <= TRANSPORT trigger AFTER 0 ns; + ELSE + trigger <= TRANSPORT not (trigger) AFTER + TriggerDelay; + END IF; + END IF; + END IF; + IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN + SkewData.Signal1Old2 := SkewData.Signal1Old1; + SkewData.Signal1Old1 := NOW; + END IF; + IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN + SkewData.Signal2Old2 := SkewData.Signal2Old1; + SkewData.Signal2Old1 := NOW; + END IF; + END VitalInPhaseSkewCheck; + + PROCEDURE VitalOutPhaseSkewCheck ( + VARIABLE Violation : OUT X01; + VARIABLE SkewData : INOUT VitalSkewDataType; + SIGNAL Signal1 : IN std_ulogic; + CONSTANT Signal1Name : IN STRING := ""; + CONSTANT Signal1Delay : IN TIME := 0 ns; + SIGNAL Signal2 : IN std_ulogic; + CONSTANT Signal2Name : IN STRING := ""; + CONSTANT Signal2Delay : IN TIME := 0 ns; + CONSTANT SkewS1S2RiseFall : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1RiseFall : IN TIME := TIME'HIGH; + CONSTANT SkewS1S2FallRise : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1FallRise : IN TIME := TIME'HIGH; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT HeaderMsg : IN STRING := ""; + SIGNAL Trigger : INOUT std_ulogic + ) IS + VARIABLE ReportType : VitalSkewExpectedType := none; + VARIABLE ExpectedType : VitalSkewExpectedType := none; + VARIABLE ReportTime : TIME; + VARIABLE TriggerDelay : TIME; + VARIABLE ViolationCertain : Boolean := TRUE; + BEGIN + Violation := '0'; + TriggerDelay := noTrigger; + IF (CheckEnabled) THEN + IF (SkewData.ExpectedType /= none) THEN + IF (trigger'Event) THEN + CASE SkewData.ExpectedType IS + WHEN s1r => ReportType := s1r; + ReportTime := NOW - Signal1Delay; + WHEN s1f => ReportType := s1f; + ReportTime := NOW - Signal1Delay; + WHEN s2r => ReportType := s2r; + ReportTime := NOW - Signal2Delay; + WHEN s2f => ReportType := s2f; + ReportTime := NOW - Signal2Delay; + WHEN OTHERS => + END CASE; + SkewData.ExpectedType := none; + ELSIF (Signal1'Event OR Signal2'Event ) THEN + IF (Signal1 /= 'X' AND Signal2 /= 'X' ) THEN + TriggerDelay := 0 ns; + SkewData.ExpectedType := none; + END IF; + END IF; + END IF; + + IF (Signal1'EVENT and Signal2'EVENT) THEN + IF (Signal1 /= Signal2) THEN + IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay - Signal2Delay) >= + SkewS1S2RiseFall) THEN + ReportType := s2f; + ReportTime := NOW - Signal1Delay + + SkewS1S2RiseFall; + ELSIF ((Signal2Delay - Signal1Delay) >= + SkewS2S1FallRise) THEN + ReportType := s1r; + ReportTime := NOW - Signal2Delay + + SkewS2S1FallRise; + END IF; + ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay - Signal2Delay) >= + SkewS1S2FallRise) THEN + ReportType := s2r; + ReportTime := NOW - Signal1Delay + + SkewS1S2FallRise; + ELSIF ((Signal2Delay - Signal1Delay) >= + SkewS2S1RiseFall) THEN + ReportType := s1f; + ReportTime := NOW - Signal2Delay + + SkewS2S1RiseFall; + END IF; + END IF; + ELSIF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay > + SkewS2S1RiseFall)) THEN + ReportType := s1f; + ReportTime := NOW - Signal2Delay + + SkewS2S1RiseFall; + ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay > + SkewS1S2RiseFall)) THEN + ReportType := s2f; + ReportTime := NOW - Signal1Delay + + SkewS1S2RiseFall; + ELSIF (Signal1Delay > Signal2Delay) THEN + SkewData.ExpectedType := s1f; + TriggerDelay := SkewS2S1RiseFall + + Signal1Delay - Signal2Delay; + ELSIF (Signal2Delay > Signal1Delay) THEN + SkewData.ExpectedType := s2f; + TriggerDelay := SkewS1S2RiseFall + + Signal2Delay - Signal1Delay; + ELSIF (SkewS2S1RiseFall < SkewS1S2RiseFall) THEN + SkewData.ExpectedType := s1f; + TriggerDelay := SkewS2S1RiseFall; + ELSE + SkewData.ExpectedType := s2f; + TriggerDelay := SkewS1S2RiseFall; + END IF; + ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay > + SkewS2S1FallRise)) THEN + ReportType := s1r; + ReportTime := NOW - Signal2Delay + + SkewS2S1FallRise; + ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay > + SkewS1S2FallRise)) THEN + ReportType := s2r; + ReportTime := NOW - Signal1Delay + + SkewS1S2FallRise; + ELSIF (Signal1Delay > Signal2Delay) THEN + SkewData.ExpectedType := s1r; + TriggerDelay := SkewS2S1FallRise + + Signal1Delay - Signal2Delay; + ELSIF (Signal2Delay > Signal1Delay) THEN + SkewData.ExpectedType := s2r; + TriggerDelay := SkewS1S2FallRise + + Signal2Delay - Signal1Delay; + ELSIF (SkewS2S1FallRise < SkewS1S2FallRise) THEN + SkewData.ExpectedType := s1r; + TriggerDelay := SkewS2S1FallRise; + ELSE + SkewData.ExpectedType := s2r; + TriggerDelay := SkewS1S2FallRise; + END IF; + END IF; + ELSIF (Signal1'EVENT) THEN + IF (Signal1 = Signal2) THEN + IF (Posedge(Signal1'LAST_VALUE,Signal1)) THEN + IF (SkewS1S2RiseFall > (Signal1Delay - + Signal2Delay)) THEN + SkewData.ExpectedType := s2f; + TriggerDelay := SkewS1S2RiseFall + + Signal2Delay - Signal1Delay; + ELSE + ReportType := s2f; + ReportTime := NOW - Signal1Delay + + SkewS1S2RiseFall; + END IF; + ELSIF ( Negedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ( SkewS1S2FallRise > (Signal1Delay - + Signal2Delay)) THEN + SkewData.ExpectedType := s2r; + TriggerDelay := SkewS1S2FallRise + + Signal2Delay - Signal1Delay; + ELSE + ReportType := s2r; + ReportTime := NOW - Signal1Delay + + SkewS1S2FallRise; + END IF; + END IF; + ELSE + IF (Posedge( Signal1'LAST_VALUE, Signal1 )) THEN + IF ((Signal1Delay - SkewS1S2RiseFall) > + (Signal2'LAST_EVENT + Signal2Delay)) THEN + IF (( SkewData.Signal2Old2 - Signal2Delay) > + (NOW - Signal1Delay + + SkewS1S2RiseFall )) THEN + ViolationCertain := FALSE; + ReportType := s2f; + ReportTime := NOW + SkewS1S2RiseFall - + Signal1Delay; + END IF; + END IF; + ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN + IF ((Signal1Delay - SkewS1S2FallRise) > + (Signal2'LAST_EVENT + Signal2Delay)) THEN + IF (( SkewData.Signal2Old2 - Signal2Delay) > + (NOW - Signal1Delay + + SkewS1S2FallRise )) THEN + ViolationCertain := FALSE; + ReportType := s2r; + ReportTime := NOW + SkewS1S2FallRise - + Signal1Delay; + END IF; + END IF; + END IF; + END IF; + ELSIF (Signal2'EVENT) THEN + IF (Signal1 = Signal2) THEN + IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN + IF (SkewS2S1RiseFall > (Signal2Delay - + Signal1Delay)) THEN + SkewData.ExpectedType := s1f; + TriggerDelay := SkewS2S1RiseFall + Signal1Delay - + Signal2Delay ; + ELSE + ReportType := s1f; + ReportTime := NOW + SkewS2S1RiseFall - + Signal2Delay; + END IF; + ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN + IF (SkewS2S1FallRise > (Signal2Delay - + Signal1Delay)) THEN + SkewData.ExpectedType := s1r; + TriggerDelay := SkewS2S1FallRise + Signal1Delay - + Signal2Delay; + ELSE + ReportType := s1r; + ReportTime := NOW + SkewS2S1FallRise - + Signal2Delay; + END IF; + END IF; + ELSE + IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN + IF ((Signal2Delay - SkewS2S1RiseFall) > + (Signal1'LAST_EVENT + Signal1Delay)) THEN + IF (( SkewData.Signal1Old2 - Signal1Delay) > + (NOW - Signal2Delay + + SkewS2S1RiseFall )) THEN + ViolationCertain := FALSE; + ReportType := s1f; + ReportTime := NOW + SkewS2S1RiseFall - + Signal2Delay; + END IF; + END IF; + ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN + IF ((Signal2Delay - SkewS2S1FallRise) > + (Signal1'LAST_EVENT + Signal1Delay)) THEN + IF (( SkewData.Signal1Old2 - Signal1Delay) > + (NOW - Signal2Delay + + SkewS2S1FallRise )) THEN + ViolationCertain := FALSE; + ReportType := s1r; + ReportTime := NOW + SkewS2S1FallRise - + Signal2Delay; + END IF; + END IF; + END IF; + END IF; + END IF; + + IF (ReportType /= none) THEN + IF (MsgOn) THEN + CASE ReportType IS + WHEN s1r => + ReportSkewViolation( + Signal2Name, + Signal1Name, + SkewS2S1FallRise, + ReportTime, + HeaderMsg, + MsgSeverity, + Outphase, + ViolationCertain); + WHEN s1f => + ReportSkewViolation( + Signal2Name, + Signal1Name, + SkewS2S1RiseFall, + ReportTime, + HeaderMsg, + MsgSeverity, + Outphase, + ViolationCertain); + WHEN s2r => + ReportSkewViolation( + Signal1Name, + Signal2Name, + SkewS1S2FallRise, + ReportTime, + HeaderMsg, + MsgSeverity, + Outphase, + ViolationCertain); + WHEN s2f => + ReportSkewViolation( + Signal1Name, + Signal2Name, + SkewS1S2RiseFall, + ReportTime, + HeaderMsg, + MsgSeverity, + Outphase, + ViolationCertain); + WHEN OTHERS => + END CASE; + END IF; + IF (XOn) THEN + Violation := 'X'; + END IF; + ReportType := none; + END IF; + IF (TriggerDelay /= noTrigger) THEN + IF (TriggerDelay = 0 ns) THEN + trigger <= TRANSPORT trigger AFTER 0 ns; + ELSE + trigger <= TRANSPORT not (trigger) AFTER + TriggerDelay; + END IF; + END IF; + END IF; + IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN + SkewData.Signal1Old2 := SkewData.Signal1Old1; + SkewData.Signal1Old1 := NOW; + END IF; + IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN + SkewData.Signal2Old2 := SkewData.Signal2Old1; + SkewData.Signal2Old1 := NOW; + END IF; + END VitalOutPhaseSkewCheck; + +END VITAL_Timing; diff --git a/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/timing_p.vhdl b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/timing_p.vhdl new file mode 100644 index 00000000..bbeb66fc --- /dev/null +++ b/server/vhdl_ls/0.84.0/vhdl_ls-aarch64-apple-darwin/vhdl_libraries/vital2000/timing_p.vhdl @@ -0,0 +1,1202 @@ +------------------------------------------------------------------------------- +-- Title : Standard VITAL TIMING Package +-- : $Revision$ +-- : +-- Library : This package shall be compiled into a library +-- : symbolically named IEEE. +-- : +-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4 +-- : +-- Purpose : This packages defines standard types, attributes, constants, +-- : functions and procedures for use in developing ASIC models. +-- : +-- Known Errors : +-- : +-- Note : No declarations or definitions shall be included in, +-- : or excluded from this package. The "package declaration" +-- : defines the objects (types, subtypes, constants, functions, +-- : procedures ... etc.) that can be used by a user. The package +-- : body shall be considered the formal definition of the +-- : semantics of this package. Tool developers may choose to +-- : implement the package body in the most efficient manner +-- : available to them. +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Acknowledgments: +-- This code was originally developed under the "VHDL Initiative Toward ASIC +-- Libraries" (VITAL), an industry sponsored initiative. Technical +-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator: +-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design +-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek, +-- Texas Instruments; Victor Martin, Hewlett-Packard Company. +-- ---------------------------------------------------------------------------- +-- +-- ---------------------------------------------------------------------------- +-- Modification History : +-- ---------------------------------------------------------------------------- +-- Version No:|Auth:| Mod.Date:| Changes Made: +-- v95.0 A | | 06/02/95 | Initial ballot draft 1995 +-- v95.1 | | 08/31/95 | #203 - Timing violations at time 0 +-- #204 - Output mapping prior to glitch detection +-- v98.0 |TAG | 03/27/98 | Initial ballot draft 1998 +-- | #IR225 - Negative Premptive Glitch +-- **Pkg_effected=VitalPathDelay, +-- VitalPathDelay01,VitalPathDelay01z. +-- #IR105 - Skew timing check needed +-- **Pkg_effected=NONE, New code added!! +-- #IR248 - Allows VPD to use a default timing +-- delay +-- **Pkg_effected=VitalPathDelay, +-- VitalPathDelay01,VitalPathDelay01z, +-- #IR250 - Corrects fastpath condition in VPD +-- **Pkg_effected=VitalPathDelay01, +-- VitalPathDelay01z, +-- #IR252 - Corrects cancelled timing check call if +-- condition expires. +-- **Pkg_effected=VitalSetupHoldCheck, +-- VitalRecoveryRemovalCheck. +-- #IR105 - Skew timing check +-- **Pkg_effected=NONE, New code added +-- v98.1 | jdc | 03/25/99 | Changed UseDefaultDelay to IgnoreDefaultDelay +-- and set default to FALSE in VitalPathDelay() +-- v00.7 | dbb | 07/18/00 | Removed "maximum" from VitalPeriodPulse() +-- comments + + +LIBRARY IEEE; +USE IEEE.Std_Logic_1164.ALL; + +PACKAGE VITAL_Timing IS + TYPE VitalTransitionType IS ( tr01, tr10, tr0z, trz1, tr1z, trz0, + tr0X, trx1, tr1x, trx0, trxz, trzx); + + SUBTYPE VitalDelayType IS TIME; + TYPE VitalDelayType01 IS ARRAY (VitalTransitionType RANGE tr01 to tr10) + OF TIME; + TYPE VitalDelayType01Z IS ARRAY (VitalTransitionType RANGE tr01 to trz0) + OF TIME; + TYPE VitalDelayType01ZX IS ARRAY (VitalTransitionType RANGE tr01 to trzx) + OF TIME; + + TYPE VitalDelayArrayType IS ARRAY (NATURAL RANGE <>) OF VitalDelayType; + TYPE VitalDelayArrayType01 IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01; + TYPE VitalDelayArrayType01Z IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01Z; + TYPE VitalDelayArrayType01ZX IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01ZX; + -- ---------------------------------------------------------------------- + -- ********************************************************************** + -- ---------------------------------------------------------------------- + + CONSTANT VitalZeroDelay : VitalDelayType := 0 ns; + CONSTANT VitalZeroDelay01 : VitalDelayType01 := ( 0 ns, 0 ns ); + CONSTANT VitalZeroDelay01Z : VitalDelayType01Z := ( OTHERS => 0 ns ); + CONSTANT VitalZeroDelay01ZX : VitalDelayType01ZX := ( OTHERS => 0 ns ); + + --------------------------------------------------------------------------- + -- examples of usage: + --------------------------------------------------------------------------- + -- tpd_CLK_Q : VitalDelayType := 5 ns; + -- tpd_CLK_Q : VitalDelayType01 := (tr01 => 2 ns, tr10 => 3 ns); + -- tpd_CLK_Q : VitalDelayType01Z := ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ); + -- tpd_CLK_Q : VitalDelayArrayType(0 to 1) + -- := (0 => 5 ns, 1 => 6 ns); + -- tpd_CLK_Q : VitalDelayArrayType01(0 to 1) + -- := (0 => (tr01 => 2 ns, tr10 => 3 ns), + -- 1 => (tr01 => 2 ns, tr10 => 3 ns)); + -- tpd_CLK_Q : VitalDelayArrayType01Z(0 to 1) + -- := (0 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ), + -- 1 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns )); + --------------------------------------------------------------------------- + + -- TRUE if the model is LEVEL0 | LEVEL1 compliant + ATTRIBUTE VITAL_Level0 : BOOLEAN; + ATTRIBUTE VITAL_Level1 : BOOLEAN; + + SUBTYPE std_logic_vector2 IS std_logic_vector(1 DOWNTO 0); + SUBTYPE std_logic_vector3 IS std_logic_vector(2 DOWNTO 0); + SUBTYPE std_logic_vector4 IS std_logic_vector(3 DOWNTO 0); + SUBTYPE std_logic_vector8 IS std_logic_vector(7 DOWNTO 0); + + -- Types for strength mapping of outputs + TYPE VitalOutputMapType IS ARRAY ( std_ulogic ) OF std_ulogic; + TYPE VitalResultMapType IS ARRAY ( UX01 ) OF std_ulogic; + TYPE VitalResultZMapType IS ARRAY ( UX01Z ) OF std_ulogic; + CONSTANT VitalDefaultOutputMap : VitalOutputMapType + := "UX01ZWLH-"; + CONSTANT VitalDefaultResultMap : VitalResultMapType + := ( 'U', 'X', '0', '1' ); + CONSTANT VitalDefaultResultZMap : VitalResultZMapType + := ( 'U', 'X', '0', '1', 'Z' ); + + -- Types for fields of VitalTimingDataType + TYPE VitalTimeArrayT IS ARRAY (INTEGER RANGE <>) OF TIME; + TYPE VitalTimeArrayPT IS ACCESS VitalTimeArrayT; + TYPE VitalBoolArrayT IS ARRAY (INTEGER RANGE <>) OF BOOLEAN; + TYPE VitalBoolArrayPT IS ACCESS VitalBoolArrayT; + TYPE VitalLogicArrayPT IS ACCESS std_logic_vector; + + TYPE VitalTimingDataType IS RECORD + NotFirstFlag : BOOLEAN; + RefLast : X01; + RefTime : TIME; + HoldEn : BOOLEAN; + TestLast : std_ulogic; + TestTime : TIME; + SetupEn : BOOLEAN; + TestLastA : VitalLogicArrayPT; + TestTimeA : VitalTimeArrayPT; + HoldEnA : VitalBoolArrayPT; + SetupEnA : VitalBoolArrayPT; + END RECORD; + + FUNCTION VitalTimingDataInit RETURN VitalTimingDataType; + + -- type for internal data of VitalPeriodPulseCheck + TYPE VitalPeriodDataType IS RECORD + Last : X01; + Rise : TIME; + Fall : TIME; + NotFirstFlag : BOOLEAN; + END RECORD; + CONSTANT VitalPeriodDataInit : VitalPeriodDataType + := ('X', 0 ns, 0 ns, FALSE ); + + -- Type for specifying the kind of Glitch handling to use + TYPE VitalGlitchKindType IS (OnEvent, + OnDetect, + VitalInertial, + VitalTransport); + + TYPE VitalGlitchDataType IS + RECORD + SchedTime : TIME; + GlitchTime : TIME; + SchedValue : std_ulogic; + LastValue : std_ulogic; + END RECORD; + TYPE VitalGlitchDataArrayType IS ARRAY (NATURAL RANGE <>) + OF VitalGlitchDataType; + + -- PathTypes: for handling simple PathDelay info + TYPE VitalPathType IS RECORD + InputChangeTime : TIME; -- timestamp for path input signal + PathDelay : VitalDelayType; -- delay for this path + PathCondition : BOOLEAN; -- path sensitize condition + END RECORD; + TYPE VitalPath01Type IS RECORD + InputChangeTime : TIME; -- timestamp for path input signal + PathDelay : VitalDelayType01; -- delay for this path + PathCondition : BOOLEAN; -- path sensitize condition + END RECORD; + TYPE VitalPath01ZType IS RECORD + InputChangeTime : TIME; -- timestamp for path input signal + PathDelay : VitalDelayType01Z;-- delay for this path + PathCondition : BOOLEAN; -- path sensitize condition + END RECORD; + + -- For representing multiple paths to an output + TYPE VitalPathArrayType IS ARRAY (NATURAL RANGE <> ) OF VitalPathType; + TYPE VitalPathArray01Type IS ARRAY (NATURAL RANGE <> ) OF VitalPath01Type; + TYPE VitalPathArray01ZType IS ARRAY (NATURAL RANGE <> ) OF VitalPath01ZType; + + TYPE VitalTableSymbolType IS ( + '/', -- 0 -> 1 + '\', -- 1 -> 0 + 'P', -- Union of '/' and '^' (any edge to 1) + 'N', -- Union of '\' and 'v' (any edge to 0) + 'r', -- 0 -> X + 'f', -- 1 -> X + 'p', -- Union of '/' and 'r' (any edge from 0) + 'n', -- Union of '\' and 'f' (any edge from 1) + 'R', -- Union of '^' and 'p' (any possible rising edge) + 'F', -- Union of 'v' and 'n' (any possible falling edge) + '^', -- X -> 1 + 'v', -- X -> 0 + 'E', -- Union of 'v' and '^' (any edge from X) + 'A', -- Union of 'r' and '^' (rising edge to or from 'X') + 'D', -- Union of 'f' and 'v' (falling edge to or from 'X') + '*', -- Union of 'R' and 'F' (any edge) + 'X', -- Unknown level + '0', -- low level + '1', -- high level + '-', -- don't care + 'B', -- 0 or 1 + 'Z', -- High Impedance + 'S' -- steady value + ); + + SUBTYPE VitalEdgeSymbolType IS VitalTableSymbolType RANGE '/' TO '*'; + + + + + -- Addition of Vital Skew Type Information + -- March 14, 1998 + + --------------------------------------------------------------------------- + -- Procedures and Type Definitions for Defining Skews + --------------------------------------------------------------------------- + + TYPE VitalSkewExpectedType IS (none, s1r, s1f, s2r, s2f); + + TYPE VitalSkewDataType IS RECORD + ExpectedType : VitalSkewExpectedType; + Signal1Old1 : TIME; + Signal2Old1 : TIME; + Signal1Old2 : TIME; + Signal2Old2 : TIME; + END RECORD; + + CONSTANT VitalSkewDataInit : VitalSkewDataType := ( none, 0 ns, 0 ns, 0 ns, 0 ns ); + + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalExtendToFillDelay + -- + -- Description: A six element array of delay values of type + -- VitalDelayType01Z is returned when a 1, 2 or 6 + -- element array is given. This function will convert + -- VitalDelayType and VitalDelayType01 delay values into + -- a VitalDelayType01Z type following these rules: + -- + -- When a VitalDelayType is passed, all six transition + -- values are assigned the input value. When a + -- VitalDelayType01 is passed, the 01 transitions are + -- assigned to the 01, 0Z and Z1 transitions and the 10 + -- transitions are assigned to 10, 1Z and Z0 transition + -- values. When a VitalDelayType01Z is passed, the values + -- are kept as is. + -- + -- The function is overloaded based on input type. + -- + -- There is no function to fill a 12 value delay + -- type. + -- + -- Arguments: + -- + -- IN Type Description + -- Delay A one, two or six delay value Vital- + -- DelayType is passed and a six delay, + -- VitalDelayType01Z, item is returned. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- VitalDelayType01Z + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalExtendToFillDelay ( + CONSTANT Delay : IN VitalDelayType + ) RETURN VitalDelayType01Z; + FUNCTION VitalExtendToFillDelay ( + CONSTANT Delay : IN VitalDelayType01 + ) RETURN VitalDelayType01Z; + FUNCTION VitalExtendToFillDelay ( + CONSTANT Delay : IN VitalDelayType01Z + ) RETURN VitalDelayType01Z; + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalCalcDelay + -- + -- Description: This function accepts a 1, 2 or 6 value delay and + -- chooses the correct delay time to delay the NewVal + -- signal. This function is overloaded based on the + -- delay type passed. The function returns a single value + -- of time. + -- + -- This function is provided for Level 0 models in order + -- to calculate the delay which should be applied + -- for the passed signal. The delay selection is performed + -- using the OldVal and the NewVal to determine the + -- transition to select. The default value of OldVal is X. + -- + -- This function cannot be used in a Level 1 model since + -- the VitalPathDelay routines perform the delay path + -- selection and output driving function. + -- + -- Arguments: + -- + -- IN Type Description + -- NewVal New value of the signal to be + -- assigned + -- OldVal Previous value of the signal. + -- Default value is 'X' + -- Delay The delay structure from which to + -- select the appropriate delay. The + -- function overload is based on the + -- type of delay passed. In the case of + -- the single delay, VitalDelayType, no + -- selection is performed, since there + -- is only one value to choose from. + -- For the other cases, the transition + -- from the old value to the new value + -- decide the value returned. + -- + -- INOUT + -- none + -- + -- OUT + -- none + -- + -- Returns + -- Time The time value selected from the + -- Delay INPUT is returned. + -- + -- ------------------------------------------------------------------------- + FUNCTION VitalCalcDelay ( + CONSTANT NewVal : IN std_ulogic := 'X'; + CONSTANT OldVal : IN std_ulogic := 'X'; + CONSTANT Delay : IN VitalDelayType + ) RETURN TIME; + FUNCTION VitalCalcDelay ( + CONSTANT NewVal : IN std_ulogic := 'X'; + CONSTANT OldVal : IN std_ulogic := 'X'; + CONSTANT Delay : IN VitalDelayType01 + ) RETURN TIME; + FUNCTION VitalCalcDelay ( + CONSTANT NewVal : IN std_ulogic := 'X'; + CONSTANT OldVal : IN std_ulogic := 'X'; + CONSTANT Delay : IN VitalDelayType01Z + ) RETURN TIME; + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalPathDelay + -- + -- Description: VitalPathDelay is the Level 1 routine used to select + -- the propagation delay path and schedule a new output + -- value. + -- + -- For single and dual delay values, VitalDelayType and + -- VitalDelayType01 are used. The output value is + -- scheduled with a calculated delay without strength + -- modification. + -- + -- For the six delay value, VitalDelayType01Z, the output + -- value is scheduled with a calculated delay. The drive + -- strength can be modified to handle weak signal strengths + -- to model tri-state devices, pull-ups and pull-downs as + -- an example. + -- + -- The correspondence between the delay type and the + -- path delay function is as follows: + -- + -- Delay Type Path Type + -- + -- VitalDelayType VitalPathDelay + -- VitalDelayType01 VitalPathDelay01 + -- VitalDelayType01Z VitalPathDelay01Z + -- + -- For each of these routines, the following capabilities + -- is provided: + -- + -- o Transition dependent path delay selection + -- o User controlled glitch detection with the ability + -- to generate "X" on output and report the violation + -- o Control of the severity level for message generation + -- o Scheduling of the computed values on the specified + -- signal. + -- + -- Selection of the appropriate path delay begins with the + -- candidate paths. The candidate paths are selected by + -- identifying the paths for which the PathCondition is + -- true. If there is a single candidate path, then that + -- delay is selected. If there is more than one candidate + -- path, then the shortest delay is selected using + -- transition dependent delay selection. If there is no + -- candidate paths, then the delay specified by the + -- DefaultDelay parameter to the path delay is used. + -- + -- Once the delay is known, the output signal is then + -- scheduled with that delay. In the case of + -- VitalPathDelay01Z, an additional result mapping of + -- the output value is performed before scheduling. The + -- result mapping is performed after transition dependent + -- delay selection but before scheduling the final output. + -- + -- In order to perform glitch detection, the user is + -- obligated to provide a variable of VitalGlitchDataType + -- for the propagation delay functions to use. The user + -- cannot modify or use this information. + -- + -- Arguments: + -- + -- IN Type Description + -- OutSignalName string The name of the output signal + -- OutTemp std_logic The new output value to be driven + -- Paths VitalPathArrayType A list of paths of VitalPathArray + -- VitalPathArrayType01 type. The VitalPathDelay routine + -- VitalPathArrayType01Z is overloaded based on the type + -- of constant passed in. With + -- VitalPathArrayType01Z, the + -- resulting output strengths can be + -- mapped. + -- DefaultDelay VitalDelayType The default delay can be changed + -- VitalDelayType01 from zero-delay to another set + -- VitalDelayType01Z of values. + -- + -- IgnoreDefaultDelay BOOLEAN If TRUE, the default delay will + -- be used when no paths are + -- selected. If false, no event + -- will be scheduled if no paths are + -- selected. + -- + -- Mode VitalGlitchKindType The value of this constant + -- selects the type of glitch + -- detection. + -- OnEvent Glitch on transition event + -- | OnDetect Glitch immediate on detection + -- | VitalInertial No glitch, use INERTIAL + -- assignment + -- | VitalTransport No glitch, use TRANSPORT + -- assignment + -- XOn BOOLEAN Control for generation of 'X' on + -- glitch. When TRUE, 'X's are + -- scheduled for glitches, otherwise + -- no are generated. + -- MsgOn BOOLEAN Control for message generation on + -- glitch detect. When TRUE, + -- glitches are reported, otherwise + -- they are not reported. + -- MsgSeverity SEVERITY_LEVEL The level at which the message, + -- or assertion, will be reported. + -- IgnoreDefaultDelay BOOLEAN Tells the VPD whether to use the + -- default delay value in the absense + -- of a valid delay for input conditions 3/14/98 MG + -- + -- OutputMap VitalOutputMapType For VitalPathDelay01Z, the output + -- can be mapped to alternate + -- strengths to model tri-state + -- devices, pull-ups and pull-downs. + -- + -- INOUT + -- GlitchData VitalGlitchDataType The internal data storage + -- variable required to detect + -- glitches. + -- + -- OUT + -- OutSignal std_logic The output signal to be driven + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalPathDelay ( + SIGNAL OutSignal : OUT std_logic; + VARIABLE GlitchData : INOUT VitalGlitchDataType; + CONSTANT OutSignalName : IN string; + CONSTANT OutTemp : IN std_logic; + CONSTANT Paths : IN VitalPathArrayType; + CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay; + CONSTANT Mode : IN VitalGlitchKindType := OnEvent; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98 + CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE --IR248 3/14/98 + ); + PROCEDURE VitalPathDelay01 ( + SIGNAL OutSignal : OUT std_logic; + VARIABLE GlitchData : INOUT VitalGlitchDataType; + CONSTANT OutSignalName : IN string; + CONSTANT OutTemp : IN std_logic; + CONSTANT Paths : IN VitalPathArray01Type; + CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01; + CONSTANT Mode : IN VitalGlitchKindType := OnEvent; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98 + CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98 + CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250 + ); + PROCEDURE VitalPathDelay01Z ( + SIGNAL OutSignal : OUT std_logic; + VARIABLE GlitchData : INOUT VitalGlitchDataType; + CONSTANT OutSignalName : IN string; + CONSTANT OutTemp : IN std_logic; + CONSTANT Paths : IN VitalPathArray01ZType; + CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z; + CONSTANT Mode : IN VitalGlitchKindType := OnEvent; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap; + CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98 + CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98 + CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250 + ); + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalWireDelay + -- + -- Description: VitalWireDelay is used to delay an input signal. + -- The delay is selected from the input parameter passed. + -- The function is useful for back annotation of actual + -- net delays. + -- + -- The function is overloaded to permit passing a delay + -- value for twire for VitalDelayType, VitalDelayType01 + -- and VitalDelayType01Z. twire is a generic which can + -- be back annotated and must be constructed to follow + -- the SDF to generic mapping rules. + -- + -- Arguments: + -- + -- IN Type Description + -- InSig std_ulogic The input signal (port) to be + -- delayed. + -- twire VitalDelayType The delay value for which the input + -- VitalDelayType01 signal should be delayed. For Vital- + -- VitalDelayType01Z DelayType, the value is single value + -- passed. For VitalDelayType01 and + -- VitalDelayType01Z, the appropriate + -- delay value is selected by VitalCalc- + -- Delay. + -- + -- INOUT + -- none + -- + -- OUT + -- OutSig std_ulogic The internal delayed signal + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalWireDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT twire : IN VitalDelayType + ); + + PROCEDURE VitalWireDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT twire : IN VitalDelayType01 + ); + + PROCEDURE VitalWireDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT twire : IN VitalDelayType01Z + ); + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalSignalDelay + -- + -- Description: The VitalSignalDelay procedure is called in a signal + -- delay block in the architecture to delay the + -- appropriate test or reference signal in order to + -- accommodate negative constraint checks. + -- + -- The amount of delay is of type TIME and is a constant. + -- + -- Arguments: + -- + -- IN Type Description + -- InSig std_ulogic The signal to be delayed. + -- dly TIME The amount of time the signal is + -- delayed. + -- + -- INOUT + -- none + -- + -- OUT + -- OutSig std_ulogic The delayed signal + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalSignalDelay ( + SIGNAL OutSig : OUT std_ulogic; + SIGNAL InSig : IN std_ulogic; + CONSTANT dly : IN TIME + ); + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalSetupHoldCheck + -- + -- Description: The VitalSetupHoldCheck procedure detects a setup or a + -- hold violation on the input test signal with respect + -- to the corresponding input reference signal. The timing + -- constraints are specified through parameters + -- representing the high and low values for the setup and + -- hold values for the setup and hold times. This + -- procedure assumes non-negative values for setup and hold + -- timing constraints. + -- + -- It is assumed that negative timing constraints + -- are handled by internally delaying the test or + -- reference signals. Negative setup times result in + -- a delayed reference signal. Negative hold times + -- result in a delayed test signal. Furthermore, the + -- delays and constraints associated with these and + -- other signals may need to be appropriately + -- adjusted so that all constraint intervals overlap + -- the delayed reference signals and all constraint + -- values (with respect to the delayed signals) are + -- non-negative. + -- + -- This function is overloaded based on the input + -- TestSignal. A vector and scalar form are provided. + -- + -- TestSignal XXXXXXXXXXXX____________________________XXXXXXXXXXXXXXXXXXXXXX + -- : + -- : -->| error region |<-- + -- : + -- _______________________________ + -- RefSignal \______________________________ + -- : | | | + -- : | -->| |<-- thold + -- : -->| tsetup |<-- + -- + -- Arguments: + -- + -- IN Type Description + -- TestSignal std_ulogic Value of test signal + -- std_logic_vector + -- TestSignalName STRING Name of test signal + -- TestDelay TIME Model's internal delay associated + -- with TestSignal + -- RefSignal std_ulogic Value of reference signal + -- RefSignalName STRING Name of reference signal + -- RefDelay TIME Model's internal delay associated + -- with RefSignal + -- SetupHigh TIME Absolute minimum time duration before + -- the transition of RefSignal for which + -- transitions of TestSignal are allowed + -- to proceed to the "1" state without + -- causing a setup violation. + -- SetupLow TIME Absolute minimum time duration before + -- the transition of RefSignal for which + -- transitions of TestSignal are allowed + -- to proceed to the "0" state without + -- causing a setup violation. + -- HoldHigh TIME Absolute minimum time duration after + -- the transition of RefSignal for which + -- transitions of TestSignal are allowed + -- to proceed to the "1" state without + -- causing a hold violation. + -- HoldLow TIME Absolute minimum time duration after + -- the transition of RefSignal for which + -- transitions of TestSignal are allowed + -- to proceed to the "0" state without + -- causing a hold violation. + -- CheckEnabled BOOLEAN Check performed if TRUE. + -- RefTransition VitalEdgeSymbolType + -- Reference edge specified. Events on + -- the RefSignal which match the edge + -- spec. are used as reference edges. + -- HeaderMsg STRING String that will accompany any + -- assertion messages produced. + -- XOn BOOLEAN If TRUE, Violation output parameter + -- is set to "X". Otherwise, Violation + -- is always set to "0". + -- MsgOn BOOLEAN If TRUE, set and hold violation + -- message will be generated. + -- Otherwise, no messages are generated, + -- even upon violations. + -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion. + -- EnableSetupOnTest BOOLEAN If FALSE at the time that the + -- TestSignal signal changes, + -- no setup check will be performed. + -- EnableSetupOnRef BOOLEAN If FALSE at the time that the + -- RefSignal signal changes, + -- no setup check will be performed. + -- EnableHoldOnRef BOOLEAN If FALSE at the time that the + -- RefSignal signal changes, + -- no hold check will be performed. + -- EnableHoldOnTest BOOLEAN If FALSE at the time that the + -- TestSignal signal changes, + -- no hold check will be performed. + -- + -- INOUT + -- TimingData VitalTimingDataType + -- VitalSetupHoldCheck information + -- storage area. This is used + -- internally to detect reference edges + -- and record the time of the last edge. + -- + -- OUT + -- Violation X01 This is the violation flag returned. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalSetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalTimingDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN TIME := 0 ns; + CONSTANT SetupLow : IN TIME := 0 ns; + CONSTANT HoldHigh : IN TIME := 0 ns; + CONSTANT HoldLow : IN TIME := 0 ns; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98 + ); + + PROCEDURE VitalSetupHoldCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalTimingDataType; + SIGNAL TestSignal : IN std_logic_vector; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT SetupHigh : IN TIME := 0 ns; + CONSTANT SetupLow : IN TIME := 0 ns; + CONSTANT HoldHigh : IN TIME := 0 ns; + CONSTANT HoldLow : IN TIME := 0 ns; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98 + ); + + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalRecoveryRemovalCheck + -- + -- Description: The VitalRecoveryRemovalCheck detects the presence of + -- a recovery or removal violation on the input test + -- signal with respect to the corresponding input reference + -- signal. It assumes non-negative values of setup and + -- hold timing constraints. The timing constraint is + -- specified through parameters representing the recovery + -- and removal times associated with a reference edge of + -- the reference signal. A flag indicates whether a test + -- signal is asserted when it is high or when it is low. + -- + -- It is assumed that negative timing constraints + -- are handled by internally delaying the test or + -- reference signals. Negative recovery times result in + -- a delayed reference signal. Negative removal times + -- result in a delayed test signal. Furthermore, the + -- delays and constraints associated with these and + -- other signals may need to be appropriately + -- adjusted so that all constraint intervals overlap + -- the delayed reference signals and all constraint + -- values (with respect to the delayed signals) are + -- non-negative. + -- + -- Arguments: + -- + -- IN Type Description + -- TestSignal std_ulogic Value of TestSignal. The routine is + -- TestSignalName STRING Name of TestSignal + -- TestDelay TIME Model internal delay associated with + -- the TestSignal + -- RefSignal std_ulogic Value of RefSignal + -- RefSignalName STRING Name of RefSignal + -- RefDelay TIME Model internal delay associated with + -- the RefSignal + -- Recovery TIME A change to an unasserted value on + -- the asynchronous TestSignal must + -- precede reference edge (on RefSignal) + -- by at least this time. + -- Removal TIME An asserted condition must be present + -- on the asynchronous TestSignal for at + -- least the removal time following a + -- reference edge on RefSignal. + -- ActiveLow BOOLEAN A flag which indicates if TestSignal + -- is asserted when it is low - "0." + -- FALSE indicate that TestSignal is + -- asserted when it has a value "1." + -- CheckEnabled BOOLEAN The check in enabled when the value + -- is TRUE, otherwise the constraints + -- are not checked. + -- RefTransition VitalEdgeSymbolType + -- Reference edge specifier. Events on + -- RefSignal will match the edge + -- specified. + -- HeaderMsg STRING A header message that will accompany + -- any assertion message. + -- XOn BOOLEAN When TRUE, the output Violation is + -- set to "X." When FALSE, it is always + -- "0." + -- MsgOn BOOLEAN When TRUE, violation messages are + -- output. When FALSE, no messages are + -- generated. + -- MsgSeverity SEVERITY_LEVEL Severity level of the asserted + -- message. + -- EnableRecOnTest BOOLEAN If FALSE at the time that the + -- TestSignal signal changes, + -- no recovery check will be performed. + -- EnableRecOnRef BOOLEAN If FALSE at the time that the + -- RefSignal signal changes, + -- no recovery check will be performed. + -- EnableRemOnRef BOOLEAN If FALSE at the time that the + -- RefSignal signal changes, + -- no removal check will be performed. + -- EnableRemOnTest BOOLEAN If FALSE at the time that the + -- TestSignal signal changes, + -- no removal check will be performed. + -- + -- INOUT + -- TimingData VitalTimingDataType + -- VitalRecoveryRemovalCheck information + -- storage area. This is used + -- internally to detect reference edges + -- and record the time of the last edge. + -- OUT + -- Violation X01 This is the violation flag returned. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalRecoveryRemovalCheck ( + VARIABLE Violation : OUT X01; + VARIABLE TimingData : INOUT VitalTimingDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName: IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + SIGNAL RefSignal : IN std_ulogic; + CONSTANT RefSignalName : IN STRING := ""; + CONSTANT RefDelay : IN TIME := 0 ns; + CONSTANT Recovery : IN TIME := 0 ns; + CONSTANT Removal : IN TIME := 0 ns; + CONSTANT ActiveLow : IN BOOLEAN := TRUE; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT RefTransition : IN VitalEdgeSymbolType; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 + CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98 + ); + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalPeriodPulseCheck + -- + -- Description: VitalPeriodPulseCheck checks for minimum + -- periodicity and pulse width for "1" and "0" values of + -- the input test signal. The timing constraint is + -- specified through parameters representing the minimal + -- period between successive rising and falling edges of + -- the input test signal and the minimum pulse widths + -- associated with high and low values. + -- + -- VitalPeriodCheck's accepts rising and falling edges + -- from 1 and 0 as well as transitions to and from 'X.' + -- + -- _______________ __________ + -- ____________| |_______| + -- + -- |<--- pw_hi --->| + -- |<-------- period ----->| + -- -->| pw_lo |<-- + -- + -- Arguments: + -- IN Type Description + -- TestSignal std_ulogic Value of test signal + -- TestSignalName STRING Name of the test signal + -- TestDelay TIME Model's internal delay associated + -- with TestSignal + -- Period TIME Minimum period allowed between + -- consecutive rising ('P') or + -- falling ('F') transitions. + -- PulseWidthHigh TIME Minimum time allowed for a high + -- pulse ('1' or 'H') + -- PulseWidthLow TIME Minimum time allowed for a low + -- pulse ('0' or 'L') + -- CheckEnabled BOOLEAN Check performed if TRUE. + -- HeaderMsg STRING String that will accompany any + -- assertion messages produced. + -- XOn BOOLEAN If TRUE, Violation output parameter + -- is set to "X". Otherwise, Violation + -- is always set to "0". + -- XOnChecks is a global that allows for + -- only timing checks to be turned on. + -- MsgOn BOOLEAN If TRUE, period/pulse violation + -- message will be generated. + -- Otherwise, no messages are generated, + -- even though a violation is detected. + -- MsgOnChecks allows for only timing + -- check messages to be turned on. + -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion. + -- + -- INOUT + -- PeriodData VitalPeriodDataType + -- VitalPeriodPulseCheck information + -- storage area. This is used + -- internally to detect reference edges + -- and record the pulse and period + -- times. + -- OUT + -- Violation X01 This is the violation flag returned. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------ + PROCEDURE VitalPeriodPulseCheck ( + VARIABLE Violation : OUT X01; + VARIABLE PeriodData : INOUT VitalPeriodDataType; + SIGNAL TestSignal : IN std_ulogic; + CONSTANT TestSignalName : IN STRING := ""; + CONSTANT TestDelay : IN TIME := 0 ns; + CONSTANT Period : IN TIME := 0 ns; + CONSTANT PulseWidthHigh : IN TIME := 0 ns; + CONSTANT PulseWidthLow : IN TIME := 0 ns; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT HeaderMsg : IN STRING := " "; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING + ); + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalInPhaseSkewCheck + -- + -- Description: The VitalInPhaseSkewCheck procedure detects an in-phase + -- skew violation between input signals Signal1 and Signal2. + -- This is a timer based skew check in which a + -- violation is detected if Signal1 and Signal2 are in + -- different logic states longer than the specified skew + -- interval. + -- + -- The timing constraints are specified through parameters + -- representing the skew values for the different states + -- of Signal1 and Signal2. + -- + -- + -- Signal2 XXXXXXXXXXXX___________________________XXXXXXXXXXXXXXXXXXXXXX + -- : + -- : -->| |<-- + -- : Signal2 should go low in this region + -- : + -- + -- ____________ + -- Signal1 \_________________________________________________ + -- : | | + -- : |<-------- tskew -------->| + -- + -- Arguments: + -- + -- IN Type Description + -- Signal1 std_ulogic Value of first signal + -- Signal1Name STRING Name of first signal + -- Signal1Delay TIME Model's internal delay associated + -- with Signal1 + -- Signal2 std_ulogic Value of second signal + -- Signal2Name STRING Name of second signal + -- Signal2Delay TIME Model's internal delay associated + -- with Signal2 + -- SkewS1S2RiseRise TIME Absolute maximum time duration for + -- which Signal2 can remain at "0" + -- after Signal1 goes to the "1" state, + -- without causing a skew violation. + -- SkewS2S1RiseRise TIME Absolute maximum time duration for + -- which Signal1 can remain at "0" + -- after Signal2 goes to the "1" state, + -- without causing a skew violation. + -- SkewS1S2FallFall TIME Absolute maximum time duration for + -- which Signal2 can remain at "1" + -- after Signal1 goes to the "0" state, + -- without causing a skew violation. + -- SkewS2S1FallFall TIME Absolute maximum time duration for + -- which Signal1 can remain at "1" + -- after Signal2 goes to the "0" state, + -- without causing a skew violation. + -- CheckEnabled BOOLEAN Check performed if TRUE. + -- HeaderMsg STRING String that will accompany any + -- assertion messages produced. + -- XOn BOOLEAN If TRUE, Violation output parameter + -- is set to "X". Otherwise, Violation + -- is always set to "0." + -- MsgOn BOOLEAN If TRUE, skew timing violation + -- messages will be generated. + -- Otherwise, no messages are generated, + -- even upon violations. + -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion. + -- + -- INOUT + -- SkewData VitalSkewDataType + -- VitalInPhaseSkewCheck information + -- storage area. This is used + -- internally to detect signal edges + -- and record the time of the last edge. + -- + -- + -- Trigger std_ulogic This signal is used to trigger the + -- process in which the timing check + -- occurs upon expiry of the skew + -- interval. + -- + -- OUT + -- Violation X01 This is the violation flag returned. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + + PROCEDURE VitalInPhaseSkewCheck ( + VARIABLE Violation : OUT X01; + VARIABLE SkewData : INOUT VitalSkewDataType; + SIGNAL Signal1 : IN std_ulogic; + CONSTANT Signal1Name : IN STRING := ""; + CONSTANT Signal1Delay : IN TIME := 0 ns; + SIGNAL Signal2 : IN std_ulogic; + CONSTANT Signal2Name : IN STRING := ""; + CONSTANT Signal2Delay : IN TIME := 0 ns; + CONSTANT SkewS1S2RiseRise : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1RiseRise : IN TIME := TIME'HIGH; + CONSTANT SkewS1S2FallFall : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1FallFall : IN TIME := TIME'HIGH; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT HeaderMsg : IN STRING := ""; + SIGNAL Trigger : INOUT std_ulogic + ); + + + -- ------------------------------------------------------------------------ + -- + -- Function Name: VitalOutPhaseSkewCheck + -- + -- Description: The VitalOutPhaseSkewCheck procedure detects an + -- out-of-phase skew violation between input signals Signal1 + -- and Signal2. This is a timer based skew check in + -- which a violation is detected if Signal1 and Signal2 are + -- in the same logic state longer than the specified skew + -- interval. + -- + -- The timing constraints are specified through parameters + -- representing the skew values for the different states + -- of Signal1 and Signal2. + -- + -- + -- Signal2 XXXXXXXXXXXX___________________________XXXXXXXXXXXXXXXXXXXXXX + -- : + -- : -->| |<-- + -- : Signal2 should go high in this region + -- : + -- + -- ____________ + -- Signal1 \_________________________________________________ + -- : | | + -- : |<-------- tskew -------->| + -- + -- Arguments: + -- + -- IN Type Description + -- Signal1 std_ulogic Value of first signal + -- Signal1Name STRING Name of first signal + -- Signal1Delay TIME Model's internal delay associated + -- with Signal1 + -- Signal2 std_ulogic Value of second signal + -- Signal2Name STRING Name of second signal + -- Signal2Delay TIME Model's internal delay associated + -- with Signal2 + -- SkewS1S2RiseFall TIME Absolute maximum time duration for + -- which Signal2 can remain at "1" + -- after Signal1 goes to the "1" state, + -- without causing a skew violation. + -- SkewS2S1RiseFall TIME Absolute maximum time duration for + -- which Signal1 can remain at "1" + -- after Signal2 goes to the "1" state, + -- without causing a skew violation. + -- SkewS1S2FallRise TIME Absolute maximum time duration for + -- which Signal2 can remain at "0" + -- after Signal1 goes to the "0" state, + -- without causing a skew violation. + -- SkewS2S1FallRise TIME Absolute maximum time duration for + -- which Signal1 can remain at "0" + -- after Signal2 goes to the "0" state, + -- without causing a skew violation. + -- CheckEnabled BOOLEAN Check performed if TRUE. + -- HeaderMsg STRING String that will accompany any + -- assertion messages produced. + -- XOn BOOLEAN If TRUE, Violation output parameter + -- is set to "X". Otherwise, Violation + -- is always set to "0." + -- MsgOn BOOLEAN If TRUE, skew timing violation + -- messages will be generated. + -- Otherwise, no messages are generated, + -- even upon violations. + -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion. + -- + -- INOUT + -- SkewData VitalSkewDataType + -- VitalInPhaseSkewCheck information + -- storage area. This is used + -- internally to detect signal edges + -- and record the time of the last edge. + -- + -- Trigger std_ulogic This signal is used to trigger the + -- process in which the timing check + -- occurs upon expiry of the skew + -- interval. + -- + -- OUT + -- Violation X01 This is the violation flag returned. + -- + -- Returns + -- none + -- + -- ------------------------------------------------------------------------- + PROCEDURE VitalOutPhaseSkewCheck ( + VARIABLE Violation : OUT X01; + VARIABLE SkewData : INOUT VitalSkewDataType; + SIGNAL Signal1 : IN std_ulogic; + CONSTANT Signal1Name : IN STRING := ""; + CONSTANT Signal1Delay : IN TIME := 0 ns; + SIGNAL Signal2 : IN std_ulogic; + CONSTANT Signal2Name : IN STRING := ""; + CONSTANT Signal2Delay : IN TIME := 0 ns; + CONSTANT SkewS1S2RiseFall : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1RiseFall : IN TIME := TIME'HIGH; + CONSTANT SkewS1S2FallRise : IN TIME := TIME'HIGH; + CONSTANT SkewS2S1FallRise : IN TIME := TIME'HIGH; + CONSTANT CheckEnabled : IN BOOLEAN := TRUE; + CONSTANT XOn : IN BOOLEAN := TRUE; + CONSTANT MsgOn : IN BOOLEAN := TRUE; + CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; + CONSTANT HeaderMsg : IN STRING := ""; + SIGNAL Trigger : INOUT std_ulogic + ); + + +END VITAL_Timing; diff --git a/src/colibri/formatter/vsg.ts b/src/colibri/formatter/vsg.ts index 61a47789..f1859e78 100644 --- a/src/colibri/formatter/vsg.ts +++ b/src/colibri/formatter/vsg.ts @@ -101,9 +101,9 @@ export class Vsg extends Base_formatter { return result; } - // Consider the formatting successful if the command executed without error - // even if no violations were found - const formatting_successful = exec_result.successful && exec_result.return_value === 0; + // VSG exit codes: 0 = no violations found, 1 = violations found (and fixed with --fix) + // Both are successful outcomes; only other codes (e.g. 2) indicate a real error + const formatting_successful = exec_result.return_value === 0 || exec_result.return_value === 1; const result: common.f_result = { code_formatted: code_formatted, diff --git a/src/colibri/process/local_process.ts b/src/colibri/process/local_process.ts index 5367b2da..b9270f1d 100644 --- a/src/colibri/process/local_process.ts +++ b/src/colibri/process/local_process.ts @@ -60,7 +60,8 @@ export class Local_process { let error_code = 0; let successful = true; if (error !== undefined && error !== null) { - error_code = -1; + // Use the actual process exit code; fall back to -1 only for signals + error_code = error.code !== undefined ? error.code : -1; successful = false; } @@ -87,7 +88,7 @@ export class Local_process { let error_code = 0; let successful = true; if (error !== undefined && error !== null) { - error_code = -1; + error_code = error.code !== undefined ? error.code : -1; successful = false; } diff --git a/src/colibri/project_manager/project_manager.ts b/src/colibri/project_manager/project_manager.ts index d200d158..75f9bad4 100644 --- a/src/colibri/project_manager/project_manager.ts +++ b/src/colibri/project_manager/project_manager.ts @@ -613,7 +613,7 @@ export class Project_manager extends ConfigManager { for (const file_in_library of library.files) { files_in_library += ` '${file_in_library}',\n`; } - if (library.name === undefined || library.name === '') { + if (library.name === undefined || library.name === '' || library.name === 'work') { library.name = DEFAULT_LIBRARY; } toml += `${library.name}.files = [\n${files_in_library}]\n\n`; diff --git a/src/colibri/project_manager/tool/edalize/run_edalize.py b/src/colibri/project_manager/tool/edalize/run_edalize.py index 02eb0734..0cc0af99 100644 --- a/src/colibri/project_manager/tool/edalize/run_edalize.py +++ b/src/colibri/project_manager/tool/edalize/run_edalize.py @@ -129,6 +129,62 @@ def print_info(working_directory, developer_mode, edam_file, config_exec_file): backend = get_edatool(tool_name)(edam=edam, work_root=working_directory) + +def fix_paths_with_spaces_in_makefile(makefile_path, edam): + """ + The edalize ghdl backend joins source file paths with spaces and writes + them verbatim into the generated Makefile. Paths that themselves contain + spaces break both the shell commands (recipe lines) and Make's own + dependency/variable parsing (non-recipe lines), but in different ways: + + * Recipe lines (tab-indented) are executed by the shell, so surrounding + the path with double-quotes is the correct fix: + ghdl -i ... "/path/with spaces/file.vhd" + + * Make variable definitions and dependency rules use Make's own word- + splitting, which does NOT respect shell quoting. The correct fix is + to escape each space with a backslash: + VHDL_SOURCES = /path/with\ spaces/file.vhd + $(TOPLEVEL): /path/with\ spaces/file.vhd work-obj08.cf + + We process the Makefile line-by-line so we can apply the right fix for + each context. Longest paths are checked first to avoid partial matches + when one path is a prefix of another. + """ + try: + files_with_spaces = [ + f["name"] for f in edam.get("files", []) if " " in f.get("name", "") + ] + if not files_with_spaces: + return + + with open(makefile_path, "r") as fh: + lines = fh.readlines() + + fixed_lines = [] + for line in lines: + is_recipe = line.startswith("\t") + for filepath in sorted(files_with_spaces, key=len, reverse=True): + if filepath not in line: + continue + if is_recipe: + # Shell context: wrap in double quotes + shell_quoted = '"{}"'.format(filepath) + if shell_quoted not in line: + line = line.replace(filepath, shell_quoted) + else: + # Make context: escape each space with a backslash + make_escaped = filepath.replace(" ", "\\ ") + if make_escaped not in line: + line = line.replace(filepath, make_escaped) + fixed_lines.append(line) + + with open(makefile_path, "w") as fh: + fh.writelines(fixed_lines) + except Exception: + pass # Never let a patching failure prevent the build from running + + ################################################################################ # Configure GUI support ################################################################################ @@ -136,6 +192,7 @@ def print_info(working_directory, developer_mode, edam_file, config_exec_file): simulator_gui_tools = ["modelsim", "xsim", "isim", "spyglass", "xcelium", "trellis"] try: backend.configure() + fix_paths_with_spaces_in_makefile(makefile_path, edam) if execution_mode == "gui" and (tool_name in build_gui_tools): p = subprocess.Popen(["make", "build-gui"], cwd=working_directory) p.wait() diff --git a/src/teroshdl/features/language_provider/language_provider.ts b/src/teroshdl/features/language_provider/language_provider.ts index 5337a8d9..64bd5eb7 100644 --- a/src/teroshdl/features/language_provider/language_provider.ts +++ b/src/teroshdl/features/language_provider/language_provider.ts @@ -182,8 +182,6 @@ export class LanguageProviderManager { this.context.subscriptions.push( vscode.languages.registerDefinitionProvider(verilogSelector, this.provider_list.def) ); - - this.context.subscriptions.push(vscode.commands.registerCommand('teroshdl.verible.restart', async () => {})); } } diff --git a/src/teroshdl/features/language_provider/lsp/rust_hdl.ts b/src/teroshdl/features/language_provider/lsp/rust_hdl.ts index 7359f069..47b1d37b 100644 --- a/src/teroshdl/features/language_provider/lsp/rust_hdl.ts +++ b/src/teroshdl/features/language_provider/lsp/rust_hdl.ts @@ -25,9 +25,16 @@ import { import { e_linter_general_linter_vhdl } from 'colibri/config/config_declaration'; const isWindows = process.platform === 'win32'; -const languageServerName = isWindows ? 'vhdl_ls-x86_64-pc-windows-msvc' : 'vhdl_ls-x86_64-unknown-linux-musl'; +const isMac = process.platform === 'darwin'; +function getLanguageServerName(): string { + if (isWindows) { return 'vhdl_ls-x86_64-pc-windows-msvc'; } + if (isMac) { return process.arch === 'arm64' ? 'vhdl_ls-aarch64-apple-darwin' : 'vhdl_ls-x86_64-apple-darwin'; } + return 'vhdl_ls-x86_64-unknown-linux-musl'; +} +const languageServerName = getLanguageServerName(); const languageServerBinaryName = 'vhdl_ls'; let languageServer: string; +let languageServerLibraries: string | undefined; export class Rusthdl_lsp { private client: LanguageClient | undefined = undefined; @@ -64,7 +71,7 @@ export class Rusthdl_lsp { const languageServerDir = this.context.asAbsolutePath(path.join('server', 'vhdl_ls')); const current_language_server_version = this.embeddedVersion(languageServerDir); - languageServer = path.join( + const bundledPath = path.join( 'server', 'vhdl_ls', current_language_server_version, @@ -72,6 +79,34 @@ export class Rusthdl_lsp { 'bin', languageServerBinaryName + (isWindows ? '.exe' : '') ); + // Store the resolved absolute path so getServerOptionsEmbedded can use it directly + languageServer = this.context.asAbsolutePath(bundledPath); + + const bundledLibrariesDir = this.context.asAbsolutePath( + path.join('server', 'vhdl_ls', current_language_server_version, languageServerName, 'vhdl_libraries') + ); + languageServerLibraries = fs.existsSync(path.join(bundledLibrariesDir, 'vhdl_ls.toml')) ? bundledLibrariesDir : undefined; + + let is_alive = await this.check_rust_hdl(languageServer); + if (is_alive === false) { + // Bundled binary failed (e.g. wrong platform); try system-installed vhdl_ls + const systemPaths = [ + '/opt/homebrew/bin/vhdl_ls', + '/usr/local/bin/vhdl_ls', + 'vhdl_ls', + ]; + for (const sysPath of systemPaths) { + is_alive = await this.check_rust_hdl(sysPath); + if (is_alive) { + languageServer = sysPath; + break; + } + } + } + if (is_alive === false) { + return false; + } + // Get language server configuration and command to start server let serverOptions: ServerOptions; serverOptions = this.getServerOptionsEmbedded(this.context); @@ -85,12 +120,6 @@ export class Rusthdl_lsp { // Create the language client this.client = new LanguageClient('vhdlls', 'VHDL LS', serverOptions, clientOptions); - let server_path = this.context.asAbsolutePath(languageServer); - let is_alive = await this.check_rust_hdl(server_path); - if (is_alive === false) { - return false; - } - // Start the client. This will also launch the server this.languageServerDisposable = await this.client.start(); this.context.subscriptions.push(this.languageServerDisposable); @@ -138,7 +167,7 @@ export class Rusthdl_lsp { } } - getServerOptionsEmbedded(context: ExtensionContext) { + getServerOptionsEmbedded(_context: ExtensionContext) { const config = utils.getConfig(this.manager); const linter_name = config.linter.general.linter_vhdl; let args: string[] = []; @@ -146,23 +175,27 @@ export class Rusthdl_lsp { args = ['--no-lint']; } args.push('--silent'); + if (languageServerLibraries) { + args.push('--libraries', languageServerLibraries); + } - let serverCommand = context.asAbsolutePath(languageServer); let serverOptions: ServerOptions = { run: { - command: serverCommand, + command: languageServer, args: args, options: { env: { + ...process.env, VHDL_LS_CONFIG: this.fileListPath } } }, debug: { - command: serverCommand, + command: languageServer, args: args, options: { env: { + ...process.env, VHDL_LS_CONFIG: this.fileListPath } } diff --git a/src/teroshdl/features/language_provider/lsp/verible.ts b/src/teroshdl/features/language_provider/lsp/verible.ts index c7037075..0c579d64 100644 --- a/src/teroshdl/features/language_provider/lsp/verible.ts +++ b/src/teroshdl/features/language_provider/lsp/verible.ts @@ -63,12 +63,35 @@ export class Verilbe_lsp { const languageServerDir = this.context.asAbsolutePath(path.join('server', 'verible')); const current_language_server_version = this.embeddedVersion(languageServerDir); - languageServer = path.join( + const bundledPath = path.join( 'server', 'verible', current_language_server_version, languageServerBinaryName + (isWindows ? '.exe' : '') ); + // Store the resolved absolute path so getServerOptionsEmbedded can use it directly + languageServer = this.context.asAbsolutePath(bundledPath); + + let is_alive = await this.check_run(languageServer); + if (is_alive === false) { + // Bundled binary failed (e.g. wrong platform); try system-installed verible + const systemPaths = [ + '/opt/homebrew/bin/verible-verilog-ls', + '/usr/local/bin/verible-verilog-ls', + 'verible-verilog-ls', + ]; + for (const sysPath of systemPaths) { + is_alive = await this.check_run(sysPath); + if (is_alive) { + languageServer = sysPath; + break; + } + } + } + if (is_alive === false) { + return false; + } + // Get language server configuration and command to start server let serverOptions: ServerOptions; serverOptions = this.getServerOptionsEmbedded(this.context); @@ -77,22 +100,11 @@ export class Verilbe_lsp { let clientOptions: LanguageClientOptions = { documentSelector: [{ scheme: 'file', language: 'verilog' }, { scheme: 'file', language: 'systemverilog' }], revealOutputChannelOn: RevealOutputChannelOn.Never, - // middleware: { - // provideDiagnostics: () => { - // return undefined; - // } - // } }; // Create the language client this.client = new LanguageClient('verible-verilog-ls', 'Verible', serverOptions, clientOptions); - let server_path = this.context.asAbsolutePath(languageServer); - let is_alive = await this.check_run(server_path); - if (is_alive === false) { - return false; - } - // Start the client. This will also launch the server this.languageServerDisposable = await this.client.start(); this.context.subscriptions.push(this.languageServerDisposable); @@ -136,17 +148,16 @@ export class Verilbe_lsp { } } - getServerOptionsEmbedded(context: ExtensionContext) { + getServerOptionsEmbedded(_context: ExtensionContext) { const args = ["--file_list_path", this.fileListPath, '--ruleset=none']; - let serverCommand = context.asAbsolutePath(languageServer); let serverOptions: ServerOptions = { run: { - command: serverCommand, + command: languageServer, args: args }, debug: { - command: serverCommand, + command: languageServer, args: args } }; diff --git a/src/teroshdl/teroshdl.ts b/src/teroshdl/teroshdl.ts index 796015eb..82f91b59 100644 --- a/src/teroshdl/teroshdl.ts +++ b/src/teroshdl/teroshdl.ts @@ -34,7 +34,7 @@ import { Completions_manager } from './features/completions/completions'; import { Number_hover_manager } from './features/number_hover'; import { Stutter_mode_manager } from './features/stutter_mode'; import { Config_manager } from './features/config'; -import { Tree_view_manager, forceRefresh } from './features/tree_views/manager'; +import { Tree_view_manager } from './features/tree_views/manager'; import { Comander } from './features/comander/run'; import { Dependency_manager } from './features/dependency'; import { ConfigurationFileWebview } from './features/views/configurationFile'; @@ -64,7 +64,7 @@ export class Teroshdl { constructor( context: vscode.ExtensionContext ) { - this.rustHDLFilePath = process_utils.create_temp_file(''); + this.rustHDLFilePath = process_utils.create_temp_file('[libraries]\n'); this.veribleLSFilePath = process_utils.create_temp_file(''); const homedir = get_home_directory(); @@ -196,7 +196,7 @@ export class Teroshdl { private async init_tree_views(schematic_manager: Schematic_manager, dependency_manager: Dependency_manager) { new ConfigurationFileWebview(this.context, this.manager); - const manager = new Tree_view_manager( + new Tree_view_manager( this.context, this.manager, this.emitterProject, @@ -207,7 +207,8 @@ export class Teroshdl { this.rustHDLFilePath, this.veribleLSFilePath ); - await forceRefresh(this.rustHDLFilePath, this.veribleLSFilePath); + // Tree_view_manager constructor emits GLOBAL_REFRESH which already calls forceRefresh + // No need to call it again here } private init_comander() {