Bit-level reference implementation of generic binary fixed-point arithmetic.
- Use clause
-
library IEEE;
use IEEE.FIXED_GENERIC_PKG.all; - Source
-
ieee/fixed_generic_pkg-body.vhdlin the IEEE 1076 OSR, tag1076-2019
Apache License 2.0, © 2019 IEEE P1076 WG Authors - Length
- 6360 lines
- Declaration
- View package declaration ›
Overview
This is the reference implementation of FIXED_GENERIC_PKG,
published with IEEE Std 1076-2019. The body represents the formal semantics
of the package per §16.10: implementers may compile it as-is or
substitute a more efficient implementation, but the resulting behaviour
shall not differ from the semantics defined here. The interface lives on
the declaration page.
The body is large because the operators are implemented from first principles - bit-by-bit add/multiply, alignment of binary points across operand widths, and explicit rounding/overflow handling that obeys the package’s generic parameters. Use your browser’s find (Ctrl/Cmd+F) to locate a specific function within this listing.
VHDL source listing
docFile header
lines 1–42
-- -----------------------------------------------------------------
--
-- Copyright 2019 IEEE P1076 WG Authors
--
-- See the LICENSE file distributed with this work for copyright and
-- licensing information and the AUTHORS file.
--
-- This file to you under the Apache License, Version 2.0 (the "License").
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-- implied. See the License for the specific language governing
-- permissions and limitations under the License.
--
-- Title : Fixed-point package (Generic package body)
-- :
-- Library : This package shall be compiled into a library
-- : symbolically named IEEE.
-- :
-- Developers: Accellera VHDL-TC and IEEE P1076 Working Group
-- :
-- Purpose : This packages defines basic binary fixed point arithmetic
-- : arithmetic functions
-- :
-- Note : This package may be modified to include additional data
-- : required by tools, but it must in no way change the
-- : external interfaces or simulation behavior of the
-- : description. It is permissible to add comments and/or
-- : attributes to the package declarations, but not to change
-- : or delete any original lines of the package declaration.
-- : The package body may be changed only in accordance with
-- : the terms of Clause 16 of this standard.
-- :
-- --------------------------------------------------------------------
-- $Revision: 1220 $
-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
-- --------------------------------------------------------------------
library IEEE;
use IEEE.MATH_REAL.all;
package body fixed_generic_pkg iscoNAUF
lines 47–50
NAUF -- 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');coNASF
lines 51–51
NASF constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0');coNSLV
lines 52–53
NSLV constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0');
cofixedsynth_or_real
lines 54–57
fixedsynth_or_real -- 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;
fnmins
lines 58–67
mins -- 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;
fnmine
lines 68–80
mine -- Special version of "minimum" to do some boundary checking with errors
function mine (l, r : INTEGER)
return INTEGER is
begin -- function mine
if (l = INTEGER'low or r = INTEGER'low) then
report fixed_generic_pkg'instance_name
& " Unbounded number passed, was a literal used?"
severity error;
return 0;
end if;
return minimum (l, r);
end function mine;
fncleanvec
lines 81–108
cleanvec -- The following functions are used only internally. Every function
-- calls "cleanvec" either directly or indirectly.
-- purpose: Fixes "downto" problem and resolves meta states
function cleanvec (
arg : UNRESOLVED_sfixed) -- input
return UNRESOLVED_sfixed
is
begin -- function cleanvec
assert not (arg'ascending and (arg'low /= INTEGER'low))
report fixed_generic_pkg'instance_name
& " Vector passed using a ""to"" range, expected is ""downto"""
severity error;
return arg;
end function cleanvec;
-- purpose: Fixes "downto" problem and resolves meta states
function cleanvec (
arg : UNRESOLVED_ufixed) -- input
return UNRESOLVED_ufixed
is
begin -- function cleanvec
assert not (arg'ascending and (arg'low /= INTEGER'low))
report fixed_generic_pkg'instance_name
& " Vector passed using a ""to"" range, expected is ""downto"""
severity error;
return arg;
end function cleanvec;
fnto_fixed
lines 109–134
to_fixed -- Type convert a "unsigned" into a "ufixed", used internally
function to_fixed (
arg : UNRESOLVED_UNSIGNED; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
begin -- function to_fixed
result := UNRESOLVED_ufixed(arg);
return result;
end function to_fixed;
-- Type convert a "signed" into an "sfixed", used internally
function to_fixed (
arg : UNRESOLVED_SIGNED; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin -- function to_fixed
result := UNRESOLVED_sfixed(arg);
return result;
end function to_fixed;
fnto_uns
lines 135–146
to_uns -- Type convert a "ufixed" into an "unsigned", used internally
function to_uns (
arg : UNRESOLVED_ufixed) -- fp vector
return UNRESOLVED_UNSIGNED
is
subtype t is UNRESOLVED_UNSIGNED(arg'high - arg'low downto 0);
variable slv : t;
begin -- function to_uns
slv := t(arg);
return slv;
end function to_uns;
fnto_s
lines 147–158
to_s -- Type convert an "sfixed" into a "signed", used internally
function to_s (
arg : UNRESOLVED_sfixed) -- fp vector
return UNRESOLVED_SIGNED
is
subtype t is UNRESOLVED_SIGNED(arg'high - arg'low downto 0);
variable slv : t;
begin -- function to_s
slv := t(arg);
return slv;
end function to_s;
prround_up
lines 159–187
round_up -- adds 1 to the LSB of the number
procedure round_up (arg : in UNRESOLVED_ufixed;
result : out UNRESOLVED_ufixed;
overflowx : out BOOLEAN) is
variable arguns, resuns : UNRESOLVED_UNSIGNED (arg'high-arg'low+1 downto 0)
:= (others => '0');
begin -- round_up
arguns (arguns'high-1 downto 0) := to_uns (arg);
resuns := arguns + 1;
result := to_fixed(resuns(arg'high-arg'low
downto 0), arg'high, arg'low);
overflowx := (resuns(resuns'high) = '1');
end procedure round_up;
-- adds 1 to the LSB of the number
procedure round_up (arg : in UNRESOLVED_sfixed;
result : out UNRESOLVED_sfixed;
overflowx : out BOOLEAN) is
variable args, ress : UNRESOLVED_SIGNED (arg'high-arg'low+1 downto 0);
begin -- round_up
args (args'high-1 downto 0) := to_s (arg);
args(args'high) := arg(arg'high); -- sign extend
ress := args + 1;
result := to_fixed(ress (ress'high-1
downto 0), arg'high, arg'low);
overflowx := ((arg(arg'high) /= ress(ress'high-1))
and (or (STD_ULOGIC_VECTOR(ress)) /= '0'));
end procedure round_up;
fnround_fixed
lines 188–262
round_fixed -- Rounding - Performs a "round_nearest" (IEEE 754) which rounds up
-- when the remainder is > 0.5. If the remainder IS 0.5 then if the
-- bottom bit is a "1" it is rounded, otherwise it remains the same.
function round_fixed (arg : UNRESOLVED_ufixed;
remainder : UNRESOLVED_ufixed;
overflow_style : fixed_overflow_style_type := fixed_overflow_style)
return UNRESOLVED_ufixed
is
variable rounds : BOOLEAN;
variable round_overflow : BOOLEAN;
variable result : UNRESOLVED_ufixed (arg'range);
begin
rounds := false;
if (remainder'length > 1) then
if (remainder (remainder'high) = '1') then
rounds := (arg(arg'low) = '1')
or (or (to_sulv(remainder(remainder'high-1 downto
remainder'low))) = '1');
end if;
else
rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
end if;
if rounds then
round_up(arg => arg,
result => result,
overflowx => round_overflow);
else
result := arg;
end if;
if (overflow_style = fixed_saturate) and round_overflow then
result := saturate (result'high, result'low);
end if;
return result;
end function round_fixed;
-- Rounding case statement
function round_fixed (arg : UNRESOLVED_sfixed;
remainder : UNRESOLVED_sfixed;
overflow_style : fixed_overflow_style_type := fixed_overflow_style)
return UNRESOLVED_sfixed
is
variable rounds : BOOLEAN;
variable round_overflow : BOOLEAN;
variable result : UNRESOLVED_sfixed (arg'range);
begin
rounds := false;
if (remainder'length > 1) then
if (remainder (remainder'high) = '1') then
rounds := (arg(arg'low) = '1')
or (or (to_sulv(remainder(remainder'high-1 downto
remainder'low))) = '1');
end if;
else
rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
end if;
if rounds then
round_up(arg => arg,
result => result,
overflowx => round_overflow);
else
result := arg;
end if;
if round_overflow then
if (overflow_style = fixed_saturate) then
if arg(arg'high) = '0' then
result := saturate (result'high, result'low);
else
result := not saturate (result'high, result'low);
end if;
-- Sign bit not fixed when wrapping
end if;
end if;
return result;
end function round_fixed;
fnto_ufixed
lines 263–280
to_ufixed -- 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
-----------------------------------------------------------------------------
-- Visible functions
-----------------------------------------------------------------------------fnto_sulv
lines 285–312
to_sulv -- Conversion functions. These are needed for synthesis where typically
-- the only input and output type is a std_logic_vector.
function to_sulv (
arg : UNRESOLVED_ufixed) -- fixed point vector
return STD_ULOGIC_VECTOR
is
variable intermediate_result : UNRESOLVED_ufixed(arg'length-1 downto 0);
begin
if arg'length < 1 then
return NSLV;
end if;
intermediate_result := arg;
return STD_ULOGIC_VECTOR (intermediate_result);
end function to_sulv;
function to_sulv (
arg : UNRESOLVED_sfixed) -- fixed point vector
return STD_ULOGIC_VECTOR
is
variable intermediate_result : UNRESOLVED_sfixed(arg'length-1 downto 0);
begin
if arg'length < 1 then
return NSLV;
end if;
intermediate_result := arg;
return STD_ULOGIC_VECTOR (intermediate_result);
end function to_sulv;
fnto_slv
lines 313–326
to_slv function to_slv (
arg : UNRESOLVED_ufixed) -- fixed point vector
return STD_LOGIC_VECTOR is
begin
return to_sulv(arg);
end function to_slv;
function to_slv (
arg : UNRESOLVED_sfixed) -- fixed point vector
return STD_LOGIC_VECTOR is
begin
return to_sulv(arg);
end function to_slv;
fnto_ufixed
lines 327–352
to_ufixed function to_ufixed (
arg : STD_ULOGIC_VECTOR; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (arg'length < 1 or right_index > left_index) then
return NAUF;
end if;
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name & "TO_UFIXED(SLV) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NAUF;
else
result := to_fixed (arg => UNRESOLVED_UNSIGNED(arg),
left_index => left_index,
right_index => right_index);
return result;
end if;
end function to_ufixed;
fnto_sfixed
lines 353–378
to_sfixed function to_sfixed (
arg : STD_ULOGIC_VECTOR; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (arg'length < 1 or right_index > left_index) then
return NASF;
end if;
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name & "TO_SFIXED(SLV) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NASF;
else
result := to_fixed (arg => UNRESOLVED_SIGNED(arg),
left_index => left_index,
right_index => right_index);
return result;
end if;
end function to_sfixed;
fn"abs"
lines 379–398
"abs" -- Two's complement number, Grows the vector by 1 bit.
-- because "abs (1000.000) = 01000.000" or abs(-16) = 16.
function "abs" (
arg : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed
is
constant left_index : INTEGER := arg'high;
constant right_index : INTEGER := mine(arg'low, arg'low);
variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
variable result : UNRESOLVED_sfixed (left_index+1 downto right_index);
begin
if (arg'length < 1 or result'length < 1) then
return NASF;
end if;
ressns (arg'length-1 downto 0) := to_s (cleanvec (arg));
ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
result := to_fixed (abs(ressns), left_index+1, right_index);
return result;
end function "abs";
fn"-"
lines 399–417
"-" -- also grows the vector by 1 bit.
function "-" (
arg : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed
is
constant left_index : INTEGER := arg'high+1;
constant right_index : INTEGER := mine(arg'low, arg'low);
variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (arg'length < 1 or result'length < 1) then
return NASF;
end if;
ressns (arg'length-1 downto 0) := to_s (cleanvec(arg));
ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
result := to_fixed (-ressns, left_index, right_index);
return result;
end function "-";
fn"+"
lines 418–466
"+" -- Addition
function "+" (
l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) + ufixed(c downto d) =
return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
result_slv := lslv + rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "+";
function "+" (
l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) + sfixed(c downto d) =
return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
result_slv := lslv + rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "+";
fn"-"
lines 467–515
"-" -- Subtraction
function "-" (
l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) - ufixed(c downto d) =
return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
result_slv := lslv - rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "-";
function "-" (
l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) - sfixed(c downto d) =
return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
result_slv := lslv - rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "-";
fn"*"
lines 516–557
"*" function "*" (
l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) * ufixed(c downto d) =
return UNRESOLVED_ufixed -- ufixed(a+c+1 downto b+d)
is
variable lslv : UNRESOLVED_UNSIGNED (l'length-1 downto 0);
variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (r'length+l'length-1 downto 0);
variable result : UNRESOLVED_ufixed (l'high + r'high+1 downto
mine(l'low, l'low) + mine(r'low, r'low));
begin
if (l'length < 1 or r'length < 1 or
result'length /= result_slv'length) then
return NAUF;
end if;
lslv := to_uns (cleanvec(l));
rslv := to_uns (cleanvec(r));
result_slv := lslv * rslv;
result := to_fixed (result_slv, result'high, result'low);
return result;
end function "*";
function "*" (
l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) * sfixed(c downto d) =
return UNRESOLVED_sfixed -- sfixed(a+c+1 downto b+d)
is
variable lslv : UNRESOLVED_SIGNED (l'length-1 downto 0);
variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_SIGNED (r'length+l'length-1 downto 0);
variable result : UNRESOLVED_sfixed (l'high + r'high+1 downto
mine(l'low, l'low) + mine(r'low, r'low));
begin
if (l'length < 1 or r'length < 1 or
result'length /= result_slv'length) then
return NASF;
end if;
lslv := to_s (cleanvec(l));
rslv := to_s (cleanvec(r));
result_slv := lslv * rslv;
result := to_fixed (result_slv, result'high, result'low);
return result;
end function "*";
fn"/"
lines 558–571
"/" 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 "/";
fndivide
lines 572–656
divide -- This version of divide gives the user more control
-- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
function divide (
l, r : UNRESOLVED_ufixed;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (l'high - mine(r'low, r'low) downto
mine (l'low, l'low) - r'high -1);
variable dresult : UNRESOLVED_ufixed (result'high downto result'low -guard_bits);
variable lresize : UNRESOLVED_ufixed (l'high downto l'high - dresult'length+1);
variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NAUF;
end if;
lresize := resize (arg => l,
left_index => lresize'high,
right_index => lresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
lslv := to_uns (cleanvec (lresize));
rslv := to_uns (cleanvec (r));
if (rslv = 0) then
report fixed_generic_pkg'instance_name
& "DIVIDE(ufixed) Division by zero" severity error;
result := saturate (result'high, result'low); -- saturate
else
result_slv := lslv / rslv;
dresult := to_fixed (result_slv, dresult'high, dresult'low);
result := resize (arg => dresult,
left_index => result'high,
right_index => result'low,
overflow_style => fixed_wrap, -- overflow impossible
round_style => round_style);
end if;
return result;
end function divide;
-- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
function divide (
l, r : UNRESOLVED_sfixed;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (l'high - mine(r'low, r'low) + 1 downto
mine (l'low, l'low) - r'high);
variable dresult : UNRESOLVED_sfixed (result'high downto result'low-guard_bits);
variable lresize : UNRESOLVED_sfixed (l'high+1 downto l'high+1 -dresult'length+1);
variable lslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NASF;
end if;
lresize := resize (arg => l,
left_index => lresize'high,
right_index => lresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
lslv := to_s (cleanvec (lresize));
rslv := to_s (cleanvec (r));
if (rslv = 0) then
report fixed_generic_pkg'instance_name
& "DIVIDE(sfixed) Division by zero" severity error;
result := saturate (result'high, result'low);
else
result_slv := lslv / rslv;
dresult := to_fixed (result_slv, dresult'high, dresult'low);
result := resize (arg => dresult,
left_index => result'high,
right_index => result'low,
overflow_style => fixed_wrap, -- overflow impossible
round_style => round_style);
end if;
return result;
end function divide;
fnreciprocal
lines 657–692
reciprocal -- 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;
fn"rem"
lines 693–711
"rem" -- 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";
fnremainder
lines 712–800
remainder -- ufixed (a downto b) rem ufixed (c downto d)
-- = ufixed (min(a,c) downto min(b,d))
function remainder (
l, r : UNRESOLVED_ufixed; -- fixed point input
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
mine(l'low, r'low));
variable lresize : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
mins(r'low, r'low)-guard_bits);
variable rresize : UNRESOLVED_ufixed (r'high downto r'low-guard_bits);
variable dresult : UNRESOLVED_ufixed (rresize'range);
variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
variable rslv : UNRESOLVED_UNSIGNED (rresize'length-1 downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (rslv'range);
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NAUF;
end if;
lresize := resize (arg => l,
left_index => lresize'high,
right_index => lresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
lslv := to_uns (lresize);
rresize := resize (arg => r,
left_index => rresize'high,
right_index => rresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
rslv := to_uns (rresize);
if (rslv = 0) then
report fixed_generic_pkg'instance_name
& "remainder(ufixed) Division by zero" severity error;
result := saturate (result'high, result'low); -- saturate
else
if (r'low <= l'high) then
result_slv := lslv rem rslv;
dresult := to_fixed (result_slv, dresult'high, dresult'low);
result := resize (arg => dresult,
left_index => result'high,
right_index => result'low,
overflow_style => fixed_wrap, -- can't overflow
round_style => round_style);
end if;
if l'low < r'low then
result(mins(r'low-1, l'high) downto l'low) :=
cleanvec(l(mins(r'low-1, l'high) downto l'low));
end if;
end if;
return result;
end function remainder;
-- remainder
-- sfixed (a downto b) rem sfixed (c downto d)
-- = sfixed (min(a,c) downto min(b,d))
function remainder (
l, r : UNRESOLVED_sfixed; -- fixed point input
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_sfixed
is
variable l_abs : UNRESOLVED_ufixed (l'range);
variable r_abs : UNRESOLVED_ufixed (r'range);
variable result : UNRESOLVED_sfixed (minimum(r'high, l'high) downto
mine(r'low, l'low));
variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
mins(r'low, l'low));
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NASF;
end if;
l_abs := to_ufixed (l);
r_abs := to_ufixed (r);
result := UNRESOLVED_sfixed (remainder (
l => l_abs,
r => r_abs,
round_style => round_style));
neg_result := -result;
if l(l'high) = '1' then
result := neg_result(result'range);
end if;
return result;
end function remainder;
fn"mod"
lines 801–819
"mod" -- 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";
fnmodulo
lines 820–895
modulo -- 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;
pradd_carry
lines 896–957
add_carry -- Procedure for those who need an "accumulator" function
procedure add_carry (
L, R : in UNRESOLVED_ufixed;
c_in : in STD_ULOGIC;
result : out UNRESOLVED_ufixed;
c_out : out STD_ULOGIC) is
constant left_index : INTEGER := maximum(L'high, R'high)+1;
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable cx : UNRESOLVED_UNSIGNED (0 downto 0); -- Carry in
begin
if (L'length < 1 or R'length < 1) then
result := NAUF;
c_out := '0';
else
cx (0) := c_in;
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
result_slv := lslv + rslv + cx;
c_out := result_slv(left_index-right_index);
result := to_fixed(result_slv (left_index-right_index-1 downto 0),
left_index-1, right_index);
end if;
end procedure add_carry;
procedure add_carry (
L, R : in UNRESOLVED_sfixed;
c_in : in STD_ULOGIC;
result : out UNRESOLVED_sfixed;
c_out : out STD_ULOGIC) is
constant left_index : INTEGER := maximum(L'high, R'high)+1;
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index
downto 0);
variable result_slv : UNRESOLVED_SIGNED (left_index-right_index
downto 0);
variable cx : UNRESOLVED_SIGNED (1 downto 0); -- Carry in
begin
if (L'length < 1 or R'length < 1) then
result := NASF;
c_out := '0';
else
cx (1) := '0';
cx (0) := c_in;
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
result_slv := lslv + rslv + cx;
c_out := result_slv(left_index-right_index);
result := to_fixed(result_slv (left_index-right_index-1 downto 0),
left_index-1, right_index);
end if;
end procedure add_carry;
fnscalb
lines 958–999
scalb -- Scales the result by a power of 2. Width of input = width of output with
-- the decimal point moved.
function scalb (y : UNRESOLVED_ufixed; N : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (y'high+N downto y'low+N);
begin
if y'length < 1 then
return NAUF;
else
result := y;
return result;
end if;
end function scalb;
function scalb (y : UNRESOLVED_ufixed; N : UNRESOLVED_SIGNED)
return UNRESOLVED_ufixed is
begin
return scalb (y => y,
N => to_integer(N));
end function scalb;
function scalb (y : UNRESOLVED_sfixed; N : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (y'high+N downto y'low+N);
begin
if y'length < 1 then
return NASF;
else
result := y;
return result;
end if;
end function scalb;
function scalb (y : UNRESOLVED_sfixed; N : UNRESOLVED_SIGNED)
return UNRESOLVED_sfixed is
begin
return scalb (y => y,
N => to_integer(N));
end function scalb;
fnIs_Negative
lines 1000–1008
Is_Negative 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;
fnfind_rightmost
lines 1009–1019
find_rightmost function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'reverse_range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'high+1; -- return out of bounds 'high
end function find_rightmost;
fnfind_leftmost
lines 1020–1030
find_leftmost function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'low-1; -- return out of bounds 'low
end function find_leftmost;
fnfind_rightmost
lines 1031–1041
find_rightmost function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'reverse_range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'high+1; -- return out of bounds 'high
end function find_rightmost;
fnfind_leftmost
lines 1042–1052
find_leftmost function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'low-1; -- return out of bounds 'low
end function find_leftmost;
fn"sll"
lines 1053–1064
"sll" function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv sll COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sll";
fn"srl"
lines 1065–1076
"srl" function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv srl COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "srl";
fn"rol"
lines 1077–1088
"rol" function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv rol COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "rol";
fn"ror"
lines 1089–1100
"ror" function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv ror COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "ror";
fn"sla"
lines 1101–1113
"sla" function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
-- Arithmetic shift on an unsigned is a logical shift
argslv := argslv sll COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sla";
fn"sra"
lines 1114–1126
"sra" function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
-- Arithmetic shift on an unsigned is a logical shift
argslv := argslv srl COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sra";
fn"sll"
lines 1127–1138
"sll" function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv sll COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sll";
fn"srl"
lines 1139–1150
"srl" function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv srl COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "srl";
fn"rol"
lines 1151–1162
"rol" function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv rol COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "rol";
fn"ror"
lines 1163–1174
"ror" function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv ror COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "ror";
fn"sla"
lines 1175–1191
"sla" function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
if COUNT > 0 then
-- Arithmetic shift left on a 2's complement number is a logic shift
argslv := argslv sll COUNT;
else
argslv := argslv sra -COUNT;
end if;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sla";
fn"sra"
lines 1192–1208
"sra" function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
if COUNT > 0 then
argslv := argslv sra COUNT;
else
-- Arithmetic shift left on a 2's complement number is a logic shift
argslv := argslv sll -COUNT;
end if;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sra";
fnSHIFT_LEFT, SHIFT_RIGHT
lines 1209–1244
SHIFT_LEFT, SHIFT_RIGHT -- 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
----------------------------------------------------------------------------
-- logical functions
----------------------------------------------------------------------------fn"not"
lines 1249–1255
"not" 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";
fn"and"
lines 1256–1270
"and" function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) and to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """and"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "and";
fn"or"
lines 1271–1285
"or" function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) or to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """or"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "or";
fn"nand"
lines 1286–1300
"nand" function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nand to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nand"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "nand";
fn"nor"
lines 1301–1315
"nor" function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "nor";
fn"xor"
lines 1316–1330
"xor" function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "xor";
fn"xnor"
lines 1331–1345
"xnor" function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xnor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xnor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "xnor";
fn"not"
lines 1346–1352
"not" 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";
fn"and"
lines 1353–1367
"and" function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) and to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """and"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "and";
fn"or"
lines 1368–1382
"or" function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) or to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """or"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "or";
fn"nand"
lines 1383–1397
"nand" function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nand to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nand"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "nand";
fn"nor"
lines 1398–1412
"nor" function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "nor";
fn"xor"
lines 1413–1427
"xor" function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "xor";
fn"xnor"
lines 1428–1442
"xnor" function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xnor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xnor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "xnor";
fn"and"
lines 1443–1465
"and" -- 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";
fn"or"
lines 1466–1487
"or" 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";
fn"nand"
lines 1488–1509
"nand" 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";
fn"nor"
lines 1510–1531
"nor" 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";
fn"xor"
lines 1532–1553
"xor" 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";
fn"xnor"
lines 1554–1575
"xnor" 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";
fn"and"
lines 1576–1597
"and" 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";
fn"or"
lines 1598–1619
"or" 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";
fn"nand"
lines 1620–1641
"nand" 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";
fn"nor"
lines 1642–1663
"nor" 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";
fn"xor"
lines 1664–1685
"xor" 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";
fn"xnor"
lines 1686–1707
"xnor" 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";
fn"and"
lines 1708–1713
"and" -- Reduction operators
function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return and to_sulv(l);
end function "and";
fn"nand"
lines 1714–1718
"nand" function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return nand to_sulv(l);
end function "nand";
fn"or"
lines 1719–1723
"or" function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return or to_sulv(l);
end function "or";
fn"nor"
lines 1724–1728
"nor" function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return nor to_sulv(l);
end function "nor";
fn"xor"
lines 1729–1733
"xor" function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return xor to_sulv(l);
end function "xor";
fn"xnor"
lines 1734–1738
"xnor" function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return xnor to_sulv(l);
end function "xnor";
fn"and"
lines 1739–1743
"and" function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return and to_sulv(l);
end function "and";
fn"nand"
lines 1744–1748
"nand" function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return nand to_sulv(l);
end function "nand";
fn"or"
lines 1749–1753
"or" function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return or to_sulv(l);
end function "or";
fn"nor"
lines 1754–1758
"nor" function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return nor to_sulv(l);
end function "nor";
fn"xor"
lines 1759–1763
"xor" function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return xor to_sulv(l);
end function "xor";
fn"xnor"
lines 1764–1767
"xnor" function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return xnor to_sulv(l);
end function "xnor";fn"?="
lines 1768–1790
"?=" -- End reduction operators
function "?=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?= rslv;
end if;
end function "?=";
fn"?/="
lines 1791–1811
"?/=" function "?/=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?/=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?/="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?/= rslv;
end if;
end function "?/=";
fn"?>"
lines 1812–1832
"?>" function "?>" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?>
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?> rslv;
end if;
end function "?>";
fn"?>="
lines 1833–1853
"?>=" function "?>=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?>=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?>= rslv;
end if;
end function "?>=";
fn"?<"
lines 1854–1874
"?<" function "?<" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?<
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?< rslv;
end if;
end function "?<";
fn"?<="
lines 1875–1895
"?<=" function "?<=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?<=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?<= rslv;
end if;
end function "?<=";
fn"?="
lines 1896–1916
"?=" function "?=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?= rslv;
end if;
end function "?=";
fn"?/="
lines 1917–1937
"?/=" function "?/=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?/=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?/="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?/= rslv;
end if;
end function "?/=";
fn"?>"
lines 1938–1958
"?>" function "?>" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?>
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?> rslv;
end if;
end function "?>";
fn"?>="
lines 1959–1979
"?>=" function "?>=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?>=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?>= rslv;
end if;
end function "?>=";
fn"?<"
lines 1980–2000
"?<" function "?<" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?<
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?< rslv;
end if;
end function "?<";
fn"?<="
lines 2001–2021
"?<=" function "?<=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?<=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?<= rslv;
end if;
end function "?<=";
fnstd_match
lines 2022–2048
std_match -- Match function, similar to "std_match" from numeric_std
function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is
begin
if (L'high = R'high and L'low = R'low) then
return std_match(to_sulv(L), to_sulv(R));
else
assert no_warning
report fixed_generic_pkg'instance_name
& "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
severity warning;
return false;
end if;
end function std_match;
function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is
begin
if (L'high = R'high and L'low = R'low) then
return std_match(to_sulv(L), to_sulv(R));
else
assert no_warning
report fixed_generic_pkg'instance_name
& "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
severity warning;
return false;
end if;
end function std_match;
fn"="
lines 2049–2107
"=" -- compare functions
function "=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv = rslv;
end function "=";
function "=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv = rslv;
end function "=";
fn"/="
lines 2108–2165
"/=" function "/=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": null argument detected, returning TRUE"
severity warning;
return true;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": metavalue detected, returning TRUE"
severity warning;
return true;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv /= rslv;
end function "/=";
function "/=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": null argument detected, returning TRUE"
severity warning;
return true;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": metavalue detected, returning TRUE"
severity warning;
return true;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv /= rslv;
end function "/=";
fn">"
lines 2166–2223
">" function ">" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv > rslv;
end function ">";
function ">" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv > rslv;
end function ">";
fn"<"
lines 2224–2281
"<" function "<" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv < rslv;
end function "<";
function "<" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv < rslv;
end function "<";
fn">="
lines 2282–2339
">=" function ">=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv >= rslv;
end function ">=";
function ">=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv >= rslv;
end function ">=";
fn"<="
lines 2340–2397
"<=" function "<=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv <= rslv;
end function "<=";
function "<=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv <= rslv;
end function "<=";
fnmaximum
lines 2398–2426
maximum -- overloads of the default maximum and minimum functions
function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(maximum(to_uns(lresize), to_uns(rresize)),
left_index, right_index);
end function maximum;
function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(maximum(to_s(lresize), to_s(rresize)),
left_index, right_index);
end function maximum;
fnminimum
lines 2427–2454
minimum function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(minimum(to_uns(lresize), to_uns(rresize)),
left_index, right_index);
end function minimum;
function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(minimum(to_s(lresize), to_s(rresize)),
left_index, right_index);
end function minimum;
fnto_ufixed
lines 2455–2501
to_ufixed function to_ufixed (
arg : NATURAL; -- integer
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER := 0; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_ufixed (left_index downto fw);
variable sresult : UNRESOLVED_ufixed (left_index downto 0) :=
(others => '0'); -- integer portion
variable argx : NATURAL; -- internal version of arg
begin
if (result'length < 1) then
return NAUF;
end if;
if arg /= 0 then
argx := arg;
for I in 0 to sresult'left loop
if (argx mod 2) = 0 then
sresult(I) := '0';
else
sresult(I) := '1';
end if;
argx := argx/2;
end loop;
if argx /= 0 then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_UFIXED(NATURAL): vector truncated"
severity warning;
if overflow_style = fixed_saturate then
return saturate (left_index, right_index);
end if;
end if;
result := resize (arg => sresult,
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
else
result := (others => '0');
end if;
return result;
end function to_ufixed;
fnto_sfixed
lines 2502–2560
to_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
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_sfixed (left_index downto fw);
variable sresult : UNRESOLVED_sfixed (left_index downto 0) :=
(others => '0'); -- integer portion
variable argx : INTEGER; -- internal version of arg
variable sign : STD_ULOGIC; -- sign of input
begin
if (result'length < 1) then -- null range
return NASF;
end if;
if arg /= 0 then
if (arg < 0) then
sign := '1';
argx := -(arg + 1);
else
sign := '0';
argx := arg;
end if;
for I in 0 to sresult'left loop
if (argx mod 2) = 0 then
sresult(I) := sign;
else
sresult(I) := not sign;
end if;
argx := argx/2;
end loop;
if argx /= 0 or left_index < 0 or sign /= sresult(sresult'left) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_SFIXED(INTEGER): vector truncated"
severity warning;
if overflow_style = fixed_saturate then -- saturate
if arg < 0 then
result := not saturate (result'high, result'low); -- underflow
else
result := saturate (result'high, result'low); -- overflow
end if;
return result;
end if;
end if;
result := resize (arg => sresult,
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
else
result := (others => '0');
end if;
return result;
end function to_sfixed;
fnto_ufixed
lines 2561–2618
to_ufixed function to_ufixed (
arg : REAL; -- real
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_ufixed (left_index downto fw) :=
(others => '0');
variable Xresult : UNRESOLVED_ufixed (left_index downto
fw-guard_bits) :=
(others => '0');
variable presult : REAL;
begin
-- If negative or null range, return.
if (left_index < fw) then
return NAUF;
end if;
if (arg < 0.0) then
report fixed_generic_pkg'instance_name
& "TO_UFIXED: Negative argument passed "
& REAL'image(arg) severity error;
return result;
end if;
presult := arg;
if presult >= (2.0**(left_index+1)) then
assert no_warning report fixed_generic_pkg'instance_name
& "TO_UFIXED(REAL): vector truncated"
severity warning;
if overflow_style = fixed_wrap then
presult := presult mod (2.0**(left_index+1)); -- wrap
else
return saturate (result'high, result'low);
end if;
end if;
for i in Xresult'range loop
if presult >= 2.0**i then
Xresult(i) := '1';
presult := presult - 2.0**i;
else
Xresult(i) := '0';
end if;
end loop;
if guard_bits > 0 and round_style = fixed_round then
result := round_fixed (arg => Xresult (left_index
downto right_index),
remainder => Xresult (right_index-1 downto
right_index-guard_bits),
overflow_style => overflow_style);
else
result := Xresult (result'range);
end if;
return result;
end function to_ufixed;
fnto_sfixed
lines 2619–2677
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) -- # of guard bits
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_sfixed (left_index downto fw) :=
(others => '0');
variable Xresult : UNRESOLVED_sfixed (left_index+1 downto fw-guard_bits) :=
(others => '0');
variable presult : REAL;
begin
if (left_index < fw) then -- null range
return NASF;
end if;
if (arg >= (2.0**left_index) or arg < -(2.0**left_index)) then
assert no_warning report fixed_generic_pkg'instance_name
& "TO_SFIXED(REAL): vector truncated"
severity warning;
if overflow_style = fixed_saturate then
if arg < 0.0 then -- saturate
result := not saturate (result'high, result'low); -- underflow
else
result := saturate (result'high, result'low); -- overflow
end if;
return result;
else
presult := abs(arg) mod (2.0**(left_index+1)); -- wrap
end if;
else
presult := abs(arg);
end if;
for i in Xresult'range loop
if presult >= 2.0**i then
Xresult(i) := '1';
presult := presult - 2.0**i;
else
Xresult(i) := '0';
end if;
end loop;
if arg < 0.0 then
Xresult := to_fixed(-to_s(Xresult), Xresult'high, Xresult'low);
end if;
if guard_bits > 0 and round_style = fixed_round then
result := round_fixed (arg => Xresult (left_index
downto right_index),
remainder => Xresult (right_index-1 downto
right_index-guard_bits),
overflow_style => overflow_style);
else
result := Xresult (result'range);
end if;
return result;
end function to_sfixed;
fnto_ufixed
lines 2678–2714
to_ufixed function to_ufixed (
arg : UNRESOLVED_UNSIGNED; -- unsigned
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER := 0; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
variable result : UNRESOLVED_ufixed (left_index downto right_index);
begin
if arg'length < 1 or (left_index < right_index) then
return NAUF;
end if;
result := resize (arg => UNRESOLVED_ufixed (XARG),
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
return result;
end function to_ufixed;
-- converted version
function to_ufixed (
arg : UNRESOLVED_UNSIGNED) -- unsigned
return UNRESOLVED_ufixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
begin
if arg'length < 1 then
return NAUF;
end if;
return UNRESOLVED_ufixed(XARG);
end function to_ufixed;
fnto_sfixed
lines 2715–2762
to_sfixed function to_sfixed (
arg : UNRESOLVED_SIGNED; -- signed
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER := 0; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin
if arg'length < 1 or (left_index < right_index) then
return NASF;
end if;
result := resize (arg => UNRESOLVED_sfixed (XARG),
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
return result;
end function to_sfixed;
-- converted version
function to_sfixed (
arg : UNRESOLVED_SIGNED) -- signed
return UNRESOLVED_sfixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
begin
if arg'length < 1 then
return NASF;
end if;
return UNRESOLVED_sfixed(XARG);
end function to_sfixed;
function to_sfixed (arg : UNRESOLVED_ufixed) return UNRESOLVED_sfixed is
variable result : UNRESOLVED_sfixed (arg'high+1 downto arg'low);
begin
if arg'length < 1 then
return NASF;
end if;
result (arg'high downto arg'low) := UNRESOLVED_sfixed(cleanvec(arg));
result (arg'high+1) := '0';
return result;
end function to_sfixed;
fnufixed_high
lines 2763–2788
ufixed_high -- 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;
fnufixed_low
lines 2789–2804
ufixed_low 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;
fnsfixed_high
lines 2805–2822
sfixed_high 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;
fnsfixed_low
lines 2823–2838
sfixed_low 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;
fnufixed_high
lines 2839–2854
ufixed_high -- 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;
fnufixed_low
lines 2855–2866
ufixed_low 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;
fnsfixed_high
lines 2867–2878
sfixed_high 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;
fnsfixed_low
lines 2879–2890
sfixed_low 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;
fnsaturate
lines 2891–2930
saturate -- 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;
fnto_UFix
lines 2931–2959
to_UFix -- As a concession to those who use a graphical DSP environment,
-- these functions take parameters in those tools format and create
-- fixed point numbers. These functions are designed to convert from
-- a std_logic_vector to the VHDL fixed point format using the conventions
-- of these packages. In a pure VHDL environment you should use the
-- "to_ufixed" and "to_sfixed" routines.
-- Unsigned fixed point
function to_UFix (
arg : STD_ULOGIC_VECTOR;
width : NATURAL; -- width of vector
fraction : NATURAL) -- width of fraction
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (width-fraction-1 downto -fraction);
begin
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name
& "TO_UFIX (STD_ULOGIC_VECTOR) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NAUF;
else
result := to_ufixed (arg, result'high, result'low);
return result;
end if;
end function to_UFix;
fnto_SFix
lines 2960–2982
to_SFix -- signed fixed point
function to_SFix (
arg : STD_ULOGIC_VECTOR;
width : NATURAL; -- width of vector
fraction : NATURAL) -- width of fraction
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (width-fraction-1 downto -fraction);
begin
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name
& "TO_SFIX (STD_ULOGIC_VECTOR) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NASF;
else
result := to_sfixed (arg, result'high, result'low);
return result;
end if;
end function to_SFix;
fnufix_high
lines 2983–3003
ufix_high -- 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;
fnufix_low
lines 3004–3016
ufix_low 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;
fnsfix_high
lines 3017–3029
sfix_high 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;
fnsfix_low
lines 3030–3042
sfix_low 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;
fnto_unsigned
lines 3043–3069
to_unsigned function to_unsigned (
arg : UNRESOLVED_ufixed; -- ufixed point input
constant size : NATURAL; -- length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_UNSIGNED is
begin
return to_uns(resize (arg => arg,
left_index => size-1,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
end function to_unsigned;
function to_unsigned (
arg : UNRESOLVED_ufixed; -- ufixed point input
size_res : UNRESOLVED_UNSIGNED; -- length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_UNSIGNED is
begin
return to_unsigned (arg => arg,
size => size_res'length,
round_style => round_style,
overflow_style => overflow_style);
end function to_unsigned;
fnto_signed
lines 3070–3096
to_signed function to_signed (
arg : UNRESOLVED_sfixed; -- sfixed point input
constant size : NATURAL; -- length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_SIGNED is
begin
return to_s(resize (arg => arg,
left_index => size-1,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
end function to_signed;
function to_signed (
arg : UNRESOLVED_sfixed; -- sfixed point input
size_res : UNRESOLVED_SIGNED; -- used for length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_SIGNED is
begin
return to_signed (arg => arg,
size => size_res'length,
round_style => round_style,
overflow_style => overflow_style);
end function to_signed;
fnto_real
lines 3097–3156
to_real function to_real (
arg : UNRESOLVED_ufixed) -- ufixed point input
return REAL
is
constant left_index : INTEGER := arg'high;
constant right_index : INTEGER := arg'low;
variable result : REAL; -- result
variable arg_int : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (arg'length < 1) then
return 0.0;
end if;
arg_int := To_X01(cleanvec(arg));
if (Is_X(arg_int)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_REAL (ufixed): metavalue detected, returning 0.0"
severity warning;
return 0.0;
end if;
result := 0.0;
for i in arg_int'range loop
if (arg_int(i) = '1') then
result := result + (2.0**i);
end if;
end loop;
return result;
end function to_real;
function to_real (
arg : UNRESOLVED_sfixed) -- ufixed point input
return REAL
is
constant left_index : INTEGER := arg'high;
constant right_index : INTEGER := arg'low;
variable result : REAL; -- result
variable arg_int : UNRESOLVED_sfixed (left_index downto right_index);
-- unsigned version of argument
variable arg_uns : UNRESOLVED_ufixed (left_index downto right_index);
-- absolute of argument
begin
if (arg'length < 1) then
return 0.0;
end if;
arg_int := to_X01(cleanvec(arg));
if (Is_X(arg_int)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_REAL (sfixed): metavalue detected, returning 0.0"
severity warning;
return 0.0;
end if;
arg_uns := to_ufixed (arg_int);
result := to_real (arg_uns);
if (arg_int(arg_int'high) = '1') then
result := -result;
end if;
return result;
end function to_real;
fnto_integer
lines 3157–3217
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
is
constant left_index : INTEGER := arg'high;
variable arg_uns : UNRESOLVED_UNSIGNED (left_index+1 downto 0)
:= (others => '0');
begin
if (arg'length < 1) then
return 0;
end if;
if (Is_X (arg)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_INTEGER (ufixed): metavalue detected, returning 0"
severity warning;
return 0;
end if;
if (left_index < -1) then
return 0;
end if;
arg_uns := to_uns(resize (arg => arg,
left_index => arg_uns'high,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
return to_integer (arg_uns);
end function to_integer;
function to_integer (
arg : UNRESOLVED_sfixed; -- fixed point input
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return INTEGER
is
constant left_index : INTEGER := arg'high;
variable arg_s : UNRESOLVED_SIGNED (left_index+1 downto 0);
begin
if (arg'length < 1) then
return 0;
end if;
if (Is_X (arg)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_INTEGER (sfixed): metavalue detected, returning 0"
severity warning;
return 0;
end if;
if (left_index < -1) then
return 0;
end if;
arg_s := to_s(resize (arg => arg,
left_index => arg_s'high,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
return to_integer (arg_s);
end function to_integer;
fnto_01
lines 3218–3249
to_01 function to_01 (
s : UNRESOLVED_ufixed; -- ufixed point input
constant XMAP : STD_ULOGIC := '0') -- Map x to
return UNRESOLVED_ufixed
is
begin
if (s'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_01(ufixed): null detected, returning NULL"
severity warning;
return NAUF;
end if;
return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low);
end function to_01;
function to_01 (
s : UNRESOLVED_sfixed; -- sfixed point input
constant XMAP : STD_ULOGIC := '0') -- Map x to
return UNRESOLVED_sfixed
is
begin
if (s'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_01(sfixed): null detected, returning NULL"
severity warning;
return NASF;
end if;
return to_fixed (to_01(to_s(s), XMAP), s'high, s'low);
end function to_01;
fnIs_X
lines 3250–3269
Is_X 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;
fnTo_X01
lines 3270–3276
To_X01 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;
fnto_X01
lines 3277–3283
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;
fnTo_X01Z
lines 3284–3290
To_X01Z 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;
fnto_X01Z
lines 3291–3297
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;
fnTo_UX01
lines 3298–3304
To_UX01 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;
fnto_UX01
lines 3305–3311
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;
fnresize
lines 3312–3473
resize function resize (
arg : UNRESOLVED_ufixed; -- input
constant left_index : INTEGER; -- integer portion
constant right_index : INTEGER; -- size of fraction
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant arghigh : INTEGER := maximum (arg'high, arg'low);
constant arglow : INTEGER := mine (arg'high, arg'low);
variable invec : UNRESOLVED_ufixed (arghigh downto arglow);
variable result : UNRESOLVED_ufixed(left_index downto right_index) :=
(others => '0');
variable needs_rounding : BOOLEAN := false;
begin -- resize
if (arg'length < 1) or (result'length < 1) then
return NAUF;
elsif (invec'length < 1) then
return result; -- string literal value
else
invec := cleanvec(arg);
if (right_index > arghigh) then -- return top zeros
needs_rounding := (round_style = fixed_round) and
(right_index = arghigh+1);
elsif (left_index < arglow) then -- return overflow
if (overflow_style = fixed_saturate) and
(or(to_sulv(invec)) = '1') then
result := saturate (result'high, result'low); -- saturate
end if;
elsif (arghigh > left_index) then
-- wrap or saturate?
if (overflow_style = fixed_saturate and
or (to_sulv(invec(arghigh downto left_index+1))) = '1')
then
result := saturate (result'high, result'low); -- saturate
else
if (arglow >= right_index) then
result (left_index downto arglow) :=
invec(left_index downto arglow);
else
result (left_index downto right_index) :=
invec (left_index downto right_index);
needs_rounding := (round_style = fixed_round); -- round
end if;
end if;
else -- arghigh <= integer width
if (arglow >= right_index) then
result (arghigh downto arglow) := invec;
else
result (arghigh downto right_index) :=
invec (arghigh downto right_index);
needs_rounding := (round_style = fixed_round); -- round
end if;
end if;
-- Round result
if needs_rounding then
result := round_fixed (arg => result,
remainder => invec (right_index-1
downto arglow),
overflow_style => overflow_style);
end if;
return result;
end if;
end function resize;
function resize (
arg : UNRESOLVED_sfixed; -- input
constant left_index : INTEGER; -- integer portion
constant right_index : INTEGER; -- size of fraction
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
is
constant arghigh : INTEGER := maximum (arg'high, arg'low);
constant arglow : INTEGER := mine (arg'high, arg'low);
variable invec : UNRESOLVED_sfixed (arghigh downto arglow);
variable result : UNRESOLVED_sfixed(left_index downto right_index) :=
(others => '0');
variable reduced : STD_ULOGIC;
variable needs_rounding : BOOLEAN := false; -- rounding
begin -- resize
if (arg'length < 1) or (result'length < 1) then
return NASF;
elsif (invec'length < 1) then
return result; -- string literal value
else
invec := cleanvec(arg);
if (right_index > arghigh) then -- return top zeros
if (arg'low /= INTEGER'low) then -- check for a literal
result := (others => arg(arghigh)); -- sign extend
end if;
needs_rounding := (round_style = fixed_round) and
(right_index = arghigh+1);
elsif (left_index < arglow) then -- return overflow
if (overflow_style = fixed_saturate) then
reduced := or (to_sulv(invec));
if (reduced = '1') then
if (invec(arghigh) = '0') then
-- saturate POSITIVE
result := saturate (result'high, result'low);
else
-- saturate negative
result := not saturate (result'high, result'low);
end if;
-- else return 0 (input was 0)
end if;
-- else return 0 (wrap)
end if;
elsif (arghigh > left_index) then
if (invec(arghigh) = '0') then
reduced := or (to_sulv(invec(arghigh-1 downto
left_index)));
if overflow_style = fixed_saturate and reduced = '1' then
-- saturate positive
result := saturate (result'high, result'low);
else
if (right_index > arglow) then
result := invec (left_index downto right_index);
needs_rounding := (round_style = fixed_round);
else
result (left_index downto arglow) :=
invec (left_index downto arglow);
end if;
end if;
else
reduced := and (to_sulv(invec(arghigh-1 downto
left_index)));
if overflow_style = fixed_saturate and reduced = '0' then
result := not saturate (result'high, result'low);
else
if (right_index > arglow) then
result := invec (left_index downto right_index);
needs_rounding := (round_style = fixed_round);
else
result (left_index downto arglow) :=
invec (left_index downto arglow);
end if;
end if;
end if;
else -- arghigh <= integer width
if (arglow >= right_index) then
result (arghigh downto arglow) := invec;
else
result (arghigh downto right_index) :=
invec (arghigh downto right_index);
needs_rounding := (round_style = fixed_round); -- round
end if;
if (left_index > arghigh) then -- sign extend
result(left_index downto arghigh+1) := (others => invec(arghigh));
end if;
end if;
-- Round result
if (needs_rounding) then
result := round_fixed (arg => result,
remainder => invec (right_index-1
downto arglow),
overflow_style => overflow_style);
end if;
return result;
end if;
end function resize;
fnto_ufixed
lines 3474–3495
to_ufixed -- 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;
fnto_sfixed
lines 3496–3513
to_sfixed 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;
fnto_ufixed
lines 3514–3535
to_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
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;
fnto_sfixed
lines 3536–3557
to_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
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;
fnto_ufixed
lines 3558–3581
to_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) -- # 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;
fnto_sfixed
lines 3582–3605
to_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) -- # 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;
fnto_ufixed
lines 3606–3627
to_ufixed function to_ufixed (
arg : UNRESOLVED_UNSIGNED; -- unsigned
size_res : UNRESOLVED_ufixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
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;
fnto_sfixed
lines 3628–3649
to_sfixed function to_sfixed (
arg : UNRESOLVED_SIGNED; -- signed
size_res : UNRESOLVED_sfixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
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;
fnresize
lines 3650–3693
resize 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;
fn"+"
lines 3694–3726
"+" -- 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 "+";
fn"-"
lines 3727–3758
"-" 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 "-";
fn"*"
lines 3759–3790
"*" 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 "*";
fn"/"
lines 3791–3822
"/" 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 "/";
fn"rem"
lines 3823–3854
"rem" 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";
fn"mod"
lines 3855–3886
"mod" 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";
fn"+"
lines 3887–3919
"+" -- 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 "+";
fn"-"
lines 3920–3952
"-" -- 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 "-";
fn"*"
lines 3953–3985
"*" -- 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 "*";
fn"/"
lines 3986–4018
"/" -- 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 "/";
fn"rem"
lines 4019–4050
"rem" 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";
fn"mod"
lines 4051–4082
"mod" 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";
fn"="
lines 4083–4091
"=" -- 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 "=";
fn"/="
lines 4092–4099
"/=" function "/=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l /= to_ufixed (r, l'high, l'low));
end function "/=";
fn">="
lines 4100–4107
">=" function ">=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l >= to_ufixed (r, l'high, l'low));
end function ">=";
fn"<="
lines 4108–4115
"<=" function "<=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l <= to_ufixed (r, l'high, l'low));
end function "<=";
fn">"
lines 4116–4123
">" function ">" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l > to_ufixed (r, l'high, l'low));
end function ">";
fn"<"
lines 4124–4131
"<" function "<" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l < to_ufixed (r, l'high, l'low));
end function "<";
fn"?="
lines 4132–4139
"?=" 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 "?=";
fn"?/="
lines 4140–4147
"?/=" 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 "?/=";
fn"?>="
lines 4148–4155
"?>=" 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 "?>=";
fn"?<="
lines 4156–4163
"?<=" 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 "?<=";
fn"?>"
lines 4164–4171
"?>" 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 "?>";
fn"?<"
lines 4172–4179
"?<" 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 "?<";
fnmaximum
lines 4180–4187
maximum 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;
fnminimum
lines 4188–4195
minimum 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;
fn"="
lines 4196–4204
"=" -- 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 "=";
fn"/="
lines 4205–4212
"/=" function "/=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) /= r);
end function "/=";
fn">="
lines 4213–4220
">=" function ">=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) >= r);
end function ">=";
fn"<="
lines 4221–4228
"<=" function "<=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) <= r);
end function "<=";
fn">"
lines 4229–4236
">" function ">" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) > r);
end function ">";
fn"<"
lines 4237–4244
"<" function "<" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) < r);
end function "<";
fn"?="
lines 4245–4252
"?=" 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 "?=";
fn"?/="
lines 4253–4260
"?/=" 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 "?/=";
fn"?>="
lines 4261–4268
"?>=" 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 "?>=";
fn"?<="
lines 4269–4276
"?<=" 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 "?<=";
fn"?>"
lines 4277–4284
"?>" 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 "?>";
fn"?<"
lines 4285–4292
"?<" 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 "?<";
fnmaximum
lines 4293–4300
maximum 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;
fnminimum
lines 4301–4308
minimum 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;
fn"="
lines 4309–4317
"=" -- 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 "=";
fn"/="
lines 4318–4325
"/=" function "/=" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l /= to_ufixed (r, l'high, l'low));
end function "/=";
fn">="
lines 4326–4333
">=" function ">=" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l >= to_ufixed (r, l'high, l'low));
end function ">=";
fn"<="
lines 4334–4341
"<=" function "<=" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l <= to_ufixed (r, l'high, l'low));
end function "<=";
fn">"
lines 4342–4349
">" function ">" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l > to_ufixed (r, l'high, l'low));
end function ">";
fn"<"
lines 4350–4357
"<" function "<" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l < to_ufixed (r, l'high, l'low));
end function "<";
fn"?="
lines 4358–4365
"?=" function "?=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?= to_ufixed (r, l'high, l'low));
end function "?=";
fn"?/="
lines 4366–4373
"?/=" function "?/=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?/= to_ufixed (r, l'high, l'low));
end function "?/=";
fn"?>="
lines 4374–4381
"?>=" function "?>=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?>= to_ufixed (r, l'high, l'low));
end function "?>=";
fn"?<="
lines 4382–4389
"?<=" function "?<=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?<= to_ufixed (r, l'high, l'low));
end function "?<=";
fn"?>"
lines 4390–4397
"?>" function "?>" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?> to_ufixed (r, l'high, l'low));
end function "?>";
fn"?<"
lines 4398–4405
"?<" function "?<" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?< to_ufixed (r, l'high, l'low));
end function "?<";
fnmaximum
lines 4406–4413
maximum 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;
fnminimum
lines 4414–4421
minimum 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;
fn"="
lines 4422–4430
"=" -- 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 "=";
fn"/="
lines 4431–4438
"/=" function "/=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) /= r);
end function "/=";
fn">="
lines 4439–4446
">=" function ">=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) >= r);
end function ">=";
fn"<="
lines 4447–4454
"<=" function "<=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) <= r);
end function "<=";
fn">"
lines 4455–4462
">" function ">" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) > r);
end function ">";
fn"<"
lines 4463–4470
"<" function "<" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) < r);
end function "<";
fn"?="
lines 4471–4478
"?=" 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 "?=";
fn"?/="
lines 4479–4486
"?/=" 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 "?/=";
fn"?>="
lines 4487–4494
"?>=" 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 "?>=";
fn"?<="
lines 4495–4502
"?<=" 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 "?<=";
fn"?>"
lines 4503–4510
"?>" 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 "?>";
fn"?<"
lines 4511–4518
"?<" 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 "?<";
fnmaximum
lines 4519–4526
maximum 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;
fnminimum
lines 4527–4534
minimum 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;
fn"="
lines 4535–4543
"=" -- 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 "=";
fn"/="
lines 4544–4551
"/=" function "/=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l /= to_sfixed (r, l'high, l'low));
end function "/=";
fn">="
lines 4552–4559
">=" function ">=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l >= to_sfixed (r, l'high, l'low));
end function ">=";
fn"<="
lines 4560–4567
"<=" function "<=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l <= to_sfixed (r, l'high, l'low));
end function "<=";
fn">"
lines 4568–4575
">" function ">" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l > to_sfixed (r, l'high, l'low));
end function ">";
fn"<"
lines 4576–4583
"<" function "<" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l < to_sfixed (r, l'high, l'low));
end function "<";
fn"?="
lines 4584–4591
"?=" function "?=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?= to_sfixed (r, l'high, l'low));
end function "?=";
fn"?/="
lines 4592–4599
"?/=" function "?/=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?/= to_sfixed (r, l'high, l'low));
end function "?/=";
fn"?>="
lines 4600–4607
"?>=" function "?>=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?>= to_sfixed (r, l'high, l'low));
end function "?>=";
fn"?<="
lines 4608–4615
"?<=" function "?<=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?<= to_sfixed (r, l'high, l'low));
end function "?<=";
fn"?>"
lines 4616–4623
"?>" function "?>" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?> to_sfixed (r, l'high, l'low));
end function "?>";
fn"?<"
lines 4624–4631
"?<" function "?<" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?< to_sfixed (r, l'high, l'low));
end function "?<";
fnmaximum
lines 4632–4639
maximum 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;
fnminimum
lines 4640–4647
minimum 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;
fn"="
lines 4648–4656
"=" -- 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 "=";
fn"/="
lines 4657–4664
"/=" function "/=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) /= r);
end function "/=";
fn">="
lines 4665–4672
">=" function ">=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) >= r);
end function ">=";
fn"<="
lines 4673–4680
"<=" function "<=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) <= r);
end function "<=";
fn">"
lines 4681–4688
">" function ">" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) > r);
end function ">";
fn"<"
lines 4689–4696
"<" function "<" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) < r);
end function "<";
fn"?="
lines 4697–4704
"?=" 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 "?=";
fn"?/="
lines 4705–4712
"?/=" 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 "?/=";
fn"?>="
lines 4713–4720
"?>=" 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 "?>=";
fn"?<="
lines 4721–4728
"?<=" 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 "?<=";
fn"?>"
lines 4729–4736
"?>" 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 "?>";
fn"?<"
lines 4737–4744
"?<" 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 "?<";
fnmaximum
lines 4745–4752
maximum 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;
fnminimum
lines 4753–4760
minimum 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;
fn"="
lines 4761–4769
"=" -- 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 "=";
fn"/="
lines 4770–4777
"/=" function "/=" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l /= to_sfixed (r, l'high, l'low));
end function "/=";
fn">="
lines 4778–4785
">=" function ">=" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l >= to_sfixed (r, l'high, l'low));
end function ">=";
fn"<="
lines 4786–4793
"<=" function "<=" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l <= to_sfixed (r, l'high, l'low));
end function "<=";
fn">"
lines 4794–4801
">" function ">" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l > to_sfixed (r, l'high, l'low));
end function ">";
fn"<"
lines 4802–4809
"<" function "<" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l < to_sfixed (r, l'high, l'low));
end function "<";
fn"?="
lines 4810–4817
"?=" function "?=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?= to_sfixed (r, l'high, l'low));
end function "?=";
fn"?/="
lines 4818–4825
"?/=" function "?/=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?/= to_sfixed (r, l'high, l'low));
end function "?/=";
fn"?>="
lines 4826–4833
"?>=" function "?>=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?>= to_sfixed (r, l'high, l'low));
end function "?>=";
fn"?<="
lines 4834–4841
"?<=" function "?<=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?<= to_sfixed (r, l'high, l'low));
end function "?<=";
fn"?>"
lines 4842–4849
"?>" function "?>" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?> to_sfixed (r, l'high, l'low));
end function "?>";
fn"?<"
lines 4850–4857
"?<" function "?<" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?< to_sfixed (r, l'high, l'low));
end function "?<";
fnmaximum
lines 4858–4865
maximum 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;
fnminimum
lines 4866–4873
minimum 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;
fn"="
lines 4874–4882
"=" -- 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 "=";
fn"/="
lines 4883–4890
"/=" function "/=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) /= r);
end function "/=";
fn">="
lines 4891–4898
">=" function ">=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) >= r);
end function ">=";
fn"<="
lines 4899–4906
"<=" function "<=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) <= r);
end function "<=";
fn">"
lines 4907–4914
">" function ">" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) > r);
end function ">";
fn"<"
lines 4915–4922
"<" function "<" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) < r);
end function "<";
fn"?="
lines 4923–4930
"?=" 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 "?=";
fn"?/="
lines 4931–4938
"?/=" 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 "?/=";
fn"?>="
lines 4939–4946
"?>=" 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 "?>=";
fn"?<="
lines 4947–4954
"?<=" 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 "?<=";
fn"?>"
lines 4955–4962
"?>" 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 "?>";
fn"?<"
lines 4963–4970
"?<" 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 "?<";
fnmaximum
lines 4971–4978
maximum 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;
fnminimum
lines 4979–4986
minimum 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;
tyMVL9plus
lines 4987–4988
MVL9plus -- copied from std_logic_textio
type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);tychar_indexed_by_MVL9
lines 4989–4989
char_indexed_by_MVL9 type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;tyMVL9_indexed_by_char
lines 4990–4990
MVL9_indexed_by_char type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;tyMVL9plus_indexed_by_char
lines 4991–4992
MVL9plus_indexed_by_char type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
coMVL9_to_char
lines 4993–4993
MVL9_to_char constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";cochar_to_MVL9
lines 4994–4996
char_to_MVL9 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');cochar_to_MVL9plus
lines 4997–4999
char_to_MVL9plus 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);coNBSP
lines 5000–5000
NBSP constant NBSP : CHARACTER := CHARACTER'val(160); -- space charactercoNUS
lines 5001–5002
NUS constant NUS : STRING(2 to 1) := (others => ' ');
prskip_whitespace
lines 5003–5019
skip_whitespace -- purpose: Skips white space
procedure skip_whitespace (
L : inout LINE) is
variable c : CHARACTER;
variable left : positive;
begin
while L /= null and L.all'length /= 0 loop
left := L.all'left;
c := L.all(left);
if (c = ' ' or c = NBSP or c = HT) then
read (L, c);
else
exit;
end if;
end loop;
end procedure skip_whitespace;
prwrite
lines 5020–5061
write -- 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;
prREAD
lines 5062–5270
READ procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_ufixed) is
-- Possible data: 00000.0000000
-- 000000000000
variable c : CHARACTER;
variable readOk : BOOLEAN;
variable i : INTEGER; -- index variable
variable mv : ufixed (VALUE'range);
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a "."
begin -- READ
VALUE := (VALUE'range => 'U');
skip_whitespace (L);
if VALUE'length > 0 then -- non Null input string
read (L, c, readOk);
i := VALUE'high;
while i >= VALUE'low loop
if readOk = false then -- Bail out if there was a bad read
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "End of string encountered"
severity error;
return;
elsif c = '_' then
if i = VALUE'high then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "String begins with an ""_""" severity error;
return;
elsif lastu then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Two underscores detected in input string ""__"""
severity error;
return;
else
lastu := true;
end if;
elsif c = '.' then -- binary point
if founddot then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Two binary points found in input string" severity error;
return;
elsif i /= -1 then -- Seperator in the wrong spot
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Decimal point does not match number format "
severity error;
return;
end if;
founddot := true;
lastu := false;
elsif c = ' ' or c = NBSP or c = HT then -- reading done.
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Short read, Space encounted in input string"
severity error;
return;
elsif char_to_MVL9plus(c) = error then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Character '" &
c & "' read, expected STD_ULOGIC literal."
severity error;
return;
else
mv(i) := char_to_MVL9(c);
i := i - 1;
if i < mv'low then
VALUE := mv;
return;
end if;
lastu := false;
end if;
read(L, c, readOk);
end loop;
end if;
end procedure READ;
procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_ufixed;
GOOD : out BOOLEAN) is
-- Possible data: 00000.0000000
-- 000000000000
variable c : CHARACTER;
variable readOk : BOOLEAN;
variable mv : ufixed (VALUE'range);
variable i : INTEGER; -- index variable
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a "."
begin -- READ
VALUE := (VALUE'range => 'U');
skip_whitespace (L);
if VALUE'length > 0 then
read (L, c, readOk);
i := VALUE'high;
GOOD := false;
while i >= VALUE'low loop
if not readOk then -- Bail out if there was a bad read
return;
elsif c = '_' then
if i = VALUE'high then -- Begins with an "_"
return;
elsif lastu then -- "__" detected
return;
else
lastu := true;
end if;
elsif c = '.' then -- binary point
if founddot then
return;
elsif i /= -1 then -- Seperator in the wrong spot
return;
end if;
founddot := true;
lastu := false;
elsif (char_to_MVL9plus(c) = error) then -- Illegal character/short read
return;
else
mv(i) := char_to_MVL9(c);
i := i - 1;
if i < mv'low then -- reading done
GOOD := true;
VALUE := mv;
return;
end if;
lastu := false;
end if;
read(L, c, readOk);
end loop;
else
GOOD := true; -- read into a null array
end if;
end procedure READ;
procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_sfixed) is
variable c : CHARACTER;
variable readOk : BOOLEAN;
variable i : INTEGER; -- index variable
variable mv : sfixed (VALUE'range);
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a "."
begin -- READ
VALUE := (VALUE'range => 'U');
skip_whitespace (L);
if VALUE'length > 0 then -- non Null input string
read (L, c, readOk);
i := VALUE'high;
while i >= VALUE'low loop
if readOk = false then -- Bail out if there was a bad read
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "End of string encountered"
severity error;
return;
elsif c = '_' then
if i = VALUE'high then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "String begins with an ""_""" severity error;
return;
elsif lastu then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Two underscores detected in input string ""__"""
severity error;
return;
else
lastu := true;
end if;
elsif c = '.' then -- binary point
if founddot then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Two binary points found in input string" severity error;
return;
elsif i /= -1 then -- Seperator in the wrong spot
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Decimal point does not match number format "
severity error;
return;
end if;
founddot := true;
lastu := false;
elsif c = ' ' or c = NBSP or c = HT then -- reading done.
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Short read, Space encounted in input string"
severity error;
return;
elsif char_to_MVL9plus(c) = error then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Character '" &
c & "' read, expected STD_ULOGIC literal."
severity error;
return;
else
mv(i) := char_to_MVL9(c);
i := i - 1;
if i < mv'low then
VALUE := mv;
return;
end if;
lastu := false;
end if;
read(L, c, readOk);
end loop;
end if;
end procedure READ;
procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_sfixed;
GOOD : out BOOLEAN) is
variable value_ufixed : UNRESOLVED_ufixed (VALUE'range);
begin -- READ
READ (L => L, VALUE => value_ufixed, GOOD => GOOD);
VALUE := UNRESOLVED_sfixed (value_ufixed);
end procedure READ;
prowrite
lines 5271–5295
owrite -- 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;
prChar2TriBits
lines 5296–5325
Char2TriBits -- Note that for Octal and Hex read, you can not start with a ".",
-- the read is for numbers formatted "A.BC". These routines go to
-- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
procedure Char2TriBits (C : CHARACTER;
RESULT : out STD_ULOGIC_VECTOR(2 downto 0);
GOOD : out BOOLEAN;
ISSUE_ERROR : in BOOLEAN) is
begin
case C is
when '0' => RESULT := o"0"; GOOD := true;
when '1' => RESULT := o"1"; GOOD := true;
when '2' => RESULT := o"2"; GOOD := true;
when '3' => RESULT := o"3"; GOOD := true;
when '4' => RESULT := o"4"; GOOD := true;
when '5' => RESULT := o"5"; GOOD := true;
when '6' => RESULT := o"6"; GOOD := true;
when '7' => RESULT := o"7"; GOOD := true;
when 'Z' => RESULT := "ZZZ"; GOOD := true;
when 'X' => RESULT := "XXX"; GOOD := true;
when others =>
assert not ISSUE_ERROR
report fixed_generic_pkg'instance_name
& "OREAD Error: Read a '" & C &
"', expected an Octal character (0-7)."
severity error;
RESULT := "UUU";
GOOD := false;
end case;
end procedure Char2TriBits;
prOREAD_common
lines 5326–5417
OREAD_common -- purpose: Routines common to the OREAD routines
procedure OREAD_common (
L : inout LINE;
slv : out STD_ULOGIC_VECTOR;
igood : out BOOLEAN;
idex : out INTEGER;
constant bpoint : in INTEGER; -- binary point
constant message : in BOOLEAN;
constant smath : in BOOLEAN) is
-- purpose: error message routine
procedure errmes (
constant mess : in STRING) is -- error message
begin
if message then
if smath then
report fixed_generic_pkg'instance_name
& "OREAD(sfixed) "
& mess
severity error;
else
report fixed_generic_pkg'instance_name
& "OREAD(ufixed) "
& mess
severity error;
end if;
end if;
end procedure errmes;
variable xgood : BOOLEAN;
variable nybble : STD_ULOGIC_VECTOR (2 downto 0); -- 3 bits
variable c : CHARACTER;
variable i : INTEGER;
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a dot.
begin
skip_whitespace (L);
if slv'length > 0 then
i := slv'high;
read (L, c, xgood);
while i > 0 loop
if xgood = false then
errmes ("Error: end of string encountered");
exit;
elsif c = '_' then
if i = slv'length then
errmes ("Error: String begins with an ""_""");
xgood := false;
exit;
elsif lastu then
errmes ("Error: Two underscores detected in input string ""__""");
xgood := false;
exit;
else
lastu := true;
end if;
elsif (c = '.') then
if (i + 1 /= bpoint) then
errmes ("encountered ""."" at wrong index");
xgood := false;
exit;
elsif i = slv'length then
errmes ("encounted a ""."" at the beginning of the line");
xgood := false;
exit;
elsif founddot then
errmes ("Two ""."" encounted in input string");
xgood := false;
exit;
end if;
founddot := true;
lastu := false;
else
Char2TriBits(c, nybble, xgood, message);
if not xgood then
exit;
end if;
slv (i downto i-2) := nybble;
i := i - 3;
lastu := false;
end if;
if i > 0 then
read (L, c, xgood);
end if;
end loop;
idex := i;
igood := xgood;
else
igood := true; -- read into a null array
idex := -1;
end if;
end procedure OREAD_common;
prOREAD
lines 5418–5556
OREAD -- Note that for Octal and Hex read, you can not start with a ".",
-- the read is for numbers formatted "A.BC". These routines go to
-- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
procedure OREAD (L : inout LINE;
VALUE : out UNRESOLVED_ufixed) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => false);
if igood then -- We did not get another error
if not ((i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
report fixed_generic_pkg'instance_name
& "OREAD(ufixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "OREAD(ufixed): Vector truncated"
severity warning;
end if;
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure OREAD;
procedure OREAD(L : inout LINE;
VALUE : out UNRESOLVED_ufixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => false);
if (igood and -- We did not get another error
(i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure OREAD;
procedure OREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => true);
if igood then -- We did not get another error
if not ((i = -1) and -- We read everything
((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
report fixed_generic_pkg'instance_name
& "OREAD(sfixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "OREAD(sfixed): Vector truncated"
severity warning;
end if;
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure OREAD;
procedure OREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => true);
if (igood -- We did not get another error
and (i = -1) -- We read everything
and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure OREAD;
prhwrite
lines 5557–5582
hwrite -- 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;
prChar2QuadBits
lines 5583–5620
Char2QuadBits -- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
-- Modified from the original to be more forgiving.
procedure Char2QuadBits (C : CHARACTER;
RESULT : out STD_ULOGIC_VECTOR(3 downto 0);
GOOD : out BOOLEAN;
ISSUE_ERROR : in BOOLEAN) is
begin
case C is
when '0' => RESULT := x"0"; GOOD := true;
when '1' => RESULT := x"1"; GOOD := true;
when '2' => RESULT := x"2"; GOOD := true;
when '3' => RESULT := x"3"; GOOD := true;
when '4' => RESULT := x"4"; GOOD := true;
when '5' => RESULT := x"5"; GOOD := true;
when '6' => RESULT := x"6"; GOOD := true;
when '7' => RESULT := x"7"; GOOD := true;
when '8' => RESULT := x"8"; GOOD := true;
when '9' => RESULT := x"9"; GOOD := true;
when 'A' | 'a' => RESULT := x"A"; GOOD := true;
when 'B' | 'b' => RESULT := x"B"; GOOD := true;
when 'C' | 'c' => RESULT := x"C"; GOOD := true;
when 'D' | 'd' => RESULT := x"D"; GOOD := true;
when 'E' | 'e' => RESULT := x"E"; GOOD := true;
when 'F' | 'f' => RESULT := x"F"; GOOD := true;
when 'Z' => RESULT := "ZZZZ"; GOOD := true;
when 'X' => RESULT := "XXXX"; GOOD := true;
when others =>
assert not ISSUE_ERROR
report fixed_generic_pkg'instance_name
& "HREAD Error: Read a '" & C &
"', expected a Hex character (0-F)."
severity error;
RESULT := "UUUU";
GOOD := false;
end case;
end procedure Char2QuadBits;
prHREAD_common
lines 5621–5712
HREAD_common -- purpose: Routines common to the HREAD routines
procedure HREAD_common (
L : inout LINE;
slv : out STD_ULOGIC_VECTOR;
igood : out BOOLEAN;
idex : out INTEGER;
constant bpoint : in INTEGER; -- binary point
constant message : in BOOLEAN;
constant smath : in BOOLEAN) is
-- purpose: error message routine
procedure errmes (
constant mess : in STRING) is -- error message
begin
if message then
if smath then
report fixed_generic_pkg'instance_name
& "HREAD(sfixed) "
& mess
severity error;
else
report fixed_generic_pkg'instance_name
& "HREAD(ufixed) "
& mess
severity error;
end if;
end if;
end procedure errmes;
variable xgood : BOOLEAN;
variable nybble : STD_ULOGIC_VECTOR (3 downto 0); -- 4 bits
variable c : CHARACTER;
variable i : INTEGER;
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a dot.
begin
skip_whitespace (L);
if slv'length > 0 then
i := slv'high;
read (L, c, xgood);
while i > 0 loop
if xgood = false then
errmes ("Error: end of string encountered");
exit;
elsif c = '_' then
if i = slv'length then
errmes ("Error: String begins with an ""_""");
xgood := false;
exit;
elsif lastu then
errmes ("Error: Two underscores detected in input string ""__""");
xgood := false;
exit;
else
lastu := true;
end if;
elsif (c = '.') then
if (i + 1 /= bpoint) then
errmes ("encountered ""."" at wrong index");
xgood := false;
exit;
elsif i = slv'length then
errmes ("encounted a ""."" at the beginning of the line");
xgood := false;
exit;
elsif founddot then
errmes ("Two ""."" encounted in input string");
xgood := false;
exit;
end if;
founddot := true;
lastu := false;
else
Char2QuadBits(c, nybble, xgood, message);
if not xgood then
exit;
end if;
slv (i downto i-3) := nybble;
i := i - 4;
lastu := false;
end if;
if i > 0 then
read (L, c, xgood);
end if;
end loop;
idex := i;
igood := xgood;
else
idex := -1;
igood := true; -- read null string
end if;
end procedure HREAD_common;
prHREAD
lines 5713–5848
HREAD procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_ufixed) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => false);
if igood then
if not ((i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
report fixed_generic_pkg'instance_name
& "HREAD(ufixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "HREAD(ufixed): Vector truncated"
severity warning;
end if;
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure HREAD;
procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_ufixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => false);
if (igood and -- We did not get another error
(i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure HREAD;
procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => true);
if igood then -- We did not get another error
if not ((i = -1) -- We read everything
and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
report fixed_generic_pkg'instance_name
& "HREAD(sfixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "HREAD(sfixed): Vector truncated"
severity warning;
end if;
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure HREAD;
procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => true);
if (igood and -- We did not get another error
(i = -1) and -- We read everything
((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure HREAD;
fnTO_STRING
lines 5849–5920
TO_STRING -- TO_STRING functions. Useful in "report" statements.
-- Example: report "result was " & TO_STRING(result);
function TO_STRING (value : UNRESOLVED_ufixed) return STRING is
variable s : STRING(1 to value'length +1) := (others => ' ');
variable subval : UNRESOLVED_ufixed (value'high downto -1);
variable sindx : INTEGER;
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
if value(value'high) = 'Z' then
return TO_STRING (resize (sfixed(value), 0, value'low));
else
return TO_STRING (resize (value, 0, value'low));
end if;
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_STRING(subval);
else
return TO_STRING (resize (value, value'high, -1));
end if;
else
sindx := 1;
for i in value'high downto value'low loop
if i = -1 then
s(sindx) := '.';
sindx := sindx + 1;
end if;
s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
sindx := sindx + 1;
end loop;
return s;
end if;
end if;
end function TO_STRING;
function TO_STRING (value : UNRESOLVED_sfixed) return STRING is
variable s : STRING(1 to value'length + 1) := (others => ' ');
variable subval : UNRESOLVED_sfixed (value'high downto -1);
variable sindx : INTEGER;
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
return TO_STRING (resize (value, 0, value'low));
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_STRING(subval);
else
return TO_STRING (resize (value, value'high, -1));
end if;
else
sindx := 1;
for i in value'high downto value'low loop
if i = -1 then
s(sindx) := '.';
sindx := sindx + 1;
end if;
s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
sindx := sindx + 1;
end loop;
return s;
end if;
end if;
end function TO_STRING;
fnTO_OSTRING
lines 5921–5957
TO_OSTRING 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;
fnTO_HSTRING
lines 5958–5994
TO_HSTRING 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;
fnTO_OSTRING
lines 5995–6030
TO_OSTRING 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;
fnTO_HSTRING
lines 6031–6066
TO_HSTRING 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;
fnfrom_string
lines 6067–6092
from_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
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(bstring);
READ (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_string: Bad string "& bstring severity error;
return result;
end function from_string;
fnfrom_ostring
lines 6093–6114
from_ostring -- Octal and hex conversions work as follows:
-- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped)
-- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped)
function from_ostring (
ostring : STRING; -- Octal string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(ostring);
OREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_ostring: Bad string "& ostring severity error;
return result;
end function from_ostring;
fnfrom_hstring
lines 6115–6133
from_hstring function from_hstring (
hstring : STRING; -- hex string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(hstring);
HREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_hstring: Bad string "& hstring severity error;
return result;
end function from_hstring;
fnfrom_string
lines 6134–6152
from_string function from_string (
bstring : STRING; -- binary string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(bstring);
READ (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_string: Bad string "& bstring severity error;
return result;
end function from_string;
fnfrom_ostring
lines 6153–6171
from_ostring function from_ostring (
ostring : STRING; -- Octal string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(ostring);
OREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_ostring: Bad string "& ostring severity error;
return result;
end function from_ostring;
fnfrom_hstring
lines 6172–6190
from_hstring function from_hstring (
hstring : STRING; -- hex string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(hstring);
HREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_hstring: Bad string "& hstring severity error;
return result;
end function from_hstring;
fnfrom_string
lines 6191–6199
from_string -- 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;
fnfrom_ostring
lines 6200–6207
from_ostring 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;
fnfrom_hstring
lines 6208–6215
from_hstring 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;
fnfrom_string
lines 6216–6223
from_string 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;
fnfrom_ostring
lines 6224–6231
from_ostring 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;
fnfrom_hstring
lines 6232–6239
from_hstring 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;
prcalculate_string_boundry
lines 6240–6290
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.
-- purpose: Calculate the string boundaries
procedure calculate_string_boundry (
arg : in STRING; -- input string
left_index : out INTEGER; -- left
right_index : out INTEGER) is -- right
-- examples "10001.111" would return +4, -3
-- "07X.44" would return +2, -2 (then the octal routine would multiply)
-- "A_B_._C" would return +1, -1 (then the hex routine would multiply)
alias xarg : STRING (arg'length downto 1) is arg; -- make it downto range
variable l, r : INTEGER; -- internal indexes
variable founddot : BOOLEAN := false;
begin
if arg'length > 0 then
l := xarg'high - 1;
r := 0;
for i in xarg'range loop
if xarg(i) = '_' then
if r = 0 then
l := l - 1;
else
r := r + 1;
end if;
elsif xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT then
report fixed_generic_pkg'instance_name
& "Found a space in the input STRING " & xarg
severity error;
elsif xarg(i) = '.' then
if founddot then
report fixed_generic_pkg'instance_name
& "Found two binary points in input string " & xarg
severity error;
else
l := l - i;
r := -i + 1;
founddot := true;
end if;
end if;
end loop;
left_index := l;
right_index := r;
else
left_index := 0;
right_index := 0;
end if;
end procedure calculate_string_boundry;
fnfrom_string
lines 6291–6305
from_string -- 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;
fnfrom_ostring
lines 6306–6319
from_ostring -- 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;
fnfrom_hstring
lines 6320–6329
from_hstring 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;
fnfrom_string
lines 6330–6339
from_string 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;
fnfrom_ostring
lines 6340–6349
from_ostring 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;
fnfrom_hstring
lines 6350–6358
from_hstring function from_hstring (
hstring : STRING) -- hex string
return UNRESOLVED_sfixed
is
variable left_index, right_index : INTEGER;
begin
calculate_string_boundry (hstring, left_index, right_index);
return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
end function from_hstring;
end package body fixed_generic_pkg;
