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
Package preamble and local constants
NAUF NASF NSLV fixedsynth_or_real
NAUF NASF NSLV fixedsynth_or_real-- -----------------------------------------------------------------
--
-- Copyright 2019 IEEE P1076 WG Authors
--
-- See the LICENSE file distributed with this work for copyright and
-- licensing information and the AUTHORS file.
--
-- This file to you under the Apache License, Version 2.0 (the "License").
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-- implied. See the License for the specific language governing
-- permissions and limitations under the License.
--
-- Title : Fixed-point package (Generic package body)
-- :
-- Library : This package shall be compiled into a library
-- : symbolically named IEEE.
-- :
-- Developers: Accellera VHDL-TC and IEEE P1076 Working Group
-- :
-- Purpose : This packages defines basic binary fixed point arithmetic
-- : arithmetic functions
-- :
-- Note : This package may be modified to include additional data
-- : required by tools, but it must in no way change the
-- : external interfaces or simulation behavior of the
-- : description. It is permissible to add comments and/or
-- : attributes to the package declarations, but not to change
-- : or delete any original lines of the package declaration.
-- : The package body may be changed only in accordance with
-- : the terms of Clause 16 of this standard.
-- :
-- --------------------------------------------------------------------
-- $Revision: 1220 $
-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
-- --------------------------------------------------------------------
library IEEE;
use IEEE.MATH_REAL.all;
package body fixed_generic_pkg is
-- Author David Bishop (dbishop@vhdl.org)
-- Other contributers: Jim Lewis, Yannick Grugni, Ryan W. Hilton
-- null array constants
constant NAUF : UNRESOLVED_ufixed (0 downto 1) := (others => '0');
constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0');
constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0');
-- This differed constant will tell you if the package body is synthesizable
-- or implemented as real numbers, set to "true" if synthesizable.
constant fixedsynth_or_real : BOOLEAN := true;
Local helper functions
mins mine cleanvec to_fixed to_uns to_s round_fixed to_ufixedround_up
mins mine cleanvec to_fixed to_uns to_s round_fixed to_ufixedround_up -- Special version of "minimum" to do some boundary checking without errors
function mins (l, r : INTEGER)
return INTEGER is
begin -- function mins
if (l = INTEGER'low or r = INTEGER'low) then
return 0; -- error condition, silent
end if;
return minimum (l, r);
end function mins;
-- Special version of "minimum" to do some boundary checking with errors
function mine (l, r : INTEGER)
return INTEGER is
begin -- function mine
if (l = INTEGER'low or r = INTEGER'low) then
report fixed_generic_pkg'instance_name
& " Unbounded number passed, was a literal used?"
severity error;
return 0;
end if;
return minimum (l, r);
end function mine;
-- The following functions are used only internally. Every function
-- calls "cleanvec" either directly or indirectly.
-- purpose: Fixes "downto" problem and resolves meta states
function cleanvec (
arg : UNRESOLVED_sfixed) -- input
return UNRESOLVED_sfixed
is
begin -- function cleanvec
assert not (arg'ascending and (arg'low /= INTEGER'low))
report fixed_generic_pkg'instance_name
& " Vector passed using a ""to"" range, expected is ""downto"""
severity error;
return arg;
end function cleanvec;
-- purpose: Fixes "downto" problem and resolves meta states
function cleanvec (
arg : UNRESOLVED_ufixed) -- input
return UNRESOLVED_ufixed
is
begin -- function cleanvec
assert not (arg'ascending and (arg'low /= INTEGER'low))
report fixed_generic_pkg'instance_name
& " Vector passed using a ""to"" range, expected is ""downto"""
severity error;
return arg;
end function cleanvec;
-- Type convert a "unsigned" into a "ufixed", used internally
function to_fixed (
arg : UNRESOLVED_UNSIGNED; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
begin -- function to_fixed
result := UNRESOLVED_ufixed(arg);
return result;
end function to_fixed;
-- Type convert a "signed" into an "sfixed", used internally
function to_fixed (
arg : UNRESOLVED_SIGNED; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin -- function to_fixed
result := UNRESOLVED_sfixed(arg);
return result;
end function to_fixed;
-- Type convert a "ufixed" into an "unsigned", used internally
function to_uns (
arg : UNRESOLVED_ufixed) -- fp vector
return UNRESOLVED_UNSIGNED
is
subtype t is UNRESOLVED_UNSIGNED(arg'high - arg'low downto 0);
variable slv : t;
begin -- function to_uns
slv := t(arg);
return slv;
end function to_uns;
-- Type convert an "sfixed" into a "signed", used internally
function to_s (
arg : UNRESOLVED_sfixed) -- fp vector
return UNRESOLVED_SIGNED
is
subtype t is UNRESOLVED_SIGNED(arg'high - arg'low downto 0);
variable slv : t;
begin -- function to_s
slv := t(arg);
return slv;
end function to_s;
-- adds 1 to the LSB of the number
procedure round_up (arg : in UNRESOLVED_ufixed;
result : out UNRESOLVED_ufixed;
overflowx : out BOOLEAN) is
variable arguns, resuns : UNRESOLVED_UNSIGNED (arg'high-arg'low+1 downto 0)
:= (others => '0');
begin -- round_up
arguns (arguns'high-1 downto 0) := to_uns (arg);
resuns := arguns + 1;
result := to_fixed(resuns(arg'high-arg'low
downto 0), arg'high, arg'low);
overflowx := (resuns(resuns'high) = '1');
end procedure round_up;
-- adds 1 to the LSB of the number
procedure round_up (arg : in UNRESOLVED_sfixed;
result : out UNRESOLVED_sfixed;
overflowx : out BOOLEAN) is
variable args, ress : UNRESOLVED_SIGNED (arg'high-arg'low+1 downto 0);
begin -- round_up
args (args'high-1 downto 0) := to_s (arg);
args(args'high) := arg(arg'high); -- sign extend
ress := args + 1;
result := to_fixed(ress (ress'high-1
downto 0), arg'high, arg'low);
overflowx := ((arg(arg'high) /= ress(ress'high-1))
and (or (STD_ULOGIC_VECTOR(ress)) /= '0'));
end procedure round_up;
-- Rounding - Performs a "round_nearest" (IEEE 754) which rounds up
-- when the remainder is > 0.5. If the remainder IS 0.5 then if the
-- bottom bit is a "1" it is rounded, otherwise it remains the same.
function round_fixed (arg : UNRESOLVED_ufixed;
remainder : UNRESOLVED_ufixed;
overflow_style : fixed_overflow_style_type := fixed_overflow_style)
return UNRESOLVED_ufixed
is
variable rounds : BOOLEAN;
variable round_overflow : BOOLEAN;
variable result : UNRESOLVED_ufixed (arg'range);
begin
rounds := false;
if (remainder'length > 1) then
if (remainder (remainder'high) = '1') then
rounds := (arg(arg'low) = '1')
or (or (to_sulv(remainder(remainder'high-1 downto
remainder'low))) = '1');
end if;
else
rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
end if;
if rounds then
round_up(arg => arg,
result => result,
overflowx => round_overflow);
else
result := arg;
end if;
if (overflow_style = fixed_saturate) and round_overflow then
result := saturate (result'high, result'low);
end if;
return result;
end function round_fixed;
-- Rounding case statement
function round_fixed (arg : UNRESOLVED_sfixed;
remainder : UNRESOLVED_sfixed;
overflow_style : fixed_overflow_style_type := fixed_overflow_style)
return UNRESOLVED_sfixed
is
variable rounds : BOOLEAN;
variable round_overflow : BOOLEAN;
variable result : UNRESOLVED_sfixed (arg'range);
begin
rounds := false;
if (remainder'length > 1) then
if (remainder (remainder'high) = '1') then
rounds := (arg(arg'low) = '1')
or (or (to_sulv(remainder(remainder'high-1 downto
remainder'low))) = '1');
end if;
else
rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
end if;
if rounds then
round_up(arg => arg,
result => result,
overflowx => round_overflow);
else
result := arg;
end if;
if round_overflow then
if (overflow_style = fixed_saturate) then
if arg(arg'high) = '0' then
result := saturate (result'high, result'low);
else
result := not saturate (result'high, result'low);
end if;
-- Sign bit not fixed when wrapping
end if;
end if;
return result;
end function round_fixed;
-- converts an sfixed into a ufixed. The output is the same length as the
-- input, because abs("1000") = "1000" = 8.
function to_ufixed (
arg : UNRESOLVED_sfixed)
return UNRESOLVED_ufixed
is
constant left_index : INTEGER := arg'high;
constant right_index : INTEGER := mine(arg'low, arg'low);
variable xarg : UNRESOLVED_sfixed(left_index+1 downto right_index);
variable result : UNRESOLVED_ufixed(left_index downto right_index);
begin
if arg'length < 1 then
return NAUF;
end if;
xarg := abs(arg);
result := UNRESOLVED_ufixed (xarg (left_index downto right_index));
return result;
end function to_ufixed;
Vector and explicit-bound conversion functions
to_sulv to_slv to_ufixed to_sfixed
to_sulv to_slv to_ufixed to_sfixed-----------------------------------------------------------------------------
-- Visible functions
-----------------------------------------------------------------------------
-- Conversion functions. These are needed for synthesis where typically
-- the only input and output type is a std_logic_vector.
function to_sulv (
arg : UNRESOLVED_ufixed) -- fixed point vector
return STD_ULOGIC_VECTOR
is
variable intermediate_result : UNRESOLVED_ufixed(arg'length-1 downto 0);
begin
if arg'length < 1 then
return NSLV;
end if;
intermediate_result := arg;
return STD_ULOGIC_VECTOR (intermediate_result);
end function to_sulv;
function to_sulv (
arg : UNRESOLVED_sfixed) -- fixed point vector
return STD_ULOGIC_VECTOR
is
variable intermediate_result : UNRESOLVED_sfixed(arg'length-1 downto 0);
begin
if arg'length < 1 then
return NSLV;
end if;
intermediate_result := arg;
return STD_ULOGIC_VECTOR (intermediate_result);
end function to_sulv;
function to_slv (
arg : UNRESOLVED_ufixed) -- fixed point vector
return STD_LOGIC_VECTOR is
begin
return to_sulv(arg);
end function to_slv;
function to_slv (
arg : UNRESOLVED_sfixed) -- fixed point vector
return STD_LOGIC_VECTOR is
begin
return to_sulv(arg);
end function to_slv;
function to_ufixed (
arg : STD_ULOGIC_VECTOR; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (arg'length < 1 or right_index > left_index) then
return NAUF;
end if;
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name & "TO_UFIXED(SLV) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NAUF;
else
result := to_fixed (arg => UNRESOLVED_UNSIGNED(arg),
left_index => left_index,
right_index => right_index);
return result;
end if;
end function to_ufixed;
function to_sfixed (
arg : STD_ULOGIC_VECTOR; -- shifted vector
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (arg'length < 1 or right_index > left_index) then
return NASF;
end if;
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name & "TO_SFIXED(SLV) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NASF;
else
result := to_fixed (arg => UNRESOLVED_SIGNED(arg),
left_index => left_index,
right_index => right_index);
return result;
end if;
end function to_sfixed;
Arithmetic operators and functions
"abs" "-" "+" "*" "/" divide reciprocal "rem" remainder "mod" modulo scalb Is_Negativeadd_carry
"abs" "-" "+" "*" "/" divide reciprocal "rem" remainder "mod" modulo scalb Is_Negativeadd_carry -- Two's complement number, Grows the vector by 1 bit.
-- because "abs (1000.000) = 01000.000" or abs(-16) = 16.
function "abs" (
arg : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed
is
constant left_index : INTEGER := arg'high;
constant right_index : INTEGER := mine(arg'low, arg'low);
variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
variable result : UNRESOLVED_sfixed (left_index+1 downto right_index);
begin
if (arg'length < 1 or result'length < 1) then
return NASF;
end if;
ressns (arg'length-1 downto 0) := to_s (cleanvec (arg));
ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
result := to_fixed (abs(ressns), left_index+1, right_index);
return result;
end function "abs";
-- also grows the vector by 1 bit.
function "-" (
arg : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed
is
constant left_index : INTEGER := arg'high+1;
constant right_index : INTEGER := mine(arg'low, arg'low);
variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (arg'length < 1 or result'length < 1) then
return NASF;
end if;
ressns (arg'length-1 downto 0) := to_s (cleanvec(arg));
ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
result := to_fixed (-ressns, left_index, right_index);
return result;
end function "-";
-- Addition
function "+" (
l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) + ufixed(c downto d) =
return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
result_slv := lslv + rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "+";
function "+" (
l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) + sfixed(c downto d) =
return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
result_slv := lslv + rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "+";
-- Subtraction
function "-" (
l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) - ufixed(c downto d) =
return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
result_slv := lslv - rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "-";
function "-" (
l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) - sfixed(c downto d) =
return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
is
constant left_index : INTEGER := maximum(l'high, r'high)+1;
constant right_index : INTEGER := mine(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
begin
if (l'length < 1 or r'length < 1 or result'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
result_slv := lslv - rslv;
result := to_fixed(result_slv, left_index, right_index);
return result;
end function "-";
function "*" (
l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) * ufixed(c downto d) =
return UNRESOLVED_ufixed -- ufixed(a+c+1 downto b+d)
is
variable lslv : UNRESOLVED_UNSIGNED (l'length-1 downto 0);
variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (r'length+l'length-1 downto 0);
variable result : UNRESOLVED_ufixed (l'high + r'high+1 downto
mine(l'low, l'low) + mine(r'low, r'low));
begin
if (l'length < 1 or r'length < 1 or
result'length /= result_slv'length) then
return NAUF;
end if;
lslv := to_uns (cleanvec(l));
rslv := to_uns (cleanvec(r));
result_slv := lslv * rslv;
result := to_fixed (result_slv, result'high, result'low);
return result;
end function "*";
function "*" (
l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) * sfixed(c downto d) =
return UNRESOLVED_sfixed -- sfixed(a+c+1 downto b+d)
is
variable lslv : UNRESOLVED_SIGNED (l'length-1 downto 0);
variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_SIGNED (r'length+l'length-1 downto 0);
variable result : UNRESOLVED_sfixed (l'high + r'high+1 downto
mine(l'low, l'low) + mine(r'low, r'low));
begin
if (l'length < 1 or r'length < 1 or
result'length /= result_slv'length) then
return NASF;
end if;
lslv := to_s (cleanvec(l));
rslv := to_s (cleanvec(r));
result_slv := lslv * rslv;
result := to_fixed (result_slv, result'high, result'low);
return result;
end function "*";
function "/" (
l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) / ufixed(c downto d) =
return UNRESOLVED_ufixed is -- ufixed(a-d downto b-c-1)
begin
return divide (l, r);
end function "/";
function "/" (
l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) / sfixed(c downto d) =
return UNRESOLVED_sfixed is -- sfixed(a-d+1 downto b-c)
begin
return divide (l, r);
end function "/";
-- This version of divide gives the user more control
-- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
function divide (
l, r : UNRESOLVED_ufixed;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (l'high - mine(r'low, r'low) downto
mine (l'low, l'low) - r'high -1);
variable dresult : UNRESOLVED_ufixed (result'high downto result'low -guard_bits);
variable lresize : UNRESOLVED_ufixed (l'high downto l'high - dresult'length+1);
variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NAUF;
end if;
lresize := resize (arg => l,
left_index => lresize'high,
right_index => lresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
lslv := to_uns (cleanvec (lresize));
rslv := to_uns (cleanvec (r));
if (rslv = 0) then
report fixed_generic_pkg'instance_name
& "DIVIDE(ufixed) Division by zero" severity error;
result := saturate (result'high, result'low); -- saturate
else
result_slv := lslv / rslv;
dresult := to_fixed (result_slv, dresult'high, dresult'low);
result := resize (arg => dresult,
left_index => result'high,
right_index => result'low,
overflow_style => fixed_wrap, -- overflow impossible
round_style => round_style);
end if;
return result;
end function divide;
-- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
function divide (
l, r : UNRESOLVED_sfixed;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (l'high - mine(r'low, r'low) + 1 downto
mine (l'low, l'low) - r'high);
variable dresult : UNRESOLVED_sfixed (result'high downto result'low-guard_bits);
variable lresize : UNRESOLVED_sfixed (l'high+1 downto l'high+1 -dresult'length+1);
variable lslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
variable result_slv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NASF;
end if;
lresize := resize (arg => l,
left_index => lresize'high,
right_index => lresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
lslv := to_s (cleanvec (lresize));
rslv := to_s (cleanvec (r));
if (rslv = 0) then
report fixed_generic_pkg'instance_name
& "DIVIDE(sfixed) Division by zero" severity error;
result := saturate (result'high, result'low);
else
result_slv := lslv / rslv;
dresult := to_fixed (result_slv, dresult'high, dresult'low);
result := resize (arg => dresult,
left_index => result'high,
right_index => result'low,
overflow_style => fixed_wrap, -- overflow impossible
round_style => round_style);
end if;
return result;
end function divide;
-- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
function reciprocal (
arg : UNRESOLVED_ufixed; -- fixed point input
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_ufixed
is
constant one : UNRESOLVED_ufixed (0 downto 0) := "1";
begin
return divide (l => one,
r => arg,
round_style => round_style,
guard_bits => guard_bits);
end function reciprocal;
-- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
function reciprocal (
arg : UNRESOLVED_sfixed; -- fixed point input
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_sfixed
is
constant one : UNRESOLVED_sfixed (1 downto 0) := "01"; -- extra bit.
variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high);
begin
if (arg'length < 1 or resultx'length < 1) then
return NASF;
else
resultx := divide (l => one,
r => arg,
round_style => round_style,
guard_bits => guard_bits);
return resultx (resultx'high-1 downto resultx'low); -- remove extra bit
end if;
end function reciprocal;
-- ufixed (a downto b) rem ufixed (c downto d)
-- = ufixed (min(a,c) downto min(b,d))
function "rem" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return remainder (l, r);
end function "rem";
-- remainder
-- sfixed (a downto b) rem sfixed (c downto d)
-- = sfixed (min(a,c) downto min(b,d))
function "rem" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return remainder (l, r);
end function "rem";
-- ufixed (a downto b) rem ufixed (c downto d)
-- = ufixed (min(a,c) downto min(b,d))
function remainder (
l, r : UNRESOLVED_ufixed; -- fixed point input
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
mine(l'low, r'low));
variable lresize : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
mins(r'low, r'low)-guard_bits);
variable rresize : UNRESOLVED_ufixed (r'high downto r'low-guard_bits);
variable dresult : UNRESOLVED_ufixed (rresize'range);
variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
variable rslv : UNRESOLVED_UNSIGNED (rresize'length-1 downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (rslv'range);
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NAUF;
end if;
lresize := resize (arg => l,
left_index => lresize'high,
right_index => lresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
lslv := to_uns (lresize);
rresize := resize (arg => r,
left_index => rresize'high,
right_index => rresize'low,
overflow_style => fixed_wrap, -- vector only grows
round_style => fixed_truncate);
rslv := to_uns (rresize);
if (rslv = 0) then
report fixed_generic_pkg'instance_name
& "remainder(ufixed) Division by zero" severity error;
result := saturate (result'high, result'low); -- saturate
else
if (r'low <= l'high) then
result_slv := lslv rem rslv;
dresult := to_fixed (result_slv, dresult'high, dresult'low);
result := resize (arg => dresult,
left_index => result'high,
right_index => result'low,
overflow_style => fixed_wrap, -- can't overflow
round_style => round_style);
end if;
if l'low < r'low then
result(mins(r'low-1, l'high) downto l'low) :=
cleanvec(l(mins(r'low-1, l'high) downto l'low));
end if;
end if;
return result;
end function remainder;
-- remainder
-- sfixed (a downto b) rem sfixed (c downto d)
-- = sfixed (min(a,c) downto min(b,d))
function remainder (
l, r : UNRESOLVED_sfixed; -- fixed point input
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_sfixed
is
variable l_abs : UNRESOLVED_ufixed (l'range);
variable r_abs : UNRESOLVED_ufixed (r'range);
variable result : UNRESOLVED_sfixed (minimum(r'high, l'high) downto
mine(r'low, l'low));
variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
mins(r'low, l'low));
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NASF;
end if;
l_abs := to_ufixed (l);
r_abs := to_ufixed (r);
result := UNRESOLVED_sfixed (remainder (
l => l_abs,
r => r_abs,
round_style => round_style));
neg_result := -result;
if l(l'high) = '1' then
result := neg_result(result'range);
end if;
return result;
end function remainder;
-- modulo
-- ufixed (a downto b) mod ufixed (c downto d)
-- = ufixed (min(a,c) downto min(b, d))
function "mod" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return modulo (l, r);
end function "mod";
-- sfixed (a downto b) mod sfixed (c downto d)
-- = sfixed (c downto min(b, d))
function "mod" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return modulo(l, r);
end function "mod";
-- modulo
-- ufixed (a downto b) mod ufixed (c downto d)
-- = ufixed (min(a,c) downto min(b, d))
function modulo (
l, r : UNRESOLVED_ufixed; -- fixed point input
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_ufixed is
begin
return remainder(l => l,
r => r,
round_style => round_style,
guard_bits => guard_bits);
end function modulo;
-- sfixed (a downto b) mod sfixed (c downto d)
-- = sfixed (c downto min(b, d))
function modulo (
l, r : UNRESOLVED_sfixed; -- fixed point input
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits)
return UNRESOLVED_sfixed
is
variable l_abs : UNRESOLVED_ufixed (l'range);
variable r_abs : UNRESOLVED_ufixed (r'range);
variable result : UNRESOLVED_sfixed (r'high downto
mine(r'low, l'low));
variable dresult : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
mins(r'low, l'low));
variable dresult_not_zero : BOOLEAN;
begin
if (l'length < 1 or r'length < 1 or
mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
return NASF;
end if;
l_abs := to_ufixed (l);
r_abs := to_ufixed (r);
dresult := "0" & UNRESOLVED_sfixed(remainder (l => l_abs,
r => r_abs,
round_style => round_style));
if (to_s(dresult) = 0) then
dresult_not_zero := false;
else
dresult_not_zero := true;
end if;
if to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '0'
and dresult_not_zero then
result := resize (arg => r - dresult,
left_index => result'high,
right_index => result'low,
overflow_style => overflow_style,
round_style => round_style);
elsif to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '1' then
result := resize (arg => -dresult,
left_index => result'high,
right_index => result'low,
overflow_style => overflow_style,
round_style => round_style);
elsif to_x01(l(l'high)) = '0' and to_x01(r(r'high)) = '1'
and dresult_not_zero then
result := resize (arg => dresult + r,
left_index => result'high,
right_index => result'low,
overflow_style => overflow_style,
round_style => round_style);
else
result := resize (arg => dresult,
left_index => result'high,
right_index => result'low,
overflow_style => overflow_style,
round_style => round_style);
end if;
return result;
end function modulo;
-- Procedure for those who need an "accumulator" function
procedure add_carry (
L, R : in UNRESOLVED_ufixed;
c_in : in STD_ULOGIC;
result : out UNRESOLVED_ufixed;
c_out : out STD_ULOGIC) is
constant left_index : INTEGER := maximum(L'high, R'high)+1;
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
downto 0);
variable cx : UNRESOLVED_UNSIGNED (0 downto 0); -- Carry in
begin
if (L'length < 1 or R'length < 1) then
result := NAUF;
c_out := '0';
else
cx (0) := c_in;
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
result_slv := lslv + rslv + cx;
c_out := result_slv(left_index-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;
-- Scales the result by a power of 2. Width of input = width of output with
-- the decimal point moved.
function scalb (y : UNRESOLVED_ufixed; N : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (y'high+N downto y'low+N);
begin
if y'length < 1 then
return NAUF;
else
result := y;
return result;
end if;
end function scalb;
function scalb (y : UNRESOLVED_ufixed; N : UNRESOLVED_SIGNED)
return UNRESOLVED_ufixed is
begin
return scalb (y => y,
N => to_integer(N));
end function scalb;
function scalb (y : UNRESOLVED_sfixed; N : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (y'high+N downto y'low+N);
begin
if y'length < 1 then
return NASF;
else
result := y;
return result;
end if;
end function scalb;
function scalb (y : UNRESOLVED_sfixed; N : UNRESOLVED_SIGNED)
return UNRESOLVED_sfixed is
begin
return scalb (y => y,
N => to_integer(N));
end function scalb;
function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN is
begin
if to_X01(arg(arg'high)) = '1' then
return true;
else
return false;
end if;
end function Is_Negative;
Find leftmost and rightmost functions
find_rightmost find_leftmost
find_rightmost find_leftmost function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'reverse_range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'high+1; -- return out of bounds 'high
end function find_rightmost;
function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'low-1; -- return out of bounds 'low
end function find_leftmost;
function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'reverse_range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'high+1; -- return out of bounds 'high
end function find_rightmost;
function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
return INTEGER is
begin
for_loop : for i in arg'range loop
if arg(i) ?= y then
return i;
end if;
end loop;
return arg'low-1; -- return out of bounds 'low
end function find_leftmost;
Shift and rotate operators and functions
"sll" "srl" "rol" "ror" "sla" "sra" SHIFT_LEFT SHIFT_RIGHT
"sll" "srl" "rol" "ror" "sla" "sra" SHIFT_LEFT SHIFT_RIGHT function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv sll COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sll";
function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv srl COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "srl";
function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv rol COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "rol";
function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
argslv := argslv ror COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "ror";
function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
-- Arithmetic shift on an unsigned is a logical shift
argslv := argslv sll COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sla";
function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
return UNRESOLVED_ufixed
is
variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_ufixed (ARG'range);
begin
argslv := to_uns (ARG);
-- Arithmetic shift on an unsigned is a logical shift
argslv := argslv srl COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sra";
function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv sll COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sll";
function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv srl COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "srl";
function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv rol COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "rol";
function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
argslv := argslv ror COUNT;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "ror";
function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
if COUNT > 0 then
-- Arithmetic shift left on a 2's complement number is a logic shift
argslv := argslv sll COUNT;
else
argslv := argslv sra -COUNT;
end if;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sla";
function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
return UNRESOLVED_sfixed
is
variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
variable result : UNRESOLVED_sfixed (ARG'range);
begin
argslv := to_s (ARG);
if COUNT > 0 then
argslv := argslv sra COUNT;
else
-- Arithmetic shift left on a 2's complement number is a logic shift
argslv := argslv sll -COUNT;
end if;
result := to_fixed (argslv, result'high, result'low);
return result;
end function "sra";
-- Because some people want the older functions.
function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
return UNRESOLVED_ufixed is
begin
if (ARG'length < 1) then
return NAUF;
end if;
return ARG sla COUNT;
end function SHIFT_LEFT;
function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
return UNRESOLVED_ufixed is
begin
if (ARG'length < 1) then
return NAUF;
end if;
return ARG sra COUNT;
end function SHIFT_RIGHT;
function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
return UNRESOLVED_sfixed is
begin
if (ARG'length < 1) then
return NASF;
end if;
return ARG sla COUNT;
end function SHIFT_LEFT;
function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
return UNRESOLVED_sfixed is
begin
if (ARG'length < 1) then
return NASF;
end if;
return ARG sra COUNT;
end function SHIFT_RIGHT;
Logical and reduction operators
"not" "and" "or" "nand" "nor" "xor" "xnor"
"not" "and" "or" "nand" "nor" "xor" "xnor"Vector logical operators
"not" "and" "or" "nand" "nor" "xor" "xnor"
"not" "and" "or" "nand" "nor" "xor" "xnor" ----------------------------------------------------------------------------
-- logical functions
----------------------------------------------------------------------------
function "not" (L : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
RESULT := not to_sulv(L);
return to_ufixed(RESULT, L'high, L'low);
end function "not";
function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) and to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """and"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "and";
function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) or to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """or"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "or";
function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nand to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nand"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "nand";
function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "nor";
function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "xor";
function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xnor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xnor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_ufixed(RESULT, L'high, L'low);
end function "xnor";
function "not" (L : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
RESULT := not to_sulv(L);
return to_sfixed(RESULT, L'high, L'low);
end function "not";
function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) and to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """and"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "and";
function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) or to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """or"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "or";
function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nand to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nand"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "nand";
function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) nor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """nor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "nor";
function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "xor";
function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
begin
if (L'high = R'high and L'low = R'low) then
RESULT := to_sulv(L) xnor to_sulv(R);
else
assert no_warning
report fixed_generic_pkg'instance_name
& """xnor"": Range error L'RANGE /= R'RANGE"
severity warning;
RESULT := (others => 'X');
end if;
return to_sfixed(RESULT, L'high, L'low);
end function "xnor";
Scalar-vector mixed logical operators
"and" "or" "nand" "nor" "xor" "xnor"
"and" "or" "nand" "nor" "xor" "xnor" -- Vector and std_ulogic functions, same as functions in numeric_std
function "and" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (R'range);
begin
for i in result'range loop
result(i) := L and R(i);
end loop;
return result;
end function "and";
function "and" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (L'range);
begin
for i in result'range loop
result(i) := L(i) and R;
end loop;
return result;
end function "and";
function "or" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (R'range);
begin
for i in result'range loop
result(i) := L or R(i);
end loop;
return result;
end function "or";
function "or" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (L'range);
begin
for i in result'range loop
result(i) := L(i) or R;
end loop;
return result;
end function "or";
function "nand" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (R'range);
begin
for i in result'range loop
result(i) := L nand R(i);
end loop;
return result;
end function "nand";
function "nand" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (L'range);
begin
for i in result'range loop
result(i) := L(i) nand R;
end loop;
return result;
end function "nand";
function "nor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (R'range);
begin
for i in result'range loop
result(i) := L nor R(i);
end loop;
return result;
end function "nor";
function "nor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (L'range);
begin
for i in result'range loop
result(i) := L(i) nor R;
end loop;
return result;
end function "nor";
function "xor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (R'range);
begin
for i in result'range loop
result(i) := L xor R(i);
end loop;
return result;
end function "xor";
function "xor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (L'range);
begin
for i in result'range loop
result(i) := L(i) xor R;
end loop;
return result;
end function "xor";
function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (R'range);
begin
for i in result'range loop
result(i) := L xnor R(i);
end loop;
return result;
end function "xnor";
function "xnor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (L'range);
begin
for i in result'range loop
result(i) := L(i) xnor R;
end loop;
return result;
end function "xnor";
function "and" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (R'range);
begin
for i in result'range loop
result(i) := L and R(i);
end loop;
return result;
end function "and";
function "and" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (L'range);
begin
for i in result'range loop
result(i) := L(i) and R;
end loop;
return result;
end function "and";
function "or" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (R'range);
begin
for i in result'range loop
result(i) := L or R(i);
end loop;
return result;
end function "or";
function "or" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (L'range);
begin
for i in result'range loop
result(i) := L(i) or R;
end loop;
return result;
end function "or";
function "nand" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (R'range);
begin
for i in result'range loop
result(i) := L nand R(i);
end loop;
return result;
end function "nand";
function "nand" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (L'range);
begin
for i in result'range loop
result(i) := L(i) nand R;
end loop;
return result;
end function "nand";
function "nor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (R'range);
begin
for i in result'range loop
result(i) := L nor R(i);
end loop;
return result;
end function "nor";
function "nor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (L'range);
begin
for i in result'range loop
result(i) := L(i) nor R;
end loop;
return result;
end function "nor";
function "xor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (R'range);
begin
for i in result'range loop
result(i) := L xor R(i);
end loop;
return result;
end function "xor";
function "xor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (L'range);
begin
for i in result'range loop
result(i) := L(i) xor R;
end loop;
return result;
end function "xor";
function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (R'range);
begin
for i in result'range loop
result(i) := L xnor R(i);
end loop;
return result;
end function "xnor";
function "xnor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (L'range);
begin
for i in result'range loop
result(i) := L(i) xnor R;
end loop;
return result;
end function "xnor";
Reduction logical operators
"and" "nand" "or" "nor" "xor" "xnor"
"and" "nand" "or" "nor" "xor" "xnor" -- Reduction operators
function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return and to_sulv(l);
end function "and";
function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return nand to_sulv(l);
end function "nand";
function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return or to_sulv(l);
end function "or";
function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return nor to_sulv(l);
end function "nor";
function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return xor to_sulv(l);
end function "xor";
function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
begin
return xnor to_sulv(l);
end function "xnor";
function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return and to_sulv(l);
end function "and";
function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return nand to_sulv(l);
end function "nand";
function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return or to_sulv(l);
end function "or";
function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return nor to_sulv(l);
end function "nor";
function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return xor to_sulv(l);
end function "xor";
function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
begin
return xnor to_sulv(l);
end function "xnor";
-- End reduction operators
Comparison, matching, and min/max functions
"?=" "?/=" "?>" "?>=" "?<" "?<=" std_match "=" "/=" ">" "<" ">=" "<=" maximum minimum
"?=" "?/=" "?>" "?>=" "?<" "?<=" std_match "=" "/=" ">" "<" ">=" "<=" maximum minimumMatching relational and std_match
"?=" "?/=" "?>" "?>=" "?<" "?<=" std_match
"?=" "?/=" "?>" "?>=" "?<" "?<=" std_match function "?=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?= rslv;
end if;
end function "?=";
function "?/=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?/=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?/="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?/= rslv;
end if;
end function "?/=";
function "?>" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?>
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?> rslv;
end if;
end function "?>";
function "?>=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?>=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?>= rslv;
end if;
end function "?>=";
function "?<" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?<
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?< rslv;
end if;
end function "?<";
function "?<=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin -- ?<=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv ?<= rslv;
end if;
end function "?<=";
function "?=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?= rslv;
end if;
end function "?=";
function "?/=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?/=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?/="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?/= rslv;
end if;
end function "?/=";
function "?>" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?>
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?> rslv;
end if;
end function "?>";
function "?>=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?>=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?>="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?>= rslv;
end if;
end function "?>=";
function "?<" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?<
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<"": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?< rslv;
end if;
end function "?<";
function "?<=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
constant left_index : INTEGER := maximum(L'high, R'high);
constant right_index : INTEGER := mins(L'low, R'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin -- ?<=
if ((L'length < 1) or (R'length < 1)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """?<="": null detected, returning X"
severity warning;
return 'X';
else
lresize := resize (L, left_index, right_index);
rresize := resize (R, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv ?<= rslv;
end if;
end function "?<=";
-- Match function, similar to "std_match" from numeric_std
function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is
begin
if (L'high = R'high and L'low = R'low) then
return std_match(to_sulv(L), to_sulv(R));
else
assert no_warning
report fixed_generic_pkg'instance_name
& "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
severity warning;
return false;
end if;
end function std_match;
function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is
begin
if (L'high = R'high and L'low = R'low) then
return std_match(to_sulv(L), to_sulv(R));
else
assert no_warning
report fixed_generic_pkg'instance_name
& "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
severity warning;
return false;
end if;
end function std_match;
Boolean relational operators
"=" "/=" ">" "<" ">=" "<="
"=" "/=" ">" "<" ">=" "<=" -- compare functions
function "=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv = rslv;
end function "=";
function "=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv = rslv;
end function "=";
function "/=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": null argument detected, returning TRUE"
severity warning;
return true;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": metavalue detected, returning TRUE"
severity warning;
return true;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv /= rslv;
end function "/=";
function "/=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": null argument detected, returning TRUE"
severity warning;
return true;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """/="": metavalue detected, returning TRUE"
severity warning;
return true;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv /= rslv;
end function "/=";
function ">" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv > rslv;
end function ">";
function ">" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv > rslv;
end function ">";
function "<" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv < rslv;
end function "<";
function "<" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<"": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv < rslv;
end function "<";
function ">=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv >= rslv;
end function ">=";
function ">=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """>="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv >= rslv;
end function ">=";
function "<=" (
l, r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_uns (lresize);
rslv := to_uns (rresize);
return lslv <= rslv;
end function "<=";
function "<=" (
l, r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN
is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
begin
if (l'length < 1 or r'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": null argument detected, returning FALSE"
severity warning;
return false;
elsif (Is_X(l) or Is_X(r)) then
assert no_warning
report fixed_generic_pkg'instance_name
& """<="": metavalue detected, returning FALSE"
severity warning;
return false;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
lslv := to_s (lresize);
rslv := to_s (rresize);
return lslv <= rslv;
end function "<=";
Minimum and maximum functions
maximum minimum
maximum minimum -- overloads of the default maximum and minimum functions
function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(maximum(to_uns(lresize), to_uns(rresize)),
left_index, right_index);
end function maximum;
function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(maximum(to_s(lresize), to_s(rresize)),
left_index, right_index);
end function maximum;
function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NAUF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(minimum(to_uns(lresize), to_uns(rresize)),
left_index, right_index);
end function minimum;
function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
constant left_index : INTEGER := maximum(l'high, r'high);
constant right_index : INTEGER := mins(l'low, r'low);
variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
begin
if (l'length < 1 or r'length < 1) then
return NASF;
end if;
lresize := resize (l, left_index, right_index);
rresize := resize (r, left_index, right_index);
return to_fixed(minimum(to_s(lresize), to_s(rresize)),
left_index, right_index);
end function minimum;
Conversion and helper functions
to_ufixed to_sfixed ufixed_high ufixed_low sfixed_high sfixed_low saturate to_UFix to_SFix ufix_high ufix_low sfix_high sfix_low to_unsigned to_signed to_real to_integer
to_ufixed to_sfixed ufixed_high ufixed_low sfixed_high sfixed_low saturate to_UFix to_SFix ufix_high ufix_low sfix_high sfix_low to_unsigned to_signed to_real to_integerConversion to ufixed and sfixed
to_ufixed to_sfixed
to_ufixed to_sfixed function to_ufixed (
arg : NATURAL; -- integer
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER := 0; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_ufixed (left_index downto fw);
variable sresult : UNRESOLVED_ufixed (left_index downto 0) :=
(others => '0'); -- integer portion
variable argx : NATURAL; -- internal version of arg
begin
if (result'length < 1) then
return NAUF;
end if;
if arg /= 0 then
argx := arg;
for I in 0 to sresult'left loop
if (argx mod 2) = 0 then
sresult(I) := '0';
else
sresult(I) := '1';
end if;
argx := argx/2;
end loop;
if argx /= 0 then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_UFIXED(NATURAL): vector truncated"
severity warning;
if overflow_style = fixed_saturate then
return saturate (left_index, right_index);
end if;
end if;
result := resize (arg => sresult,
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
else
result := (others => '0');
end if;
return result;
end function to_ufixed;
function to_sfixed (
arg : INTEGER; -- integer
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER := 0; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_sfixed (left_index downto fw);
variable sresult : UNRESOLVED_sfixed (left_index downto 0) :=
(others => '0'); -- integer portion
variable argx : INTEGER; -- internal version of arg
variable sign : STD_ULOGIC; -- sign of input
begin
if (result'length < 1) then -- null range
return NASF;
end if;
if arg /= 0 then
if (arg < 0) then
sign := '1';
argx := -(arg + 1);
else
sign := '0';
argx := arg;
end if;
for I in 0 to sresult'left loop
if (argx mod 2) = 0 then
sresult(I) := sign;
else
sresult(I) := not sign;
end if;
argx := argx/2;
end loop;
if argx /= 0 or left_index < 0 or sign /= sresult(sresult'left) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_SFIXED(INTEGER): vector truncated"
severity warning;
if overflow_style = fixed_saturate then -- saturate
if arg < 0 then
result := not saturate (result'high, result'low); -- underflow
else
result := saturate (result'high, result'low); -- overflow
end if;
return result;
end if;
end if;
result := resize (arg => sresult,
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
else
result := (others => '0');
end if;
return result;
end function to_sfixed;
function to_ufixed (
arg : REAL; -- real
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_ufixed (left_index downto fw) :=
(others => '0');
variable Xresult : UNRESOLVED_ufixed (left_index downto
fw-guard_bits) :=
(others => '0');
variable presult : REAL;
begin
-- If negative or null range, return.
if (left_index < fw) then
return NAUF;
end if;
if (arg < 0.0) then
report fixed_generic_pkg'instance_name
& "TO_UFIXED: Negative argument passed "
& REAL'image(arg) severity error;
return result;
end if;
presult := arg;
if presult >= (2.0**(left_index+1)) then
assert no_warning report fixed_generic_pkg'instance_name
& "TO_UFIXED(REAL): vector truncated"
severity warning;
if overflow_style = fixed_wrap then
presult := presult mod (2.0**(left_index+1)); -- wrap
else
return saturate (result'high, result'low);
end if;
end if;
for i in Xresult'range loop
if presult >= 2.0**i then
Xresult(i) := '1';
presult := presult - 2.0**i;
else
Xresult(i) := '0';
end if;
end loop;
if guard_bits > 0 and round_style = fixed_round then
result := round_fixed (arg => Xresult (left_index
downto right_index),
remainder => Xresult (right_index-1 downto
right_index-guard_bits),
overflow_style => overflow_style);
else
result := Xresult (result'range);
end if;
return result;
end function to_ufixed;
function to_sfixed (
arg : REAL; -- real
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mins (right_index, right_index); -- catch literals
variable result : UNRESOLVED_sfixed (left_index downto fw) :=
(others => '0');
variable Xresult : UNRESOLVED_sfixed (left_index+1 downto fw-guard_bits) :=
(others => '0');
variable presult : REAL;
begin
if (left_index < fw) then -- null range
return NASF;
end if;
if (arg >= (2.0**left_index) or arg < -(2.0**left_index)) then
assert no_warning report fixed_generic_pkg'instance_name
& "TO_SFIXED(REAL): vector truncated"
severity warning;
if overflow_style = fixed_saturate then
if arg < 0.0 then -- saturate
result := not saturate (result'high, result'low); -- underflow
else
result := saturate (result'high, result'low); -- overflow
end if;
return result;
else
presult := abs(arg) mod (2.0**(left_index+1)); -- wrap
end if;
else
presult := abs(arg);
end if;
for i in Xresult'range loop
if presult >= 2.0**i then
Xresult(i) := '1';
presult := presult - 2.0**i;
else
Xresult(i) := '0';
end if;
end loop;
if arg < 0.0 then
Xresult := to_fixed(-to_s(Xresult), Xresult'high, Xresult'low);
end if;
if guard_bits > 0 and round_style = fixed_round then
result := round_fixed (arg => Xresult (left_index
downto right_index),
remainder => Xresult (right_index-1 downto
right_index-guard_bits),
overflow_style => overflow_style);
else
result := Xresult (result'range);
end if;
return result;
end function to_sfixed;
function to_ufixed (
arg : UNRESOLVED_UNSIGNED; -- unsigned
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER := 0; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
variable result : UNRESOLVED_ufixed (left_index downto right_index);
begin
if arg'length < 1 or (left_index < right_index) then
return NAUF;
end if;
result := resize (arg => UNRESOLVED_ufixed (XARG),
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
return result;
end function to_ufixed;
-- converted version
function to_ufixed (
arg : UNRESOLVED_UNSIGNED) -- unsigned
return UNRESOLVED_ufixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
begin
if arg'length < 1 then
return NAUF;
end if;
return UNRESOLVED_ufixed(XARG);
end function to_ufixed;
function to_sfixed (
arg : UNRESOLVED_SIGNED; -- signed
constant left_index : INTEGER; -- left index (high index)
constant right_index : INTEGER := 0; -- right index
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
variable result : UNRESOLVED_sfixed (left_index downto right_index);
begin
if arg'length < 1 or (left_index < right_index) then
return NASF;
end if;
result := resize (arg => UNRESOLVED_sfixed (XARG),
left_index => left_index,
right_index => right_index,
round_style => round_style,
overflow_style => overflow_style);
return result;
end function to_sfixed;
-- converted version
function to_sfixed (
arg : UNRESOLVED_SIGNED) -- signed
return UNRESOLVED_sfixed
is
constant ARG_LEFT : INTEGER := arg'length-1;
alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
begin
if arg'length < 1 then
return NASF;
end if;
return UNRESOLVED_sfixed(XARG);
end function to_sfixed;
function to_sfixed (arg : UNRESOLVED_ufixed) return UNRESOLVED_sfixed is
variable result : UNRESOLVED_sfixed (arg'high+1 downto arg'low);
begin
if arg'length < 1 then
return NASF;
end if;
result (arg'high downto arg'low) := UNRESOLVED_sfixed(cleanvec(arg));
result (arg'high+1) := '0';
return result;
end function to_sfixed;
Bound calculation functions
ufixed_high ufixed_low sfixed_high sfixed_low
ufixed_high ufixed_low sfixed_high sfixed_low -- Because of the fairly complicated sizing rules in the fixed point
-- packages these functions are provided to compute the result ranges
-- Example:
-- signal uf1 : ufixed (3 downto -3);
-- signal uf2 : ufixed (4 downto -2);
-- signal uf1multuf2 : ufixed (ufixed_high (3, -3, '*', 4, -2) downto
-- ufixed_low (3, -3, '*', 4, -2));
-- uf1multuf2 <= uf1 * uf2;
-- Valid characters: '+', '-', '*', '/', 'r' or 'R' (rem), 'm' or 'M' (mod),
-- '1' (reciprocal), 'A', 'a' (abs), 'N', 'n' (-sfixed)
function ufixed_high (left_index, right_index : INTEGER;
operation : CHARACTER := 'X';
left_index2, right_index2 : INTEGER := 0)
return INTEGER is
begin
case operation is
when '+'| '-' => return maximum (left_index, left_index2) + 1;
when '*' => return left_index + left_index2 + 1;
when '/' => return left_index - right_index2;
when '1' => return -right_index; -- reciprocal
when 'R'|'r' => return mins (left_index, left_index2); -- "rem"
when 'M'|'m' => return mins (left_index, left_index2); -- "mod"
when others => return left_index; -- For abs and default
end case;
end function ufixed_high;
function ufixed_low (left_index, right_index : INTEGER;
operation : CHARACTER := 'X';
left_index2, right_index2 : INTEGER := 0)
return INTEGER is
begin
case operation is
when '+'| '-' => return mins (right_index, right_index2);
when '*' => return right_index + right_index2;
when '/' => return right_index - left_index2 - 1;
when '1' => return -left_index - 1; -- reciprocal
when 'R'|'r' => return mins (right_index, right_index2); -- "rem"
when 'M'|'m' => return mins (right_index, right_index2); -- "mod"
when others => return right_index; -- for abs and default
end case;
end function ufixed_low;
function sfixed_high (left_index, right_index : INTEGER;
operation : CHARACTER := 'X';
left_index2, right_index2 : INTEGER := 0)
return INTEGER is
begin
case operation is
when '+'| '-' => return maximum (left_index, left_index2) + 1;
when '*' => return left_index + left_index2 + 1;
when '/' => return left_index - right_index2 + 1;
when '1' => return -right_index + 1; -- reciprocal
when 'R'|'r' => return mins (left_index, left_index2); -- "rem"
when 'M'|'m' => return left_index2; -- "mod"
when 'A'|'a' => return left_index + 1; -- "abs"
when 'N'|'n' => return left_index + 1; -- -sfixed
when others => return left_index;
end case;
end function sfixed_high;
function sfixed_low (left_index, right_index : INTEGER;
operation : CHARACTER := 'X';
left_index2, right_index2 : INTEGER := 0)
return INTEGER is
begin
case operation is
when '+'| '-' => return mins (right_index, right_index2);
when '*' => return right_index + right_index2;
when '/' => return right_index - left_index2;
when '1' => return -left_index; -- reciprocal
when 'R'|'r' => return mins (right_index, right_index2); -- "rem"
when 'M'|'m' => return mins (right_index, right_index2); -- "mod"
when others => return right_index; -- default for abs, neg and default
end case;
end function sfixed_low;
-- Same as above, but using the "size_res" input only for their ranges:
-- signal uf1multuf2 : ufixed (ufixed_high (uf1, '*', uf2) downto
-- ufixed_low (uf1, '*', uf2));
-- uf1multuf2 <= uf1 * uf2;
function ufixed_high (size_res : UNRESOLVED_ufixed;
operation : CHARACTER := 'X';
size_res2 : UNRESOLVED_ufixed)
return INTEGER is
begin
return ufixed_high (left_index => size_res'high,
right_index => size_res'low,
operation => operation,
left_index2 => size_res2'high,
right_index2 => size_res2'low);
end function ufixed_high;
function ufixed_low (size_res : UNRESOLVED_ufixed;
operation : CHARACTER := 'X';
size_res2 : UNRESOLVED_ufixed)
return INTEGER is
begin
return ufixed_low (left_index => size_res'high,
right_index => size_res'low,
operation => operation,
left_index2 => size_res2'high,
right_index2 => size_res2'low);
end function ufixed_low;
function sfixed_high (size_res : UNRESOLVED_sfixed;
operation : CHARACTER := 'X';
size_res2 : UNRESOLVED_sfixed)
return INTEGER is
begin
return sfixed_high (left_index => size_res'high,
right_index => size_res'low,
operation => operation,
left_index2 => size_res2'high,
right_index2 => size_res2'low);
end function sfixed_high;
function sfixed_low (size_res : UNRESOLVED_sfixed;
operation : CHARACTER := 'X';
size_res2 : UNRESOLVED_sfixed)
return INTEGER is
begin
return sfixed_low (left_index => size_res'high,
right_index => size_res'low,
operation => operation,
left_index2 => size_res2'high,
right_index2 => size_res2'low);
end function sfixed_low;
Saturate functions
saturate
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;
DSP-style conversion and bound functions
to_UFix to_SFix ufix_high ufix_low sfix_high sfix_low
to_UFix to_SFix ufix_high ufix_low sfix_high sfix_low -- As a concession to those who use a graphical DSP environment,
-- these functions take parameters in those tools format and create
-- fixed point numbers. These functions are designed to convert from
-- a std_logic_vector to the VHDL fixed point format using the conventions
-- of these packages. In a pure VHDL environment you should use the
-- "to_ufixed" and "to_sfixed" routines.
-- Unsigned fixed point
function to_UFix (
arg : STD_ULOGIC_VECTOR;
width : NATURAL; -- width of vector
fraction : NATURAL) -- width of fraction
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (width-fraction-1 downto -fraction);
begin
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name
& "TO_UFIX (STD_ULOGIC_VECTOR) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NAUF;
else
result := to_ufixed (arg, result'high, result'low);
return result;
end if;
end function to_UFix;
-- signed fixed point
function to_SFix (
arg : STD_ULOGIC_VECTOR;
width : NATURAL; -- width of vector
fraction : NATURAL) -- width of fraction
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (width-fraction-1 downto -fraction);
begin
if (arg'length /= result'length) then
report fixed_generic_pkg'instance_name
& "TO_SFIX (STD_ULOGIC_VECTOR) "
& "Vector lengths do not match. Input length is "
& INTEGER'image(arg'length) & " and output will be "
& INTEGER'image(result'length) & " wide."
severity error;
return NASF;
else
result := to_sfixed (arg, result'high, result'low);
return result;
end if;
end function to_SFix;
-- finding the bounds of a number. These functions can be used like this:
-- signal xxx : ufixed (7 downto -3);
-- -- Which is the same as "ufixed (UFix_high (11,3) downto UFix_low(11,3))"
-- signal yyy : ufixed (UFix_high (11, 3, "+", 11, 3)
-- downto UFix_low(11, 3, "+", 11, 3));
-- Where "11" is the width of xxx (xxx'length),
-- and 3 is the lower bound (abs (xxx'low))
-- In a pure VHDL environment use "ufixed_high" and "ufixed_low"
function ufix_high (
width, fraction : NATURAL;
operation : CHARACTER := 'X';
width2, fraction2 : NATURAL := 0)
return INTEGER is
begin
return ufixed_high (left_index => width - 1 - fraction,
right_index => -fraction,
operation => operation,
left_index2 => width2 - 1 - fraction2,
right_index2 => -fraction2);
end function ufix_high;
function ufix_low (
width, fraction : NATURAL;
operation : CHARACTER := 'X';
width2, fraction2 : NATURAL := 0)
return INTEGER is
begin
return ufixed_low (left_index => width - 1 - fraction,
right_index => -fraction,
operation => operation,
left_index2 => width2 - 1 - fraction2,
right_index2 => -fraction2);
end function ufix_low;
function sfix_high (
width, fraction : NATURAL;
operation : CHARACTER := 'X';
width2, fraction2 : NATURAL := 0)
return INTEGER is
begin
return sfixed_high (left_index => width - fraction,
right_index => -fraction,
operation => operation,
left_index2 => width2 - fraction2,
right_index2 => -fraction2);
end function sfix_high;
function sfix_low (
width, fraction : NATURAL;
operation : CHARACTER := 'X';
width2, fraction2 : NATURAL := 0)
return INTEGER is
begin
return sfixed_low (left_index => width - fraction,
right_index => -fraction,
operation => operation,
left_index2 => width2 - fraction2,
right_index2 => -fraction2);
end function sfix_low;
Conversion to scalar types
to_unsigned to_signed to_real to_integer
to_unsigned to_signed to_real to_integer function to_unsigned (
arg : UNRESOLVED_ufixed; -- ufixed point input
constant size : NATURAL; -- length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_UNSIGNED is
begin
return to_uns(resize (arg => arg,
left_index => size-1,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
end function to_unsigned;
function to_unsigned (
arg : UNRESOLVED_ufixed; -- ufixed point input
size_res : UNRESOLVED_UNSIGNED; -- length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_UNSIGNED is
begin
return to_unsigned (arg => arg,
size => size_res'length,
round_style => round_style,
overflow_style => overflow_style);
end function to_unsigned;
function to_signed (
arg : UNRESOLVED_sfixed; -- sfixed point input
constant size : NATURAL; -- length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_SIGNED is
begin
return to_s(resize (arg => arg,
left_index => size-1,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
end function to_signed;
function to_signed (
arg : UNRESOLVED_sfixed; -- sfixed point input
size_res : UNRESOLVED_SIGNED; -- used for length of output
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_SIGNED is
begin
return to_signed (arg => arg,
size => size_res'length,
round_style => round_style,
overflow_style => overflow_style);
end function to_signed;
function to_real (
arg : UNRESOLVED_ufixed) -- ufixed point input
return REAL
is
constant left_index : INTEGER := arg'high;
constant right_index : INTEGER := arg'low;
variable result : REAL; -- result
variable arg_int : UNRESOLVED_ufixed (left_index downto right_index);
begin
if (arg'length < 1) then
return 0.0;
end if;
arg_int := To_X01(cleanvec(arg));
if (Is_X(arg_int)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_REAL (ufixed): metavalue detected, returning 0.0"
severity warning;
return 0.0;
end if;
result := 0.0;
for i in arg_int'range loop
if (arg_int(i) = '1') then
result := result + (2.0**i);
end if;
end loop;
return result;
end function to_real;
function to_real (
arg : UNRESOLVED_sfixed) -- ufixed point input
return REAL
is
constant left_index : INTEGER := arg'high;
constant right_index : INTEGER := arg'low;
variable result : REAL; -- result
variable arg_int : UNRESOLVED_sfixed (left_index downto right_index);
-- unsigned version of argument
variable arg_uns : UNRESOLVED_ufixed (left_index downto right_index);
-- absolute of argument
begin
if (arg'length < 1) then
return 0.0;
end if;
arg_int := to_X01(cleanvec(arg));
if (Is_X(arg_int)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_REAL (sfixed): metavalue detected, returning 0.0"
severity warning;
return 0.0;
end if;
arg_uns := to_ufixed (arg_int);
result := to_real (arg_uns);
if (arg_int(arg_int'high) = '1') then
result := -result;
end if;
return result;
end function to_real;
function to_integer (
arg : UNRESOLVED_ufixed; -- fixed point input
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return NATURAL
is
constant left_index : INTEGER := arg'high;
variable arg_uns : UNRESOLVED_UNSIGNED (left_index+1 downto 0)
:= (others => '0');
begin
if (arg'length < 1) then
return 0;
end if;
if (Is_X (arg)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_INTEGER (ufixed): metavalue detected, returning 0"
severity warning;
return 0;
end if;
if (left_index < -1) then
return 0;
end if;
arg_uns := to_uns(resize (arg => arg,
left_index => arg_uns'high,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
return to_integer (arg_uns);
end function to_integer;
function to_integer (
arg : UNRESOLVED_sfixed; -- fixed point input
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return INTEGER
is
constant left_index : INTEGER := arg'high;
variable arg_s : UNRESOLVED_SIGNED (left_index+1 downto 0);
begin
if (arg'length < 1) then
return 0;
end if;
if (Is_X (arg)) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_INTEGER (sfixed): metavalue detected, returning 0"
severity warning;
return 0;
end if;
if (left_index < -1) then
return 0;
end if;
arg_s := to_s(resize (arg => arg,
left_index => arg_s'high,
right_index => 0,
round_style => round_style,
overflow_style => overflow_style));
return to_integer (arg_s);
end function to_integer;
Metavalue translation functions
to_01 Is_X To_X01 to_X01 To_X01Z to_X01Z To_UX01 to_UX01
to_01 Is_X To_X01 to_X01 To_X01Z to_X01Z To_UX01 to_UX01 function to_01 (
s : UNRESOLVED_ufixed; -- ufixed point input
constant XMAP : STD_ULOGIC := '0') -- Map x to
return UNRESOLVED_ufixed
is
begin
if (s'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_01(ufixed): null detected, returning NULL"
severity warning;
return NAUF;
end if;
return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low);
end function to_01;
function to_01 (
s : UNRESOLVED_sfixed; -- sfixed point input
constant XMAP : STD_ULOGIC := '0') -- Map x to
return UNRESOLVED_sfixed
is
begin
if (s'length < 1) then
assert no_warning
report fixed_generic_pkg'instance_name
& "TO_01(sfixed): null detected, returning NULL"
severity warning;
return NASF;
end if;
return to_fixed (to_01(to_s(s), XMAP), s'high, s'low);
end function to_01;
function Is_X (
arg : UNRESOLVED_ufixed)
return BOOLEAN
is
variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv
begin
argslv := to_sulv(arg);
return Is_X (argslv);
end function Is_X;
function Is_X (
arg : UNRESOLVED_sfixed)
return BOOLEAN
is
variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv
begin
argslv := to_sulv(arg);
return Is_X (argslv);
end function Is_X;
function To_X01 (
arg : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed is
begin
return to_ufixed (To_X01(to_sulv(arg)), arg'high, arg'low);
end function To_X01;
function to_X01 (
arg : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return to_sfixed (To_X01(to_sulv(arg)), arg'high, arg'low);
end function to_X01;
function To_X01Z (
arg : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed is
begin
return to_ufixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
end function To_X01Z;
function to_X01Z (
arg : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return to_sfixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
end function to_X01Z;
function To_UX01 (
arg : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed is
begin
return to_ufixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
end function To_UX01;
function to_UX01 (
arg : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return to_sfixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
end function to_UX01;
Resize functions
resize
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;
Size_res conversion and resize functions
to_ufixed to_sfixed resize
to_ufixed to_sfixed resize -- size_res functions
-- These functions compute the size from a passed variable named "size_res"
-- The only part of this variable used it it's size, it is never passed
-- to a lower level routine.
function to_ufixed (
arg : STD_ULOGIC_VECTOR; -- shifted vector
size_res : UNRESOLVED_ufixed) -- for size only
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_ufixed (size_res'left downto fw);
begin
if (result'length < 1 or arg'length < 1) then
return NAUF;
else
result := to_ufixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low);
return result;
end if;
end function to_ufixed;
function to_sfixed (
arg : STD_ULOGIC_VECTOR; -- shifted vector
size_res : UNRESOLVED_sfixed) -- for size only
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_sfixed (size_res'left downto fw);
begin
if (result'length < 1 or arg'length < 1) then
return NASF;
else
result := to_sfixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low);
return result;
end if;
end function to_sfixed;
function to_ufixed (
arg : NATURAL; -- integer
size_res : UNRESOLVED_ufixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_ufixed (size_res'left downto fw);
begin
if (result'length < 1) then
return NAUF;
else
result := to_ufixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function to_ufixed;
function to_sfixed (
arg : INTEGER; -- integer
size_res : UNRESOLVED_sfixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_sfixed (size_res'left downto fw);
begin
if (result'length < 1) then
return NASF;
else
result := to_sfixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function to_sfixed;
function to_ufixed (
arg : REAL; -- real
size_res : UNRESOLVED_ufixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_ufixed (size_res'left downto fw);
begin
if (result'length < 1) then
return NAUF;
else
result := to_ufixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
guard_bits => guard_bits,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function to_ufixed;
function to_sfixed (
arg : REAL; -- real
size_res : UNRESOLVED_sfixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style;
constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_sfixed (size_res'left downto fw);
begin
if (result'length < 1) then
return NASF;
else
result := to_sfixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
guard_bits => guard_bits,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function to_sfixed;
function to_ufixed (
arg : UNRESOLVED_UNSIGNED; -- unsigned
size_res : UNRESOLVED_ufixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_ufixed (size_res'left downto fw);
begin
if (result'length < 1 or arg'length < 1) then
return NAUF;
else
result := to_ufixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function to_ufixed;
function to_sfixed (
arg : UNRESOLVED_SIGNED; -- signed
size_res : UNRESOLVED_sfixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_sfixed (size_res'left downto fw);
begin
if (result'length < 1 or arg'length < 1) then
return NASF;
else
result := to_sfixed (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function to_sfixed;
function resize (
arg : UNRESOLVED_ufixed; -- input
size_res : UNRESOLVED_ufixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_ufixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_ufixed (size_res'high downto fw);
begin
if (result'length < 1 or arg'length < 1) then
return NAUF;
else
result := resize (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function resize;
function resize (
arg : UNRESOLVED_sfixed; -- input
size_res : UNRESOLVED_sfixed; -- for size only
constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
constant round_style : fixed_round_style_type := fixed_round_style)
return UNRESOLVED_sfixed
is
constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
variable result : UNRESOLVED_sfixed (size_res'high downto fw);
begin
if (result'length < 1 or arg'length < 1) then
return NASF;
else
result := resize (arg => arg,
left_index => size_res'high,
right_index => size_res'low,
round_style => round_style,
overflow_style => overflow_style);
return result;
end if;
end function resize;
Arithmetic operators and functions with REAL and INTEGER
"+" "-" "*" "/" "rem" "mod"
"+" "-" "*" "/" "rem" "mod" -- Overloaded math functions for real
function "+" (
l : UNRESOLVED_ufixed; -- fixed point input
r : REAL)
return UNRESOLVED_ufixed is
begin
return (l + to_ufixed (r, l'high, l'low));
end function "+";
function "+" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, r'low) + r);
end function "+";
function "+" (
l : UNRESOLVED_sfixed; -- fixed point input
r : REAL)
return UNRESOLVED_sfixed is
begin
return (l + to_sfixed (r, l'high, l'low));
end function "+";
function "+" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, r'low) + r);
end function "+";
function "-" (
l : UNRESOLVED_ufixed; -- fixed point input
r : REAL)
return UNRESOLVED_ufixed is
begin
return (l - to_ufixed (r, l'high, l'low));
end function "-";
function "-" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, r'low) - r);
end function "-";
function "-" (
l : UNRESOLVED_sfixed; -- fixed point input
r : REAL)
return UNRESOLVED_sfixed is
begin
return (l - to_sfixed (r, l'high, l'low));
end function "-";
function "-" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, r'low) - r);
end function "-";
function "*" (
l : UNRESOLVED_ufixed; -- fixed point input
r : REAL)
return UNRESOLVED_ufixed is
begin
return (l * to_ufixed (r, l'high, l'low));
end function "*";
function "*" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, r'low) * r);
end function "*";
function "*" (
l : UNRESOLVED_sfixed; -- fixed point input
r : REAL)
return UNRESOLVED_sfixed is
begin
return (l * to_sfixed (r, l'high, l'low));
end function "*";
function "*" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, r'low) * r);
end function "*";
function "/" (
l : UNRESOLVED_ufixed; -- fixed point input
r : REAL)
return UNRESOLVED_ufixed is
begin
return (l / to_ufixed (r, l'high, l'low));
end function "/";
function "/" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, r'low) / r);
end function "/";
function "/" (
l : UNRESOLVED_sfixed; -- fixed point input
r : REAL)
return UNRESOLVED_sfixed is
begin
return (l / to_sfixed (r, l'high, l'low));
end function "/";
function "/" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, r'low) / r);
end function "/";
function "rem" (
l : UNRESOLVED_ufixed; -- fixed point input
r : REAL)
return UNRESOLVED_ufixed is
begin
return (l rem to_ufixed (r, l'high, l'low));
end function "rem";
function "rem" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, r'low) rem r);
end function "rem";
function "rem" (
l : UNRESOLVED_sfixed; -- fixed point input
r : REAL)
return UNRESOLVED_sfixed is
begin
return (l rem to_sfixed (r, l'high, l'low));
end function "rem";
function "rem" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, r'low) rem r);
end function "rem";
function "mod" (
l : UNRESOLVED_ufixed; -- fixed point input
r : REAL)
return UNRESOLVED_ufixed is
begin
return (l mod to_ufixed (r, l'high, l'low));
end function "mod";
function "mod" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, r'low) mod r);
end function "mod";
function "mod" (
l : UNRESOLVED_sfixed; -- fixed point input
r : REAL)
return UNRESOLVED_sfixed is
begin
return (l mod to_sfixed (r, l'high, l'low));
end function "mod";
function "mod" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, r'low) mod r);
end function "mod";
-- Overloaded math functions for integers
function "+" (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return (l + to_ufixed (r, l'high, 0));
end function "+";
function "+" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, 0) + r);
end function "+";
function "+" (
l : UNRESOLVED_sfixed; -- fixed point input
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return (l + to_sfixed (r, l'high, 0));
end function "+";
function "+" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, 0) + r);
end function "+";
-- Overloaded functions
function "-" (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return (l - to_ufixed (r, l'high, 0));
end function "-";
function "-" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, 0) - r);
end function "-";
function "-" (
l : UNRESOLVED_sfixed; -- fixed point input
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return (l - to_sfixed (r, l'high, 0));
end function "-";
function "-" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, 0) - r);
end function "-";
-- Overloaded functions
function "*" (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return (l * to_ufixed (r, l'high, 0));
end function "*";
function "*" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, 0) * r);
end function "*";
function "*" (
l : UNRESOLVED_sfixed; -- fixed point input
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return (l * to_sfixed (r, l'high, 0));
end function "*";
function "*" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, 0) * r);
end function "*";
-- Overloaded functions
function "/" (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return (l / to_ufixed (r, l'high, 0));
end function "/";
function "/" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, 0) / r);
end function "/";
function "/" (
l : UNRESOLVED_sfixed; -- fixed point input
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return (l / to_sfixed (r, l'high, 0));
end function "/";
function "/" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, 0) / r);
end function "/";
function "rem" (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return (l rem to_ufixed (r, l'high, 0));
end function "rem";
function "rem" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, 0) rem r);
end function "rem";
function "rem" (
l : UNRESOLVED_sfixed; -- fixed point input
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return (l rem to_sfixed (r, l'high, 0));
end function "rem";
function "rem" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, 0) rem r);
end function "rem";
function "mod" (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return (l mod to_ufixed (r, l'high, 0));
end function "mod";
function "mod" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return (to_ufixed (l, r'high, 0) mod r);
end function "mod";
function "mod" (
l : UNRESOLVED_sfixed; -- fixed point input
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return (l mod to_sfixed (r, l'high, 0));
end function "mod";
function "mod" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return UNRESOLVED_sfixed is
begin
return (to_sfixed (l, r'high, 0) mod r);
end function "mod";
Comparison, matching, and min/max functions with REAL and INTEGER
"=" "/=" ">=" "<=" ">" "<" "?=" "?/=" "?>=" "?<=" "?>" "?<" maximum minimum
"=" "/=" ">=" "<=" ">" "<" "?=" "?/=" "?>=" "?<=" "?>" "?<" maximum minimum -- overloaded ufixed compare functions with integer
function "=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l = to_ufixed (r, l'high, l'low));
end function "=";
function "/=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l /= to_ufixed (r, l'high, l'low));
end function "/=";
function ">=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l >= to_ufixed (r, l'high, l'low));
end function ">=";
function "<=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l <= to_ufixed (r, l'high, l'low));
end function "<=";
function ">" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l > to_ufixed (r, l'high, l'low));
end function ">";
function "<" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return BOOLEAN is
begin
return (l < to_ufixed (r, l'high, l'low));
end function "<";
function "?=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return STD_ULOGIC is
begin
return (l ?= to_ufixed (r, l'high, l'low));
end function "?=";
function "?/=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return STD_ULOGIC is
begin
return (l ?/= to_ufixed (r, l'high, l'low));
end function "?/=";
function "?>=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return STD_ULOGIC is
begin
return (l ?>= to_ufixed (r, l'high, l'low));
end function "?>=";
function "?<=" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return STD_ULOGIC is
begin
return (l ?<= to_ufixed (r, l'high, l'low));
end function "?<=";
function "?>" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return STD_ULOGIC is
begin
return (l ?> to_ufixed (r, l'high, l'low));
end function "?>";
function "?<" (
l : UNRESOLVED_ufixed;
r : NATURAL) -- fixed point input
return STD_ULOGIC is
begin
return (l ?< to_ufixed (r, l'high, l'low));
end function "?<";
function maximum (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return maximum (l, to_ufixed (r, l'high, l'low));
end function maximum;
function minimum (
l : UNRESOLVED_ufixed; -- fixed point input
r : NATURAL)
return UNRESOLVED_ufixed is
begin
return minimum (l, to_ufixed (r, l'high, l'low));
end function minimum;
-- NATURAL to ufixed
function "=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) = r);
end function "=";
function "/=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) /= r);
end function "/=";
function ">=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) >= r);
end function ">=";
function "<=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) <= r);
end function "<=";
function ">" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) > r);
end function ">";
function "<" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) < r);
end function "<";
function "?=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?= r);
end function "?=";
function "?/=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?/= r);
end function "?/=";
function "?>=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?>= r);
end function "?>=";
function "?<=" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?<= r);
end function "?<=";
function "?>" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?> r);
end function "?>";
function "?<" (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?< r);
end function "?<";
function maximum (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return maximum (to_ufixed (l, r'high, r'low), r);
end function maximum;
function minimum (
l : NATURAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return minimum (to_ufixed (l, r'high, r'low), r);
end function minimum;
-- overloaded ufixed compare functions with real
function "=" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l = to_ufixed (r, l'high, l'low));
end function "=";
function "/=" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l /= to_ufixed (r, l'high, l'low));
end function "/=";
function ">=" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l >= to_ufixed (r, l'high, l'low));
end function ">=";
function "<=" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l <= to_ufixed (r, l'high, l'low));
end function "<=";
function ">" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l > to_ufixed (r, l'high, l'low));
end function ">";
function "<" (
l : UNRESOLVED_ufixed;
r : REAL)
return BOOLEAN is
begin
return (l < to_ufixed (r, l'high, l'low));
end function "<";
function "?=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?= to_ufixed (r, l'high, l'low));
end function "?=";
function "?/=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?/= to_ufixed (r, l'high, l'low));
end function "?/=";
function "?>=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?>= to_ufixed (r, l'high, l'low));
end function "?>=";
function "?<=" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?<= to_ufixed (r, l'high, l'low));
end function "?<=";
function "?>" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?> to_ufixed (r, l'high, l'low));
end function "?>";
function "?<" (
l : UNRESOLVED_ufixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?< to_ufixed (r, l'high, l'low));
end function "?<";
function maximum (
l : UNRESOLVED_ufixed;
r : REAL)
return UNRESOLVED_ufixed is
begin
return maximum (l, to_ufixed (r, l'high, l'low));
end function maximum;
function minimum (
l : UNRESOLVED_ufixed;
r : REAL)
return UNRESOLVED_ufixed is
begin
return minimum (l, to_ufixed (r, l'high, l'low));
end function minimum;
-- real and ufixed
function "=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) = r);
end function "=";
function "/=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) /= r);
end function "/=";
function ">=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) >= r);
end function ">=";
function "<=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) <= r);
end function "<=";
function ">" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) > r);
end function ">";
function "<" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return BOOLEAN is
begin
return (to_ufixed (l, r'high, r'low) < r);
end function "<";
function "?=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?= r);
end function "?=";
function "?/=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?/= r);
end function "?/=";
function "?>=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?>= r);
end function "?>=";
function "?<=" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?<= r);
end function "?<=";
function "?>" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?> r);
end function "?>";
function "?<" (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_ufixed (l, r'high, r'low) ?< r);
end function "?<";
function maximum (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return maximum (to_ufixed (l, r'high, r'low), r);
end function maximum;
function minimum (
l : REAL;
r : UNRESOLVED_ufixed) -- fixed point input
return UNRESOLVED_ufixed is
begin
return minimum (to_ufixed (l, r'high, r'low), r);
end function minimum;
-- overloaded sfixed compare functions with integer
function "=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l = to_sfixed (r, l'high, l'low));
end function "=";
function "/=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l /= to_sfixed (r, l'high, l'low));
end function "/=";
function ">=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l >= to_sfixed (r, l'high, l'low));
end function ">=";
function "<=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l <= to_sfixed (r, l'high, l'low));
end function "<=";
function ">" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l > to_sfixed (r, l'high, l'low));
end function ">";
function "<" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return BOOLEAN is
begin
return (l < to_sfixed (r, l'high, l'low));
end function "<";
function "?=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?= to_sfixed (r, l'high, l'low));
end function "?=";
function "?/=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?/= to_sfixed (r, l'high, l'low));
end function "?/=";
function "?>=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?>= to_sfixed (r, l'high, l'low));
end function "?>=";
function "?<=" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?<= to_sfixed (r, l'high, l'low));
end function "?<=";
function "?>" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?> to_sfixed (r, l'high, l'low));
end function "?>";
function "?<" (
l : UNRESOLVED_sfixed;
r : INTEGER)
return STD_ULOGIC is
begin
return (l ?< to_sfixed (r, l'high, l'low));
end function "?<";
function maximum (
l : UNRESOLVED_sfixed;
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return maximum (l, to_sfixed (r, l'high, l'low));
end function maximum;
function minimum (
l : UNRESOLVED_sfixed;
r : INTEGER)
return UNRESOLVED_sfixed is
begin
return minimum (l, to_sfixed (r, l'high, l'low));
end function minimum;
-- integer and sfixed
function "=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) = r);
end function "=";
function "/=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) /= r);
end function "/=";
function ">=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) >= r);
end function ">=";
function "<=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) <= r);
end function "<=";
function ">" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) > r);
end function ">";
function "<" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) < r);
end function "<";
function "?=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?= r);
end function "?=";
function "?/=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?/= r);
end function "?/=";
function "?>=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?>= r);
end function "?>=";
function "?<=" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?<= r);
end function "?<=";
function "?>" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?> r);
end function "?>";
function "?<" (
l : INTEGER;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?< r);
end function "?<";
function maximum (
l : INTEGER;
r : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return maximum (to_sfixed (l, r'high, r'low), r);
end function maximum;
function minimum (
l : INTEGER;
r : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return minimum (to_sfixed (l, r'high, r'low), r);
end function minimum;
-- overloaded sfixed compare functions with real
function "=" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l = to_sfixed (r, l'high, l'low));
end function "=";
function "/=" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l /= to_sfixed (r, l'high, l'low));
end function "/=";
function ">=" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l >= to_sfixed (r, l'high, l'low));
end function ">=";
function "<=" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l <= to_sfixed (r, l'high, l'low));
end function "<=";
function ">" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l > to_sfixed (r, l'high, l'low));
end function ">";
function "<" (
l : UNRESOLVED_sfixed;
r : REAL)
return BOOLEAN is
begin
return (l < to_sfixed (r, l'high, l'low));
end function "<";
function "?=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?= to_sfixed (r, l'high, l'low));
end function "?=";
function "?/=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?/= to_sfixed (r, l'high, l'low));
end function "?/=";
function "?>=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?>= to_sfixed (r, l'high, l'low));
end function "?>=";
function "?<=" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?<= to_sfixed (r, l'high, l'low));
end function "?<=";
function "?>" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?> to_sfixed (r, l'high, l'low));
end function "?>";
function "?<" (
l : UNRESOLVED_sfixed;
r : REAL)
return STD_ULOGIC is
begin
return (l ?< to_sfixed (r, l'high, l'low));
end function "?<";
function maximum (
l : UNRESOLVED_sfixed;
r : REAL)
return UNRESOLVED_sfixed is
begin
return maximum (l, to_sfixed (r, l'high, l'low));
end function maximum;
function minimum (
l : UNRESOLVED_sfixed;
r : REAL)
return UNRESOLVED_sfixed is
begin
return minimum (l, to_sfixed (r, l'high, l'low));
end function minimum;
-- REAL and sfixed
function "=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) = r);
end function "=";
function "/=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) /= r);
end function "/=";
function ">=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) >= r);
end function ">=";
function "<=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) <= r);
end function "<=";
function ">" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) > r);
end function ">";
function "<" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return BOOLEAN is
begin
return (to_sfixed (l, r'high, r'low) < r);
end function "<";
function "?=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?= r);
end function "?=";
function "?/=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?/= r);
end function "?/=";
function "?>=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?>= r);
end function "?>=";
function "?<=" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?<= r);
end function "?<=";
function "?>" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?> r);
end function "?>";
function "?<" (
l : REAL;
r : UNRESOLVED_sfixed) -- fixed point input
return STD_ULOGIC is
begin
return (to_sfixed (l, r'high, r'low) ?< r);
end function "?<";
function maximum (
l : REAL;
r : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return maximum (to_sfixed (l, r'high, r'low), r);
end function maximum;
function minimum (
l : REAL;
r : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return minimum (to_sfixed (l, r'high, r'low), r);
end function minimum;
String conversion and text I/O functions
MVL9plus char_indexed_by_MVL9 MVL9_indexed_by_char MVL9plus_indexed_by_charMVL9_to_char char_to_MVL9 char_to_MVL9plus NBSP NUSTO_STRING TO_OSTRING TO_HSTRING from_string from_ostring from_hstringskip_whitespace write READ owrite Char2TriBits OREAD_common OREAD hwrite Char2QuadBits HREAD_common HREAD calculate_string_boundry
MVL9plus char_indexed_by_MVL9 MVL9_indexed_by_char MVL9plus_indexed_by_charMVL9_to_char char_to_MVL9 char_to_MVL9plus NBSP NUSTO_STRING TO_OSTRING TO_HSTRING from_string from_ostring from_hstringskip_whitespace write READ owrite Char2TriBits OREAD_common OREAD hwrite Char2QuadBits HREAD_common HREAD calculate_string_boundryHelper types and parsing utilities
MVL9plus char_indexed_by_MVL9 MVL9_indexed_by_char MVL9plus_indexed_by_charMVL9_to_char char_to_MVL9 char_to_MVL9plus NBSP NUSskip_whitespace
MVL9plus char_indexed_by_MVL9 MVL9_indexed_by_char MVL9plus_indexed_by_charMVL9_to_char char_to_MVL9 char_to_MVL9plus NBSP NUSskip_whitespace -- copied from std_logic_textio
type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
constant char_to_MVL9 : MVL9_indexed_by_char :=
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
constant char_to_MVL9plus : MVL9plus_indexed_by_char :=
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error);
constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
constant NUS : STRING(2 to 1) := (others => ' ');
-- purpose: Skips white space
procedure skip_whitespace (
L : inout LINE) is
variable c : CHARACTER;
variable left : positive;
begin
while L /= null and L.all'length /= 0 loop
left := L.all'left;
c := L.all(left);
if (c = ' ' or c = NBSP or c = HT) then
read (L, c);
else
exit;
end if;
end loop;
end procedure skip_whitespace;
Binary text I/O procedures
write READ
write READ -- purpose: writes fixed point into a line
procedure write (
L : inout LINE; -- input line
VALUE : in UNRESOLVED_ufixed; -- fixed point input
JUSTIFIED : in SIDE := right;
FIELD : in WIDTH := 0) is
variable s : STRING(1 to VALUE'length +1) := (others => ' ');
variable sindx : INTEGER;
begin -- function write Example: 0011.1100
sindx := 1;
for i in VALUE'high downto VALUE'low loop
if i = -1 then
s(sindx) := '.';
sindx := sindx + 1;
end if;
s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i)));
sindx := sindx + 1;
end loop;
write(L, s, JUSTIFIED, FIELD);
end procedure write;
-- purpose: writes fixed point into a line
procedure write (
L : inout LINE; -- input line
VALUE : in UNRESOLVED_sfixed; -- fixed point input
JUSTIFIED : in SIDE := right;
FIELD : in WIDTH := 0) is
variable s : STRING(1 to VALUE'length +1);
variable sindx : INTEGER;
begin -- function write Example: 0011.1100
sindx := 1;
for i in VALUE'high downto VALUE'low loop
if i = -1 then
s(sindx) := '.';
sindx := sindx + 1;
end if;
s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i)));
sindx := sindx + 1;
end loop;
write(L, s, JUSTIFIED, FIELD);
end procedure write;
procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_ufixed) is
-- Possible data: 00000.0000000
-- 000000000000
variable c : CHARACTER;
variable readOk : BOOLEAN;
variable i : INTEGER; -- index variable
variable mv : ufixed (VALUE'range);
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a "."
begin -- READ
VALUE := (VALUE'range => 'U');
skip_whitespace (L);
if VALUE'length > 0 then -- non Null input string
read (L, c, readOk);
i := VALUE'high;
while i >= VALUE'low loop
if readOk = false then -- Bail out if there was a bad read
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "End of string encountered"
severity error;
return;
elsif c = '_' then
if i = VALUE'high then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "String begins with an ""_""" severity error;
return;
elsif lastu then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Two underscores detected in input string ""__"""
severity error;
return;
else
lastu := true;
end if;
elsif c = '.' then -- binary point
if founddot then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Two binary points found in input string" severity error;
return;
elsif i /= -1 then -- Seperator in the wrong spot
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Decimal point does not match number format "
severity error;
return;
end if;
founddot := true;
lastu := false;
elsif c = ' ' or c = NBSP or c = HT then -- reading done.
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Short read, Space encounted in input string"
severity error;
return;
elsif char_to_MVL9plus(c) = error then
report fixed_generic_pkg'instance_name & "READ(ufixed) "
& "Character '" &
c & "' read, expected STD_ULOGIC literal."
severity error;
return;
else
mv(i) := char_to_MVL9(c);
i := i - 1;
if i < mv'low then
VALUE := mv;
return;
end if;
lastu := false;
end if;
read(L, c, readOk);
end loop;
end if;
end procedure READ;
procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_ufixed;
GOOD : out BOOLEAN) is
-- Possible data: 00000.0000000
-- 000000000000
variable c : CHARACTER;
variable readOk : BOOLEAN;
variable mv : ufixed (VALUE'range);
variable i : INTEGER; -- index variable
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a "."
begin -- READ
VALUE := (VALUE'range => 'U');
skip_whitespace (L);
if VALUE'length > 0 then
read (L, c, readOk);
i := VALUE'high;
GOOD := false;
while i >= VALUE'low loop
if not readOk then -- Bail out if there was a bad read
return;
elsif c = '_' then
if i = VALUE'high then -- Begins with an "_"
return;
elsif lastu then -- "__" detected
return;
else
lastu := true;
end if;
elsif c = '.' then -- binary point
if founddot then
return;
elsif i /= -1 then -- Seperator in the wrong spot
return;
end if;
founddot := true;
lastu := false;
elsif (char_to_MVL9plus(c) = error) then -- Illegal character/short read
return;
else
mv(i) := char_to_MVL9(c);
i := i - 1;
if i < mv'low then -- reading done
GOOD := true;
VALUE := mv;
return;
end if;
lastu := false;
end if;
read(L, c, readOk);
end loop;
else
GOOD := true; -- read into a null array
end if;
end procedure READ;
procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_sfixed) is
variable c : CHARACTER;
variable readOk : BOOLEAN;
variable i : INTEGER; -- index variable
variable mv : sfixed (VALUE'range);
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a "."
begin -- READ
VALUE := (VALUE'range => 'U');
skip_whitespace (L);
if VALUE'length > 0 then -- non Null input string
read (L, c, readOk);
i := VALUE'high;
while i >= VALUE'low loop
if readOk = false then -- Bail out if there was a bad read
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "End of string encountered"
severity error;
return;
elsif c = '_' then
if i = VALUE'high then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "String begins with an ""_""" severity error;
return;
elsif lastu then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Two underscores detected in input string ""__"""
severity error;
return;
else
lastu := true;
end if;
elsif c = '.' then -- binary point
if founddot then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Two binary points found in input string" severity error;
return;
elsif i /= -1 then -- Seperator in the wrong spot
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Decimal point does not match number format "
severity error;
return;
end if;
founddot := true;
lastu := false;
elsif c = ' ' or c = NBSP or c = HT then -- reading done.
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Short read, Space encounted in input string"
severity error;
return;
elsif char_to_MVL9plus(c) = error then
report fixed_generic_pkg'instance_name & "READ(sfixed) "
& "Character '" &
c & "' read, expected STD_ULOGIC literal."
severity error;
return;
else
mv(i) := char_to_MVL9(c);
i := i - 1;
if i < mv'low then
VALUE := mv;
return;
end if;
lastu := false;
end if;
read(L, c, readOk);
end loop;
end if;
end procedure READ;
procedure READ(L : inout LINE;
VALUE : out UNRESOLVED_sfixed;
GOOD : out BOOLEAN) is
variable value_ufixed : UNRESOLVED_ufixed (VALUE'range);
begin -- READ
READ (L => L, VALUE => value_ufixed, GOOD => GOOD);
VALUE := UNRESOLVED_sfixed (value_ufixed);
end procedure READ;
Octal text I/O procedures
owrite Char2TriBits OREAD_common OREAD
owrite Char2TriBits OREAD_common OREAD -- octal read and write
procedure owrite (
L : inout LINE; -- input line
VALUE : in UNRESOLVED_ufixed; -- fixed point input
JUSTIFIED : in SIDE := right;
FIELD : in WIDTH := 0) is
begin -- Example 03.30
write (L => L,
VALUE => TO_OSTRING (VALUE),
JUSTIFIED => JUSTIFIED,
FIELD => FIELD);
end procedure owrite;
procedure owrite (
L : inout LINE; -- input line
VALUE : in UNRESOLVED_sfixed; -- fixed point input
JUSTIFIED : in SIDE := right;
FIELD : in WIDTH := 0) is
begin -- Example 03.30
write (L => L,
VALUE => TO_OSTRING (VALUE),
JUSTIFIED => JUSTIFIED,
FIELD => FIELD);
end procedure owrite;
-- Note that for Octal and Hex read, you can not start with a ".",
-- the read is for numbers formatted "A.BC". These routines go to
-- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
procedure Char2TriBits (C : CHARACTER;
RESULT : out STD_ULOGIC_VECTOR(2 downto 0);
GOOD : out BOOLEAN;
ISSUE_ERROR : in BOOLEAN) is
begin
case C is
when '0' => RESULT := o"0"; GOOD := true;
when '1' => RESULT := o"1"; GOOD := true;
when '2' => RESULT := o"2"; GOOD := true;
when '3' => RESULT := o"3"; GOOD := true;
when '4' => RESULT := o"4"; GOOD := true;
when '5' => RESULT := o"5"; GOOD := true;
when '6' => RESULT := o"6"; GOOD := true;
when '7' => RESULT := o"7"; GOOD := true;
when 'Z' => RESULT := "ZZZ"; GOOD := true;
when 'X' => RESULT := "XXX"; GOOD := true;
when others =>
assert not ISSUE_ERROR
report fixed_generic_pkg'instance_name
& "OREAD Error: Read a '" & C &
"', expected an Octal character (0-7)."
severity error;
RESULT := "UUU";
GOOD := false;
end case;
end procedure Char2TriBits;
-- purpose: Routines common to the OREAD routines
procedure OREAD_common (
L : inout LINE;
slv : out STD_ULOGIC_VECTOR;
igood : out BOOLEAN;
idex : out INTEGER;
constant bpoint : in INTEGER; -- binary point
constant message : in BOOLEAN;
constant smath : in BOOLEAN) is
-- purpose: error message routine
procedure errmes (
constant mess : in STRING) is -- error message
begin
if message then
if smath then
report fixed_generic_pkg'instance_name
& "OREAD(sfixed) "
& mess
severity error;
else
report fixed_generic_pkg'instance_name
& "OREAD(ufixed) "
& mess
severity error;
end if;
end if;
end procedure errmes;
variable xgood : BOOLEAN;
variable nybble : STD_ULOGIC_VECTOR (2 downto 0); -- 3 bits
variable c : CHARACTER;
variable i : INTEGER;
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a dot.
begin
skip_whitespace (L);
if slv'length > 0 then
i := slv'high;
read (L, c, xgood);
while i > 0 loop
if xgood = false then
errmes ("Error: end of string encountered");
exit;
elsif c = '_' then
if i = slv'length then
errmes ("Error: String begins with an ""_""");
xgood := false;
exit;
elsif lastu then
errmes ("Error: Two underscores detected in input string ""__""");
xgood := false;
exit;
else
lastu := true;
end if;
elsif (c = '.') then
if (i + 1 /= bpoint) then
errmes ("encountered ""."" at wrong index");
xgood := false;
exit;
elsif i = slv'length then
errmes ("encounted a ""."" at the beginning of the line");
xgood := false;
exit;
elsif founddot then
errmes ("Two ""."" encounted in input string");
xgood := false;
exit;
end if;
founddot := true;
lastu := false;
else
Char2TriBits(c, nybble, xgood, message);
if not xgood then
exit;
end if;
slv (i downto i-2) := nybble;
i := i - 3;
lastu := false;
end if;
if i > 0 then
read (L, c, xgood);
end if;
end loop;
idex := i;
igood := xgood;
else
igood := true; -- read into a null array
idex := -1;
end if;
end procedure OREAD_common;
-- Note that for Octal and Hex read, you can not start with a ".",
-- the read is for numbers formatted "A.BC". These routines go to
-- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
procedure OREAD (L : inout LINE;
VALUE : out UNRESOLVED_ufixed) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => false);
if igood then -- We did not get another error
if not ((i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
report fixed_generic_pkg'instance_name
& "OREAD(ufixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "OREAD(ufixed): Vector truncated"
severity warning;
end if;
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure OREAD;
procedure OREAD(L : inout LINE;
VALUE : out UNRESOLVED_ufixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => false);
if (igood and -- We did not get another error
(i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure OREAD;
procedure OREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => true);
if igood then -- We did not get another error
if not ((i = -1) and -- We read everything
((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
report fixed_generic_pkg'instance_name
& "OREAD(sfixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "OREAD(sfixed): Vector truncated"
severity warning;
end if;
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure OREAD;
procedure OREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
OREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => true);
if (igood -- We did not get another error
and (i = -1) -- We read everything
and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure OREAD;
Hexadecimal text I/O procedures
hwrite Char2QuadBits HREAD_common HREAD
hwrite Char2QuadBits HREAD_common HREAD -- hex read and write
procedure hwrite (
L : inout LINE; -- input line
VALUE : in UNRESOLVED_ufixed; -- fixed point input
JUSTIFIED : in SIDE := right;
FIELD : in WIDTH := 0) is
begin -- Example 03.30
write (L => L,
VALUE => TO_HSTRING (VALUE),
JUSTIFIED => JUSTIFIED,
FIELD => FIELD);
end procedure hwrite;
-- purpose: writes fixed point into a line
procedure hwrite (
L : inout LINE; -- input line
VALUE : in UNRESOLVED_sfixed; -- fixed point input
JUSTIFIED : in SIDE := right;
FIELD : in WIDTH := 0) is
begin -- Example 03.30
write (L => L,
VALUE => TO_HSTRING (VALUE),
JUSTIFIED => JUSTIFIED,
FIELD => FIELD);
end procedure hwrite;
-- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
-- Modified from the original to be more forgiving.
procedure Char2QuadBits (C : CHARACTER;
RESULT : out STD_ULOGIC_VECTOR(3 downto 0);
GOOD : out BOOLEAN;
ISSUE_ERROR : in BOOLEAN) is
begin
case C is
when '0' => RESULT := x"0"; GOOD := true;
when '1' => RESULT := x"1"; GOOD := true;
when '2' => RESULT := x"2"; GOOD := true;
when '3' => RESULT := x"3"; GOOD := true;
when '4' => RESULT := x"4"; GOOD := true;
when '5' => RESULT := x"5"; GOOD := true;
when '6' => RESULT := x"6"; GOOD := true;
when '7' => RESULT := x"7"; GOOD := true;
when '8' => RESULT := x"8"; GOOD := true;
when '9' => RESULT := x"9"; GOOD := true;
when 'A' | 'a' => RESULT := x"A"; GOOD := true;
when 'B' | 'b' => RESULT := x"B"; GOOD := true;
when 'C' | 'c' => RESULT := x"C"; GOOD := true;
when 'D' | 'd' => RESULT := x"D"; GOOD := true;
when 'E' | 'e' => RESULT := x"E"; GOOD := true;
when 'F' | 'f' => RESULT := x"F"; GOOD := true;
when 'Z' => RESULT := "ZZZZ"; GOOD := true;
when 'X' => RESULT := "XXXX"; GOOD := true;
when others =>
assert not ISSUE_ERROR
report fixed_generic_pkg'instance_name
& "HREAD Error: Read a '" & C &
"', expected a Hex character (0-F)."
severity error;
RESULT := "UUUU";
GOOD := false;
end case;
end procedure Char2QuadBits;
-- purpose: Routines common to the HREAD routines
procedure HREAD_common (
L : inout LINE;
slv : out STD_ULOGIC_VECTOR;
igood : out BOOLEAN;
idex : out INTEGER;
constant bpoint : in INTEGER; -- binary point
constant message : in BOOLEAN;
constant smath : in BOOLEAN) is
-- purpose: error message routine
procedure errmes (
constant mess : in STRING) is -- error message
begin
if message then
if smath then
report fixed_generic_pkg'instance_name
& "HREAD(sfixed) "
& mess
severity error;
else
report fixed_generic_pkg'instance_name
& "HREAD(ufixed) "
& mess
severity error;
end if;
end if;
end procedure errmes;
variable xgood : BOOLEAN;
variable nybble : STD_ULOGIC_VECTOR (3 downto 0); -- 4 bits
variable c : CHARACTER;
variable i : INTEGER;
variable lastu : BOOLEAN := false; -- last character was an "_"
variable founddot : BOOLEAN := false; -- found a dot.
begin
skip_whitespace (L);
if slv'length > 0 then
i := slv'high;
read (L, c, xgood);
while i > 0 loop
if xgood = false then
errmes ("Error: end of string encountered");
exit;
elsif c = '_' then
if i = slv'length then
errmes ("Error: String begins with an ""_""");
xgood := false;
exit;
elsif lastu then
errmes ("Error: Two underscores detected in input string ""__""");
xgood := false;
exit;
else
lastu := true;
end if;
elsif (c = '.') then
if (i + 1 /= bpoint) then
errmes ("encountered ""."" at wrong index");
xgood := false;
exit;
elsif i = slv'length then
errmes ("encounted a ""."" at the beginning of the line");
xgood := false;
exit;
elsif founddot then
errmes ("Two ""."" encounted in input string");
xgood := false;
exit;
end if;
founddot := true;
lastu := false;
else
Char2QuadBits(c, nybble, xgood, message);
if not xgood then
exit;
end if;
slv (i downto i-3) := nybble;
i := i - 4;
lastu := false;
end if;
if i > 0 then
read (L, c, xgood);
end if;
end loop;
idex := i;
igood := xgood;
else
idex := -1;
igood := true; -- read null string
end if;
end procedure HREAD_common;
procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_ufixed) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => false);
if igood then
if not ((i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
report fixed_generic_pkg'instance_name
& "HREAD(ufixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "HREAD(ufixed): Vector truncated"
severity warning;
end if;
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure HREAD;
procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_ufixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => false);
if (igood and -- We did not get another error
(i = -1) and -- We read everything, and high bits 0
(or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
valuex := to_ufixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure HREAD;
procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => true,
smath => true);
if igood then -- We did not get another error
if not ((i = -1) -- We read everything
and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
report fixed_generic_pkg'instance_name
& "HREAD(sfixed): Vector truncated."
severity error;
else
if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
assert no_warning
report fixed_generic_pkg'instance_name
& "HREAD(sfixed): Vector truncated"
severity warning;
end if;
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
end if;
end if;
end procedure HREAD;
procedure HREAD(L : inout LINE;
VALUE : out UNRESOLVED_sfixed;
GOOD : out BOOLEAN) is
constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
variable igood : BOOLEAN;
variable i : INTEGER;
begin
VALUE := (VALUE'range => 'U');
HREAD_common ( L => L,
slv => slv,
igood => igood,
idex => i,
bpoint => -lbv,
message => false,
smath => true);
if (igood and -- We did not get another error
(i = -1) and -- We read everything
((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
(slv(VALUE'high-lbv) = '1' and
and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
valuex := to_sfixed (slv, hbv, lbv);
VALUE := valuex (VALUE'range);
GOOD := true;
else
GOOD := false;
end if;
end procedure HREAD;
Conversion to string functions
TO_STRING TO_OSTRING TO_HSTRING
TO_STRING TO_OSTRING TO_HSTRING -- TO_STRING functions. Useful in "report" statements.
-- Example: report "result was " & TO_STRING(result);
function TO_STRING (value : UNRESOLVED_ufixed) return STRING is
variable s : STRING(1 to value'length +1) := (others => ' ');
variable subval : UNRESOLVED_ufixed (value'high downto -1);
variable sindx : INTEGER;
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
if value(value'high) = 'Z' then
return TO_STRING (resize (sfixed(value), 0, value'low));
else
return TO_STRING (resize (value, 0, value'low));
end if;
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_STRING(subval);
else
return TO_STRING (resize (value, value'high, -1));
end if;
else
sindx := 1;
for i in value'high downto value'low loop
if i = -1 then
s(sindx) := '.';
sindx := sindx + 1;
end if;
s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
sindx := sindx + 1;
end loop;
return s;
end if;
end if;
end function TO_STRING;
function TO_STRING (value : UNRESOLVED_sfixed) return STRING is
variable s : STRING(1 to value'length + 1) := (others => ' ');
variable subval : UNRESOLVED_sfixed (value'high downto -1);
variable sindx : INTEGER;
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
return TO_STRING (resize (value, 0, value'low));
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_STRING(subval);
else
return TO_STRING (resize (value, value'high, -1));
end if;
else
sindx := 1;
for i in value'high downto value'low loop
if i = -1 then
s(sindx) := '.';
sindx := sindx + 1;
end if;
s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
sindx := sindx + 1;
end loop;
return s;
end if;
end if;
end function TO_STRING;
function TO_OSTRING (value : UNRESOLVED_ufixed) return STRING is
constant lne : INTEGER := (-value'low+2)/3;
variable subval : UNRESOLVED_ufixed (value'high downto -3);
variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1);
variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
if value(value'high) = 'Z' then
return TO_OSTRING (resize (sfixed(value), 2, value'low));
else
return TO_OSTRING (resize (value, 2, value'low));
end if;
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_OSTRING(subval);
else
return TO_OSTRING (resize (value, value'high, -3));
end if;
else
slv := to_sulv (value);
if Is_X (value (value'low)) then
lpad := (others => value (value'low));
else
lpad := (others => '0');
end if;
return TO_OSTRING(slv(slv'high downto slv'high-value'high))
& "."
& TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
end if;
end if;
end function TO_OSTRING;
function TO_HSTRING (value : UNRESOLVED_ufixed) return STRING is
constant lne : INTEGER := (-value'low+3)/4;
variable subval : UNRESOLVED_ufixed (value'high downto -4);
variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1);
variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
if value(value'high) = 'Z' then
return TO_HSTRING (resize (sfixed(value), 3, value'low));
else
return TO_HSTRING (resize (value, 3, value'low));
end if;
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_HSTRING(subval);
else
return TO_HSTRING (resize (value, value'high, -4));
end if;
else
slv := to_sulv (value);
if Is_X (value (value'low)) then
lpad := (others => value(value'low));
else
lpad := (others => '0');
end if;
return TO_HSTRING(slv(slv'high downto slv'high-value'high))
& "."
& TO_HSTRING(slv(slv'high-value'high-1 downto 0)&lpad);
end if;
end if;
end function TO_HSTRING;
function TO_OSTRING (value : UNRESOLVED_sfixed) return STRING is
constant ne : INTEGER := ((value'high+1)+2)/3;
variable pad : STD_ULOGIC_VECTOR(0 to (ne*3 - (value'high+1)) - 1);
constant lne : INTEGER := (-value'low+2)/3;
variable subval : UNRESOLVED_sfixed (value'high downto -3);
variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1);
variable slv : STD_ULOGIC_VECTOR (value'high - value'low downto 0);
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
return TO_OSTRING (resize (value, 2, value'low));
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_OSTRING(subval);
else
return TO_OSTRING (resize (value, value'high, -3));
end if;
else
pad := (others => value(value'high));
slv := to_sulv (value);
if Is_X (value (value'low)) then
lpad := (others => value(value'low));
else
lpad := (others => '0');
end if;
return TO_OSTRING(pad & slv(slv'high downto slv'high-value'high))
& "."
& TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
end if;
end if;
end function TO_OSTRING;
function TO_HSTRING (value : UNRESOLVED_sfixed) return STRING is
constant ne : INTEGER := ((value'high+1)+3)/4;
variable pad : STD_ULOGIC_VECTOR(0 to (ne*4 - (value'high+1)) - 1);
constant lne : INTEGER := (-value'low+3)/4;
variable subval : UNRESOLVED_sfixed (value'high downto -4);
variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1);
variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
begin
if value'length < 1 then
return NUS;
else
if value'high < 0 then
return TO_HSTRING (resize (value, 3, value'low));
elsif value'low >= 0 then
if Is_X (value(value'low)) then
subval := (others => value(value'low));
subval (value'range) := value;
return TO_HSTRING(subval);
else
return TO_HSTRING (resize (value, value'high, -4));
end if;
else
slv := to_sulv (value);
pad := (others => value(value'high));
if Is_X (value (value'low)) then
lpad := (others => value(value'low));
else
lpad := (others => '0');
end if;
return TO_HSTRING(pad & slv(slv'high downto slv'high-value'high))
& "."
& TO_HSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
end if;
end if;
end function TO_HSTRING;
Conversion from string with explicit bounds
from_string from_ostring from_hstring
from_string from_ostring from_hstring -- From string functions allow you to convert a string into a fixed
-- point number. Example:
-- signal uf1 : ufixed (3 downto -3);
-- uf1 <= from_string ("0110.100", uf1'high, uf1'low); -- 6.5
-- The "." is optional in this syntax, however it exist and is
-- in the wrong location an error is produced. Overflow will
-- result in saturation.
function from_string (
bstring : STRING; -- binary string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(bstring);
READ (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_string: Bad string "& bstring severity error;
return result;
end function from_string;
-- Octal and hex conversions work as follows:
-- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped)
-- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped)
function from_ostring (
ostring : STRING; -- Octal string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(ostring);
OREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_ostring: Bad string "& ostring severity error;
return result;
end function from_ostring;
function from_hstring (
hstring : STRING; -- hex string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_ufixed
is
variable result : UNRESOLVED_ufixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(hstring);
HREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_hstring: Bad string "& hstring severity error;
return result;
end function from_hstring;
function from_string (
bstring : STRING; -- binary string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(bstring);
READ (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_string: Bad string "& bstring severity error;
return result;
end function from_string;
function from_ostring (
ostring : STRING; -- Octal string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(ostring);
OREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_ostring: Bad string "& ostring severity error;
return result;
end function from_ostring;
function from_hstring (
hstring : STRING; -- hex string
constant left_index : INTEGER;
constant right_index : INTEGER)
return UNRESOLVED_sfixed
is
variable result : UNRESOLVED_sfixed (left_index downto right_index);
variable L : LINE;
variable good : BOOLEAN;
begin
L := new STRING'(hstring);
HREAD (L, result, good);
deallocate (L);
assert (good)
report fixed_generic_pkg'instance_name
& "from_hstring: Bad string "& hstring severity error;
return result;
end function from_hstring;
Conversion from string using result size
from_string from_ostring from_hstring
from_string from_ostring from_hstring -- Same as above, "size_res" is used for it's range only.
function from_string (
bstring : STRING; -- binary string
size_res : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed is
begin
return from_string (bstring, size_res'high, size_res'low);
end function from_string;
function from_ostring (
ostring : STRING; -- Octal string
size_res : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed is
begin
return from_ostring (ostring, size_res'high, size_res'low);
end function from_ostring;
function from_hstring (
hstring : STRING; -- hex string
size_res : UNRESOLVED_ufixed)
return UNRESOLVED_ufixed is
begin
return from_hstring(hstring, size_res'high, size_res'low);
end function from_hstring;
function from_string (
bstring : STRING; -- binary string
size_res : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return from_string (bstring, size_res'high, size_res'low);
end function from_string;
function from_ostring (
ostring : STRING; -- Octal string
size_res : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return from_ostring (ostring, size_res'high, size_res'low);
end function from_ostring;
function from_hstring (
hstring : STRING; -- hex string
size_res : UNRESOLVED_sfixed)
return UNRESOLVED_sfixed is
begin
return from_hstring (hstring, size_res'high, size_res'low);
end function from_hstring;
Direct conversion from string
from_string from_ostring from_hstringcalculate_string_boundry
from_string from_ostring from_hstringcalculate_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;
-- Direct conversion functions. Example:
-- signal uf1 : ufixed (3 downto -3);
-- uf1 <= from_string ("0110.100"); -- 6.5
-- In this case the "." is not optional, and the size of
-- the output must match exactly.
function from_string (
bstring : STRING) -- binary string
return UNRESOLVED_ufixed
is
variable left_index, right_index : INTEGER;
begin
calculate_string_boundry (bstring, left_index, right_index);
return from_string (bstring, left_index, right_index);
end function from_string;
-- Direct octal and hex conversion functions. In this case
-- the string lengths must match. Example:
-- signal sf1 := sfixed (5 downto -3);
-- sf1 <= from_ostring ("71.4") -- -6.5
function from_ostring (
ostring : STRING) -- Octal string
return UNRESOLVED_ufixed
is
variable left_index, right_index : INTEGER;
begin
calculate_string_boundry (ostring, left_index, right_index);
return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
end function from_ostring;
function from_hstring (
hstring : STRING) -- hex string
return UNRESOLVED_ufixed
is
variable left_index, right_index : INTEGER;
begin
calculate_string_boundry (hstring, left_index, right_index);
return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
end function from_hstring;
function from_string (
bstring : STRING) -- binary string
return UNRESOLVED_sfixed
is
variable left_index, right_index : INTEGER;
begin
calculate_string_boundry (bstring, left_index, right_index);
return from_string (bstring, left_index, right_index);
end function from_string;
function from_ostring (
ostring : STRING) -- Octal string
return UNRESOLVED_sfixed
is
variable left_index, right_index : INTEGER;
begin
calculate_string_boundry (ostring, left_index, right_index);
return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
end function from_ostring;
function from_hstring (
hstring : STRING) -- hex string
return UNRESOLVED_sfixed
is
variable left_index, right_index : INTEGER;
begin
calculate_string_boundry (hstring, left_index, right_index);
return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
end function from_hstring;
end package body fixed_generic_pkg;

