URL
https://opencores.org/ocsvn/fixed_extensions/fixed_extensions/trunk
Subversion Repositories fixed_extensions
Compare Revisions
- This comparison shows the changes necessary to convert path
/fixed_extensions
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/bench/vhdl/testrounding_tb.vhd
0,0 → 1,66
-- File automatically generated by "cdfg2hdl". |
-- Filename: testrounding_tb.vhd |
-- Date: 28 April 2011 02:50:35 PM |
-- Author: Nikolaos Kavvadias (C) 2009, 2010 |
|
library IEEE, STD; |
use STD.textio.all; |
use IEEE.numeric_std.all; |
use WORK.fixed_float_types.all; |
use WORK.fixed_pkg.all; |
use WORK.fixed_extensions_pkg.all; |
use IEEE.std_logic_1164.all; |
|
entity testrounding_tb is |
end testrounding_tb; |
|
architecture tb_arch of testrounding_tb is |
component testrounding |
port ( |
clk : in std_logic; |
reset : in std_logic; |
start : in std_logic; |
ok : out sfixed(3 downto -4) |
); |
end component; |
signal clk : std_logic; |
signal reset : std_logic; |
signal start : std_logic; |
signal ok : sfixed(3 downto -4); |
-- Profiling signals |
signal ncycles : integer; |
-- Constant declarations |
constant CLK_PERIOD : time := 10 ns; |
begin |
uut : testrounding |
port map ( |
clk => clk, |
reset => reset, |
start => start, |
ok => ok |
); |
|
CLK_GEN_PROC: process(clk) |
begin |
if (clk = 'U') then |
clk <= '1'; |
else |
clk <= not clk after CLK_PERIOD/2; |
end if; |
end process CLK_GEN_PROC; |
|
RESET_START_STIM: process |
begin |
reset <= '1'; |
start <= '0'; |
wait for CLK_PERIOD; |
reset <= '0'; |
start <= '1'; |
wait for 2000*CLK_PERIOD; |
-- Automatic end of the current simulation. |
assert false |
report "NONE. End simulation time reached" |
severity failure; |
end process RESET_START_STIM; |
|
end tb_arch; |
trunk/bench/vhdl/testrounding_tb.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/rtl/vhdl/fixed_extensions_pkg_sim.vhd
===================================================================
--- trunk/rtl/vhdl/fixed_extensions_pkg_sim.vhd (nonexistent)
+++ trunk/rtl/vhdl/fixed_extensions_pkg_sim.vhd (revision 2)
@@ -0,0 +1,456 @@
+--------------------------------------------------------------------------------
+-- Filename: fixed_extensions_pkg_sim.vhd
+-- Purpose : Package adding various extensions to the VHDL-2008 (VHDL'93, 2002
+-- compatibility versions) fixed-point arithmetic package by David
+-- Bishop.
+-- Supported operators:
+-- * ceil : round towards plus infinity.
+-- * fix : round towards zero.
+-- * floor : round towards minus infinity.
+-- * round : round to nearest; ties to greatest absolute value.
+-- * nearest : round to nearest; ties to plus infinity.
+-- * convergent: round to nearest; ties to closest even.
+-- * bitinsert : bit-field insertion to word
+-- * bitextract: bit-field extraction from word
+--
+-- Author : Nikolaos Kavvadias (C) 2011
+-- Date : 25-Jul-2011
+-- Revision: 0.0.0 (01/05/11)
+-- Initial version. Supports ceil, fix, floor, round, nearest,
+-- convergent based on their MATLAB documentation.
+-- 0.0.1 (03/05/11)
+-- Added bitinsert.
+-- 0.0.2 (16/07/11)
+-- Added bitextract (sfixed, ufixed), bitinsert (ufixed). Commented
+-- non-synthesizable part (assertions) of bitinsert.
+-- 0.0.3 (19/07/11)
+-- Fixed ceil bug with rounding integral (zero fractional part)
+-- values.
+-- 0.0.4 (21/07/11)
+-- Fixed more bugs regarding fix, round and convergent.
+-- 0.0.5 (25/07/11)
+-- Design edited for simulation-oriented use.
+--------------------------------------------------------------------------------
+
+use STD.TEXTIO.all;
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+--library IEEE_PROPOSED;
+--use IEEE_PROPOSED.fixed_float_types.all;
+--use IEEE_PROPOSED.fixed_pkg.all;
+--use WORK.fixed_float_types.all;
+use WORK.fixed_pkg.all;
+
+package fixed_extensions_pkg is
+
+ function ceil (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
+ function ceil (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
+ function fix (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
+ function fix (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
+ function floor (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
+ function floor (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
+ function round (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
+ function round (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
+ function nearest (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
+ function nearest (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
+ function convergent (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
+ function convergent (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
+ function bitinsert (a, y0 : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed;
+ function bitinsert (a, y0 : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed;
+ function bitextract (a : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed;
+ function bitextract (a : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed;
+
+end package fixed_extensions_pkg;
+
+--library IEEE;
+--use IEEE.MATH_REAL.all;
+--use WORK.MATH_REAL.all;
+
+package body fixed_extensions_pkg is
+
+ -- ceil: round towards plus infinity.
+ function ceil (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (arg'high downto arg'low);
+ variable fract_zero : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ if (to_slv(arg(-1 downto arg'low)) = fract_zero) then
+ result := arg;
+ else
+ result := arg + 1;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function ceil;
+
+ -- ceil: round towards plus infinity.
+ function ceil (
+ arg : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ variable result : UNRESOLVED_ufixed (arg'high downto arg'low);
+ variable fract_zero : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ if (to_slv(arg(-1 downto arg'low)) = fract_zero) then
+ result := arg;
+ else
+ result := arg + 1;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function ceil;
+
+ -- fix: round towards zero.
+ function fix (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (arg'high downto arg'low);
+ variable fract_zero : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ if (is_negative(arg)) then
+ if (to_slv(arg(-1 downto arg'low)) = fract_zero) then
+ result := arg;
+ else
+ result := arg + 1;
+ end if;
+ else
+ result := arg;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function fix;
+
+ -- fix: round towards zero.
+ function fix (
+ arg : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ variable result : UNRESOLVED_ufixed (arg'high downto arg'low);
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ result := arg;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function fix;
+
+ -- floor: round towards minus infinity.
+ function floor (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (arg'high downto arg'low);
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ result := arg;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function floor;
+
+ -- floor: round towards plus infinity.
+ function floor (
+ arg : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ variable result : UNRESOLVED_ufixed (arg'high downto arg'low);
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ result := arg;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function floor;
+
+ -- round: round to nearest; ties to greatest absolute value.
+ function round (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (arg'high downto arg'low);
+ variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ onehalf_vec(-arg'low-1) := '1';
+ if (is_negative(arg)) then
+ if (to_slv(arg(-1 downto arg'low)) > onehalf_vec) then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ else
+ if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function round;
+
+ -- round: round to nearest; ties to greatest absolute value.
+ function round (
+ arg : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ variable result : UNRESOLVED_ufixed (arg'high downto arg'low);
+ variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ onehalf_vec(-arg'low-1) := '1';
+ if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function round;
+
+ -- nearest: round to nearest; ties to plus infinity.
+ function nearest (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (arg'high downto arg'low);
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ if (arg(-1) = '1') then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ else
+ result := arg;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function nearest;
+
+ -- nearest: round to nearest; ties to plus infinity.
+ function nearest (
+ arg : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ variable result : UNRESOLVED_ufixed (arg'high downto arg'low);
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ if (arg(-1) = '1') then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ else
+ result := arg;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function nearest;
+
+ -- convergent: round to nearest; ties to closest even.
+ function convergent (
+ arg : UNRESOLVED_sfixed) -- fixed point input
+ return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (arg'high downto arg'low);
+ variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ onehalf_vec(-arg'low-1) := '1';
+ if (arg(0) = '1') then
+ if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ else
+ if (to_slv(arg(-1 downto arg'low)) > onehalf_vec) then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function convergent;
+
+ -- convergent: round to nearest; ties to closest even.
+ function convergent (
+ arg : UNRESOLVED_ufixed) -- fixed point input
+ return UNRESOLVED_ufixed is
+ variable result : UNRESOLVED_ufixed (arg'high downto arg'low);
+ variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
+ begin
+ if (arg'high <= 0) then
+ result := (others => '0');
+ return result;
+ end if;
+ if (arg'low > 0) then
+ result := arg;
+ return result;
+ end if;
+ if (arg'low < 0) then
+ onehalf_vec(-arg'low-1) := '1';
+ if (arg(0) = '1') then
+ if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ else
+ if (to_slv(arg(-1 downto arg'low)) > onehalf_vec) then
+ result := arg + 1;
+ else
+ result := arg;
+ end if;
+ end if;
+ result(-1 downto arg'low) := (others => '0');
+ end if;
+ return result;
+ end function convergent;
+
+ function bitinsert (a, y0 : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed is
+ variable y : UNRESOLVED_sfixed(a'RANGE);
+ begin
+-- if (bhi < blo) then
+-- assert false
+-- report "Error: Invalid range for bitfield insert."
+-- severity failure;
+-- end if;
+-- if (to_integer(signed(bhi)) > y'HIGH) then
+-- assert false
+-- report "Error: High bound (bhi) is out of result range."
+-- severity failure;
+-- end if;
+-- if (to_integer(signed(blo)) < y'LOW) then
+-- assert false
+-- report "Error: Low bound (blo) is out of result range."
+-- severity failure;
+-- end if;
+ y := y0;
+ y(to_integer(signed(bhi)) downto to_integer(signed(blo))) :=
+ a(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW);
+ return (y);
+ end bitinsert;
+
+ function bitinsert (a, y0 : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed is
+ variable y : UNRESOLVED_ufixed(a'RANGE);
+ begin
+ y := y0;
+ y(to_integer(signed(bhi)) downto to_integer(signed(blo))) :=
+ a(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW);
+ return (y);
+ end bitinsert;
+
+ function bitextract (a : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed is
+ variable y : sfixed(a'HIGH downto a'LOW);
+ begin
+ y := a;
+ y(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW) :=
+ a(to_integer(signed(bhi)) downto to_integer(signed(blo)));
+ return (y);
+ end bitextract;
+
+ function bitextract (a : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed is
+ variable y : ufixed(a'HIGH downto a'LOW);
+ begin
+ y := a;
+ y(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW) :=
+ a(to_integer(signed(bhi)) downto to_integer(signed(blo)));
+ return (y);
+ end bitextract;
+
+end package body fixed_extensions_pkg;
trunk/rtl/vhdl/fixed_extensions_pkg_sim.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/COPYING.BSD
===================================================================
--- trunk/doc/COPYING.BSD (nonexistent)
+++ trunk/doc/COPYING.BSD (revision 2)
@@ -0,0 +1,31 @@
+*** MODIFIED BSD LICENSE
+===============================================================================
+
+Copyright (c) 2011, Nikolaos Kavvadias
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * 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.
+
+ * Neither the name of "Nikolaos Kavvadias" 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
\ No newline at end of file
trunk/doc/COPYING.BSD
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/BUGS
===================================================================
--- trunk/doc/BUGS (nonexistent)
+++ trunk/doc/BUGS (revision 2)
@@ -0,0 +1,11 @@
+fixed_extensions BUGS -- known bugs. Last updated: 2011-07-25
+
+Known bugs in fixed_extensions-0.0.5
+------------------------------------
+
+ **
+ -
+ -
+
+
+BUGS ends here.
trunk/doc/BUGS
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/VERSION
===================================================================
--- trunk/doc/VERSION (nonexistent)
+++ trunk/doc/VERSION (revision 2)
@@ -0,0 +1 @@
+0.0.5
trunk/doc/VERSION
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/AUTHORS
===================================================================
--- trunk/doc/AUTHORS (nonexistent)
+++ trunk/doc/AUTHORS (revision 2)
@@ -0,0 +1,5 @@
+Authors of fixed_extensions.
+
+fixed_extensions Nikolaos Kavvadias
+
+AUTHORS ends here
trunk/doc/AUTHORS
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/TODO
===================================================================
--- trunk/doc/TODO (nonexistent)
+++ trunk/doc/TODO (revision 2)
@@ -0,0 +1,8 @@
+fixed_extensions --- TODO
+
+Todo:
+
+ * Add more bit-manipulation operators for fixed-point arithmetic.
+ * Test with GHDL (has some problems with s/ufixed entity ports.
+
+end of file TODO
trunk/doc/TODO
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/ChangeLog
===================================================================
--- trunk/doc/ChangeLog (nonexistent)
+++ trunk/doc/ChangeLog (revision 2)
@@ -0,0 +1,5 @@
+2011-07-25 Nikolaos Kavvadias
+
+ * First release 0.0.5.
+
+ChangeLog ends here
trunk/doc/ChangeLog
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/THANKS
===================================================================
--- trunk/doc/THANKS (nonexistent)
+++ trunk/doc/THANKS (revision 2)
@@ -0,0 +1,7 @@
+Thanks to:
+
+ X.Y. for whatever.
+
+
+Thessaloniki, Greece, 2011-07-25
+
trunk/doc/THANKS
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/doc/README
===================================================================
--- trunk/doc/README (nonexistent)
+++ trunk/doc/README (revision 2)
@@ -0,0 +1,103 @@
+------------------------------------------------------------------------------
+-- Title : fixed_extensions (VHDL fixed-point arithmetic --
+-- : extensions package). --
+-- Author : Nikolaos Kavvadias --
+-- Contact : nikolaos.kavvadias@gmail.com --
+-- : http://www.nkavvadias.com --
+-- Release Date : 25 July 2011 --
+-- Version : 0.0.5 --
+--------------------:---------------------------------------------------------
+-- Revision history : --
+-- v0.0.5 : 2011-07-25 --
+-- : Initial release. --
+------------------------------------------------------------------------------
+
+
+1. INTRODUCTION
+---------------
+
+"fixed_extensions_pkg" is a fixed-point arithmetic package written in VHDL
+according to the VHDL-2008 update of the standard. It uses VHDL-2008 back-
+compatible libraries (by David Bishop) that are included in this distribution
+for the sake of completeness.
+
+Currently, the "fixed_extensions_pkg" package implements the following:
+
+ - ceil : round towards plus infinity.
+ - fix : round towards zero.
+ - floor : round towards minus infinity.
+ - round : round to nearest; ties to greatest absolute value.
+ - nearest : round to nearest; ties to plus infinity.
+ - convergent: round to nearest; ties to closest even.
+ - bitinsert : bit-field insertion to word
+ - bitextract: bit-field extraction from word
+
+"fixed_extensions" is distributed along with a tool (gentestround) to generate
+customized VHDL test designs.
+
+
+2. FILE LISTING
+---------------
+
+ The fixed_extensions distributions includes the following files:
+
+ /fixed_extensions-
+ /bench/vhdl
+ testrounding_tb.vhd Standard testbench file.
+ /doc
+ AUTHORS List of "fixed_extensions" authors.
+ BUGS Bug list.
+ ChangeLog A log for code changes.
+ COPYING.BSD The Modified BSD License.
+ README This file.
+ THANKS Acknowledgements.
+ TODO A list of future enhancements.
+ /gen/vhdl
+ testroundings.vhd Auto-generated test file for sfixed arithmetic.
+ testroundingu.vhd Auto-generated test file for ufixed arithmetic.
+ /rtl/vhdl
+ fixed_extensions_pkg_sim.vhd
+ The VHDL package for simulation-oriented use.
+ fixed_extensions_pkg_synth.vhd
+ The VHDL package for synthesis-oriented use.
+ /sim/rtl_sim/bin
+ run.sh A bash script for testing the package.
+ testroundings.do Modelsim macro script for testing sfixed arithmetic.
+ testroundings.sh Bash script for running an sfixed simulation.
+ testroundingu.do Modelsim macro script for testing ufixed arithmetic.
+ testroundingu.sh Bash script for running an ufixed simulation.
+ /sim/rtl_sim/src
+ fixed_float_types_custom.vhd
+ VHDL package with definitions for fixed-point arith.
+ fixed_pkg_c.vhd VHDL package implementing fixed-point arithmetic.
+ math_real.vhd VHDL package with some real arithmetic functions.
+ /sw
+ gentestround.c Test design generator written in ANSI C.
+ Makefile Makefile for compiling the test design generator.
+
+
+3. FIXED_EXTENSIONS USAGE
+-------------------------
+
+ The fixed_extensions package can be used as follows:
+ $./run.sh
+
+
+4. PREREQUISITIES
+-----------------
+
+- Standard UNIX-based tools (tested on cygwin/x86)
+ make, bash
+- [optional] Mentor Modelsim ("mti") (http://www.mentor.com)
+ Provides a simulation environment to run the tests.
+
+
+5. CONTACT
+----------
+
+You may contact me for further questions/suggestions/corrections at:
+
+ Nikolaos Kavvadias
+
+
+ http://www.nkavvadias.com
trunk/doc/README
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/src/fixed_float_types_custom.vhd
===================================================================
--- trunk/sim/rtl_sim/src/fixed_float_types_custom.vhd (nonexistent)
+++ trunk/sim/rtl_sim/src/fixed_float_types_custom.vhd (revision 2)
@@ -0,0 +1,23 @@
+-- File automatically generated by "cdfg2hdl".
+-- Filename: fixed_float_types_custom.vhd
+-- Date: 29 April 2011 05:52:35 PM
+-- Author: Nikolaos Kavvadias (C) 2009, 2010, 2011
+
+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 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)
+
+ -- Rounding routine to use in fixed point, fixed_round or fixed_truncate
+ constant fixed_round_style : fixed_round_style_type := fixed_truncate;
+ -- Overflow routine to use in fixed point, fixed_saturate or fixed_wrap
+ constant fixed_overflow_style : fixed_overflow_style_type := fixed_wrap;
+ -- Extra bits used in divide routines
+ constant fixed_guard_bits : NATURAL := 3;
+ -- If TRUE, then turn off warnings on "X" propagation
+ constant no_warning : BOOLEAN := (false);
+end package fixed_float_types;
trunk/sim/rtl_sim/src/fixed_float_types_custom.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/src/fixed_pkg_c.vhd
===================================================================
--- trunk/sim/rtl_sim/src/fixed_pkg_c.vhd (nonexistent)
+++ trunk/sim/rtl_sim/src/fixed_pkg_c.vhd (revision 2)
@@ -0,0 +1,8389 @@
+-- --------------------------------------------------------------------
+-- "fixed_pkg_c.vhdl" package contains functions for fixed point math.
+-- Please see the documentation for the fixed point package.
+-- This package should be compiled into "ieee_proposed" and used as follows:
+-- use ieee.std_logic_1164.all;
+-- use ieee.numeric_std.all;
+-- use ieee_proposed.fixed_float_types.all;
+-- use ieee_proposed.fixed_pkg.all;
+--
+-- This verison is designed to work with the VHDL-93 compilers
+-- synthesis tools. Please note the "%%%" comments. These are where we
+-- diverge from the VHDL-200X LRM.
+-- --------------------------------------------------------------------
+-- Version : $Revision: 1.21 $
+-- Date : $Date: 2007/09/26 18:08:53 $
+-- --------------------------------------------------------------------
+
+use STD.TEXTIO.all;
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+use work.fixed_float_types.all;
+
+package fixed_pkg is
+-- generic (
+ -- Rounding routine to use in fixed point, fixed_round or fixed_truncate
+ constant fixed_round_style : fixed_round_style_type := fixed_round;
+ -- Overflow routine to use in fixed point, fixed_saturate or fixed_wrap
+ constant fixed_overflow_style : fixed_overflow_style_type := fixed_saturate;
+ -- Extra bits used in divide routines
+ constant fixed_guard_bits : NATURAL := 3;
+ -- If TRUE, then turn off warnings on "X" propagation
+ constant no_warning : BOOLEAN := (false
+ );
+
+ -- Author David Bishop (dbishop@vhdl.org)
+
+ -- 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;
+
+ subtype U_ufixed is UNRESOLVED_ufixed;
+ subtype U_sfixed is UNRESOLVED_sfixed;
+
+ subtype ufixed is UNRESOLVED_ufixed;
+ subtype sfixed is 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 : SIGNED) return UNRESOLVED_ufixed;
+ function scalb (y : UNRESOLVED_sfixed; N : INTEGER) return UNRESOLVED_sfixed;
+ function scalb (y : UNRESOLVED_sfixed; N : 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_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
+ function nand_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
+ function or_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
+ function nor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
+ function xor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
+ function xnor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
+ function and_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
+ function nand_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
+ function or_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
+ function nor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
+ function xor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
+ function xnor_reduce (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 : 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 : 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 : 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 UNSIGNED;
+
+ -- unsigned fixed point to unsigned
+ function to_unsigned (
+ arg : UNRESOLVED_ufixed; -- fixed point input
+ size_res : 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 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 : 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 : 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 : 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 SIGNED;
+
+ -- signed fixed point to signed
+ function to_signed (
+ arg : UNRESOLVED_sfixed; -- fixed point input
+ size_res : 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 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;
+-- rtl_synthesis off
+-- pragma synthesis_off
+ --===========================================================================
+ -- 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];
+-- rtl_synthesis on
+-- pragma synthesis_on
+
+ -- IN VHDL-2006 std_logic_vector is a subtype of std_ulogic_vector, so these
+ -- extra functions are needed for compatability.
+ function to_ufixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_ufixed;
+
+ function to_ufixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ size_res : UNRESOLVED_ufixed) -- for size only
+ return UNRESOLVED_ufixed;
+
+ function to_sfixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_sfixed;
+
+ function to_sfixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ size_res : UNRESOLVED_sfixed) -- for size only
+ return UNRESOLVED_sfixed;
+
+ -- unsigned fixed point
+ function to_UFix (
+ arg : STD_LOGIC_VECTOR;
+ width : NATURAL; -- width of vector
+ fraction : NATURAL) -- width of fraction
+ return UNRESOLVED_ufixed;
+
+ -- signed fixed point
+ function to_SFix (
+ arg : STD_LOGIC_VECTOR;
+ width : NATURAL; -- width of vector
+ fraction : NATURAL) -- width of fraction
+ return UNRESOLVED_sfixed;
+
+end package fixed_pkg;
+-------------------------------------------------------------------------------
+-- Proposed package body for the VHDL-200x-FT fixed_pkg package
+-- (Fixed point math package)
+-- This package body supplies a recommended implementation of these functions
+-- Version : $Revision: 1.21 $
+-- Date : $Date: 2007/09/26 18:08:53 $
+--
+-- Created for VHDL-200X-ft, David Bishop (dbishop@vhdl.org)
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.MATH_REAL.all;
+
+package body fixed_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;
+
+ -- %%% Replicated functions
+ function maximum (
+ l, r : integer) -- inputs
+ return integer is
+ begin -- function max
+ if l > r then return l;
+ else return r;
+ end if;
+ end function maximum;
+
+ function minimum (
+ l, r : integer) -- inputs
+ return integer is
+ begin -- function min
+ if l > r then return r;
+ else return l;
+ end if;
+ end function minimum;
+
+ 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";
+
+ function or_reduce (arg : STD_ULOGIC_VECTOR)
+ return STD_LOGIC is
+ variable Upper, Lower : STD_ULOGIC;
+ variable Half : INTEGER;
+ variable BUS_int : STD_ULOGIC_VECTOR (arg'length - 1 downto 0);
+ variable Result : STD_ULOGIC;
+ begin
+ if (arg'length < 1) then -- In the case of a NULL range
+ Result := '0';
+ else
+ BUS_int := to_ux01 (arg);
+ if (BUS_int'length = 1) then
+ Result := BUS_int (BUS_int'left);
+ elsif (BUS_int'length = 2) then
+ Result := BUS_int (BUS_int'right) or BUS_int (BUS_int'left);
+ else
+ Half := (BUS_int'length + 1) / 2 + BUS_int'right;
+ Upper := or_reduce (BUS_int (BUS_int'left downto Half));
+ Lower := or_reduce (BUS_int (Half - 1 downto BUS_int'right));
+ Result := Upper or Lower;
+ end if;
+ end if;
+ return Result;
+ end function or_reduce;
+
+ -- purpose: AND all of the bits in a vector together
+ -- This is a copy of the proposed "and_reduce" from 1076.3
+ function and_reduce (arg : STD_ULOGIC_VECTOR)
+ return STD_LOGIC is
+ variable Upper, Lower : STD_ULOGIC;
+ variable Half : INTEGER;
+ variable BUS_int : STD_ULOGIC_VECTOR (arg'length - 1 downto 0);
+ variable Result : STD_ULOGIC;
+ begin
+ if (arg'length < 1) then -- In the case of a NULL range
+ Result := '1';
+ else
+ BUS_int := to_ux01 (arg);
+ if (BUS_int'length = 1) then
+ Result := BUS_int (BUS_int'left);
+ elsif (BUS_int'length = 2) then
+ Result := BUS_int (BUS_int'right) and BUS_int (BUS_int'left);
+ else
+ Half := (BUS_int'length + 1) / 2 + BUS_int'right;
+ Upper := and_reduce (BUS_int (BUS_int'left downto Half));
+ Lower := and_reduce (BUS_int (Half - 1 downto BUS_int'right));
+ Result := Upper and Lower;
+ end if;
+ end if;
+ return Result;
+ end function and_reduce;
+
+ function xor_reduce (arg : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ variable Upper, Lower : STD_ULOGIC;
+ variable Half : INTEGER;
+ variable BUS_int : STD_ULOGIC_VECTOR (arg'length - 1 downto 0);
+ variable Result : STD_ULOGIC := '0'; -- In the case of a NULL range
+ begin
+ if (arg'length >= 1) then
+ BUS_int := to_ux01 (arg);
+ if (BUS_int'length = 1) then
+ Result := BUS_int (BUS_int'left);
+ elsif (BUS_int'length = 2) then
+ Result := BUS_int(BUS_int'right) xor BUS_int(BUS_int'left);
+ else
+ Half := (BUS_int'length + 1) / 2 + BUS_int'right;
+ Upper := xor_reduce (BUS_int (BUS_int'left downto Half));
+ Lower := xor_reduce (BUS_int (Half - 1 downto BUS_int'right));
+ Result := Upper xor Lower;
+ end if;
+ end if;
+ return Result;
+ end function xor_reduce;
+
+ function nand_reduce(arg : std_ulogic_vector) return STD_ULOGIC is
+ begin
+ return not and_reduce (arg);
+ end function nand_reduce;
+ function nor_reduce(arg : std_ulogic_vector) return STD_ULOGIC is
+ begin
+ return not or_reduce (arg);
+ end function nor_reduce;
+ function xnor_reduce(arg : std_ulogic_vector) return STD_ULOGIC is
+ begin
+ return not xor_reduce (arg);
+ end function xnor_reduce;
+ -- Match table, copied form new std_logic_1164
+-- type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;
+-- constant match_logic_table : stdlogic_table := (
+-- -----------------------------------------------------
+-- -- U X 0 1 Z W L H - | |
+-- -----------------------------------------------------
+-- ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '1'), -- | U |
+-- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | X |
+-- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'), -- | 0 |
+-- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'), -- | 1 |
+-- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | Z |
+-- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | W |
+-- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'), -- | L |
+-- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'), -- | H |
+-- ('1', '1', '1', '1', '1', '1', '1', '1', '1') -- | - |
+-- );
+
+-- constant no_match_logic_table : stdlogic_table := (
+-- -----------------------------------------------------
+-- -- U X 0 1 Z W L H - | |
+-- -----------------------------------------------------
+-- ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '0'), -- | U |
+-- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | X |
+-- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'), -- | 0 |
+-- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'), -- | 1 |
+-- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | Z |
+-- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | W |
+-- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'), -- | L |
+-- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'), -- | H |
+-- ('0', '0', '0', '0', '0', '0', '0', '0', '0') -- | - |
+-- );
+
+ -------------------------------------------------------------------
+ -- ?= functions, Similar to "std_match", but returns "std_ulogic".
+ -------------------------------------------------------------------
+ function \?=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ variable lx, rx : STD_ULOGIC;
+ begin
+-- return match_logic_table (l, r);
+ lx := to_x01(l);
+ rx := to_x01(r);
+ if lx = 'X' or rx = 'X' then
+ return 'X';
+ elsif lx = rx then
+ return '1';
+ else
+ return '0';
+ end if;
+ end function \?=\;
+ function \?/=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ begin
+-- return no_match_logic_table (l, r);
+ return not \?=\ (l, r);
+ end function \?/=\;
+ -- "?=" operator is similar to "std_match", but returns a std_ulogic..
+ -- Id: M.2B
+ function \?=\ (L, R: UNSIGNED) return STD_ULOGIC 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;
+ constant SIZE : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
+ variable LX : UNSIGNED(SIZE-1 downto 0);
+ variable RX : 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: M.3B
+ function \?=\ (L, R: SIGNED) return std_ulogic is
+ constant L_LEFT : INTEGER := L'LENGTH-1;
+ constant R_LEFT : INTEGER := R'LENGTH-1;
+ alias XL : SIGNED(L_LEFT downto 0) is L;
+ alias XR : SIGNED(R_LEFT downto 0) is R;
+ constant SIZE : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
+ variable LX : SIGNED(SIZE-1 downto 0);
+ variable RX : 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 \?=\;
+
+ function \?/=\ (L, R : UNSIGNED) return std_ulogic 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;
+ constant SIZE : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
+ variable LX : UNSIGNED(SIZE-1 downto 0);
+ variable RX : 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 \?/=\;
+
+ function \?/=\ (L, R : SIGNED) return std_ulogic is
+ constant L_LEFT : INTEGER := L'LENGTH-1;
+ constant R_LEFT : INTEGER := R'LENGTH-1;
+ alias XL : SIGNED(L_LEFT downto 0) is L;
+ alias XR : SIGNED(R_LEFT downto 0) is R;
+ constant SIZE : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
+ variable LX : SIGNED(SIZE-1 downto 0);
+ variable RX : 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 \?/=\;
+
+ function Is_X ( s : UNSIGNED ) return BOOLEAN is
+ begin
+ return Is_X (STD_LOGIC_VECTOR (s));
+ end function Is_X;
+
+ function Is_X ( s : SIGNED ) return BOOLEAN is
+ begin
+ return Is_X (STD_LOGIC_VECTOR (s));
+ end function Is_X;
+ function \?>\ (L, R : 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 \?>\;
+ -- %%% function "?>" (L, R : UNSIGNED) return std_ulogic is
+ -- %%% end function "?>"\;
+ function \?>\ (L, R : 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 \?>\;
+ function \?>=\ (L, R : 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 \?>=\;
+ -- %%% function "?>=" (L, R : UNSIGNED) return std_ulogic is
+ -- %%% end function "?>=";
+ function \?>=\ (L, R : 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 \?>=\;
+ function \?<\ (L, R : 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 \?<\;
+ -- %%% function "?<" (L, R : UNSIGNED) return std_ulogic is
+ -- %%% end function "?<";
+ function \?<\ (L, R : 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 \?<\;
+ function \?<=\ (L, R : 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 \?<=\;
+ -- %%% function "?<=" (L, R : UNSIGNED) return std_ulogic is
+ -- %%% end function "?<=";
+ function \?<=\ (L, R : 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 \?<=\;
+
+-- %%% END replicated functions
+ -- 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_pkg:"
+ & " Unbounded number passed, was a literal used?"
+ severity error;
+ return 0;
+ end if;
+ return minimum (L, R);
+ end function mine;
+
+ -- The following functions are used only internally. Every function
+ -- calls "cleanvec" either directly or indirectly.
+ -- purpose: Fixes "downto" problem and resolves meta states
+ function cleanvec (
+ arg : UNRESOLVED_sfixed) -- input
+ return UNRESOLVED_sfixed is
+ constant left_index : INTEGER := maximum(arg'left, arg'right);
+ constant right_index : INTEGER := mins(arg'left, arg'right);
+ variable result : UNRESOLVED_sfixed (arg'range);
+ begin -- function cleanvec
+ assert not (arg'ascending and (arg'low /= INTEGER'low))
+ report "fixed_pkg:"
+ & " Vector passed using a ""to"" range, expected is ""downto"""
+ severity error;
+ return arg;
+ end function cleanvec;
+
+ -- purpose: Fixes "downto" problem and resolves meta states
+ function cleanvec (
+ arg : UNRESOLVED_ufixed) -- input
+ return UNRESOLVED_ufixed is
+ constant left_index : INTEGER := maximum(arg'left, arg'right);
+ constant right_index : INTEGER := mins(arg'left, arg'right);
+ variable result : UNRESOLVED_ufixed (arg'range);
+ begin -- function cleanvec
+ assert not (arg'ascending and (arg'low /= INTEGER'low))
+ report "fixed_pkg:"
+ & " 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 : 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 : 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 UNSIGNED is
+ subtype t is 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 SIGNED is
+ subtype t is 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 : 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 : 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_reduce (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_reduce (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_reduce (to_sulv(remainder(remainder'high-1 downto
+ remainder'low))) = '1');
+ end if;
+ else
+ rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
+ end if;
+ if rounds then
+ round_up(arg => arg,
+ result => result,
+ overflowx => round_overflow);
+ else
+ result := arg;
+ end if;
+ if round_overflow then
+ if (overflow_style = fixed_saturate) then
+ if arg(arg'high) = '0' then
+ result := saturate (result'high, result'low);
+ else
+ result := not saturate (result'high, result'low);
+ end if;
+ -- Sign bit not fixed when wrapping
+ end if;
+ end if;
+ return result;
+ end function round_fixed;
+
+ -- converts an sfixed into a ufixed. The output is the same length as the
+ -- input, because abs("1000") = "1000" = 8.
+ function to_ufixed (
+ arg : UNRESOLVED_sfixed)
+ return UNRESOLVED_ufixed
+ is
+ constant left_index : INTEGER := arg'high;
+ constant right_index : INTEGER := mine(arg'low, arg'low);
+ variable xarg : UNRESOLVED_sfixed(left_index+1 downto right_index);
+ variable result : UNRESOLVED_ufixed(left_index downto right_index);
+ begin
+ if arg'length < 1 then
+ return NAUF;
+ end if;
+ xarg := abs(arg);
+ result := UNRESOLVED_ufixed (xarg (left_index downto right_index));
+ return result;
+ end function to_ufixed;
+
+-----------------------------------------------------------------------------
+-- Visible functions
+-----------------------------------------------------------------------------
+
+ -- Conversion functions. These are needed for synthesis where typically
+ -- the only input and output type is a std_logic_vector.
+ function to_sulv (
+ arg : UNRESOLVED_ufixed) -- fixed point vector
+ return STD_ULOGIC_VECTOR is
+ variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
+ begin
+ if arg'length < 1 then
+ return NSLV;
+ end if;
+ result := STD_ULOGIC_VECTOR (arg);
+ return result;
+ end function to_sulv;
+
+ function to_sulv (
+ arg : UNRESOLVED_sfixed) -- fixed point vector
+ return STD_ULOGIC_VECTOR is
+ variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
+ begin
+ if arg'length < 1 then
+ return NSLV;
+ end if;
+ result := STD_ULOGIC_VECTOR (arg);
+ return result;
+ end function to_sulv;
+
+ function to_slv (
+ arg : UNRESOLVED_ufixed) -- fixed point vector
+ return STD_LOGIC_VECTOR is
+ begin
+ return std_logic_vector(to_sulv(arg));
+ end function to_slv;
+
+ function to_slv (
+ arg : UNRESOLVED_sfixed) -- fixed point vector
+ return STD_LOGIC_VECTOR is
+ begin
+ return std_logic_vector(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_pkg:" & "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 => 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_pkg:" & "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 => 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 : 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 : 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 is -- ufixed(max(a,c)+1 downto min(b,d))
+ 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 : UNSIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : 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 is -- sfixed(max(a,c)+1 downto min(b,d))
+ 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 : SIGNED (left_index-right_index downto 0);
+ variable result_slv : 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 is -- ufixed(max(a,c)+1 downto min(b,d))
+ 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 : UNSIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : 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 is -- sfixed(max(a,c)+1 downto min(b,d))
+ 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 : SIGNED (left_index-right_index downto 0);
+ variable result_slv : 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 is -- ufixed(a+c+1 downto b+d)
+ variable lslv : UNSIGNED (l'length-1 downto 0);
+ variable rslv : UNSIGNED (r'length-1 downto 0);
+ variable result_slv : 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 is -- sfixed(a+c+1 downto b+d)
+ variable lslv : SIGNED (l'length-1 downto 0);
+ variable rslv : SIGNED (r'length-1 downto 0);
+ variable result_slv : 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 : UNSIGNED (lresize'length-1 downto 0);
+-- variable rslv : UNSIGNED (r'length-1 downto 0);
+-- variable result_slv : 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_pkg:"
+-- & "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 : SIGNED (lresize'length-1 downto 0);
+-- variable rslv : SIGNED (r'length-1 downto 0);
+-- variable result_slv : 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_pkg:"
+-- & "DIVIDE(sfixed) Division by zero" severity error;
+-- result := saturate (result'high, result'low);
+-- else
+-- result_slv := lslv / rslv;
+-- dresult := to_fixed (result_slv, dresult'high, dresult'low);
+-- result := resize (arg => dresult,
+-- left_index => result'high,
+-- right_index => result'low,
+-- overflow_style => fixed_wrap, -- overflow impossible
+-- round_style => round_style);
+-- end if;
+-- return result;
+-- end function divide;
+
+ -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
+-- function reciprocal (
+-- arg : UNRESOLVED_ufixed; -- fixed point input
+-- constant round_style : fixed_round_style_type := fixed_round_style;
+-- constant guard_bits : NATURAL := fixed_guard_bits)
+-- return UNRESOLVED_ufixed is
+-- constant one : UNRESOLVED_ufixed (0 downto 0) := "1";
+-- begin
+-- return divide (l => one,
+-- r => arg,
+-- round_style => round_style,
+-- guard_bits => guard_bits);
+-- end function reciprocal;
+
+ -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
+-- function reciprocal (
+-- arg : UNRESOLVED_sfixed; -- fixed point input
+-- constant round_style : fixed_round_style_type := fixed_round_style;
+-- constant guard_bits : NATURAL := fixed_guard_bits)
+-- return UNRESOLVED_sfixed is
+-- constant one : UNRESOLVED_sfixed (1 downto 0) := "01"; -- extra bit.
+-- variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high);
+-- begin
+-- if (arg'length < 1 or resultx'length < 1) then
+-- return NASF;
+-- else
+-- resultx := divide (l => one,
+-- r => arg,
+-- round_style => round_style,
+-- guard_bits => guard_bits);
+-- return resultx (resultx'high-1 downto resultx'low); -- remove extra bit
+-- end if;
+-- end function reciprocal;
+
+ -- ufixed (a downto b) rem ufixed (c downto d)
+ -- = ufixed (min(a,c) downto min(b,d))
+-- function "rem" (
+-- l, r : UNRESOLVED_ufixed) -- fixed point input
+-- return UNRESOLVED_ufixed is
+-- begin
+-- return remainder (l, r);
+-- end function "rem";
+
+-- -- remainder
+-- -- sfixed (a downto b) rem sfixed (c downto d)
+-- -- = sfixed (min(a,c) downto min(b,d))
+-- function "rem" (
+-- l, r : UNRESOLVED_sfixed) -- fixed point input
+-- return UNRESOLVED_sfixed is
+-- begin
+-- return remainder (l, r);
+-- end function "rem";
+
+ -- ufixed (a downto b) rem ufixed (c downto d)
+ -- = ufixed (min(a,c) downto min(b,d))
+-- function remainder (
+-- l, r : UNRESOLVED_ufixed; -- fixed point input
+-- constant round_style : fixed_round_style_type := fixed_round_style;
+-- constant guard_bits : NATURAL := fixed_guard_bits)
+-- return UNRESOLVED_ufixed is
+-- variable result : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
+-- mine(l'low, r'low));
+-- variable lresize : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
+-- mins(r'low, r'low)-guard_bits);
+-- variable rresize : UNRESOLVED_ufixed (r'high downto r'low-guard_bits);
+-- variable dresult : UNRESOLVED_ufixed (rresize'range);
+-- variable lslv : UNSIGNED (lresize'length-1 downto 0);
+-- variable rslv : UNSIGNED (rresize'length-1 downto 0);
+-- variable result_slv : 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_pkg:"
+-- & "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 : UNSIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : UNSIGNED (left_index-right_index
+ downto 0);
+ variable cx : 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 : SIGNED (left_index-right_index
+ downto 0);
+ variable result_slv : SIGNED (left_index-right_index
+ downto 0);
+ variable cx : 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 : 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 : 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) = '1' 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) = '1' 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) = '1' 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) = '1' 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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_pkg:"
+ & """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 operator_reduces
+ function and_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return and_reduce (to_sulv(l));
+ end function and_reduce;
+
+ function nand_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return nand_reduce (to_sulv(l));
+ end function nand_reduce;
+
+ function or_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return or_reduce (to_sulv(l));
+ end function or_reduce;
+
+ function nor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return nor_reduce (to_sulv(l));
+ end function nor_reduce;
+
+ function xor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return xor_reduce (to_sulv(l));
+ end function xor_reduce;
+
+ function xnor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
+ begin
+ return xnor_reduce (to_sulv(l));
+ end function xnor_reduce;
+
+ function and_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return and_reduce (to_sulv(l));
+ end function and_reduce;
+
+ function nand_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return nand_reduce (to_sulv(l));
+ end function nand_reduce;
+
+ function or_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return or_reduce (to_sulv(l));
+ end function or_reduce;
+
+ function nor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return nor_reduce (to_sulv(l));
+ end function nor_reduce;
+
+ function xor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return xor_reduce (to_sulv(l));
+ end function xor_reduce;
+
+ function xnor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
+ begin
+ return xnor_reduce (to_sulv(l));
+ end function xnor_reduce;
+ -- End reduction operator_reduces
+
+ 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?="": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?/=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?/="": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?>
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?>"": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?>=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?>="": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?<
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?<"": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin -- ?<=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?<="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin -- ?=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin -- ?/=
+ if ((L'length < 1) or (R'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?/="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin -- ?>
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?>"": 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 : SIGNED (lresize'length-1 downto 0);
+ begin -- ?>=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?>="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin -- ?<
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?<"": 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 : SIGNED (lresize'length-1 downto 0);
+ begin -- ?<=
+ if ((l'length < 1) or (r'length < 1)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """?<="": 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_pkg:"
+ & "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_pkg:"
+ & "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 : UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """="": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """/="": null argument detected, returning TRUE"
+ severity warning;
+ return true;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """/="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """/="": null argument detected, returning TRUE"
+ severity warning;
+ return true;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """/="": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>"": 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 : SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>"": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<"": 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 : SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<"": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<"": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """>="": 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 : UNSIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<="": 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 : SIGNED (lresize'length-1 downto 0);
+ begin
+ if (l'length < 1 or r'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<="": null argument detected, returning FALSE"
+ severity warning;
+ return false;
+ elsif (Is_X(l) or Is_X(r)) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & """<="": 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);
+ if lresize > rresize then return lresize;
+ else return rresize;
+ end if;
+ 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);
+ if lresize > rresize then return lresize;
+ else return rresize;
+ end if;
+ 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);
+ if lresize > rresize then return rresize;
+ else return lresize;
+ end if;
+ 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);
+ if lresize > rresize then return rresize;
+ else return lresize;
+ end if;
+ 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_pkg:"
+ & "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_pkg:"
+ & "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;
+-- variable overflow_needed : BOOLEAN;
+ begin
+ -- If negative or null range, return.
+ if (left_index < fw) then
+ return NAUF;
+ end if;
+ if (arg < 0.0) then
+ report "fixed_pkg:"
+ & "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_pkg:"
+ & "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_pkg:"
+ & "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 : 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 : 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 : UNSIGNED) -- unsigned
+ return UNRESOLVED_ufixed is
+ constant ARG_LEFT : INTEGER := ARG'length-1;
+ alias XARG : 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 : 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 : 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 : SIGNED) -- signed
+ return UNRESOLVED_sfixed is
+ constant ARG_LEFT : INTEGER := ARG'length-1;
+ alias XARG : 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_pkg:"
+ & "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_pkg:"
+ & "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 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 : 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 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 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 : 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 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_pkg:"
+ & "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_pkg:"
+ & "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 : 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_pkg:"
+ & "TO_INTEGER (ufixed): metavalue detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ if (left_index < -1) then
+ return 0;
+ end if;
+ arg_uns := to_uns(resize (arg => arg,
+ left_index => arg_uns'high,
+ right_index => 0,
+ round_style => round_style,
+ overflow_style => overflow_style));
+ return to_integer (arg_uns);
+ end function to_integer;
+
+ function to_integer (
+ arg : UNRESOLVED_sfixed; -- fixed point input
+ constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
+ constant round_style : fixed_round_style_type := fixed_round_style)
+ return INTEGER is
+ constant left_index : INTEGER := arg'high;
+ constant right_index : INTEGER := arg'low;
+ variable arg_s : 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_pkg:"
+ & "TO_INTEGER (sfixed): metavalue detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ if (left_index < -1) then
+ return 0;
+ end if;
+ arg_s := to_s(resize (arg => arg,
+ left_index => arg_s'high,
+ right_index => 0,
+ round_style => round_style,
+ overflow_style => overflow_style));
+ return to_integer (arg_s);
+ end function to_integer;
+
+ function to_01 (
+ s : UNRESOLVED_ufixed; -- ufixed point input
+ constant XMAP : STD_ULOGIC := '0') -- Map x to
+ return UNRESOLVED_ufixed is
+ variable result : UNRESOLVED_ufixed (s'range); -- result
+ begin
+ if (s'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & "TO_01(ufixed): null detected, returning NULL"
+ severity warning;
+ return NAUF;
+ end if;
+ return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low);
+ end function to_01;
+
+ function to_01 (
+ s : UNRESOLVED_sfixed; -- sfixed point input
+ constant XMAP : STD_ULOGIC := '0') -- Map x to
+ return UNRESOLVED_sfixed is
+ variable result : UNRESOLVED_sfixed (s'range);
+ begin
+ if (s'length < 1) then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & "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_reduce(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_reduce (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_reduce (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_reduce (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_reduce (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 : 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 : 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;
+-- rtl_synthesis off
+-- pragma synthesis_off
+ -- 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 => ' ');
+
+ -- %%% Replicated Textio functions
+ 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_pkg:"
+ & "OREAD Error: Read a '" & c &
+ "', expected an Octal character (0-7)."
+ severity error;
+ result := "UUU";
+ good := false;
+ end case;
+ end procedure Char2TriBits;
+ -- 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_pkg:"
+ & "HREAD Error: Read a '" & c &
+ "', expected a Hex character (0-F)."
+ severity error;
+ result := "UUUU";
+ good := false;
+ end case;
+ end procedure Char2QuadBits;
+
+ -- purpose: Skips white space
+ procedure skip_whitespace (
+ L : inout LINE) is
+ variable readOk : BOOLEAN;
+ variable c : CHARACTER;
+ begin
+ while L /= null and L.all'length /= 0 loop
+ if (L.all(1) = ' ' or L.all(1) = NBSP or L.all(1) = HT) then
+ read (l, c, readOk);
+ else
+ exit;
+ end if;
+ end loop;
+ end procedure skip_whitespace;
+
+ function to_ostring (value : STD_ULOGIC_VECTOR) return STRING is
+ constant ne : INTEGER := (value'length+2)/3;
+ variable pad : STD_ULOGIC_VECTOR(0 to (ne*3 - value'length) - 1);
+ variable ivalue : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
+ variable result : STRING(1 to ne);
+ variable tri : STD_ULOGIC_VECTOR(0 to 2);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value (value'left) = 'Z' then
+ pad := (others => 'Z');
+ else
+ pad := (others => '0');
+ end if;
+ ivalue := pad & value;
+ for i in 0 to ne-1 loop
+ tri := To_X01Z(ivalue(3*i to 3*i+2));
+ case tri is
+ when o"0" => result(i+1) := '0';
+ when o"1" => result(i+1) := '1';
+ when o"2" => result(i+1) := '2';
+ when o"3" => result(i+1) := '3';
+ when o"4" => result(i+1) := '4';
+ when o"5" => result(i+1) := '5';
+ when o"6" => result(i+1) := '6';
+ when o"7" => result(i+1) := '7';
+ when "ZZZ" => result(i+1) := 'Z';
+ when others => result(i+1) := 'X';
+ end case;
+ end loop;
+ return result;
+ end if;
+ end function to_ostring;
+ -------------------------------------------------------------------
+ function to_hstring (value : STD_ULOGIC_VECTOR) return STRING is
+ constant ne : INTEGER := (value'length+3)/4;
+ variable pad : STD_ULOGIC_VECTOR(0 to (ne*4 - value'length) - 1);
+ variable ivalue : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
+ variable result : STRING(1 to ne);
+ variable quad : STD_ULOGIC_VECTOR(0 to 3);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value (value'left) = 'Z' then
+ pad := (others => 'Z');
+ else
+ pad := (others => '0');
+ end if;
+ ivalue := pad & value;
+ for i in 0 to ne-1 loop
+ quad := To_X01Z(ivalue(4*i to 4*i+3));
+ case quad is
+ when x"0" => result(i+1) := '0';
+ when x"1" => result(i+1) := '1';
+ when x"2" => result(i+1) := '2';
+ when x"3" => result(i+1) := '3';
+ when x"4" => result(i+1) := '4';
+ when x"5" => result(i+1) := '5';
+ when x"6" => result(i+1) := '6';
+ when x"7" => result(i+1) := '7';
+ when x"8" => result(i+1) := '8';
+ when x"9" => result(i+1) := '9';
+ when x"A" => result(i+1) := 'A';
+ when x"B" => result(i+1) := 'B';
+ when x"C" => result(i+1) := 'C';
+ when x"D" => result(i+1) := 'D';
+ when x"E" => result(i+1) := 'E';
+ when x"F" => result(i+1) := 'F';
+ when "ZZZZ" => result(i+1) := 'Z';
+ when others => result(i+1) := 'X';
+ end case;
+ end loop;
+ return result;
+ end if;
+ end function to_hstring;
+
+
+-- %%% END replicated 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) 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_pkg:" & "READ(ufixed) "
+ & "End of string encountered"
+ severity error;
+ return;
+ elsif c = '_' then
+ if i = value'high then
+ report "fixed_pkg:" & "READ(ufixed) "
+ & "String begins with an ""_""" severity error;
+ return;
+ elsif lastu then
+ report "fixed_pkg:" & "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_pkg:" & "READ(ufixed) "
+ & "Two binary points found in input string" severity error;
+ return;
+ elsif i /= -1 then -- Seperator in the wrong spot
+ report "fixed_pkg:" & "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_pkg:" & "READ(ufixed) "
+ & "Short read, Space encounted in input string"
+ severity error;
+ return;
+ elsif char_to_MVL9plus(c) = error then
+ report "fixed_pkg:" & "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_pkg:" & "READ(sfixed) "
+ & "End of string encountered"
+ severity error;
+ return;
+ elsif c = '_' then
+ if i = value'high then
+ report "fixed_pkg:" & "READ(sfixed) "
+ & "String begins with an ""_""" severity error;
+ return;
+ elsif lastu then
+ report "fixed_pkg:" & "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_pkg:" & "READ(sfixed) "
+ & "Two binary points found in input string" severity error;
+ return;
+ elsif i /= -1 then -- Seperator in the wrong spot
+ report "fixed_pkg:" & "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_pkg:" & "READ(sfixed) "
+ & "Short read, Space encounted in input string"
+ severity error;
+ return;
+ elsif char_to_MVL9plus(c) = error then
+ report "fixed_pkg:" & "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;
+
+ -- 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_pkg:"
+ & "OREAD(sfixed) "
+ & mess
+ severity error;
+ else
+ report "fixed_pkg:"
+ & "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_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
+ report "fixed_pkg:"
+ & "OREAD(ufixed): Vector truncated."
+ severity error;
+ else
+ if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & "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_reduce (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_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
+ report "fixed_pkg:"
+ & "OREAD(sfixed): Vector truncated."
+ severity error;
+ else
+ if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & "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_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and_reduce (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;
+
+ -- purpose: Routines common to the OREAD 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_pkg:"
+ & "HREAD(sfixed) "
+ & mess
+ severity error;
+ else
+ report "fixed_pkg:"
+ & "HREAD(ufixed) "
+ & mess
+ severity error;
+ end if;
+ end if;
+ end procedure errmes;
+ variable xgood : BOOLEAN;
+ variable nybble : STD_ULOGIC_VECTOR (3 downto 0); -- 4 bits
+ variable c : CHARACTER;
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ variable founddot : BOOLEAN := false; -- found a dot.
+ begin
+ Skip_whitespace (L);
+ if slv'length > 0 then
+ i := slv'high;
+ read (l, c, xgood);
+ while i > 0 loop
+ if xgood = false then
+ errmes ("Error: end of string encountered");
+ exit;
+ elsif c = '_' then
+ if i = slv'length then
+ errmes ("Error: String begins with an ""_""");
+ xgood := false;
+ exit;
+ elsif lastu then
+ errmes ("Error: Two underscores detected in input string ""__""");
+ xgood := false;
+ exit;
+ else
+ lastu := true;
+ end if;
+ elsif (c = '.') then
+ if (i + 1 /= bpoint) then
+ errmes ("encountered ""."" at wrong index");
+ xgood := false;
+ exit;
+ elsif i = slv'length then
+ errmes ("encounted a ""."" at the beginning of the line");
+ xgood := false;
+ exit;
+ elsif founddot then
+ errmes ("Two ""."" encounted in input string");
+ xgood := false;
+ exit;
+ end if;
+ founddot := true;
+ lastu := false;
+ else
+ Char2QuadBits(c, nybble, xgood, message);
+ if not xgood then
+ exit;
+ end if;
+ slv (i downto i-3) := nybble;
+ i := i - 4;
+ lastu := false;
+ end if;
+ if i > 0 then
+ read (L, c, xgood);
+ end if;
+ end loop;
+ idex := i;
+ igood := xgood;
+ else
+ idex := -1;
+ igood := true; -- read null string
+ end if;
+ end procedure HREAD_common;
+
+ procedure HREAD(L : inout LINE;
+ VALUE : out UNRESOLVED_ufixed) is
+ constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
+ constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
+ variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
+ variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
+ variable igood : BOOLEAN;
+ variable i : INTEGER;
+ begin
+ VALUE := (VALUE'range => 'U');
+ HREAD_common ( L => L,
+ slv => slv,
+ igood => igood,
+ idex => i,
+ bpoint => -lbv,
+ message => false,
+ smath => false);
+ if igood then
+ if not ((i = -1) and -- We read everything, and high bits 0
+ (or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
+ report "fixed_pkg:"
+ & "HREAD(ufixed): Vector truncated."
+ severity error;
+ else
+ if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & "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_reduce (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_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
+ report "fixed_pkg:"
+ & "HREAD(sfixed): Vector truncated."
+ severity error;
+ else
+ if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
+ assert NO_WARNING
+ report "fixed_pkg:"
+ & "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_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
+ (slv(VALUE'high-lbv) = '1' and
+ and_reduce (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;
+
+ 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_pkg:"
+ & "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_pkg:"
+ & "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_pkg:"
+ & "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_pkg:"
+ & "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_pkg:"
+ & "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_pkg:"
+ & "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;
+
+ -- 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_pkg:"
+ & "Found a space in the input STRING " & xarg
+ severity error;
+ elsif xarg(i) = '.' then
+ if founddot then
+ report "fixed_pkg:"
+ & "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;
+-- pragma synthesis_on
+-- rtl_synthesis on
+ -- IN VHDL-2006 std_logic_vector is a subtype of std_ulogic_vector, so these
+ -- extra functions are needed for compatability.
+ function to_ufixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_ufixed is
+ begin
+ return to_ufixed (
+ arg => std_ulogic_vector (arg),
+ left_index => left_index,
+ right_index => right_index);
+ end function to_ufixed;
+
+ function to_ufixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ size_res : UNRESOLVED_ufixed) -- for size only
+ return UNRESOLVED_ufixed is
+ begin
+ return to_ufixed (
+ arg => std_ulogic_vector (arg),
+ size_res => size_res);
+ end function to_ufixed;
+
+ function to_sfixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ constant left_index : INTEGER;
+ constant right_index : INTEGER)
+ return UNRESOLVED_sfixed is
+ begin
+ return to_sfixed (
+ arg => std_ulogic_vector (arg),
+ left_index => left_index,
+ right_index => right_index);
+ end function to_sfixed;
+
+ function to_sfixed (
+ arg : STD_LOGIC_VECTOR; -- shifted vector
+ size_res : UNRESOLVED_sfixed) -- for size only
+ return UNRESOLVED_sfixed is
+ begin
+ return to_sfixed (
+ arg => std_ulogic_vector (arg),
+ size_res => size_res);
+ end function to_sfixed;
+
+ -- unsigned fixed point
+ function to_UFix (
+ arg : STD_LOGIC_VECTOR;
+ width : NATURAL; -- width of vector
+ fraction : NATURAL) -- width of fraction
+ return UNRESOLVED_ufixed is
+ begin
+ return to_UFix (
+ arg => std_ulogic_vector (arg),
+ width => width,
+ fraction => fraction);
+ end function to_UFix;
+
+ -- signed fixed point
+ function to_SFix (
+ arg : STD_LOGIC_VECTOR;
+ width : NATURAL; -- width of vector
+ fraction : NATURAL) -- width of fraction
+ return UNRESOLVED_sfixed is
+ begin
+ return to_SFix (
+ arg => std_ulogic_vector (arg),
+ width => width,
+ fraction => fraction);
+ end function to_SFix;
+
+end package body fixed_pkg;
trunk/sim/rtl_sim/src/fixed_pkg_c.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/src/math_real.vhd
===================================================================
--- trunk/sim/rtl_sim/src/math_real.vhd (nonexistent)
+++ trunk/sim/rtl_sim/src/math_real.vhd (revision 2)
@@ -0,0 +1,2507 @@
+-- --------------------------------------------------------------------
+--
+-- Copyright © 2008 by IEEE. All rights reserved.
+--
+-- This source file is an essential part of IEEE Std 1076-2008,
+-- IEEE Standard VHDL Language Reference Manual. This source file may not be
+-- copied, sold, or included with software that is sold without written
+-- permission from the IEEE Standards Department. This source file may be
+-- copied for individual use between licensed users. This source file is
+-- provided on an AS IS basis. The IEEE disclaims ANY WARRANTY EXPRESS OR
+-- IMPLIED INCLUDING ANY WARRANTY OF MERCHANTABILITY AND FITNESS FOR USE
+-- FOR A PARTICULAR PURPOSE. The user of the source file shall indemnify
+-- and hold IEEE harmless from any damages or liability arising out of the
+-- use thereof.
+--
+-- Title : Standard VHDL Mathematical Packages
+-- : (MATH_REAL package declaration)
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers: IEEE DASC VHDL Mathematical Packages Working Group
+-- :
+-- Purpose : This package defines a standard for designers to use in
+-- : describing VHDL models that make use of common REAL
+-- : constants and common REAL elementary mathematical
+-- : functions.
+-- :
+-- Limitation: The values generated by the functions in this package
+-- : may vary from platform to platform, and the precision
+-- : of results is only guaranteed to be the minimum required
+-- : by IEEE Std 1076-2008.
+-- :
+-- Note : This package may be modified to include additional data
+-- : required by tools, but it must in no way change the
+-- : external interfaces or simulation behavior of the
+-- : description. It is permissible to add comments and/or
+-- : attributes to the package declarations, but not to change
+-- : or delete any original lines of the package declaration.
+-- : The package body may be changed only in accordance with
+-- : the terms of Clause 16 of this standard.
+-- :
+-- --------------------------------------------------------------------
+-- $Revision: 1220 $
+-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
+-- --------------------------------------------------------------------
+
+package MATH_REAL is
+ constant CopyRightNotice : STRING
+ := "Copyright 2008 IEEE. All rights reserved.";
+
+ --
+ -- Constant Definitions
+ --
+ constant MATH_E : REAL := 2.71828_18284_59045_23536;
+ -- Value of e
+ constant MATH_1_OVER_E : REAL := 0.36787_94411_71442_32160;
+ -- Value of 1/e
+ constant MATH_PI : REAL := 3.14159_26535_89793_23846;
+ -- Value of pi
+ constant MATH_2_PI : REAL := 6.28318_53071_79586_47693;
+ -- Value of 2*pi
+ constant MATH_1_OVER_PI : REAL := 0.31830_98861_83790_67154;
+ -- Value of 1/pi
+ constant MATH_PI_OVER_2 : REAL := 1.57079_63267_94896_61923;
+ -- Value of pi/2
+ constant MATH_PI_OVER_3 : REAL := 1.04719_75511_96597_74615;
+ -- Value of pi/3
+ constant MATH_PI_OVER_4 : REAL := 0.78539_81633_97448_30962;
+ -- Value of pi/4
+ constant MATH_3_PI_OVER_2 : REAL := 4.71238_89803_84689_85769;
+ -- Value 3*pi/2
+ constant MATH_LOG_OF_2 : REAL := 0.69314_71805_59945_30942;
+ -- Natural log of 2
+ constant MATH_LOG_OF_10 : REAL := 2.30258_50929_94045_68402;
+ -- Natural log of 10
+ constant MATH_LOG2_OF_E : REAL := 1.44269_50408_88963_4074;
+ -- Log base 2 of e
+ constant MATH_LOG10_OF_E : REAL := 0.43429_44819_03251_82765;
+ -- Log base 10 of e
+ constant MATH_SQRT_2 : REAL := 1.41421_35623_73095_04880;
+ -- square root of 2
+ constant MATH_1_OVER_SQRT_2 : REAL := 0.70710_67811_86547_52440;
+ -- square root of 1/2
+ constant MATH_SQRT_PI : REAL := 1.77245_38509_05516_02730;
+ -- square root of pi
+ constant MATH_DEG_TO_RAD : REAL := 0.01745_32925_19943_29577;
+ -- Conversion factor from degree to radian
+ constant MATH_RAD_TO_DEG : REAL := 57.29577_95130_82320_87680;
+ -- Conversion factor from radian to degree
+
+ --
+ -- Function Declarations
+ --
+ function SIGN (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns 1.0 if X > 0.0; 0.0 if X = 0.0; -1.0 if X < 0.0
+ -- Special values:
+ -- None
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- ABS(SIGN(X)) <= 1.0
+ -- Notes:
+ -- None
+
+ function CEIL (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns smallest INTEGER value (as REAL) not less than X
+ -- Special values:
+ -- None
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- CEIL(X) is mathematically unbounded
+ -- Notes:
+ -- a) Implementations have to support at least the domain
+ -- ABS(X) < REAL(INTEGER'HIGH)
+
+ function FLOOR (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns largest INTEGER value (as REAL) not greater than X
+ -- Special values:
+ -- FLOOR(0.0) = 0.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- FLOOR(X) is mathematically unbounded
+ -- Notes:
+ -- a) Implementations have to support at least the domain
+ -- ABS(X) < REAL(INTEGER'HIGH)
+
+ function ROUND (X : in REAL) return REAL;
+ -- Purpose:
+ -- Rounds X to the nearest integer value (as real). If X is
+ -- halfway between two integers, rounding is away from 0.0
+ -- Special values:
+ -- ROUND(0.0) = 0.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- ROUND(X) is mathematically unbounded
+ -- Notes:
+ -- a) Implementations have to support at least the domain
+ -- ABS(X) < REAL(INTEGER'HIGH)
+
+ function TRUNC (X : in REAL) return REAL;
+ -- Purpose:
+ -- Truncates X towards 0.0 and returns truncated value
+ -- Special values:
+ -- TRUNC(0.0) = 0.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- TRUNC(X) is mathematically unbounded
+ -- Notes:
+ -- a) Implementations have to support at least the domain
+ -- ABS(X) < REAL(INTEGER'HIGH)
+
+ function "MOD" (X, Y : in REAL) return REAL;
+ -- Purpose:
+ -- Returns floating point modulus of X/Y, with the same sign as
+ -- Y, and absolute value less than the absolute value of Y, and
+ -- for some INTEGER value N the result satisfies the relation
+ -- X = Y*N + MOD(X,Y)
+ -- Special values:
+ -- None
+ -- Domain:
+ -- X in REAL; Y in REAL and Y /= 0.0
+ -- Error conditions:
+ -- Error if Y = 0.0
+ -- Range:
+ -- ABS(MOD(X,Y)) < ABS(Y)
+ -- Notes:
+ -- None
+
+ function REALMAX (X, Y : in REAL) return REAL;
+ -- Purpose:
+ -- Returns the algebraically larger of X and Y
+ -- Special values:
+ -- REALMAX(X,Y) = X when X = Y
+ -- Domain:
+ -- X in REAL; Y in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- REALMAX(X,Y) is mathematically unbounded
+ -- Notes:
+ -- None
+
+ function REALMIN (X, Y : in REAL) return REAL;
+ -- Purpose:
+ -- Returns the algebraically smaller of X and Y
+ -- Special values:
+ -- REALMIN(X,Y) = X when X = Y
+ -- Domain:
+ -- X in REAL; Y in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- REALMIN(X,Y) is mathematically unbounded
+ -- Notes:
+ -- None
+
+ procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL);
+ -- Purpose:
+ -- Returns, in X, a pseudo-random number with uniform
+ -- distribution in the open interval (0.0, 1.0).
+ -- Special values:
+ -- None
+ -- Domain:
+ -- 1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398
+ -- Error conditions:
+ -- Error if SEED1 or SEED2 outside of valid domain
+ -- Range:
+ -- 0.0 < X < 1.0
+ -- Notes:
+ -- a) The semantics for this function are described by the
+ -- algorithm published by Pierre L'Ecuyer in "Communications
+ -- of the ACM," vol. 31, no. 6, June 1988, pp. 742-774.
+ -- The algorithm is based on the combination of two
+ -- multiplicative linear congruential generators for 32-bit
+ -- platforms.
+ --
+ -- b) Before the first call to UNIFORM, the seed values
+ -- (SEED1, SEED2) have to be initialized to values in the range
+ -- [1, 2147483562] and [1, 2147483398] respectively. The
+ -- seed values are modified after each call to UNIFORM.
+ --
+ -- c) This random number generator is portable for 32-bit
+ -- computers, and it has a period of ~2.30584*(10**18) for each
+ -- set of seed values.
+ --
+ -- d) For information on spectral tests for the algorithm, refer
+ -- to the L'Ecuyer article.
+
+ function SQRT (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns square root of X
+ -- Special values:
+ -- SQRT(0.0) = 0.0
+ -- SQRT(1.0) = 1.0
+ -- Domain:
+ -- X >= 0.0
+ -- Error conditions:
+ -- Error if X < 0.0
+ -- Range:
+ -- SQRT(X) >= 0.0
+ -- Notes:
+ -- a) The upper bound of the reachable range of SQRT is
+ -- approximately given by:
+ -- SQRT(X) <= SQRT(REAL'HIGH)
+
+ function CBRT (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns cube root of X
+ -- Special values:
+ -- CBRT(0.0) = 0.0
+ -- CBRT(1.0) = 1.0
+ -- CBRT(-1.0) = -1.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- CBRT(X) is mathematically unbounded
+ -- Notes:
+ -- a) The reachable range of CBRT is approximately given by:
+ -- ABS(CBRT(X)) <= CBRT(REAL'HIGH)
+
+ function "**" (X : in INTEGER; Y : in REAL) return REAL;
+ -- Purpose:
+ -- Returns Y power of X ==> X**Y
+ -- Special values:
+ -- X**0.0 = 1.0; X /= 0
+ -- 0**Y = 0.0; Y > 0.0
+ -- X**1.0 = REAL(X); X >= 0
+ -- 1**Y = 1.0
+ -- Domain:
+ -- X > 0
+ -- X = 0 for Y > 0.0
+ -- X < 0 for Y = 0.0
+ -- Error conditions:
+ -- Error if X < 0 and Y /= 0.0
+ -- Error if X = 0 and Y <= 0.0
+ -- Range:
+ -- X**Y >= 0.0
+ -- Notes:
+ -- a) The upper bound of the reachable range for "**" is
+ -- approximately given by:
+ -- X**Y <= REAL'HIGH
+
+ function "**" (X : in REAL; Y : in REAL) return REAL;
+ -- Purpose:
+ -- Returns Y power of X ==> X**Y
+ -- Special values:
+ -- X**0.0 = 1.0; X /= 0.0
+ -- 0.0**Y = 0.0; Y > 0.0
+ -- X**1.0 = X; X >= 0.0
+ -- 1.0**Y = 1.0
+ -- Domain:
+ -- X > 0.0
+ -- X = 0.0 for Y > 0.0
+ -- X < 0.0 for Y = 0.0
+ -- Error conditions:
+ -- Error if X < 0.0 and Y /= 0.0
+ -- Error if X = 0.0 and Y <= 0.0
+ -- Range:
+ -- X**Y >= 0.0
+ -- Notes:
+ -- a) The upper bound of the reachable range for "**" is
+ -- approximately given by:
+ -- X**Y <= REAL'HIGH
+
+ function EXP (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns e**X; where e = MATH_E
+ -- Special values:
+ -- EXP(0.0) = 1.0
+ -- EXP(1.0) = MATH_E
+ -- EXP(-1.0) = MATH_1_OVER_E
+ -- EXP(X) = 0.0 for X <= -LOG(REAL'HIGH)
+ -- Domain:
+ -- X in REAL such that EXP(X) <= REAL'HIGH
+ -- Error conditions:
+ -- Error if X > LOG(REAL'HIGH)
+ -- Range:
+ -- EXP(X) >= 0.0
+ -- Notes:
+ -- a) The usable domain of EXP is approximately given by:
+ -- X <= LOG(REAL'HIGH)
+
+ function LOG (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns natural logarithm of X
+ -- Special values:
+ -- LOG(1.0) = 0.0
+ -- LOG(MATH_E) = 1.0
+ -- Domain:
+ -- X > 0.0
+ -- Error conditions:
+ -- Error if X <= 0.0
+ -- Range:
+ -- LOG(X) is mathematically unbounded
+ -- Notes:
+ -- a) The reachable range of LOG is approximately given by:
+ -- LOG(0+) <= LOG(X) <= LOG(REAL'HIGH)
+
+ function LOG2 (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns logarithm base 2 of X
+ -- Special values:
+ -- LOG2(1.0) = 0.0
+ -- LOG2(2.0) = 1.0
+ -- Domain:
+ -- X > 0.0
+ -- Error conditions:
+ -- Error if X <= 0.0
+ -- Range:
+ -- LOG2(X) is mathematically unbounded
+ -- Notes:
+ -- a) The reachable range of LOG2 is approximately given by:
+ -- LOG2(0+) <= LOG2(X) <= LOG2(REAL'HIGH)
+
+ function LOG10 (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns logarithm base 10 of X
+ -- Special values:
+ -- LOG10(1.0) = 0.0
+ -- LOG10(10.0) = 1.0
+ -- Domain:
+ -- X > 0.0
+ -- Error conditions:
+ -- Error if X <= 0.0
+ -- Range:
+ -- LOG10(X) is mathematically unbounded
+ -- Notes:
+ -- a) The reachable range of LOG10 is approximately given by:
+ -- LOG10(0+) <= LOG10(X) <= LOG10(REAL'HIGH)
+
+ function LOG (X : in REAL; BASE : in REAL) return REAL;
+ -- Purpose:
+ -- Returns logarithm base BASE of X
+ -- Special values:
+ -- LOG(1.0, BASE) = 0.0
+ -- LOG(BASE, BASE) = 1.0
+ -- Domain:
+ -- X > 0.0
+ -- BASE > 0.0
+ -- BASE /= 1.0
+ -- Error conditions:
+ -- Error if X <= 0.0
+ -- Error if BASE <= 0.0
+ -- Error if BASE = 1.0
+ -- Range:
+ -- LOG(X, BASE) is mathematically unbounded
+ -- Notes:
+ -- a) When BASE > 1.0, the reachable range of LOG is
+ -- approximately given by:
+ -- LOG(0+, BASE) <= LOG(X, BASE) <= LOG(REAL'HIGH, BASE)
+ -- b) When 0.0 < BASE < 1.0, the reachable range of LOG is
+ -- approximately given by:
+ -- LOG(REAL'HIGH, BASE) <= LOG(X, BASE) <= LOG(0+, BASE)
+
+ function SIN (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns sine of X; X in radians
+ -- Special values:
+ -- SIN(X) = 0.0 for X = k*MATH_PI, where k is an INTEGER
+ -- SIN(X) = 1.0 for X = (4*k+1)*MATH_PI_OVER_2, where k is an
+ -- INTEGER
+ -- SIN(X) = -1.0 for X = (4*k+3)*MATH_PI_OVER_2, where k is an
+ -- INTEGER
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- ABS(SIN(X)) <= 1.0
+ -- Notes:
+ -- a) For larger values of ABS(X), degraded accuracy is allowed.
+
+ function COS (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns cosine of X; X in radians
+ -- Special values:
+ -- COS(X) = 0.0 for X = (2*k+1)*MATH_PI_OVER_2, where k is an
+ -- INTEGER
+ -- COS(X) = 1.0 for X = (2*k)*MATH_PI, where k is an INTEGER
+ -- COS(X) = -1.0 for X = (2*k+1)*MATH_PI, where k is an INTEGER
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- ABS(COS(X)) <= 1.0
+ -- Notes:
+ -- a) For larger values of ABS(X), degraded accuracy is allowed.
+
+ function TAN (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns tangent of X; X in radians
+ -- Special values:
+ -- TAN(X) = 0.0 for X = k*MATH_PI, where k is an INTEGER
+ -- Domain:
+ -- X in REAL and
+ -- X /= (2*k+1)*MATH_PI_OVER_2, where k is an INTEGER
+ -- Error conditions:
+ -- Error if X = ((2*k+1) * MATH_PI_OVER_2), where k is an
+ -- INTEGER
+ -- Range:
+ -- TAN(X) is mathematically unbounded
+ -- Notes:
+ -- a) For larger values of ABS(X), degraded accuracy is allowed.
+
+ function ARCSIN (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns inverse sine of X
+ -- Special values:
+ -- ARCSIN(0.0) = 0.0
+ -- ARCSIN(1.0) = MATH_PI_OVER_2
+ -- ARCSIN(-1.0) = -MATH_PI_OVER_2
+ -- Domain:
+ -- ABS(X) <= 1.0
+ -- Error conditions:
+ -- Error if ABS(X) > 1.0
+ -- Range:
+ -- ABS(ARCSIN(X) <= MATH_PI_OVER_2
+ -- Notes:
+ -- None
+
+ function ARCCOS (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns inverse cosine of X
+ -- Special values:
+ -- ARCCOS(1.0) = 0.0
+ -- ARCCOS(0.0) = MATH_PI_OVER_2
+ -- ARCCOS(-1.0) = MATH_PI
+ -- Domain:
+ -- ABS(X) <= 1.0
+ -- Error conditions:
+ -- Error if ABS(X) > 1.0
+ -- Range:
+ -- 0.0 <= ARCCOS(X) <= MATH_PI
+ -- Notes:
+ -- None
+
+ function ARCTAN (Y : in REAL) return REAL;
+ -- Purpose:
+ -- Returns the value of the angle in radians of the point
+ -- (1.0, Y), which is in rectangular coordinates
+ -- Special values:
+ -- ARCTAN(0.0) = 0.0
+ -- Domain:
+ -- Y in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- ABS(ARCTAN(Y)) <= MATH_PI_OVER_2
+ -- Notes:
+ -- None
+
+ function ARCTAN (Y : in REAL; X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns the principal value of the angle in radians of
+ -- the point (X, Y), which is in rectangular coordinates
+ -- Special values:
+ -- ARCTAN(0.0, X) = 0.0 if X > 0.0
+ -- ARCTAN(0.0, X) = MATH_PI if X < 0.0
+ -- ARCTAN(Y, 0.0) = MATH_PI_OVER_2 if Y > 0.0
+ -- ARCTAN(Y, 0.0) = -MATH_PI_OVER_2 if Y < 0.0
+ -- Domain:
+ -- Y in REAL
+ -- X in REAL, X /= 0.0 when Y = 0.0
+ -- Error conditions:
+ -- Error if X = 0.0 and Y = 0.0
+ -- Range:
+ -- -MATH_PI < ARCTAN(Y,X) <= MATH_PI
+ -- Notes:
+ -- None
+
+ function SINH (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns hyperbolic sine of X
+ -- Special values:
+ -- SINH(0.0) = 0.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- SINH(X) is mathematically unbounded
+ -- Notes:
+ -- a) The usable domain of SINH is approximately given by:
+ -- ABS(X) <= LOG(REAL'HIGH)
+
+
+ function COSH (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns hyperbolic cosine of X
+ -- Special values:
+ -- COSH(0.0) = 1.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- COSH(X) >= 1.0
+ -- Notes:
+ -- a) The usable domain of COSH is approximately given by:
+ -- ABS(X) <= LOG(REAL'HIGH)
+
+ function TANH (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns hyperbolic tangent of X
+ -- Special values:
+ -- TANH(0.0) = 0.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- ABS(TANH(X)) <= 1.0
+ -- Notes:
+ -- None
+
+ function ARCSINH (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns inverse hyperbolic sine of X
+ -- Special values:
+ -- ARCSINH(0.0) = 0.0
+ -- Domain:
+ -- X in REAL
+ -- Error conditions:
+ -- None
+ -- Range:
+ -- ARCSINH(X) is mathematically unbounded
+ -- Notes:
+ -- a) The reachable range of ARCSINH is approximately given by:
+ -- ABS(ARCSINH(X)) <= LOG(REAL'HIGH)
+
+ function ARCCOSH (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns inverse hyperbolic cosine of X
+ -- Special values:
+ -- ARCCOSH(1.0) = 0.0
+ -- Domain:
+ -- X >= 1.0
+ -- Error conditions:
+ -- Error if X < 1.0
+ -- Range:
+ -- ARCCOSH(X) >= 0.0
+ -- Notes:
+ -- a) The upper bound of the reachable range of ARCCOSH is
+ -- approximately given by: ARCCOSH(X) <= LOG(REAL'HIGH)
+
+ function ARCTANH (X : in REAL) return REAL;
+ -- Purpose:
+ -- Returns inverse hyperbolic tangent of X
+ -- Special values:
+ -- ARCTANH(0.0) = 0.0
+ -- Domain:
+ -- ABS(X) < 1.0
+ -- Error conditions:
+ -- Error if ABS(X) >= 1.0
+ -- Range:
+ -- ARCTANH(X) is mathematically unbounded
+ -- Notes:
+ -- a) The reachable range of ARCTANH is approximately given by:
+ -- ABS(ARCTANH(X)) < LOG(REAL'HIGH)
+
+end package MATH_REAL;
+
+package body MATH_REAL is
+
+ --
+ -- Local Constants for Use in the Package Body Only
+ --
+ constant MATH_E_P2 : REAL := 7.38905_60989_30650; -- e**2
+ constant MATH_E_P10 : REAL := 22026.46579_48067_17; -- e**10
+ constant MATH_EIGHT_PI : REAL := 25.13274_12287_18345_90770_115; --8*pi
+ constant MAX_ITER: INTEGER := 27; -- Maximum precision factor for cordic
+ constant MAX_COUNT: INTEGER := 150; -- Maximum count for number of tries
+ constant BASE_EPS: REAL := 0.00001; -- Factor for convergence criteria
+ constant KC : REAL := 6.0725293500888142e-01; -- Constant for cordic
+
+ --
+ -- Local Type Declarations for Cordic Operations
+ --
+ type REAL_VECTOR is array (NATURAL range <>) of REAL;
+ type NATURAL_VECTOR is array (NATURAL range <>) of NATURAL;
+ subtype REAL_VECTOR_N is REAL_VECTOR (0 to MAX_ITER);
+ subtype REAL_ARR_2 is REAL_VECTOR (0 to 1);
+ subtype REAL_ARR_3 is REAL_VECTOR (0 to 2);
+ subtype QUADRANT is INTEGER range 0 to 3;
+ type CORDIC_MODE_TYPE is (ROTATION, VECTORING);
+
+ --
+ -- Auxiliary Functions for Cordic Algorithms
+ --
+ function POWER_OF_2_SERIES (D : in NATURAL_VECTOR; INITIAL_VALUE : in REAL;
+ NUMBER_OF_VALUES : in NATURAL) return REAL_VECTOR is
+ -- Description:
+ -- Returns power of two for a vector of values
+ -- Notes:
+ -- None
+ --
+ variable V : REAL_VECTOR (0 to NUMBER_OF_VALUES);
+ variable TEMP : REAL := INITIAL_VALUE;
+ variable FLAG : BOOLEAN := TRUE;
+ begin
+ for I in 0 to NUMBER_OF_VALUES loop
+ V(I) := TEMP;
+ for P in D'RANGE loop
+ if I = D(P) then
+ FLAG := FALSE;
+ exit;
+ end if;
+ end loop;
+ if FLAG then
+ TEMP := TEMP/2.0;
+ end if;
+ FLAG := TRUE;
+ end loop;
+ return V;
+ end function POWER_OF_2_SERIES;
+
+
+ constant TWO_AT_MINUS : REAL_VECTOR := POWER_OF_2_SERIES(
+ NATURAL_VECTOR'(100, 90),1.0,
+ MAX_ITER);
+
+ constant EPSILON : REAL_VECTOR_N := (
+ 7.8539816339744827e-01,
+ 4.6364760900080606e-01,
+ 2.4497866312686413e-01,
+ 1.2435499454676144e-01,
+ 6.2418809995957351e-02,
+ 3.1239833430268277e-02,
+ 1.5623728620476830e-02,
+ 7.8123410601011116e-03,
+ 3.9062301319669717e-03,
+ 1.9531225164788189e-03,
+ 9.7656218955931937e-04,
+ 4.8828121119489829e-04,
+ 2.4414062014936175e-04,
+ 1.2207031189367021e-04,
+ 6.1035156174208768e-05,
+ 3.0517578115526093e-05,
+ 1.5258789061315760e-05,
+ 7.6293945311019699e-06,
+ 3.8146972656064960e-06,
+ 1.9073486328101870e-06,
+ 9.5367431640596080e-07,
+ 4.7683715820308876e-07,
+ 2.3841857910155801e-07,
+ 1.1920928955078067e-07,
+ 5.9604644775390553e-08,
+ 2.9802322387695303e-08,
+ 1.4901161193847654e-08,
+ 7.4505805969238281e-09
+ );
+
+ function CORDIC ( X0 : in REAL;
+ Y0 : in REAL;
+ Z0 : in REAL;
+ N : in NATURAL; -- Precision factor
+ CORDIC_MODE : in CORDIC_MODE_TYPE -- Rotation (Z -> 0)
+ -- or vectoring (Y -> 0)
+ ) return REAL_ARR_3 is
+ -- Description:
+ -- Compute cordic values
+ -- Notes:
+ -- None
+ variable X : REAL := X0;
+ variable Y : REAL := Y0;
+ variable Z : REAL := Z0;
+ variable X_TEMP : REAL;
+ begin
+ if CORDIC_MODE = ROTATION then
+ for K in 0 to N loop
+ X_TEMP := X;
+ if ( Z >= 0.0) then
+ X := X - Y * TWO_AT_MINUS(K);
+ Y := Y + X_TEMP * TWO_AT_MINUS(K);
+ Z := Z - EPSILON(K);
+ else
+ X := X + Y * TWO_AT_MINUS(K);
+ Y := Y - X_TEMP * TWO_AT_MINUS(K);
+ Z := Z + EPSILON(K);
+ end if;
+ end loop;
+ else
+ for K in 0 to N loop
+ X_TEMP := X;
+ if ( Y < 0.0) then
+ X := X - Y * TWO_AT_MINUS(K);
+ Y := Y + X_TEMP * TWO_AT_MINUS(K);
+ Z := Z - EPSILON(K);
+ else
+ X := X + Y * TWO_AT_MINUS(K);
+ Y := Y - X_TEMP * TWO_AT_MINUS(K);
+ Z := Z + EPSILON(K);
+ end if;
+ end loop;
+ end if;
+ return REAL_ARR_3'(X, Y, Z);
+ end function CORDIC;
+
+ --
+ -- Bodies for Global Mathematical Functions Start Here
+ --
+ function SIGN (X: in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- None
+ begin
+ if ( X > 0.0 ) then
+ return 1.0;
+ elsif ( X < 0.0 ) then
+ return -1.0;
+ else
+ return 0.0;
+ end if;
+ end function SIGN;
+
+ function CEIL (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) No conversion to an INTEGER type is expected, so truncate
+ -- cannot overflow for large arguments
+ -- b) The domain supported by this function is X <= LARGE
+ -- c) Returns X if ABS(X) >= LARGE
+
+ constant LARGE: REAL := REAL(INTEGER'HIGH);
+ variable RD: REAL;
+
+ begin
+ if ABS(X) >= LARGE then
+ return X;
+ end if;
+
+ RD := REAL ( INTEGER(X));
+ if RD = X then
+ return X;
+ end if;
+
+ if X > 0.0 then
+ if RD >= X then
+ return RD;
+ else
+ return RD + 1.0;
+ end if;
+ elsif X = 0.0 then
+ return 0.0;
+ else
+ if RD <= X then
+ return RD + 1.0;
+ else
+ return RD;
+ end if;
+ end if;
+ end function CEIL;
+
+ function FLOOR (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) No conversion to an INTEGER type is expected, so truncate
+ -- cannot overflow for large arguments
+ -- b) The domain supported by this function is ABS(X) <= LARGE
+ -- c) Returns X if ABS(X) >= LARGE
+
+ constant LARGE: REAL := REAL(INTEGER'HIGH);
+ variable RD: REAL;
+
+ begin
+ if ABS( X ) >= LARGE then
+ return X;
+ end if;
+
+ RD := REAL ( INTEGER(X));
+ if RD = X then
+ return X;
+ end if;
+
+ if X > 0.0 then
+ if RD <= X then
+ return RD;
+ else
+ return RD - 1.0;
+ end if;
+ elsif X = 0.0 then
+ return 0.0;
+ else
+ if RD >= X then
+ return RD - 1.0;
+ else
+ return RD;
+ end if;
+ end if;
+ end function FLOOR;
+
+ function ROUND (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns 0.0 if X = 0.0
+ -- b) Returns FLOOR(X + 0.5) if X > 0
+ -- c) Returns CEIL(X - 0.5) if X < 0
+
+ begin
+ if X > 0.0 then
+ return FLOOR(X + 0.5);
+ elsif X < 0.0 then
+ return CEIL( X - 0.5);
+ else
+ return 0.0;
+ end if;
+ end function ROUND;
+
+ function TRUNC (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns 0.0 if X = 0.0
+ -- b) Returns FLOOR(X) if X > 0
+ -- c) Returns CEIL(X) if X < 0
+
+ begin
+ if X > 0.0 then
+ return FLOOR(X);
+ elsif X < 0.0 then
+ return CEIL( X);
+ else
+ return 0.0;
+ end if;
+ end function TRUNC;
+
+
+
+
+ function "MOD" (X, Y: in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns 0.0 on error
+
+ variable XNEGATIVE : BOOLEAN := X < 0.0;
+ variable YNEGATIVE : BOOLEAN := Y < 0.0;
+ variable VALUE : REAL;
+ begin
+ -- Check validity of input arguments
+ if (Y = 0.0) then
+ assert FALSE
+ report "MOD(X, 0.0) is undefined"
+ severity ERROR;
+ return 0.0;
+ end if;
+
+ -- Compute value
+ if ( XNEGATIVE ) then
+ if ( YNEGATIVE ) then
+ VALUE := X + (FLOOR(ABS(X)/ABS(Y)))*ABS(Y);
+ else
+ VALUE := X + (CEIL(ABS(X)/ABS(Y)))*ABS(Y);
+ end if;
+ else
+ if ( YNEGATIVE ) then
+ VALUE := X - (CEIL(ABS(X)/ABS(Y)))*ABS(Y);
+ else
+ VALUE := X - (FLOOR(ABS(X)/ABS(Y)))*ABS(Y);
+ end if;
+ end if;
+
+ return VALUE;
+ end function "MOD";
+
+
+ function REALMAX (X, Y : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) REALMAX(X,Y) = X when X = Y
+ --
+ begin
+ if X >= Y then
+ return X;
+ else
+ return Y;
+ end if;
+ end function REALMAX;
+
+ function REALMIN (X, Y : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) REALMIN(X,Y) = X when X = Y
+ --
+ begin
+ if X <= Y then
+ return X;
+ else
+ return Y;
+ end if;
+ end function REALMIN;
+
+
+ procedure UNIFORM(variable SEED1,SEED2:inout POSITIVE;variable X:out REAL)
+ is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns 0.0 on error
+ --
+ variable Z, K: INTEGER;
+ variable TSEED1 : INTEGER := INTEGER'(SEED1);
+ variable TSEED2 : INTEGER := INTEGER'(SEED2);
+ begin
+ -- Check validity of arguments
+ if SEED1 > 2147483562 then
+ assert FALSE
+ report "SEED1 > 2147483562 in UNIFORM"
+ severity ERROR;
+ X := 0.0;
+ return;
+ end if;
+
+ if SEED2 > 2147483398 then
+ assert FALSE
+ report "SEED2 > 2147483398 in UNIFORM"
+ severity ERROR;
+ X := 0.0;
+ return;
+ end if;
+
+ -- Compute new seed values and pseudo-random number
+ K := TSEED1/53668;
+ TSEED1 := 40014 * (TSEED1 - K * 53668) - K * 12211;
+
+ if TSEED1 < 0 then
+ TSEED1 := TSEED1 + 2147483563;
+ end if;
+
+ K := TSEED2/52774;
+ TSEED2 := 40692 * (TSEED2 - K * 52774) - K * 3791;
+
+ if TSEED2 < 0 then
+ TSEED2 := TSEED2 + 2147483399;
+ end if;
+
+ Z := TSEED1 - TSEED2;
+ if Z < 1 then
+ Z := Z + 2147483562;
+ end if;
+
+ -- Get output values
+ SEED1 := POSITIVE'(TSEED1);
+ SEED2 := POSITIVE'(TSEED2);
+ X := REAL(Z)*4.656613e-10;
+ end procedure UNIFORM;
+
+
+
+ function SQRT (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Uses the Newton-Raphson approximation:
+ -- F(n+1) = 0.5*[F(n) + x/F(n)]
+ -- b) Returns 0.0 on error
+ --
+
+ constant EPS : REAL := BASE_EPS*BASE_EPS; -- Convergence factor
+
+ variable INIVAL: REAL;
+ variable OLDVAL : REAL ;
+ variable NEWVAL : REAL ;
+ variable COUNT : INTEGER := 1;
+
+ begin
+ -- Check validity of argument
+ if ( X < 0.0 ) then
+ assert FALSE
+ report "X < 0.0 in SQRT(X)"
+ severity ERROR;
+ return 0.0;
+ end if;
+
+ -- Get the square root for special cases
+ if X = 0.0 then
+ return 0.0;
+ else
+ if ( X = 1.0 ) then
+ return 1.0;
+ end if;
+ end if;
+
+ -- Get the square root for general cases
+ INIVAL := EXP(LOG(X)*(0.5)); -- Mathematically correct but imprecise
+ OLDVAL := INIVAL;
+ NEWVAL := (X/OLDVAL + OLDVAL)*0.5;
+
+ -- Check for relative and absolute error and max count
+ while ( ( (ABS((NEWVAL -OLDVAL)/NEWVAL) > EPS) OR
+ (ABS(NEWVAL - OLDVAL) > EPS) ) AND
+ (COUNT < MAX_COUNT) ) loop
+ OLDVAL := NEWVAL;
+ NEWVAL := (X/OLDVAL + OLDVAL)*0.5;
+ COUNT := COUNT + 1;
+ end loop;
+ return NEWVAL;
+ end function SQRT;
+
+ function CBRT (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Uses the Newton-Raphson approximation:
+ -- F(n+1) = (1/3)*[2*F(n) + x/F(n)**2];
+ --
+ constant EPS : REAL := BASE_EPS*BASE_EPS;
+
+ variable INIVAL: REAL;
+ variable XLOCAL : REAL := X;
+ variable NEGATIVE : BOOLEAN := X < 0.0;
+ variable OLDVAL : REAL ;
+ variable NEWVAL : REAL ;
+ variable COUNT : INTEGER := 1;
+
+ begin
+
+ -- Compute root for special cases
+ if X = 0.0 then
+ return 0.0;
+ elsif ( X = 1.0 ) then
+ return 1.0;
+ else
+ if X = -1.0 then
+ return -1.0;
+ end if;
+ end if;
+
+ -- Compute root for general cases
+ if NEGATIVE then
+ XLOCAL := -X;
+ end if;
+
+ INIVAL := EXP(LOG(XLOCAL)/(3.0)); -- Mathematically correct but
+ -- imprecise
+ OLDVAL := INIVAL;
+ NEWVAL := (XLOCAL/(OLDVAL*OLDVAL) + 2.0*OLDVAL)/3.0;
+
+ -- Check for relative and absolute errors and max count
+ while ( ( (ABS((NEWVAL -OLDVAL)/NEWVAL) > EPS ) OR
+ (ABS(NEWVAL - OLDVAL) > EPS ) ) AND
+ ( COUNT < MAX_COUNT ) ) loop
+ OLDVAL := NEWVAL;
+ NEWVAL :=(XLOCAL/(OLDVAL*OLDVAL) + 2.0*OLDVAL)/3.0;
+ COUNT := COUNT + 1;
+ end loop;
+
+ if NEGATIVE then
+ NEWVAL := -NEWVAL;
+ end if;
+
+ return NEWVAL;
+ end function CBRT;
+
+ function "**" (X : in INTEGER; Y : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns 0.0 on error condition
+
+ begin
+ -- Check validity of argument
+ if ( ( X < 0 ) and ( Y /= 0.0 ) ) then
+ assert FALSE
+ report "X < 0 and Y /= 0.0 in X**Y"
+ severity ERROR;
+ return 0.0;
+ end if;
+
+ if ( ( X = 0 ) and ( Y <= 0.0 ) ) then
+ assert FALSE
+ report "X = 0 and Y <= 0.0 in X**Y"
+ severity ERROR;
+ return 0.0;
+ end if;
+
+ -- Get value for special cases
+ if ( X = 0 and Y > 0.0 ) then
+ return 0.0;
+ end if;
+
+ if ( X = 1 ) then
+ return 1.0;
+ end if;
+
+ if ( Y = 0.0 and X /= 0 ) then
+ return 1.0;
+ end if;
+
+ if ( Y = 1.0) then
+ return (REAL(X));
+ end if;
+
+ -- Get value for general case
+ return EXP (Y * LOG (REAL(X)));
+ end function "**";
+
+ function "**" (X : in REAL; Y : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns 0.0 on error condition
+
+ begin
+ -- Check validity of argument
+ if ( ( X < 0.0 ) and ( Y /= 0.0 ) ) then
+ assert FALSE
+ report "X < 0.0 and Y /= 0.0 in X**Y"
+ severity ERROR;
+ return 0.0;
+ end if;
+
+ if ( ( X = 0.0 ) and ( Y <= 0.0 ) ) then
+ assert FALSE
+ report "X = 0.0 and Y <= 0.0 in X**Y"
+ severity ERROR;
+ return 0.0;
+ end if;
+
+ -- Get value for special cases
+ if ( X = 0.0 and Y > 0.0 ) then
+ return 0.0;
+ end if;
+
+ if ( X = 1.0 ) then
+ return 1.0;
+ end if;
+
+ if ( Y = 0.0 and X /= 0.0 ) then
+ return 1.0;
+ end if;
+
+ if ( Y = 1.0) then
+ return (X);
+ end if;
+
+ -- Get value for general case
+ return EXP (Y * LOG (X));
+ end function "**";
+
+ function EXP (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) This function computes the exponential using the following
+ -- series:
+ -- exp(x) = 1 + x + x**2/2! + x**3/3! + ... ; |x| < 1.0
+ -- and reduces argument X to take advantage of exp(x+y) =
+ -- exp(x)*exp(y)
+ --
+ -- b) This implementation limits X to be less than LOG(REAL'HIGH)
+ -- to avoid overflow. Returns REAL'HIGH when X reaches that
+ -- limit
+ --
+ constant EPS : REAL := BASE_EPS*BASE_EPS*BASE_EPS;-- Precision criteria
+
+ variable RECIPROCAL: BOOLEAN := X < 0.0;-- Check sign of argument
+ variable XLOCAL : REAL := ABS(X); -- Use positive value
+ variable OLDVAL: REAL ;
+ variable COUNT: INTEGER ;
+ variable NEWVAL: REAL ;
+ variable LAST_TERM: REAL ;
+ variable FACTOR : REAL := 1.0;
+
+ begin
+ -- Compute value for special cases
+ if X = 0.0 then
+ return 1.0;
+ end if;
+
+ if XLOCAL = 1.0 then
+ if RECIPROCAL then
+ return MATH_1_OVER_E;
+ else
+ return MATH_E;
+ end if;
+ end if;
+
+ if XLOCAL = 2.0 then
+ if RECIPROCAL then
+ return 1.0/MATH_E_P2;
+ else
+ return MATH_E_P2;
+ end if;
+ end if;
+
+ if XLOCAL = 10.0 then
+ if RECIPROCAL then
+ return 1.0/MATH_E_P10;
+ else
+ return MATH_E_P10;
+ end if;
+ end if;
+
+ if XLOCAL > LOG(REAL'HIGH) then
+ if RECIPROCAL then
+ return 0.0;
+ else
+ assert FALSE
+ report "X > LOG(REAL'HIGH) in EXP(X)"
+ severity NOTE;
+ return REAL'HIGH;
+ end if;
+ end if;
+
+ -- Reduce argument to ABS(X) < 1.0
+ while XLOCAL > 10.0 loop
+ XLOCAL := XLOCAL - 10.0;
+ FACTOR := FACTOR*MATH_E_P10;
+ end loop;
+
+ while XLOCAL > 1.0 loop
+ XLOCAL := XLOCAL - 1.0;
+ FACTOR := FACTOR*MATH_E;
+ end loop;
+
+ -- Compute value for case 0 < XLOCAL < 1
+ OLDVAL := 1.0;
+ LAST_TERM := XLOCAL;
+ NEWVAL:= OLDVAL + LAST_TERM;
+ COUNT := 2;
+
+ -- Check for relative and absolute errors and max count
+ while ( ( (ABS((NEWVAL - OLDVAL)/NEWVAL) > EPS) OR
+ (ABS(NEWVAL - OLDVAL) > EPS) ) AND
+ (COUNT < MAX_COUNT ) ) loop
+ OLDVAL := NEWVAL;
+ LAST_TERM := LAST_TERM*(XLOCAL / (REAL(COUNT)));
+ NEWVAL := OLDVAL + LAST_TERM;
+ COUNT := COUNT + 1;
+ end loop;
+
+ -- Compute final value using exp(x+y) = exp(x)*exp(y)
+ NEWVAL := NEWVAL*FACTOR;
+
+ if RECIPROCAL then
+ NEWVAL := 1.0/NEWVAL;
+ end if;
+
+ return NEWVAL;
+ end function EXP;
+
+
+ --
+ -- Auxiliary Functions to Compute LOG
+ --
+ function ILOGB(X: in REAL) return INTEGER IS
+ -- Description:
+ -- Returns n such that -1 <= ABS(X)/2^n < 2
+ -- Notes:
+ -- None
+
+ variable N: INTEGER := 0;
+ variable Y: REAL := ABS(X);
+
+ begin
+ if(Y = 1.0 or Y = 0.0) then
+ return 0;
+ end if;
+
+ if( Y > 1.0) then
+ while Y >= 2.0 loop
+ Y := Y/2.0;
+ N := N+1;
+ end loop;
+ return N;
+ end if;
+
+ -- O < Y < 1
+ while Y < 1.0 loop
+ Y := Y*2.0;
+ N := N -1;
+ end loop;
+ return N;
+ end function ILOGB;
+
+ function LDEXP(X: in REAL; N: in INTEGER) RETURN REAL IS
+ -- Description:
+ -- Returns X*2^n
+ -- Notes:
+ -- None
+ begin
+ return X*(2.0 ** N);
+ end function LDEXP;
+
+ function LOG (X : in REAL ) return REAL IS
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ --
+ -- Notes:
+ -- a) Returns REAL'LOW on error
+ --
+ -- Copyright (c) 1992 Regents of the University of California.
+ -- All rights reserved.
+ --
+ -- Redistribution and use in source and binary forms, with or without
+ -- modification, are permitted provided that the following conditions
+ -- are met:
+ -- 1. Redistributions of source code must retain the above copyright
+ -- notice, this list of conditions and the following disclaimer.
+ -- 2. Redistributions in binary form must reproduce the above copyright
+ -- notice, this list of conditions and the following disclaimer in the
+ -- documentation and/or other materials provided with the distribution.
+ -- 3. All advertising materials mentioning features or use of this
+ -- software must display the following acknowledgement:
+ -- This product includes software developed by the University of
+ -- California, Berkeley and its contributors.
+ -- 4. Neither the name of the University nor the names of its
+ -- contributors may be used to endorse or promote products derived
+ -- from this software without specific prior written permission.
+ --
+ -- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
+ -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ -- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ -- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ -- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ -- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ -- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ -- USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ -- DAMAGE.
+ --
+ -- NOTE: This VHDL version was generated using the C version of the
+ -- original function by the IEEE VHDL Mathematical Package
+ -- Working Group (CS/JT)
+
+ constant N: INTEGER := 128;
+
+ -- Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
+ -- Used for generation of extend precision logarithms.
+ -- The constant 35184372088832 is 2^45, so the divide is exact.
+ -- It ensures correct reading of logF_head, even for inaccurate
+ -- decimal-to-binary conversion routines. (Everybody gets the
+ -- right answer for INTEGERs less than 2^53.)
+ -- Values for LOG(F) were generated using error < 10^-57 absolute
+ -- with the bc -l package.
+
+ type REAL_VECTOR is array (NATURAL range <>) of REAL;
+
+ constant A1:REAL := 0.08333333333333178827;
+ constant A2:REAL := 0.01250000000377174923;
+ constant A3:REAL := 0.002232139987919447809;
+ constant A4:REAL := 0.0004348877777076145742;
+
+ constant LOGF_HEAD: REAL_VECTOR(0 TO N) := (
+ 0.0,
+ 0.007782140442060381246,
+ 0.015504186535963526694,
+ 0.023167059281547608406,
+ 0.030771658666765233647,
+ 0.038318864302141264488,
+ 0.045809536031242714670,
+ 0.053244514518837604555,
+ 0.060624621816486978786,
+ 0.067950661908525944454,
+ 0.075223421237524235039,
+ 0.082443669210988446138,
+ 0.089612158689760690322,
+ 0.096729626458454731618,
+ 0.103796793681567578460,
+ 0.110814366340264314203,
+ 0.117783035656430001836,
+ 0.124703478501032805070,
+ 0.131576357788617315236,
+ 0.138402322859292326029,
+ 0.145182009844575077295,
+ 0.151916042025732167530,
+ 0.158605030176659056451,
+ 0.165249572895390883786,
+ 0.171850256926518341060,
+ 0.178407657472689606947,
+ 0.184922338493834104156,
+ 0.191394852999565046047,
+ 0.197825743329758552135,
+ 0.204215541428766300668,
+ 0.210564769107350002741,
+ 0.216873938300523150246,
+ 0.223143551314024080056,
+ 0.229374101064877322642,
+ 0.235566071312860003672,
+ 0.241719936886966024758,
+ 0.247836163904594286577,
+ 0.253915209980732470285,
+ 0.259957524436686071567,
+ 0.265963548496984003577,
+ 0.271933715484010463114,
+ 0.277868451003087102435,
+ 0.283768173130738432519,
+ 0.289633292582948342896,
+ 0.295464212893421063199,
+ 0.301261330578199704177,
+ 0.307025035294827830512,
+ 0.312755710004239517729,
+ 0.318453731118097493890,
+ 0.324119468654316733591,
+ 0.329753286372579168528,
+ 0.335355541920762334484,
+ 0.340926586970454081892,
+ 0.346466767346100823488,
+ 0.351976423156884266063,
+ 0.357455888922231679316,
+ 0.362905493689140712376,
+ 0.368325561158599157352,
+ 0.373716409793814818840,
+ 0.379078352934811846353,
+ 0.384411698910298582632,
+ 0.389716751140440464951,
+ 0.394993808240542421117,
+ 0.400243164127459749579,
+ 0.405465108107819105498,
+ 0.410659924985338875558,
+ 0.415827895143593195825,
+ 0.420969294644237379543,
+ 0.426084395310681429691,
+ 0.431173464818130014464,
+ 0.436236766774527495726,
+ 0.441274560805140936281,
+ 0.446287102628048160113,
+ 0.451274644139630254358,
+ 0.456237433481874177232,
+ 0.461175715122408291790,
+ 0.466089729924533457960,
+ 0.470979715219073113985,
+ 0.475845904869856894947,
+ 0.480688529345570714212,
+ 0.485507815781602403149,
+ 0.490303988045525329653,
+ 0.495077266798034543171,
+ 0.499827869556611403822,
+ 0.504556010751912253908,
+ 0.509261901790523552335,
+ 0.513945751101346104405,
+ 0.518607764208354637958,
+ 0.523248143765158602036,
+ 0.527867089620485785417,
+ 0.532464798869114019908,
+ 0.537041465897345915436,
+ 0.541597282432121573947,
+ 0.546132437597407260909,
+ 0.550647117952394182793,
+ 0.555141507540611200965,
+ 0.559615787935399566777,
+ 0.564070138285387656651,
+ 0.568504735352689749561,
+ 0.572919753562018740922,
+ 0.577315365035246941260,
+ 0.581691739635061821900,
+ 0.586049045003164792433,
+ 0.590387446602107957005,
+ 0.594707107746216934174,
+ 0.599008189645246602594,
+ 0.603290851438941899687,
+ 0.607555250224322662688,
+ 0.611801541106615331955,
+ 0.616029877215623855590,
+ 0.620240409751204424537,
+ 0.624433288012369303032,
+ 0.628608659422752680256,
+ 0.632766669570628437213,
+ 0.636907462236194987781,
+ 0.641031179420679109171,
+ 0.645137961373620782978,
+ 0.649227946625615004450,
+ 0.653301272011958644725,
+ 0.657358072709030238911,
+ 0.661398482245203922502,
+ 0.665422632544505177065,
+ 0.669430653942981734871,
+ 0.673422675212350441142,
+ 0.677398823590920073911,
+ 0.681359224807238206267,
+ 0.685304003098281100392,
+ 0.689233281238557538017,
+ 0.693147180560117703862);
+
+ constant LOGF_TAIL: REAL_VECTOR(0 TO N) := (
+ 0.0,
+ -0.00000000000000543229938420049,
+ 0.00000000000000172745674997061,
+ -0.00000000000001323017818229233,
+ -0.00000000000001154527628289872,
+ -0.00000000000000466529469958300,
+ 0.00000000000005148849572685810,
+ -0.00000000000002532168943117445,
+ -0.00000000000005213620639136504,
+ -0.00000000000001819506003016881,
+ 0.00000000000006329065958724544,
+ 0.00000000000008614512936087814,
+ -0.00000000000007355770219435028,
+ 0.00000000000009638067658552277,
+ 0.00000000000007598636597194141,
+ 0.00000000000002579999128306990,
+ -0.00000000000004654729747598444,
+ -0.00000000000007556920687451336,
+ 0.00000000000010195735223708472,
+ -0.00000000000017319034406422306,
+ -0.00000000000007718001336828098,
+ 0.00000000000010980754099855238,
+ -0.00000000000002047235780046195,
+ -0.00000000000008372091099235912,
+ 0.00000000000014088127937111135,
+ 0.00000000000012869017157588257,
+ 0.00000000000017788850778198106,
+ 0.00000000000006440856150696891,
+ 0.00000000000016132822667240822,
+ -0.00000000000007540916511956188,
+ -0.00000000000000036507188831790,
+ 0.00000000000009120937249914984,
+ 0.00000000000018567570959796010,
+ -0.00000000000003149265065191483,
+ -0.00000000000009309459495196889,
+ 0.00000000000017914338601329117,
+ -0.00000000000001302979717330866,
+ 0.00000000000023097385217586939,
+ 0.00000000000023999540484211737,
+ 0.00000000000015393776174455408,
+ -0.00000000000036870428315837678,
+ 0.00000000000036920375082080089,
+ -0.00000000000009383417223663699,
+ 0.00000000000009433398189512690,
+ 0.00000000000041481318704258568,
+ -0.00000000000003792316480209314,
+ 0.00000000000008403156304792424,
+ -0.00000000000034262934348285429,
+ 0.00000000000043712191957429145,
+ -0.00000000000010475750058776541,
+ -0.00000000000011118671389559323,
+ 0.00000000000037549577257259853,
+ 0.00000000000013912841212197565,
+ 0.00000000000010775743037572640,
+ 0.00000000000029391859187648000,
+ -0.00000000000042790509060060774,
+ 0.00000000000022774076114039555,
+ 0.00000000000010849569622967912,
+ -0.00000000000023073801945705758,
+ 0.00000000000015761203773969435,
+ 0.00000000000003345710269544082,
+ -0.00000000000041525158063436123,
+ 0.00000000000032655698896907146,
+ -0.00000000000044704265010452446,
+ 0.00000000000034527647952039772,
+ -0.00000000000007048962392109746,
+ 0.00000000000011776978751369214,
+ -0.00000000000010774341461609578,
+ 0.00000000000021863343293215910,
+ 0.00000000000024132639491333131,
+ 0.00000000000039057462209830700,
+ -0.00000000000026570679203560751,
+ 0.00000000000037135141919592021,
+ -0.00000000000017166921336082431,
+ -0.00000000000028658285157914353,
+ -0.00000000000023812542263446809,
+ 0.00000000000006576659768580062,
+ -0.00000000000028210143846181267,
+ 0.00000000000010701931762114254,
+ 0.00000000000018119346366441110,
+ 0.00000000000009840465278232627,
+ -0.00000000000033149150282752542,
+ -0.00000000000018302857356041668,
+ -0.00000000000016207400156744949,
+ 0.00000000000048303314949553201,
+ -0.00000000000071560553172382115,
+ 0.00000000000088821239518571855,
+ -0.00000000000030900580513238244,
+ -0.00000000000061076551972851496,
+ 0.00000000000035659969663347830,
+ 0.00000000000035782396591276383,
+ -0.00000000000046226087001544578,
+ 0.00000000000062279762917225156,
+ 0.00000000000072838947272065741,
+ 0.00000000000026809646615211673,
+ -0.00000000000010960825046059278,
+ 0.00000000000002311949383800537,
+ -0.00000000000058469058005299247,
+ -0.00000000000002103748251144494,
+ -0.00000000000023323182945587408,
+ -0.00000000000042333694288141916,
+ -0.00000000000043933937969737844,
+ 0.00000000000041341647073835565,
+ 0.00000000000006841763641591466,
+ 0.00000000000047585534004430641,
+ 0.00000000000083679678674757695,
+ -0.00000000000085763734646658640,
+ 0.00000000000021913281229340092,
+ -0.00000000000062242842536431148,
+ -0.00000000000010983594325438430,
+ 0.00000000000065310431377633651,
+ -0.00000000000047580199021710769,
+ -0.00000000000037854251265457040,
+ 0.00000000000040939233218678664,
+ 0.00000000000087424383914858291,
+ 0.00000000000025218188456842882,
+ -0.00000000000003608131360422557,
+ -0.00000000000050518555924280902,
+ 0.00000000000078699403323355317,
+ -0.00000000000067020876961949060,
+ 0.00000000000016108575753932458,
+ 0.00000000000058527188436251509,
+ -0.00000000000035246757297904791,
+ -0.00000000000018372084495629058,
+ 0.00000000000088606689813494916,
+ 0.00000000000066486268071468700,
+ 0.00000000000063831615170646519,
+ 0.00000000000025144230728376072,
+ -0.00000000000017239444525614834);
+
+ variable M, J:INTEGER;
+ variable F1, F2, G, Q, U, U2, V: REAL;
+ variable ZERO: REAL := 0.0;--Made variable so no constant folding occurs
+ variable ONE: REAL := 1.0; --Made variable so no constant folding occurs
+
+ -- double logb(), ldexp();
+
+ variable U1:REAL;
+
+ begin
+
+ -- Check validity of argument
+ if ( X <= 0.0 ) then
+ assert FALSE
+ report "X <= 0.0 in LOG(X)"
+ severity ERROR;
+ return(REAL'LOW);
+ end if;
+
+ -- Compute value for special cases
+ if ( X = 1.0 ) then
+ return 0.0;
+ end if;
+
+ if ( X = MATH_E ) then
+ return 1.0;
+ end if;
+
+ -- Argument reduction: 1 <= g < 2; x/2^m = g;
+ -- y = F*(1 + f/F) for |f| <= 2^-8
+
+ M := ILOGB(X);
+ G := LDEXP(X, -M);
+ J := INTEGER(REAL(N)*(G-1.0)); -- C code adds 0.5 for rounding
+ F1 := (1.0/REAL(N)) * REAL(J) + 1.0; --F1*128 is an INTEGER in [128,512]
+ F2 := G - F1;
+
+ -- Approximate expansion for log(1+f2/F1) ~= u + q
+ G := 1.0/(2.0*F1+F2);
+ U := 2.0*F2*G;
+ V := U*U;
+ Q := U*V*(A1 + V*(A2 + V*(A3 + V*A4)));
+
+ -- Case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8,
+ -- u1 has at most 35 bits, and F1*u1 is exact, as F1 has < 8 bits.
+ -- It also adds exactly to |m*log2_hi + log_F_head[j] | < 750.
+ --
+ if ( J /= 0 or M /= 0) then
+ U1 := U + 513.0;
+ U1 := U1 - 513.0;
+
+ -- Case 2: |1-x| < 1/256. The m- and j- dependent terms are zero
+ -- u1 = u to 24 bits.
+ --
+ else
+ U1 := U;
+ --TRUNC(U1); --In c this is u1 = (double) (float) (u1)
+ end if;
+
+ U2 := (2.0*(F2 - F1*U1) - U1*F2) * G;
+ -- u1 + u2 = 2f/(2F+f) to extra precision.
+
+ -- log(x) = log(2^m*F1*(1+f2/F1)) =
+ -- (m*log2_hi+LOGF_HEAD(j)+u1) + (m*log2_lo+LOGF_TAIL(j)+q);
+ -- (exact) + (tiny)
+
+ U1 := U1 + REAL(M)*LOGF_HEAD(N) + LOGF_HEAD(J); -- Exact
+ U2 := (U2 + LOGF_TAIL(J)) + Q; -- Tiny
+ U2 := U2 + LOGF_TAIL(N)*REAL(M);
+ return (U1 + U2);
+ end function LOG;
+
+
+ function LOG2 (X: in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns REAL'LOW on error
+ begin
+ -- Check validity of arguments
+ if ( X <= 0.0 ) then
+ assert FALSE
+ report "X <= 0.0 in LOG2(X)"
+ severity ERROR;
+ return(REAL'LOW);
+ end if;
+
+ -- Compute value for special cases
+ if ( X = 1.0 ) then
+ return 0.0;
+ end if;
+
+ if ( X = 2.0 ) then
+ return 1.0;
+ end if;
+
+ -- Compute value for general case
+ return ( MATH_LOG2_OF_E*LOG(X) );
+ end function LOG2;
+
+
+ function LOG10 (X: in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns REAL'LOW on error
+ begin
+ -- Check validity of arguments
+ if ( X <= 0.0 ) then
+ assert FALSE
+ report "X <= 0.0 in LOG10(X)"
+ severity ERROR;
+ return(REAL'LOW);
+ end if;
+
+ -- Compute value for special cases
+ if ( X = 1.0 ) then
+ return 0.0;
+ end if;
+
+ if ( X = 10.0 ) then
+ return 1.0;
+ end if;
+
+ -- Compute value for general case
+ return ( MATH_LOG10_OF_E*LOG(X) );
+ end function LOG10;
+
+
+ function LOG (X: in REAL; BASE: in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns REAL'LOW on error
+ begin
+ -- Check validity of arguments
+ if ( X <= 0.0 ) then
+ assert FALSE
+ report "X <= 0.0 in LOG(X, BASE)"
+ severity ERROR;
+ return(REAL'LOW);
+ end if;
+
+ if ( BASE <= 0.0 or BASE = 1.0 ) then
+ assert FALSE
+ report "BASE <= 0.0 or BASE = 1.0 in LOG(X, BASE)"
+ severity ERROR;
+ return(REAL'LOW);
+ end if;
+
+ -- Compute value for special cases
+ if ( X = 1.0 ) then
+ return 0.0;
+ end if;
+
+ if ( X = BASE ) then
+ return 1.0;
+ end if;
+
+ -- Compute value for general case
+ return ( LOG(X)/LOG(BASE));
+ end function LOG;
+
+
+ function SIN (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) SIN(-X) = -SIN(X)
+ -- b) SIN(X) = X if ABS(X) < EPS
+ -- c) SIN(X) = X - X**3/3! if EPS < ABS(X) < BASE_EPS
+ -- d) SIN(MATH_PI_OVER_2 - X) = COS(X)
+ -- e) COS(X) = 1.0 - 0.5*X**2 if ABS(X) < EPS
+ -- f) COS(X) = 1.0 - 0.5*X**2 + (X**4)/4! if
+ -- EPS< ABS(X) 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
+
+ variable NEGATIVE : BOOLEAN := X < 0.0;
+ variable XLOCAL : REAL := ABS(X) ;
+ variable VALUE: REAL;
+ variable TEMP : REAL;
+
+ begin
+ -- Make 0.0 <= XLOCAL <= MATH_2_PI
+ if XLOCAL > MATH_2_PI then
+ TEMP := FLOOR(XLOCAL/MATH_2_PI);
+ XLOCAL := XLOCAL - TEMP*MATH_2_PI;
+ end if;
+
+ if XLOCAL < 0.0 then
+ -- adjust for rounding error
+ XLOCAL := 0.0;
+ end if;
+
+ -- Check validity of argument
+ if XLOCAL = MATH_PI_OVER_2 then
+ assert FALSE
+ report "X is a multiple of MATH_PI_OVER_2 in TAN(X)"
+ severity ERROR;
+ if NEGATIVE then
+ return(REAL'LOW);
+ else
+ return(REAL'HIGH);
+ end if;
+ end if;
+
+ if XLOCAL = MATH_3_PI_OVER_2 then
+ assert FALSE
+ report "X is a multiple of MATH_3_PI_OVER_2 in TAN(X)"
+ severity ERROR;
+ if NEGATIVE then
+ return(REAL'HIGH);
+ else
+ return(REAL'LOW);
+ end if;
+ end if;
+
+ -- Compute value for special cases
+ if XLOCAL = 0.0 or XLOCAL = MATH_PI then
+ return 0.0;
+ end if;
+
+ -- Compute value for general cases
+ VALUE := SIN(XLOCAL)/COS(XLOCAL);
+ if NEGATIVE then
+ return -VALUE;
+ else
+ return VALUE;
+ end if;
+ end function TAN;
+
+ function ARCSIN (X : in REAL ) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) ARCSIN(-X) = -ARCSIN(X)
+ -- b) Returns X on error
+
+ variable NEGATIVE : BOOLEAN := X < 0.0;
+ variable XLOCAL : REAL := ABS(X);
+ variable VALUE : REAL;
+
+ begin
+ -- Check validity of arguments
+ if XLOCAL > 1.0 then
+ assert FALSE
+ report "ABS(X) > 1.0 in ARCSIN(X)"
+ severity ERROR;
+ return X;
+ end if;
+
+ -- Compute value for special cases
+ if XLOCAL = 0.0 then
+ return 0.0;
+ elsif XLOCAL = 1.0 then
+ if NEGATIVE then
+ return -MATH_PI_OVER_2;
+ else
+ return MATH_PI_OVER_2;
+ end if;
+ end if;
+
+ -- Compute value for general cases
+ if XLOCAL < 0.9 then
+ VALUE := ARCTAN(XLOCAL/(SQRT(1.0 - XLOCAL*XLOCAL)));
+ else
+ VALUE := MATH_PI_OVER_2 - ARCTAN(SQRT(1.0 - XLOCAL*XLOCAL)/XLOCAL);
+ end if;
+
+ if NEGATIVE then
+ VALUE := -VALUE;
+ end if;
+
+ return VALUE;
+ end function ARCSIN;
+
+ function ARCCOS (X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) ARCCOS(-X) = MATH_PI - ARCCOS(X)
+ -- b) Returns X on error
+
+ variable NEGATIVE : BOOLEAN := X < 0.0;
+ variable XLOCAL : REAL := ABS(X);
+ variable VALUE : REAL;
+
+ begin
+ -- Check validity of argument
+ if XLOCAL > 1.0 then
+ assert FALSE
+ report "ABS(X) > 1.0 in ARCCOS(X)"
+ severity ERROR;
+ return X;
+ end if;
+
+ -- Compute value for special cases
+ if X = 1.0 then
+ return 0.0;
+ elsif X = 0.0 then
+ return MATH_PI_OVER_2;
+ elsif X = -1.0 then
+ return MATH_PI;
+ end if;
+
+ -- Compute value for general cases
+ if XLOCAL > 0.9 then
+ VALUE := ARCTAN(SQRT(1.0 - XLOCAL*XLOCAL)/XLOCAL);
+ else
+ VALUE := MATH_PI_OVER_2 - ARCTAN(XLOCAL/SQRT(1.0 - XLOCAL*XLOCAL));
+ end if;
+
+
+ if NEGATIVE then
+ VALUE := MATH_PI - VALUE;
+ end if;
+
+ return VALUE;
+ end function ARCCOS;
+
+
+ function ARCTAN (Y : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) ARCTAN(-Y) = -ARCTAN(Y)
+ -- b) ARCTAN(Y) = -ARCTAN(1.0/Y) + MATH_PI_OVER_2 for |Y| > 1.0
+ -- c) ARCTAN(Y) = Y for |Y| < EPS
+
+ constant EPS : REAL := BASE_EPS*BASE_EPS*BASE_EPS;
+
+ variable NEGATIVE : BOOLEAN := Y < 0.0;
+ variable RECIPROCAL : BOOLEAN;
+ variable YLOCAL : REAL := ABS(Y);
+ variable VALUE : REAL;
+
+ begin
+ -- Make argument |Y| <=1.0
+ if YLOCAL > 1.0 then
+ YLOCAL := 1.0/YLOCAL;
+ RECIPROCAL := TRUE;
+ else
+ RECIPROCAL := FALSE;
+ end if;
+
+ -- Compute value for special cases
+ if YLOCAL = 0.0 then
+ if RECIPROCAL then
+ if NEGATIVE then
+ return (-MATH_PI_OVER_2);
+ else
+ return (MATH_PI_OVER_2);
+ end if;
+ else
+ return 0.0;
+ end if;
+ end if;
+
+ if YLOCAL < EPS then
+ if NEGATIVE then
+ if RECIPROCAL then
+ return (-MATH_PI_OVER_2 + YLOCAL);
+ else
+ return -YLOCAL;
+ end if;
+ else
+ if RECIPROCAL then
+ return (MATH_PI_OVER_2 - YLOCAL);
+ else
+ return YLOCAL;
+ end if;
+ end if;
+ end if;
+
+ -- Compute value for general cases
+ VALUE := CORDIC( 1.0, YLOCAL, 0.0, 27, VECTORING )(2);
+
+ if RECIPROCAL then
+ VALUE := MATH_PI_OVER_2 - VALUE;
+ end if;
+
+ if NEGATIVE then
+ VALUE := -VALUE;
+ end if;
+
+ return VALUE;
+ end function ARCTAN;
+
+
+ function ARCTAN (Y : in REAL; X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns 0.0 on error
+
+ variable YLOCAL : REAL;
+ variable VALUE : REAL;
+ begin
+
+ -- Check validity of arguments
+ if (Y = 0.0 and X = 0.0 ) then
+ assert FALSE report
+ "ARCTAN(0.0, 0.0) is undetermined"
+ severity ERROR;
+ return 0.0;
+ end if;
+
+ -- Compute value for special cases
+ if Y = 0.0 then
+ if X > 0.0 then
+ return 0.0;
+ else
+ return MATH_PI;
+ end if;
+ end if;
+
+ if X = 0.0 then
+ if Y > 0.0 then
+ return MATH_PI_OVER_2;
+ else
+ return -MATH_PI_OVER_2;
+ end if;
+ end if;
+
+
+ -- Compute value for general cases
+ YLOCAL := ABS(Y/X);
+
+ VALUE := ARCTAN(YLOCAL);
+
+ if X < 0.0 then
+ VALUE := MATH_PI - VALUE;
+ end if;
+
+ if Y < 0.0 then
+ VALUE := -VALUE;
+ end if;
+
+ return VALUE;
+ end function ARCTAN;
+
+
+ function SINH (X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns (EXP(X) - EXP(-X))/2.0
+ -- b) SINH(-X) = SINH(X)
+
+ variable NEGATIVE : BOOLEAN := X < 0.0;
+ variable XLOCAL : REAL := ABS(X);
+ variable TEMP : REAL;
+ variable VALUE : REAL;
+
+ begin
+ -- Compute value for special cases
+ if XLOCAL = 0.0 then
+ return 0.0;
+ end if;
+
+ -- Compute value for general cases
+ TEMP := EXP(XLOCAL);
+ VALUE := (TEMP - 1.0/TEMP)*0.5;
+
+ if NEGATIVE then
+ VALUE := -VALUE;
+ end if;
+
+ return VALUE;
+ end function SINH;
+
+ function COSH (X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns (EXP(X) + EXP(-X))/2.0
+ -- b) COSH(-X) = COSH(X)
+
+ variable XLOCAL : REAL := ABS(X);
+ variable TEMP : REAL;
+ variable VALUE : REAL;
+ begin
+ -- Compute value for special cases
+ if XLOCAL = 0.0 then
+ return 1.0;
+ end if;
+
+
+ -- Compute value for general cases
+ TEMP := EXP(XLOCAL);
+ VALUE := (TEMP + 1.0/TEMP)*0.5;
+
+ return VALUE;
+ end function COSH;
+
+ function TANH (X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns (EXP(X) - EXP(-X))/(EXP(X) + EXP(-X))
+ -- b) TANH(-X) = -TANH(X)
+
+ variable NEGATIVE : BOOLEAN := X < 0.0;
+ variable XLOCAL : REAL := ABS(X);
+ variable TEMP : REAL;
+ variable VALUE : REAL;
+
+ begin
+ -- Compute value for special cases
+ if XLOCAL = 0.0 then
+ return 0.0;
+ end if;
+
+ -- Compute value for general cases
+ TEMP := EXP(XLOCAL);
+ VALUE := (TEMP - 1.0/TEMP)/(TEMP + 1.0/TEMP);
+
+ if NEGATIVE then
+ return -VALUE;
+ else
+ return VALUE;
+ end if;
+ end function TANH;
+
+ function ARCSINH (X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns LOG( X + SQRT( X*X + 1.0))
+
+ begin
+ -- Compute value for special cases
+ if X = 0.0 then
+ return 0.0;
+ end if;
+
+ -- Compute value for general cases
+ return ( LOG( X + SQRT( X*X + 1.0)) );
+ end function ARCSINH;
+
+
+
+ function ARCCOSH (X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns LOG( X + SQRT( X*X - 1.0)); X >= 1.0
+ -- b) Returns X on error
+
+ begin
+ -- Check validity of arguments
+ if X < 1.0 then
+ assert FALSE
+ report "X < 1.0 in ARCCOSH(X)"
+ severity ERROR;
+ return X;
+ end if;
+
+ -- Compute value for special cases
+ if X = 1.0 then
+ return 0.0;
+ end if;
+
+ -- Compute value for general cases
+ return ( LOG( X + SQRT( X*X - 1.0)));
+ end function ARCCOSH;
+
+ function ARCTANH (X : in REAL) return REAL is
+ -- Description:
+ -- See function declaration in IEEE Std 1076.2-1996
+ -- Notes:
+ -- a) Returns (LOG( (1.0 + X)/(1.0 - X)))/2.0 ; | X | < 1.0
+ -- b) Returns X on error
+ begin
+ -- Check validity of arguments
+ if ABS(X) >= 1.0 then
+ assert FALSE
+ report "ABS(X) >= 1.0 in ARCTANH(X)"
+ severity ERROR;
+ return X;
+ end if;
+
+ -- Compute value for special cases
+ if X = 0.0 then
+ return 0.0;
+ end if;
+
+ -- Compute value for general cases
+ return( 0.5*LOG( (1.0+X)/(1.0-X) ) );
+ end function ARCTANH;
+
+end package body MATH_REAL;
trunk/sim/rtl_sim/src/math_real.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/bin/testroundings.sh
===================================================================
--- trunk/sim/rtl_sim/bin/testroundings.sh (nonexistent)
+++ trunk/sim/rtl_sim/bin/testroundings.sh (revision 2)
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+vsim -c -do "testroundings.do"
+if [ "$SECONDS" -eq 1 ]
+then
+ units=second
+else
+ units=seconds
+fi
+echo "This script has been running for $SECONDS $units."
+exit 0
trunk/sim/rtl_sim/bin/testroundings.sh
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/bin/testroundingu.sh
===================================================================
--- trunk/sim/rtl_sim/bin/testroundingu.sh (nonexistent)
+++ trunk/sim/rtl_sim/bin/testroundingu.sh (revision 2)
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+vsim -c -do "testroundingu.do"
+if [ "$SECONDS" -eq 1 ]
+then
+ units=second
+else
+ units=seconds
+fi
+echo "This script has been running for $SECONDS $units."
+exit 0
trunk/sim/rtl_sim/bin/testroundingu.sh
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/bin/testroundings.do
===================================================================
--- trunk/sim/rtl_sim/bin/testroundings.do (nonexistent)
+++ trunk/sim/rtl_sim/bin/testroundings.do (revision 2)
@@ -0,0 +1,13 @@
+# Author: Nikolaos Kavvadias (C) 2009, 2010, 2011
+vlib work
+vcom ../src/math_real.vhd
+vcom ../src/fixed_float_types_custom.vhd
+vcom ../src/fixed_pkg_c.vhd
+vcom ../../../rtl/vhdl/fixed_extensions_pkg_sim.vhd
+vcom ../../../gen/vhdl/testroundings.vhd
+vcom ../../../bench/vhdl/testrounding_tb.vhd
+vsim testrounding_tb
+vcd dumpports -file testrounding_fsmd.vcd /testrounding_tb/uut/* -unique
+onbreak {quit -f}
+run -all
+exit -f
trunk/sim/rtl_sim/bin/testroundings.do
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/bin/testroundingu.do
===================================================================
--- trunk/sim/rtl_sim/bin/testroundingu.do (nonexistent)
+++ trunk/sim/rtl_sim/bin/testroundingu.do (revision 2)
@@ -0,0 +1,13 @@
+# Author: Nikolaos Kavvadias (C) 2009, 2010, 2011
+vlib work
+vcom ../src/math_real.vhd
+vcom ../src/fixed_float_types_custom.vhd
+vcom ../src/fixed_pkg_c.vhd
+vcom ../../../rtl/vhdl/fixed_extensions_pkg_sim.vhd
+vcom ../../../gen/vhdl/testroundingu.vhd
+vcom ../../../bench/vhdl/testrounding_tb.vhd
+vsim testrounding_tb
+vcd dumpports -file testrounding_fsmd.vcd /testrounding_tb/uut/* -unique
+onbreak {quit -f}
+run -all
+exit -f
trunk/sim/rtl_sim/bin/testroundingu.do
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/rtl_sim/bin/run.sh
===================================================================
--- trunk/sim/rtl_sim/bin/run.sh (nonexistent)
+++ trunk/sim/rtl_sim/bin/run.sh (revision 2)
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Test sfixed rounding
+#../../../sw/gentestround -signed -iw 4 -fw 4 -step 0.25 ../../../gen/vhdl/testroundings.vhd
+#./testroundings.sh
+
+# Test ufixed rounding
+../../../sw/gentestround -unsigned -iw 4 -fw 4 -step 0.25 ../../../gen/vhdl/testroundingu.vhd
+./testroundingu.sh
+
+if [ "$SECONDS" -eq 1 ]
+then
+ units=second
+else
+ units=seconds
+fi
+echo "This script has been running for $SECONDS $units."
+exit 0
trunk/sim/rtl_sim/bin/run.sh
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sw/gentestround.c
===================================================================
--- trunk/sw/gentestround.c (nonexistent)
+++ trunk/sw/gentestround.c (revision 2)
@@ -0,0 +1,493 @@
+/*
+ * File : gentestround.c
+ * Description: Generator for test designs for evaluating signed/unsigned
+ * fixed-point (sfixed/ufixed) rounding operators.
+ * Author : Nikolaos Kavvadias
+ * Copyright : (C) Nikolaos Kavvadias 2011
+ * Website : http://www.nkavvadias.com
+ *
+ * This file is part of fixed_extensions, and is distributed under the terms
+ * of the Modified BSD License.
+ *
+ * A copy of the Modified BSD License is included with this distrubution
+ * in the files /doc/COPYING.BSD.
+ * fixed_extensions is free software: you can redistribute it and/or modify
+ * it under the terms of the Modified BSD License.
+ * fixed_extensions is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Modified BSD License for more
+ * details.
+ *
+ * You should have received a copy of the Modified BSD License along with
+ * fixed_extensions. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+/* Absolute value of an integer. */
+#define ABS(x) ((x) > 0 ? (x) : (-x))
+
+int enable_debug=0;
+int iw_val=4, fw_val=4;
+double step_val=0.25;
+int enable_signed=0, enable_unsigned=1;
+
+
+/* print_spaces:
+ * Print a configurable number of space characters to an output file (specified
+ * by the given filename; the file is assumed already opened).
+ */
+void print_spaces(FILE *f, int nspaces)
+{
+ int i;
+ for (i = 0; i < nspaces; i++)
+ {
+ fprintf(f, " ");
+ }
+}
+
+/* pfprintf:
+ * fprintf prefixed by a number of space characters.
+ */
+void pfprintf(FILE *f, int nspaces, char *fmt, ...)
+{
+ va_list args;
+ print_spaces(f, nspaces);
+ va_start(args, fmt);
+ vfprintf(f, fmt, args);
+ va_end(args);
+}
+
+/* ipowul:
+ * Calculate integer power supporting results up to 64-bits.
+ */
+unsigned long long int ipowul(int base, int exponent)
+{
+ unsigned long long int temp;
+ int i;
+
+ temp = 1;
+
+ for (i = 0; i < exponent; i++)
+ {
+ temp *= (unsigned int)base;
+ }
+
+ return (temp);
+}
+
+/* calculate_samples:
+ * Calculate the number of samples needed for the test design.
+ */
+unsigned long long int calculate_samples(int iw, int fw, int step)
+{
+ unsigned long long int nsamples;
+
+ /* FIXME: Should be the same for both cases! */
+ /* Samples range: 0 to 2^IW-2^FW. */
+ if (enable_unsigned == 1)
+ {
+// nsamples = (ipowul(2, iw) - ipowul(2, -fw)) / ipowul(2, -fw) + 1;
+ nsamples = ipowul(2, iw+fw);
+ }
+ /* Samples range: -2^(IW-1) to 2^(IW-1)-2^FW. */
+ else if (enable_signed == 1)
+ {
+// nsamples = ipowul(2, iw) / ipowul(2, fw);
+ nsamples = ipowul(2, iw+fw);
+ }
+
+ return nsamples;
+}
+
+/* print_test_prologue:
+ * Prints the prologue for the generated test design file.
+ */
+void print_test_prologue(FILE *infile)
+{
+ pfprintf(infile, 0, "library IEEE;\n");
+ pfprintf(infile, 0, "use IEEE.std_logic_1164.all;\n");
+ pfprintf(infile, 0, "use IEEE.numeric_std.all;\n");
+ pfprintf(infile, 0, "use WORK.fixed_float_types.all;\n");
+ pfprintf(infile, 0, "use WORK.fixed_pkg.all;\n");
+ pfprintf(infile, 0, "use WORK.fixed_extensions_pkg.all;\n");
+ fprintf(infile, "\n");
+}
+
+/* print_test_entity:
+ * Prints the entity of the generated test design file.
+ */
+void print_test_entity(FILE *infile, unsigned int iw, unsigned int fw)
+{
+ pfprintf(infile, 0, "entity testrounding is\n");
+ pfprintf(infile, 2, "port (\n");
+ pfprintf(infile, 4, "clk : in std_logic;\n");
+ pfprintf(infile, 4, "reset : in std_logic;\n");
+ pfprintf(infile, 4, "start : in std_logic;\n");
+ pfprintf(infile, 4, "ok : out sfixed(%d downto -%d)\n", iw-1, fw);
+ pfprintf(infile, 2, ");\n");
+ pfprintf(infile, 0, "end testrounding;\n\n");
+}
+
+/* print_test_architecture_prologue:
+ * Prints the declaration part of the architecture for the generated test design
+ * file.
+ */
+void print_test_architecture_prologue(FILE *infile, unsigned int iw, unsigned int fw, unsigned int step)
+{
+ long long int i;
+ unsigned long long int nsteps = calculate_samples(iw, fw, step);
+ char c = 'X';
+ if (enable_unsigned == 1)
+ {
+ c = 'u';
+ }
+ else if (enable_signed == 1)
+ {
+ c = 's';
+ }
+
+ pfprintf(infile, 0, "architecture fsmd of testrounding is\n");
+ pfprintf(infile, 2, "type state_type is (S_ENTRY, S_EXIT,\n");
+
+ for (i = 0; i < nsteps; i++)
+ {
+ pfprintf(infile, 4, "S_%08d_1,", i);
+ fprintf(infile, " S_%08d_2", i);
+ fprintf(infile, ", S_%08d_3", i);
+ if (enable_signed == 1)
+ {
+ fprintf(infile, ", S_%08d_4", i);
+ }
+ if (i < nsteps-1)
+ {
+ fprintf(infile, ",");
+ }
+ fprintf(infile, "\n");
+ }
+ pfprintf(infile, 2, ");\n");
+ pfprintf(infile, 2, "signal current_state, next_state: state_type;\n");
+ pfprintf(infile, 2, "signal a_reg, a_next : %cfixed(%d downto -%d);\n", c, iw-1, fw);
+ pfprintf(infile, 2, "signal y_ceil_reg, y_ceil_next : %cfixed(%d downto -%d);\n", c, iw-1, fw);
+ pfprintf(infile, 2, "signal y_fix_reg, y_fix_next : %cfixed(%d downto -%d);\n", c, iw-1, fw);
+ pfprintf(infile, 2, "signal y_floor_reg, y_floor_next : %cfixed(%d downto -%d);\n", c, iw-1, fw);
+ pfprintf(infile, 2, "signal y_round_reg, y_round_next : %cfixed(%d downto -%d);\n", c, iw-1, fw);
+ pfprintf(infile, 2, "signal y_nearest_reg, y_nearest_next : %cfixed(%d downto -%d);\n", c, iw-1, fw);
+ pfprintf(infile, 2, "signal y_convergent_reg, y_convergent_next : %cfixed(%d downto -%d);\n", c, iw-1, fw);
+ pfprintf(infile, 2, "signal ok_reg, ok_next : sfixed(%d downto -%d);\n", iw-1, fw);
+
+ pfprintf(infile, 0, "begin\n");
+}
+
+/* print_test_architecture_csl:
+ * Prints the current state logic process of the architecture for the generated
+ * test design file.
+ */
+void print_test_architecture_csl(FILE *infile)
+{
+ pfprintf(infile, 2, "-- current state logic\n");
+ pfprintf(infile, 2, "process (clk, reset)\n");
+ pfprintf(infile, 4, "begin\n");
+ pfprintf(infile, 6, "if (reset = '1') then\n");
+ pfprintf(infile, 6, "current_state <= S_ENTRY;\n");
+ pfprintf(infile, 6, "a_reg <= (others => '0');\n");
+ pfprintf(infile, 6, "y_ceil_reg <= (others => '0');\n");
+ pfprintf(infile, 6, "y_fix_reg <= (others => '0');\n");
+ pfprintf(infile, 6, "y_floor_reg <= (others => '0');\n");
+ pfprintf(infile, 6, "y_round_reg <= (others => '0');\n");
+ pfprintf(infile, 6, "y_nearest_reg <= (others => '0');\n");
+ pfprintf(infile, 6, "y_convergent_reg <= (others => '0');\n");
+ pfprintf(infile, 6, "ok_reg <= (others => '0');\n");
+ pfprintf(infile, 4, "elsif (clk = '1' and clk'EVENT) then\n");
+ pfprintf(infile, 6, "current_state <= next_state;\n");
+ pfprintf(infile, 6, "a_reg <= a_next;\n");
+ pfprintf(infile, 6, "y_ceil_reg <= y_ceil_next;\n");
+ pfprintf(infile, 6, "y_fix_reg <= y_fix_next;\n");
+ pfprintf(infile, 6, "y_floor_reg <= y_floor_next;\n");
+ pfprintf(infile, 6, "y_round_reg <= y_round_next;\n");
+ pfprintf(infile, 6, "y_nearest_reg <= y_nearest_next;\n");
+ pfprintf(infile, 6, "y_convergent_reg <= y_convergent_next;\n");
+ pfprintf(infile, 6, "ok_reg <= ok_next;\n");
+ pfprintf(infile, 4, "end if;\n");
+ pfprintf(infile, 2, "end process;\n\n");
+}
+
+/* print_test_architecture_nsol_prologue:
+ * Prints the next state and output logic process prologue of the architecture
+ * for the generated test design file.
+ */
+void print_test_architecture_nsol_prologue(FILE *infile)
+{
+ pfprintf(infile, 2, "-- next state and output logic\n");
+ pfprintf(infile, 2, "process (current_state, start,\n");
+ pfprintf(infile, 4, "ok_reg,\n");
+ pfprintf(infile, 4, "a_reg, a_next,\n");
+ pfprintf(infile, 4, "y_ceil_reg, y_ceil_next,\n");
+ pfprintf(infile, 4, "y_fix_reg, y_fix_next,\n");
+ pfprintf(infile, 4, "y_floor_reg, y_floor_next,\n");
+ pfprintf(infile, 4, "y_round_reg, y_round_next,\n");
+ pfprintf(infile, 4, "y_nearest_reg, y_nearest_next,\n");
+ pfprintf(infile, 4, "y_convergent_reg, y_convergent_next\n");
+ pfprintf(infile, 2, ")\n");
+ pfprintf(infile, 2, "begin\n");
+ pfprintf(infile, 4, "a_next <= a_reg;\n");
+ pfprintf(infile, 4, "y_ceil_next <= y_ceil_reg;\n");
+ pfprintf(infile, 4, "y_fix_next <= y_fix_reg;\n");
+ pfprintf(infile, 4, "y_floor_next <= y_floor_reg;\n");
+ pfprintf(infile, 4, "y_round_next <= y_round_reg;\n");
+ pfprintf(infile, 4, "y_nearest_next <= y_nearest_reg;\n");
+ pfprintf(infile, 4, "y_convergent_next <= y_convergent_reg;\n");
+ pfprintf(infile, 4, "ok_next <= ok_reg;\n");
+}
+
+/* print_test_architecture_nsol_csdec:
+ * Prints the current state decoding part. It resides in the next state and
+ * output logic process of the architecture for the generated test design file.
+ */
+void print_test_architecture_nsol_csdec(FILE *infile, unsigned int iw, unsigned int fw, unsigned int step)
+{
+ long long int i;
+ int k;
+ unsigned long long int nsteps = calculate_samples(iw, fw, step);
+ double val = 0.0;
+ char c = 'X';
+ if (enable_unsigned == 1)
+ {
+ c = 'u';
+ }
+ else if (enable_signed == 1)
+ {
+ c = 's';
+ }
+
+ pfprintf(infile, 4, "case current_state is\n");
+ pfprintf(infile, 6, "when S_ENTRY =>\n");
+ pfprintf(infile, 8, "if (start = '1') then\n");
+ pfprintf(infile, 10, "next_state <= S_00000001_1;\n");
+ pfprintf(infile, 8, "else\n");
+ pfprintf(infile, 10, "next_state <= S_ENTRY;\n");
+ pfprintf(infile, 8, "end if;\n");
+
+ if (enable_unsigned == 1)
+ {
+ val = 0.0;
+ }
+ else if (enable_signed == 1)
+ {
+ val = - 1.0 * ipowul(2, iw-1);
+ }
+ for (i = 0; i < nsteps; i++)
+ {
+ pfprintf(infile, 6, "when S_%08d_1 =>\n", i);
+ pfprintf(infile, 8, "a_next <= to_%cfixed(%lf, %d, -%d);\n", c, val, iw-1, fw);
+ val += 1.0/(float)ipowul(2, fw);
+ pfprintf(infile, 8, "next_state <= S_%08d_2;\n", i);
+ //
+ if (enable_signed == 1)
+ {
+ pfprintf(infile, 6, "when S_%08d_2 =>\n", i);
+ if (val < 0.0)
+ {
+ pfprintf(infile, 8, "a_next <= resize(-a_reg, a_next'high, a_next'low);\n");
+ }
+ pfprintf(infile, 8, "next_state <= S_%08d_3;\n", i);
+ k++;
+ }
+ //
+ if (enable_unsigned == 1)
+ {
+ pfprintf(infile, 6, "when S_%08d_2 =>\n", i);
+ }
+ else if (enable_signed == 1)
+ {
+ pfprintf(infile, 6, "when S_%08d_3 =>\n", i);
+ }
+ pfprintf(infile, 8, "y_ceil_next <= ceil(a_reg);\n");
+ pfprintf(infile, 8, "y_fix_next <= fix(a_reg);\n");
+ pfprintf(infile, 8, "y_floor_next <= floor(a_reg);\n");
+ pfprintf(infile, 8, "y_round_next <= round(a_reg);\n");
+ pfprintf(infile, 8, "y_nearest_next <= nearest(a_reg);\n");
+ pfprintf(infile, 8, "y_convergent_next <= convergent(a_reg);\n");
+ if (enable_unsigned == 1)
+ {
+ pfprintf(infile, 8, "next_state <= S_%08d_3;\n", i);
+ }
+ else if (enable_signed == 1)
+ {
+ pfprintf(infile, 8, "next_state <= S_%08d_4;\n", i);
+ }
+ //
+ if (enable_unsigned == 1)
+ {
+ pfprintf(infile, 6, "when S_%08d_3 =>\n", i);
+ }
+ else if (enable_signed == 1)
+ {
+ pfprintf(infile, 6, "when S_%08d_4 =>\n", i);
+ }
+ pfprintf(infile, 8, "assert false report \"a_reg = \" & to_bstring(a_reg) severity note;\n");
+ pfprintf(infile, 8, "assert false report \"y_ceil_reg = \" & to_bstring(y_ceil_reg) severity note;\n");
+ pfprintf(infile, 8, "assert false report \"y_fix_reg = \" & to_bstring(y_fix_reg) severity note;\n");
+ pfprintf(infile, 8, "assert false report \"y_floor_reg = \" & to_bstring(y_floor_reg) severity note;\n");
+ pfprintf(infile, 8, "assert false report \"y_round_reg = \" & to_bstring(y_round_reg) severity note;\n");
+ pfprintf(infile, 8, "assert false report \"y_nearest_reg = \" & to_bstring(y_nearest_reg) severity note;\n");
+ pfprintf(infile, 8, "assert false report \"y_convergent_reg = \" & to_bstring(y_convergent_reg) severity note;\n");
+ if (i == nsteps-1)
+ {
+ pfprintf(infile, 8, "next_state <= S_EXIT;\n");
+ }
+ else
+ {
+ pfprintf(infile, 8, "next_state <= S_%08d_1;\n", i+1);
+ }
+ }
+ pfprintf(infile, 6, "when S_EXIT =>\n");
+ pfprintf(infile, 8, "ok_next <= to_sfixed(%lf, %d, %d);\n", 1.0, iw-1, -fw);
+ pfprintf(infile, 8, "assert false report \"DONE!\" severity note;\n");
+ pfprintf(infile, 8, "next_state <= S_ENTRY;\n");
+ pfprintf(infile, 4, "end case;\n");
+}
+
+/* print_test_architecture_epilogue:
+ * Prints the epilogue of the architecture for the generated test design file.
+ */
+void print_test_architecture_epilogue(FILE *infile)
+{
+ pfprintf(infile, 2, "end process;\n\n");
+ pfprintf(infile, 2, "ok <= ok_reg;\n\n");
+ pfprintf(infile, 0, "end fsmd;\n");
+}
+
+/* print_test_design:
+ * Prints the generated test design file.
+ */
+void print_test_design(FILE *infile, unsigned int iw, unsigned int fw, unsigned step)
+{
+ print_test_prologue(infile);
+ print_test_entity(infile, iw, fw);
+ print_test_architecture_prologue(infile, iw, fw, step);
+ print_test_architecture_csl(infile);
+ print_test_architecture_nsol_prologue(infile);
+ print_test_architecture_nsol_csdec(infile, iw, fw, step);
+ print_test_architecture_epilogue(infile);
+}
+
+/* print_usage:
+ * Print usage instructions for the "gentestround" program.
+ */
+static void print_usage()
+{
+ printf("\n");
+ printf("* Usage:\n");
+ printf("* gentestround [options]\n");
+ printf("* \n");
+ printf("* Options:\n");
+ printf("* \n");
+ printf("* -h:\n");
+ printf("* Print this help.\n");
+ printf("* -d:\n");
+ printf("* Enable debug/diagnostic output.\n");
+ printf("* -iw :\n");
+ printf("* Set the integral part width of the fixed-point numbers. Default: 4.\n");
+ printf("* -fw :\n");
+ printf("* Set the fractional part width of the fixed-point numbers. Default: 4.\n");
+ printf("* -step :\n");
+ printf("* Set the step value indicating the difference between two consecutive\n");
+ printf("* samples. Default: 0.25\n");
+ printf("* -signed:\n");
+ printf("* Generate test design for sfixed vectors.\n");
+ printf("* -unsigned:\n");
+ printf("* Generate test design for ufixed vectors (default).\n");
+ printf("* \n");
+ printf("* For further information, please refer to the website:\n");
+ printf("* http://www.nkavvadias.com\n");
+}
+
+/* main:
+ * Program entry.
+ */
+int main(int argc, char *argv[])
+{
+ int i;
+ FILE *file_o;
+
+ // Read input arguments
+ for (i=1; i < argc; i++)
+ {
+ if (strcmp("-h", argv[i]) == 0)
+ {
+ print_usage();
+ exit(1);
+ }
+ else if (strcmp("-d", argv[i]) == 0)
+ {
+ enable_debug = 1;
+ }
+ else if (strcmp("-unsigned", argv[i]) == 0)
+ {
+ enable_unsigned = 1;
+ enable_signed = 0;
+ }
+ else if (strcmp("-signed", argv[i]) == 0)
+ {
+ enable_unsigned = 0;
+ enable_signed = 1;
+ }
+ else if (strcmp("-iw",argv[i]) == 0)
+ {
+ if ((i+1) < argc)
+ {
+ i++;
+ iw_val = atoi(argv[i]);
+ }
+ }
+ else if (strcmp("-fw",argv[i]) == 0)
+ {
+ if ((i+1) < argc)
+ {
+ i++;
+ fw_val = atoi(argv[i]);
+ }
+ }
+ else if (strcmp("-step",argv[i]) == 0)
+ {
+ if ((i+1) < argc)
+ {
+ i++;
+ step_val = atof(argv[i]);
+ }
+ }
+ else
+ {
+ if (argv[i][0] != '-')
+ {
+ file_o = fopen(argv[i], "wb");
+ if (file_o == NULL)
+ {
+ fprintf(stderr,"Error: Can't write %s!\n", argv[i]);
+ return -1;
+ }
+ }
+ }
+ }
+
+ if (iw_val <= 0)
+ {
+ fprintf(stderr, "Error: IW must be greater than zero.\n");
+ exit(1);
+ }
+ if (fw_val < 0)
+ {
+ fprintf(stderr, "Error: FW must be greater than or equal to zero.\n");
+ exit(1);
+ }
+
+ /* Generate the test design. */
+ print_test_design(file_o, iw_val, fw_val, step_val);
+ fclose(file_o);
+
+ return 0;
+}
trunk/sw/gentestround.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sw/Makefile
===================================================================
--- trunk/sw/Makefile (nonexistent)
+++ trunk/sw/Makefile (revision 2)
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -Wall -O2
+EXE = .exe
+
+all: gentestround
+
+gentestround: gentestround.o
+ $(CC) gentestround.o -o gentestround
+
+tidy:
+ rm -f *.o
+
+clean:
+ rm -f *.o gentestround$(EXE)
trunk/sw/Makefile
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property