FIXED_GENERIC_PKG package body

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.vhdl in the IEEE 1076 OSR, tag 1076-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

ieee/fixed_generic_pkg-body.vhdl: package body (6360 lines) 319 groups
License: Apache License 2.0 Download
doc

File header Comment block (42 lines)

lines 1–42
-- -----------------------------------------------------------------
-- 
-- Copyright 2019 IEEE P1076 WG Authors
-- 
-- See the LICENSE file distributed with this work for copyright and
-- licensing information and the AUTHORS file.
-- 
-- This file to you under the Apache License, Version 2.0 (the "License").
-- You may obtain a copy of the License at
-- 
--     http://www.apache.org/licenses/LICENSE-2.0
-- 
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-- implied.  See the License for the specific language governing
-- permissions and limitations under the License.
--
--   Title     :  Fixed-point package (Generic package body)
--             :
--   Library   :  This package shall be compiled into a library
--             :  symbolically named IEEE.
--             :
--   Developers:  Accellera VHDL-TC and IEEE P1076 Working Group
--             :
--   Purpose   :  This packages defines basic binary fixed point arithmetic
--             :  arithmetic functions
--             :
--   Note      :  This package may be modified to include additional data
--             :  required by tools, but it must in no way change the
--             :  external interfaces or simulation behavior of the
--             :  description. It is permissible to add comments and/or
--             :  attributes to the package declarations, but not to change
--             :  or delete any original lines of the package declaration.
--             :  The package body may be changed only in accordance with
--             :  the terms of Clause 16 of this standard.
--             :
-- --------------------------------------------------------------------
-- $Revision: 1220 $
-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
-- --------------------------------------------------------------------
library IEEE;
use IEEE.MATH_REAL.all;

package body fixed_generic_pkg is
co

NAUF

lines 47–50
  -- 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');
co

NASF

lines 51–51
  constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0');
co

NSLV

lines 52–53
  constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0');
co

fixedsynth_or_real

lines 54–57
  -- 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;
fn

mins

lines 58–67
  -- 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;
fn

mine

lines 68–80
  -- 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;
fn

cleanvec 2 functions

lines 81–108
  -- 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;
fn

to_fixed 2 functions

lines 109–134
  -- 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;
fn

to_uns

lines 135–146
  -- 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;
fn

to_s

lines 147–158
  -- 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;
pr

round_up 2 procedures

lines 159–187
  -- 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;
fn

round_fixed 2 functions

lines 188–262
  -- 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;
fn

to_ufixed

lines 263–280
  -- converts an sfixed into a ufixed.  The output is the same length as the
  -- input, because abs("1000") = "1000" = 8.
  function to_ufixed (
    arg : UNRESOLVED_sfixed)
    return UNRESOLVED_ufixed
  is
    constant left_index  : INTEGER := arg'high;
    constant right_index : INTEGER := mine(arg'low, arg'low);
    variable xarg        : UNRESOLVED_sfixed(left_index+1 downto right_index);
    variable result      : UNRESOLVED_ufixed(left_index downto right_index);
  begin
    if arg'length < 1 then
      return NAUF;
    end if;
    xarg   := abs(arg);
    result := UNRESOLVED_ufixed (xarg (left_index downto right_index));
    return result;
  end function to_ufixed;

Visible functions


-----------------------------------------------------------------------------
-- Visible functions
-----------------------------------------------------------------------------
fn

to_sulv 2 functions

lines 285–312
  -- 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;
fn

to_slv 2 functions

lines 313–326
  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;
fn

to_ufixed

lines 327–352
  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;
fn

to_sfixed

lines 353–378
  function to_sfixed (
    arg                  : STD_ULOGIC_VECTOR;  -- shifted vector
    constant left_index  : INTEGER;
    constant right_index : INTEGER)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (left_index downto right_index);
  begin
    if (arg'length < 1 or right_index > left_index) then
      return NASF;
    end if;
    if (arg'length /= result'length) then
      report fixed_generic_pkg'instance_name & "TO_SFIXED(SLV) "
        & "Vector lengths do not match.  Input length is "
        & INTEGER'image(arg'length) & " and output will be "
        & INTEGER'image(result'length) & " wide."
        severity error;
      return NASF;
    else
      result := to_fixed (arg         => UNRESOLVED_SIGNED(arg),
                          left_index  => left_index,
                          right_index => right_index);
      return result;
    end if;
  end function to_sfixed;
fn

"abs"

lines 379–398
  -- Two's complement number, Grows the vector by 1 bit.
  -- because "abs (1000.000) = 01000.000" or abs(-16) = 16.
  function "abs" (
    arg : UNRESOLVED_sfixed)            -- fixed point input
    return UNRESOLVED_sfixed
  is
    constant left_index  : INTEGER := arg'high;
    constant right_index : INTEGER := mine(arg'low, arg'low);
    variable ressns      : UNRESOLVED_SIGNED (arg'length downto 0);
    variable result      : UNRESOLVED_sfixed (left_index+1 downto right_index);
  begin
    if (arg'length < 1 or result'length < 1) then
      return NASF;
    end if;
    ressns (arg'length-1 downto 0) := to_s (cleanvec (arg));
    ressns (arg'length)            := ressns (arg'length-1);  -- expand sign bit
    result                         := to_fixed (abs(ressns), left_index+1, right_index);
    return result;
  end function "abs";
fn

"-"

lines 399–417
  -- also grows the vector by 1 bit.
  function "-" (
    arg : UNRESOLVED_sfixed)            -- fixed point input
    return UNRESOLVED_sfixed
  is
    constant left_index  : INTEGER := arg'high+1;
    constant right_index : INTEGER := mine(arg'low, arg'low);
    variable ressns      : UNRESOLVED_SIGNED (arg'length downto 0);
    variable result      : UNRESOLVED_sfixed (left_index downto right_index);
  begin
    if (arg'length < 1 or result'length < 1) then
      return NASF;
    end if;
    ressns (arg'length-1 downto 0) := to_s (cleanvec(arg));
    ressns (arg'length)            := ressns (arg'length-1);  -- expand sign bit
    result                         := to_fixed (-ressns, left_index, right_index);
    return result;
  end function "-";
fn

"+" 2 functions

lines 418–466
  -- Addition
  function "+" (
    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) + ufixed(c downto d) =
    return UNRESOLVED_ufixed     -- ufixed(max(a,c)+1 downto min(b,d))
  is
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
    constant right_index      : INTEGER := mine(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable result           : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
                                               downto 0);
    variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
                                               downto 0);
  begin
    if (l'length < 1 or r'length < 1 or result'length < 1) then
      return NAUF;
    end if;
    lresize    := resize (l, left_index, right_index);
    rresize    := resize (r, left_index, right_index);
    lslv       := to_uns (lresize);
    rslv       := to_uns (rresize);
    result_slv := lslv + rslv;
    result     := to_fixed(result_slv, left_index, right_index);
    return result;
  end function "+";

  function "+" (
    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) + sfixed(c downto d) =
    return UNRESOLVED_sfixed     -- sfixed(max(a,c)+1 downto min(b,d))
  is
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
    constant right_index      : INTEGER := mine(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable result           : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
    variable result_slv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
  begin
    if (l'length < 1 or r'length < 1 or result'length < 1) then
      return NASF;
    end if;
    lresize    := resize (l, left_index, right_index);
    rresize    := resize (r, left_index, right_index);
    lslv       := to_s (lresize);
    rslv       := to_s (rresize);
    result_slv := lslv + rslv;
    result     := to_fixed(result_slv, left_index, right_index);
    return result;
  end function "+";
fn

"-" 2 functions

lines 467–515
  -- Subtraction
  function "-" (
    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) - ufixed(c downto d) =
    return UNRESOLVED_ufixed     -- ufixed(max(a,c)+1 downto min(b,d))
  is
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
    constant right_index      : INTEGER := mine(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable result           : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
                                               downto 0);
    variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
                                               downto 0);
  begin
    if (l'length < 1 or r'length < 1 or result'length < 1) then
      return NAUF;
    end if;
    lresize    := resize (l, left_index, right_index);
    rresize    := resize (r, left_index, right_index);
    lslv       := to_uns (lresize);
    rslv       := to_uns (rresize);
    result_slv := lslv - rslv;
    result     := to_fixed(result_slv, left_index, right_index);
    return result;
  end function "-";

  function "-" (
    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) - sfixed(c downto d) =
    return UNRESOLVED_sfixed     -- sfixed(max(a,c)+1 downto min(b,d))
  is
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
    constant right_index      : INTEGER := mine(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable result           : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
    variable result_slv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
  begin
    if (l'length < 1 or r'length < 1 or result'length < 1) then
      return NASF;
    end if;
    lresize    := resize (l, left_index, right_index);
    rresize    := resize (r, left_index, right_index);
    lslv       := to_s (lresize);
    rslv       := to_s (rresize);
    result_slv := lslv - rslv;
    result     := to_fixed(result_slv, left_index, right_index);
    return result;
  end function "-";
fn

"*" 2 functions

lines 516–557
  function "*" (
    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) * ufixed(c downto d) =
    return UNRESOLVED_ufixed     -- ufixed(a+c+1 downto b+d)
  is
    variable lslv       : UNRESOLVED_UNSIGNED (l'length-1 downto 0);
    variable rslv       : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
    variable result_slv : UNRESOLVED_UNSIGNED (r'length+l'length-1 downto 0);
    variable result     : UNRESOLVED_ufixed (l'high + r'high+1 downto
                                             mine(l'low, l'low) + mine(r'low, r'low));
  begin
    if (l'length < 1 or r'length < 1 or
        result'length /= result_slv'length) then
      return NAUF;
    end if;
    lslv       := to_uns (cleanvec(l));
    rslv       := to_uns (cleanvec(r));
    result_slv := lslv * rslv;
    result     := to_fixed (result_slv, result'high, result'low);
    return result;
  end function "*";

  function "*" (
    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) * sfixed(c downto d) =
    return UNRESOLVED_sfixed     -- sfixed(a+c+1 downto b+d)
  is
    variable lslv       : UNRESOLVED_SIGNED (l'length-1 downto 0);
    variable rslv       : UNRESOLVED_SIGNED (r'length-1 downto 0);
    variable result_slv : UNRESOLVED_SIGNED (r'length+l'length-1 downto 0);
    variable result     : UNRESOLVED_sfixed (l'high + r'high+1 downto
                                             mine(l'low, l'low) + mine(r'low, r'low));
  begin
    if (l'length < 1 or r'length < 1 or
        result'length /= result_slv'length) then
      return NASF;
    end if;
    lslv       := to_s (cleanvec(l));
    rslv       := to_s (cleanvec(r));
    result_slv := lslv * rslv;
    result     := to_fixed (result_slv, result'high, result'low);
    return result;
  end function "*";
fn

"/" 2 functions

lines 558–571
  function "/" (
    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) / ufixed(c downto d) =
    return UNRESOLVED_ufixed is         --  ufixed(a-d downto b-c-1)
  begin
    return divide (l, r);
  end function "/";

  function "/" (
    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) / sfixed(c downto d) =
    return UNRESOLVED_sfixed is         -- sfixed(a-d+1 downto b-c)
  begin
    return divide (l, r);
  end function "/";
fn

divide 2 functions

lines 572–656
  -- 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;
fn

reciprocal 2 functions

lines 657–692
  -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
  function reciprocal (
    arg                  : UNRESOLVED_ufixed;  -- fixed point input
    constant round_style : fixed_round_style_type := fixed_round_style;
    constant guard_bits  : NATURAL                := fixed_guard_bits)
    return UNRESOLVED_ufixed
  is
    constant one : UNRESOLVED_ufixed (0 downto 0) := "1";
  begin
    return divide (l           => one,
                   r           => arg,
                   round_style => round_style,
                   guard_bits  => guard_bits);
  end function reciprocal;

  -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
  function reciprocal (
    arg                  : UNRESOLVED_sfixed;              -- fixed point input
    constant round_style : fixed_round_style_type := fixed_round_style;
    constant guard_bits  : NATURAL                := fixed_guard_bits)
    return UNRESOLVED_sfixed
  is
    constant one     : UNRESOLVED_sfixed (1 downto 0) := "01";  -- extra bit.
    variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high);
  begin
    if (arg'length < 1 or resultx'length < 1) then
      return NASF;
    else
      resultx := divide (l           => one,
                         r           => arg,
                         round_style => round_style,
                         guard_bits  => guard_bits);
      return resultx (resultx'high-1 downto resultx'low);  -- remove extra bit
    end if;
  end function reciprocal;
fn

"rem" 2 functions

lines 693–711
  -- 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";
fn

remainder 2 functions

lines 712–800
  -- ufixed (a downto b) rem ufixed (c downto d)
  --        = ufixed (min(a,c) downto min(b,d))
  function remainder (
    l, r                 : UNRESOLVED_ufixed;            -- fixed point input
    constant round_style : fixed_round_style_type := fixed_round_style;
    constant guard_bits  : NATURAL                := fixed_guard_bits)
    return UNRESOLVED_ufixed
  is
    variable result     : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
                                             mine(l'low, r'low));
    variable lresize    : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
                                             mins(r'low, r'low)-guard_bits);
    variable rresize    : UNRESOLVED_ufixed (r'high downto r'low-guard_bits);
    variable dresult    : UNRESOLVED_ufixed (rresize'range);
    variable lslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
    variable rslv       : UNRESOLVED_UNSIGNED (rresize'length-1 downto 0);
    variable result_slv : UNRESOLVED_UNSIGNED (rslv'range);
  begin
    if (l'length < 1 or r'length < 1 or
        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
      return NAUF;
    end if;
    lresize := resize (arg            => l,
                       left_index     => lresize'high,
                       right_index    => lresize'low,
                       overflow_style => fixed_wrap,     -- vector only grows
                       round_style    => fixed_truncate);
    lslv := to_uns (lresize);
    rresize := resize (arg            => r,
                       left_index     => rresize'high,
                       right_index    => rresize'low,
                       overflow_style => fixed_wrap,     -- vector only grows
                       round_style    => fixed_truncate);
    rslv := to_uns (rresize);
    if (rslv = 0) then
      report fixed_generic_pkg'instance_name
        & "remainder(ufixed) Division by zero" severity error;
      result := saturate (result'high, result'low);      -- saturate
    else
      if (r'low <= l'high) then
        result_slv := lslv rem rslv;
        dresult    := to_fixed (result_slv, dresult'high, dresult'low);
        result := resize (arg            => dresult,
                          left_index     => result'high,
                          right_index    => result'low,
                          overflow_style => fixed_wrap,  -- can't overflow
                          round_style    => round_style);
      end if;
      if l'low < r'low then
        result(mins(r'low-1, l'high) downto l'low) :=
          cleanvec(l(mins(r'low-1, l'high) downto l'low));
      end if;
    end if;
    return result;
  end function remainder;

  -- remainder
  -- sfixed (a downto b) rem sfixed (c downto d)
  --        = sfixed (min(a,c) downto min(b,d))
  function remainder (
    l, r                 : UNRESOLVED_sfixed;  -- fixed point input
    constant round_style : fixed_round_style_type := fixed_round_style;
    constant guard_bits  : NATURAL                := fixed_guard_bits)
    return UNRESOLVED_sfixed
  is
    variable l_abs      : UNRESOLVED_ufixed (l'range);
    variable r_abs      : UNRESOLVED_ufixed (r'range);
    variable result     : UNRESOLVED_sfixed (minimum(r'high, l'high) downto
                                             mine(r'low, l'low));
    variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
                                             mins(r'low, l'low));
  begin
    if (l'length < 1 or r'length < 1 or
        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
      return NASF;
    end if;
    l_abs := to_ufixed (l);
    r_abs := to_ufixed (r);
    result := UNRESOLVED_sfixed (remainder (
      l           => l_abs,
      r           => r_abs,
      round_style => round_style));
    neg_result := -result;
    if l(l'high) = '1' then
      result := neg_result(result'range);
    end if;
    return result;
  end function remainder;
fn

"mod" 2 functions

lines 801–819
  -- 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";
fn

modulo 2 functions

lines 820–895
  -- 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;
pr

add_carry 2 procedures

lines 896–957
  -- 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;
fn

scalb 4 functions

lines 958–999
  -- 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;
fn

Is_Negative

lines 1000–1008
  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;
fn

find_rightmost

lines 1009–1019
  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;
fn

find_leftmost

lines 1020–1030
  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;
fn

find_rightmost

lines 1031–1041
  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;
fn

find_leftmost

lines 1042–1052
  function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
    return INTEGER is
  begin
    for_loop : for i in arg'range loop
      if arg(i) ?= y then
        return i;
      end if;
    end loop;
    return arg'low-1;                   -- return out of bounds 'low
  end function find_leftmost;
fn

"sll"

lines 1053–1064
  function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
    return UNRESOLVED_ufixed
  is
    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_ufixed (ARG'range);
  begin
    argslv := to_uns (ARG);
    argslv := argslv sll COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "sll";
fn

"srl"

lines 1065–1076
  function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
    return UNRESOLVED_ufixed
  is
    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_ufixed (ARG'range);
  begin
    argslv := to_uns (ARG);
    argslv := argslv srl COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "srl";
fn

"rol"

lines 1077–1088
  function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
    return UNRESOLVED_ufixed
  is
    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_ufixed (ARG'range);
  begin
    argslv := to_uns (ARG);
    argslv := argslv rol COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "rol";
fn

"ror"

lines 1089–1100
  function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
    return UNRESOLVED_ufixed
  is
    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_ufixed (ARG'range);
  begin
    argslv := to_uns (ARG);
    argslv := argslv ror COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "ror";
fn

"sla"

lines 1101–1113
  function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
    return UNRESOLVED_ufixed
  is
    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_ufixed (ARG'range);
  begin
    argslv := to_uns (ARG);
    -- Arithmetic shift on an unsigned is a logical shift
    argslv := argslv sll COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "sla";
fn

"sra"

lines 1114–1126
  function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
    return UNRESOLVED_ufixed
  is
    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_ufixed (ARG'range);
  begin
    argslv := to_uns (ARG);
    -- Arithmetic shift on an unsigned is a logical shift
    argslv := argslv srl COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "sra";
fn

"sll"

lines 1127–1138
  function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
    return UNRESOLVED_sfixed
  is
    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_sfixed (ARG'range);
  begin
    argslv := to_s (ARG);
    argslv := argslv sll COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "sll";
fn

"srl"

lines 1139–1150
  function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
    return UNRESOLVED_sfixed
  is
    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_sfixed (ARG'range);
  begin
    argslv := to_s (ARG);
    argslv := argslv srl COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "srl";
fn

"rol"

lines 1151–1162
  function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
    return UNRESOLVED_sfixed
  is
    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_sfixed (ARG'range);
  begin
    argslv := to_s (ARG);
    argslv := argslv rol COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "rol";
fn

"ror"

lines 1163–1174
  function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
    return UNRESOLVED_sfixed
  is
    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_sfixed (ARG'range);
  begin
    argslv := to_s (ARG);
    argslv := argslv ror COUNT;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "ror";
fn

"sla"

lines 1175–1191
  function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
    return UNRESOLVED_sfixed
  is
    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
    variable result : UNRESOLVED_sfixed (ARG'range);
  begin
    argslv := to_s (ARG);
    if COUNT > 0 then
      -- Arithmetic shift left on a 2's complement number is a logic shift
      argslv := argslv sll COUNT;
    else
      argslv := argslv sra -COUNT;
    end if;
    result := to_fixed (argslv, result'high, result'low);
    return result;
  end function "sla";
fn

"sra"

lines 1192–1208
  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";
fn

SHIFT_LEFT, SHIFT_RIGHT 4 functions

lines 1209–1244
  -- Because some people want the older functions.
  function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    if (ARG'length < 1) then
      return NAUF;
    end if;
    return ARG sla COUNT;
  end function SHIFT_LEFT;

  function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    if (ARG'length < 1) then
      return NAUF;
    end if;
    return ARG sra COUNT;
  end function SHIFT_RIGHT;

  function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
    return UNRESOLVED_sfixed is
  begin
    if (ARG'length < 1) then
      return NASF;
    end if;
    return ARG sla COUNT;
  end function SHIFT_LEFT;

  function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
    return UNRESOLVED_sfixed is
  begin
    if (ARG'length < 1) then
      return NASF;
    end if;
    return ARG sra COUNT;
  end function SHIFT_RIGHT;

Logical functions


  ----------------------------------------------------------------------------
  -- logical functions
  ----------------------------------------------------------------------------
fn

"not"

lines 1249–1255
  function "not" (L : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    RESULT := not to_sulv(L);
    return to_ufixed(RESULT, L'high, L'low);
  end function "not";
fn

"and"

lines 1256–1270
  function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) and to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """and"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_ufixed(RESULT, L'high, L'low);
  end function "and";
fn

"or"

lines 1271–1285
  function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) or to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """or"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_ufixed(RESULT, L'high, L'low);
  end function "or";
fn

"nand"

lines 1286–1300
  function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) nand to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """nand"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_ufixed(RESULT, L'high, L'low);
  end function "nand";
fn

"nor"

lines 1301–1315
  function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) nor to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """nor"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_ufixed(RESULT, L'high, L'low);
  end function "nor";
fn

"xor"

lines 1316–1330
  function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) xor to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """xor"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_ufixed(RESULT, L'high, L'low);
  end function "xor";
fn

"xnor"

lines 1331–1345
  function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) xnor to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """xnor"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_ufixed(RESULT, L'high, L'low);
  end function "xnor";
fn

"not"

lines 1346–1352
  function "not" (L : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    RESULT := not to_sulv(L);
    return to_sfixed(RESULT, L'high, L'low);
  end function "not";
fn

"and"

lines 1353–1367
  function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) and to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """and"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_sfixed(RESULT, L'high, L'low);
  end function "and";
fn

"or"

lines 1368–1382
  function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) or to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """or"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_sfixed(RESULT, L'high, L'low);
  end function "or";
fn

"nand"

lines 1383–1397
  function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) nand to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """nand"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_sfixed(RESULT, L'high, L'low);
  end function "nand";
fn

"nor"

lines 1398–1412
  function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) nor to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """nor"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_sfixed(RESULT, L'high, L'low);
  end function "nor";
fn

"xor"

lines 1413–1427
  function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) xor to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """xor"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_sfixed(RESULT, L'high, L'low);
  end function "xor";
fn

"xnor"

lines 1428–1442
  function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
  begin
    if (L'high = R'high and L'low = R'low) then
      RESULT := to_sulv(L) xnor to_sulv(R);
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """xnor"": Range error L'RANGE /= R'RANGE"
        severity warning;
      RESULT := (others => 'X');
    end if;
    return to_sfixed(RESULT, L'high, L'low);
  end function "xnor";
fn

"and" 2 functions

lines 1443–1465
  -- Vector and std_ulogic functions, same as functions in numeric_std
  function "and" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (R'range);
  begin
    for i in result'range loop
      result(i) := L and R(i);
    end loop;
    return result;
  end function "and";

  function "and" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) and R;
    end loop;
    return result;
  end function "and";
fn

"or" 2 functions

lines 1466–1487
  function "or" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (R'range);
  begin
    for i in result'range loop
      result(i) := L or R(i);
    end loop;
    return result;
  end function "or";

  function "or" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) or R;
    end loop;
    return result;
  end function "or";
fn

"nand" 2 functions

lines 1488–1509
  function "nand" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (R'range);
  begin
    for i in result'range loop
      result(i) := L nand R(i);
    end loop;
    return result;
  end function "nand";

  function "nand" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) nand R;
    end loop;
    return result;
  end function "nand";
fn

"nor" 2 functions

lines 1510–1531
  function "nor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (R'range);
  begin
    for i in result'range loop
      result(i) := L nor R(i);
    end loop;
    return result;
  end function "nor";

  function "nor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) nor R;
    end loop;
    return result;
  end function "nor";
fn

"xor" 2 functions

lines 1532–1553
  function "xor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (R'range);
  begin
    for i in result'range loop
      result(i) := L xor R(i);
    end loop;
    return result;
  end function "xor";

  function "xor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) xor R;
    end loop;
    return result;
  end function "xor";
fn

"xnor" 2 functions

lines 1554–1575
  function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (R'range);
  begin
    for i in result'range loop
      result(i) := L xnor R(i);
    end loop;
    return result;
  end function "xnor";

  function "xnor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
    return UNRESOLVED_ufixed
  is
    variable result : UNRESOLVED_ufixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) xnor R;
    end loop;
    return result;
  end function "xnor";
fn

"and" 2 functions

lines 1576–1597
  function "and" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (R'range);
  begin
    for i in result'range loop
      result(i) := L and R(i);
    end loop;
    return result;
  end function "and";

  function "and" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) and R;
    end loop;
    return result;
  end function "and";
fn

"or" 2 functions

lines 1598–1619
  function "or" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (R'range);
  begin
    for i in result'range loop
      result(i) := L or R(i);
    end loop;
    return result;
  end function "or";

  function "or" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) or R;
    end loop;
    return result;
  end function "or";
fn

"nand" 2 functions

lines 1620–1641
  function "nand" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (R'range);
  begin
    for i in result'range loop
      result(i) := L nand R(i);
    end loop;
    return result;
  end function "nand";

  function "nand" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) nand R;
    end loop;
    return result;
  end function "nand";
fn

"nor" 2 functions

lines 1642–1663
  function "nor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (R'range);
  begin
    for i in result'range loop
      result(i) := L nor R(i);
    end loop;
    return result;
  end function "nor";

  function "nor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) nor R;
    end loop;
    return result;
  end function "nor";
fn

"xor" 2 functions

lines 1664–1685
  function "xor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (R'range);
  begin
    for i in result'range loop
      result(i) := L xor R(i);
    end loop;
    return result;
  end function "xor";

  function "xor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) xor R;
    end loop;
    return result;
  end function "xor";
fn

"xnor" 2 functions

lines 1686–1707
  function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (R'range);
  begin
    for i in result'range loop
      result(i) := L xnor R(i);
    end loop;
    return result;
  end function "xnor";

  function "xnor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
    return UNRESOLVED_sfixed
  is
    variable result : UNRESOLVED_sfixed (L'range);
  begin
    for i in result'range loop
      result(i) := L(i) xnor R;
    end loop;
    return result;
  end function "xnor";
fn

"and"

lines 1708–1713
  -- Reduction operators
  function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  begin
    return and to_sulv(l);
  end function "and";
fn

"nand"

lines 1714–1718
  function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  begin
    return nand to_sulv(l);
  end function "nand";
fn

"or"

lines 1719–1723
  function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  begin
    return or to_sulv(l);
  end function "or";
fn

"nor"

lines 1724–1728
  function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  begin
    return nor to_sulv(l);
  end function "nor";
fn

"xor"

lines 1729–1733
  function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  begin
    return xor to_sulv(l);
  end function "xor";
fn

"xnor"

lines 1734–1738
  function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  begin
    return xnor to_sulv(l);
  end function "xnor";
fn

"and"

lines 1739–1743
  function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  begin
    return and to_sulv(l);
  end function "and";
fn

"nand"

lines 1744–1748
  function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  begin
    return nand to_sulv(l);
  end function "nand";
fn

"or"

lines 1749–1753
  function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  begin
    return or to_sulv(l);
  end function "or";
fn

"nor"

lines 1754–1758
  function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  begin
    return nor to_sulv(l);
  end function "nor";
fn

"xor"

lines 1759–1763
  function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  begin
    return xor to_sulv(l);
  end function "xor";
fn

"xnor"

lines 1764–1767
  function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  begin
    return xnor to_sulv(l);
  end function "xnor";
fn

"?="

lines 1768–1790
  -- End reduction operators

  function "?=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin  -- ?=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_uns (lresize);
      rslv    := to_uns (rresize);
      return lslv ?= rslv;
    end if;
  end function "?=";
fn

"?/="

lines 1791–1811
  function "?/=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin  -- ?/=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?/="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_uns (lresize);
      rslv    := to_uns (rresize);
      return lslv ?/= rslv;
    end if;
  end function "?/=";
fn

"?>"

lines 1812–1832
  function "?>" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin  -- ?>
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?>"": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_uns (lresize);
      rslv    := to_uns (rresize);
      return lslv ?> rslv;
    end if;
  end function "?>";
fn

"?>="

lines 1833–1853
  function "?>=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin  -- ?>=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?>="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_uns (lresize);
      rslv    := to_uns (rresize);
      return lslv ?>= rslv;
    end if;
  end function "?>=";
fn

"?<"

lines 1854–1874
  function "?<" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin  -- ?<
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?<"": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_uns (lresize);
      rslv    := to_uns (rresize);
      return lslv ?< rslv;
    end if;
  end function "?<";
fn

"?<="

lines 1875–1895
  function "?<=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin  -- ?<=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?<="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_uns (lresize);
      rslv    := to_uns (rresize);
      return lslv ?<= rslv;
    end if;
  end function "?<=";
fn

"?="

lines 1896–1916
  function "?=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin  -- ?=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_s (lresize);
      rslv    := to_s (rresize);
      return lslv ?= rslv;
    end if;
  end function "?=";
fn

"?/="

lines 1917–1937
  function "?/=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin  -- ?/=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?/="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_s (lresize);
      rslv    := to_s (rresize);
      return lslv ?/= rslv;
    end if;
  end function "?/=";
fn

"?>"

lines 1938–1958
  function "?>" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin  -- ?>
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?>"": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_s (lresize);
      rslv    := to_s (rresize);
      return lslv ?> rslv;
    end if;
  end function "?>";
fn

"?>="

lines 1959–1979
  function "?>=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin  -- ?>=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?>="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_s (lresize);
      rslv    := to_s (rresize);
      return lslv ?>= rslv;
    end if;
  end function "?>=";
fn

"?<"

lines 1980–2000
  function "?<" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin  -- ?<
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?<"": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_s (lresize);
      rslv    := to_s (rresize);
      return lslv ?< rslv;
    end if;
  end function "?<";
fn

"?<="

lines 2001–2021
  function "?<=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
    constant left_index       : INTEGER := maximum(L'high, R'high);
    constant right_index      : INTEGER := mins(L'low, R'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin  -- ?<=
    if ((L'length < 1) or (R'length < 1)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """?<="": null detected, returning X"
        severity warning;
      return 'X';
    else
      lresize := resize (L, left_index, right_index);
      rresize := resize (R, left_index, right_index);
      lslv    := to_s (lresize);
      rslv    := to_s (rresize);
      return lslv ?<= rslv;
    end if;
  end function "?<=";
fn

std_match 2 functions

lines 2022–2048
  -- Match function, similar to "std_match" from numeric_std
  function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is
  begin
    if (L'high = R'high and L'low = R'low) then
      return std_match(to_sulv(L), to_sulv(R));
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
        severity warning;
      return false;
    end if;
  end function std_match;

  function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is
  begin
    if (L'high = R'high and L'low = R'low) then
      return std_match(to_sulv(L), to_sulv(R));
    else
      assert no_warning
        report fixed_generic_pkg'instance_name
        & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
        severity warning;
      return false;
    end if;
  end function std_match;
fn

"=" 2 functions

lines 2049–2107
  -- compare functions
  function "=" (
    l, r : UNRESOLVED_ufixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """="": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """="": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_uns (lresize);
    rslv    := to_uns (rresize);
    return lslv = rslv;
  end function "=";

  function "=" (
    l, r : UNRESOLVED_sfixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """="": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """="": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_s (lresize);
    rslv    := to_s (rresize);
    return lslv = rslv;
  end function "=";
fn

"/=" 2 functions

lines 2108–2165
  function "/=" (
    l, r : UNRESOLVED_ufixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """/="": null argument detected, returning TRUE"
        severity warning;
      return true;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """/="": metavalue detected, returning TRUE"
        severity warning;
      return true;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_uns (lresize);
    rslv    := to_uns (rresize);
    return lslv /= rslv;
  end function "/=";

  function "/=" (
    l, r : UNRESOLVED_sfixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """/="": null argument detected, returning TRUE"
        severity warning;
      return true;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """/="": metavalue detected, returning TRUE"
        severity warning;
      return true;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_s (lresize);
    rslv    := to_s (rresize);
    return lslv /= rslv;
  end function "/=";
fn

">" 2 functions

lines 2166–2223
  function ">" (
    l, r : UNRESOLVED_ufixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>"": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>"": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_uns (lresize);
    rslv    := to_uns (rresize);
    return lslv > rslv;
  end function ">";

  function ">" (
    l, r : UNRESOLVED_sfixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>"": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>"": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_s (lresize);
    rslv    := to_s (rresize);
    return lslv > rslv;
  end function ">";
fn

"<" 2 functions

lines 2224–2281
  function "<" (
    l, r : UNRESOLVED_ufixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<"": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<"": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_uns (lresize);
    rslv    := to_uns (rresize);
    return lslv < rslv;
  end function "<";

  function "<" (
    l, r : UNRESOLVED_sfixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<"": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<"": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_s (lresize);
    rslv    := to_s (rresize);
    return lslv < rslv;
  end function "<";
fn

">=" 2 functions

lines 2282–2339
  function ">=" (
    l, r : UNRESOLVED_ufixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>="": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>="": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_uns (lresize);
    rslv    := to_uns (rresize);
    return lslv >= rslv;
  end function ">=";

  function ">=" (
    l, r : UNRESOLVED_sfixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>="": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """>="": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize := resize (l, left_index, right_index);
    rresize := resize (r, left_index, right_index);
    lslv    := to_s (lresize);
    rslv    := to_s (rresize);
    return lslv >= rslv;
  end function ">=";
fn

"<=" 2 functions

lines 2340–2397
  function "<=" (
    l, r : UNRESOLVED_ufixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<="": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<="": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize     := resize (l, left_index, right_index);
    rresize     := resize (r, left_index, right_index);
    lslv        := to_uns (lresize);
    rslv        := to_uns (rresize);
    return lslv <= rslv;
  end function "<=";

  function "<=" (
    l, r : UNRESOLVED_sfixed)           -- fixed point input
    return BOOLEAN
  is
    constant left_index       : INTEGER := maximum(l'high, r'high);
    constant right_index      : INTEGER := mins(l'low, r'low);
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  begin
    if (l'length < 1 or r'length < 1) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<="": null argument detected, returning FALSE"
        severity warning;
      return false;
    elsif (Is_X(l) or Is_X(r)) then
      assert no_warning
        report fixed_generic_pkg'instance_name
        & """<="": metavalue detected, returning FALSE"
        severity warning;
      return false;
    end if;
    lresize     := resize (l, left_index, right_index);
    rresize     := resize (r, left_index, right_index);
    lslv        := to_s (lresize);
    rslv        := to_s (rresize);
    return lslv <= rslv;
  end function "<=";
fn

maximum 2 functions

lines 2398–2426
  -- 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;
fn

minimum 2 functions

lines 2427–2454
  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;
fn

to_ufixed

lines 2455–2501
  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;
fn

to_sfixed

lines 2502–2560
  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;
fn

to_ufixed

lines 2561–2618
  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;
fn

to_sfixed

lines 2619–2677
  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;
fn

to_ufixed 2 functions

lines 2678–2714
  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;
fn

to_sfixed 3 functions

lines 2715–2762
  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;
fn

ufixed_high

lines 2763–2788
  -- 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;
fn

ufixed_low

lines 2789–2804
  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;
fn

sfixed_high

lines 2805–2822
  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;
fn

sfixed_low

lines 2823–2838
  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;
fn

ufixed_high

lines 2839–2854
  -- 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;
fn

ufixed_low

lines 2855–2866
  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;
fn

sfixed_high

lines 2867–2878
  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;
fn

sfixed_low

lines 2879–2890
  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;
fn

saturate 4 functions

lines 2891–2930
  -- 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;
fn

to_UFix

lines 2931–2959
  -- 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;
fn

to_SFix

lines 2960–2982
  -- 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;
fn

ufix_high

lines 2983–3003
  -- 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;
fn

ufix_low

lines 3004–3016
  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;
fn

sfix_high

lines 3017–3029
  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;
fn

sfix_low

lines 3030–3042
  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;
fn

to_unsigned 2 functions

lines 3043–3069
  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;
fn

to_signed 2 functions

lines 3070–3096
  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;
fn

to_real 2 functions

lines 3097–3156
  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;
fn

to_integer 2 functions

lines 3157–3217
  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;
fn

to_01 2 functions

lines 3218–3249
  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;
fn

Is_X 2 functions

lines 3250–3269
  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;
fn

To_X01

lines 3270–3276
  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;
fn

to_X01

lines 3277–3283
  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;
fn

To_X01Z

lines 3284–3290
  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;
fn

to_X01Z

lines 3291–3297
  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;
fn

To_UX01

lines 3298–3304
  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;
fn

to_UX01

lines 3305–3311
  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;
fn

resize 2 functions

lines 3312–3473
  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;
fn

to_ufixed

lines 3474–3495
  -- 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;
fn

to_sfixed

lines 3496–3513
  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;
fn

to_ufixed

lines 3514–3535
  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;
fn

to_sfixed

lines 3536–3557
  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;
fn

to_ufixed

lines 3558–3581
  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;
fn

to_sfixed

lines 3582–3605
  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;
fn

to_ufixed

lines 3606–3627
  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;
fn

to_sfixed

lines 3628–3649
  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;
fn

resize 2 functions

lines 3650–3693
  function resize (
    arg                     : UNRESOLVED_ufixed;  -- input
    size_res                : UNRESOLVED_ufixed;  -- for size only
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
    constant round_style    : fixed_round_style_type    := fixed_round_style)
    return UNRESOLVED_ufixed
  is
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
    variable result : UNRESOLVED_ufixed (size_res'high downto fw);
  begin
    if (result'length < 1 or arg'length < 1) then
      return NAUF;
    else
      result := resize (arg            => arg,
                        left_index     => size_res'high,
                        right_index    => size_res'low,
                        round_style    => round_style,
                        overflow_style => overflow_style);
      return result;
    end if;
  end function resize;

  function resize (
    arg                     : UNRESOLVED_sfixed;  -- input
    size_res                : UNRESOLVED_sfixed;  -- for size only
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
    constant round_style    : fixed_round_style_type    := fixed_round_style)
    return UNRESOLVED_sfixed
  is
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
    variable result : UNRESOLVED_sfixed (size_res'high downto fw);
  begin
    if (result'length < 1 or arg'length < 1) then
      return NASF;
    else
      result := resize (arg            => arg,
                        left_index     => size_res'high,
                        right_index    => size_res'low,
                        round_style    => round_style,
                        overflow_style => overflow_style);
      return result;
    end if;
  end function resize;
fn

"+" 4 functions

lines 3694–3726
  -- Overloaded math functions for real
  function "+" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_ufixed is
  begin
    return (l + to_ufixed (r, l'high, l'low));
  end function "+";

  function "+" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, r'low) + r);
  end function "+";

  function "+" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_sfixed is
  begin
    return (l + to_sfixed (r, l'high, l'low));
  end function "+";

  function "+" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, r'low) + r);
  end function "+";
fn

"-" 4 functions

lines 3727–3758
  function "-" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_ufixed is
  begin
    return (l - to_ufixed (r, l'high, l'low));
  end function "-";

  function "-" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, r'low) - r);
  end function "-";

  function "-" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_sfixed is
  begin
    return (l - to_sfixed (r, l'high, l'low));
  end function "-";

  function "-" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, r'low) - r);
  end function "-";
fn

"*" 4 functions

lines 3759–3790
  function "*" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_ufixed is
  begin
    return (l * to_ufixed (r, l'high, l'low));
  end function "*";

  function "*" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, r'low) * r);
  end function "*";

  function "*" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_sfixed is
  begin
    return (l * to_sfixed (r, l'high, l'low));
  end function "*";

  function "*" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, r'low) * r);
  end function "*";
fn

"/" 4 functions

lines 3791–3822
  function "/" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_ufixed is
  begin
    return (l / to_ufixed (r, l'high, l'low));
  end function "/";

  function "/" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, r'low) / r);
  end function "/";

  function "/" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_sfixed is
  begin
    return (l / to_sfixed (r, l'high, l'low));
  end function "/";

  function "/" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, r'low) / r);
  end function "/";
fn

"rem" 4 functions

lines 3823–3854
  function "rem" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_ufixed is
  begin
    return (l rem to_ufixed (r, l'high, l'low));
  end function "rem";

  function "rem" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, r'low) rem r);
  end function "rem";

  function "rem" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_sfixed is
  begin
    return (l rem to_sfixed (r, l'high, l'low));
  end function "rem";

  function "rem" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, r'low) rem r);
  end function "rem";
fn

"mod" 4 functions

lines 3855–3886
  function "mod" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_ufixed is
  begin
    return (l mod to_ufixed (r, l'high, l'low));
  end function "mod";

  function "mod" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, r'low) mod r);
  end function "mod";

  function "mod" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : REAL)
    return UNRESOLVED_sfixed is
  begin
    return (l mod to_sfixed (r, l'high, l'low));
  end function "mod";

  function "mod" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, r'low) mod r);
  end function "mod";
fn

"+" 4 functions

lines 3887–3919
  -- Overloaded math functions for integers
  function "+" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    return (l + to_ufixed (r, l'high, 0));
  end function "+";

  function "+" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, 0) + r);
  end function "+";

  function "+" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : INTEGER)
    return UNRESOLVED_sfixed is
  begin
    return (l + to_sfixed (r, l'high, 0));
  end function "+";

  function "+" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, 0) + r);
  end function "+";
fn

"-" 4 functions

lines 3920–3952
  -- Overloaded functions
  function "-" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    return (l - to_ufixed (r, l'high, 0));
  end function "-";

  function "-" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, 0) - r);
  end function "-";

  function "-" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : INTEGER)
    return UNRESOLVED_sfixed is
  begin
    return (l - to_sfixed (r, l'high, 0));
  end function "-";

  function "-" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, 0) - r);
  end function "-";
fn

"*" 4 functions

lines 3953–3985
  -- Overloaded functions
  function "*" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    return (l * to_ufixed (r, l'high, 0));
  end function "*";

  function "*" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, 0) * r);
  end function "*";

  function "*" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : INTEGER)
    return UNRESOLVED_sfixed is
  begin
    return (l * to_sfixed (r, l'high, 0));
  end function "*";

  function "*" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, 0) * r);
  end function "*";
fn

"/" 4 functions

lines 3986–4018
  -- Overloaded functions
  function "/" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    return (l / to_ufixed (r, l'high, 0));
  end function "/";

  function "/" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, 0) / r);
  end function "/";

  function "/" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : INTEGER)
    return UNRESOLVED_sfixed is
  begin
    return (l / to_sfixed (r, l'high, 0));
  end function "/";

  function "/" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, 0) / r);
  end function "/";
fn

"rem" 4 functions

lines 4019–4050
  function "rem" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    return (l rem to_ufixed (r, l'high, 0));
  end function "rem";

  function "rem" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, 0) rem r);
  end function "rem";

  function "rem" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : INTEGER)
    return UNRESOLVED_sfixed is
  begin
    return (l rem to_sfixed (r, l'high, 0));
  end function "rem";

  function "rem" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, 0) rem r);
  end function "rem";
fn

"mod" 4 functions

lines 4051–4082
  function "mod" (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    return (l mod to_ufixed (r, l'high, 0));
  end function "mod";

  function "mod" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return (to_ufixed (l, r'high, 0) mod r);
  end function "mod";

  function "mod" (
    l : UNRESOLVED_sfixed;              -- fixed point input
    r : INTEGER)
    return UNRESOLVED_sfixed is
  begin
    return (l mod to_sfixed (r, l'high, 0));
  end function "mod";

  function "mod" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return UNRESOLVED_sfixed is
  begin
    return (to_sfixed (l, r'high, 0) mod r);
  end function "mod";
fn

"="

lines 4083–4091
  -- overloaded ufixed compare functions with integer
  function "=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return BOOLEAN is
  begin
    return (l = to_ufixed (r, l'high, l'low));
  end function "=";
fn

"/="

lines 4092–4099
  function "/=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return BOOLEAN is
  begin
    return (l /= to_ufixed (r, l'high, l'low));
  end function "/=";
fn

">="

lines 4100–4107
  function ">=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return BOOLEAN is
  begin
    return (l >= to_ufixed (r, l'high, l'low));
  end function ">=";
fn

"<="

lines 4108–4115
  function "<=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return BOOLEAN is
  begin
    return (l <= to_ufixed (r, l'high, l'low));
  end function "<=";
fn

">"

lines 4116–4123
  function ">" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return BOOLEAN is
  begin
    return (l > to_ufixed (r, l'high, l'low));
  end function ">";
fn

"<"

lines 4124–4131
  function "<" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return BOOLEAN is
  begin
    return (l < to_ufixed (r, l'high, l'low));
  end function "<";
fn

"?="

lines 4132–4139
  function "?=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return STD_ULOGIC is
  begin
    return (l ?= to_ufixed (r, l'high, l'low));
  end function "?=";
fn

"?/="

lines 4140–4147
  function "?/=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return STD_ULOGIC is
  begin
    return (l ?/= to_ufixed (r, l'high, l'low));
  end function "?/=";
fn

"?>="

lines 4148–4155
  function "?>=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return STD_ULOGIC is
  begin
    return (l ?>= to_ufixed (r, l'high, l'low));
  end function "?>=";
fn

"?<="

lines 4156–4163
  function "?<=" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return STD_ULOGIC is
  begin
    return (l ?<= to_ufixed (r, l'high, l'low));
  end function "?<=";
fn

"?>"

lines 4164–4171
  function "?>" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return STD_ULOGIC is
  begin
    return (l ?> to_ufixed (r, l'high, l'low));
  end function "?>";
fn

"?<"

lines 4172–4179
  function "?<" (
    l : UNRESOLVED_ufixed;
    r : NATURAL)                        -- fixed point input
    return STD_ULOGIC is
  begin
    return (l ?< to_ufixed (r, l'high, l'low));
  end function "?<";
fn

maximum

lines 4180–4187
  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;
fn

minimum

lines 4188–4195
  function minimum (
    l : UNRESOLVED_ufixed;              -- fixed point input
    r : NATURAL)
    return UNRESOLVED_ufixed is
  begin
    return minimum (l, to_ufixed (r, l'high, l'low));
  end function minimum;
fn

"="

lines 4196–4204
  -- NATURAL to ufixed
  function "=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) = r);
  end function "=";
fn

"/="

lines 4205–4212
  function "/=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) /= r);
  end function "/=";
fn

">="

lines 4213–4220
  function ">=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) >= r);
  end function ">=";
fn

"<="

lines 4221–4228
  function "<=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) <= r);
  end function "<=";
fn

">"

lines 4229–4236
  function ">" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) > r);
  end function ">";
fn

"<"

lines 4237–4244
  function "<" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) < r);
  end function "<";
fn

"?="

lines 4245–4252
  function "?=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?= r);
  end function "?=";
fn

"?/="

lines 4253–4260
  function "?/=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?/= r);
  end function "?/=";
fn

"?>="

lines 4261–4268
  function "?>=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?>= r);
  end function "?>=";
fn

"?<="

lines 4269–4276
  function "?<=" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?<= r);
  end function "?<=";
fn

"?>"

lines 4277–4284
  function "?>" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?> r);
  end function "?>";
fn

"?<"

lines 4285–4292
  function "?<" (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?< r);
  end function "?<";
fn

maximum

lines 4293–4300
  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;
fn

minimum

lines 4301–4308
  function minimum (
    l : NATURAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return minimum (to_ufixed (l, r'high, r'low), r);
  end function minimum;
fn

"="

lines 4309–4317
  -- overloaded ufixed compare functions with real
  function "=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l = to_ufixed (r, l'high, l'low));
  end function "=";
fn

"/="

lines 4318–4325
  function "/=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l /= to_ufixed (r, l'high, l'low));
  end function "/=";
fn

">="

lines 4326–4333
  function ">=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l >= to_ufixed (r, l'high, l'low));
  end function ">=";
fn

"<="

lines 4334–4341
  function "<=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l <= to_ufixed (r, l'high, l'low));
  end function "<=";
fn

">"

lines 4342–4349
  function ">" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l > to_ufixed (r, l'high, l'low));
  end function ">";
fn

"<"

lines 4350–4357
  function "<" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l < to_ufixed (r, l'high, l'low));
  end function "<";
fn

"?="

lines 4358–4365
  function "?=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?= to_ufixed (r, l'high, l'low));
  end function "?=";
fn

"?/="

lines 4366–4373
  function "?/=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?/= to_ufixed (r, l'high, l'low));
  end function "?/=";
fn

"?>="

lines 4374–4381
  function "?>=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?>= to_ufixed (r, l'high, l'low));
  end function "?>=";
fn

"?<="

lines 4382–4389
  function "?<=" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?<= to_ufixed (r, l'high, l'low));
  end function "?<=";
fn

"?>"

lines 4390–4397
  function "?>" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?> to_ufixed (r, l'high, l'low));
  end function "?>";
fn

"?<"

lines 4398–4405
  function "?<" (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?< to_ufixed (r, l'high, l'low));
  end function "?<";
fn

maximum

lines 4406–4413
  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;
fn

minimum

lines 4414–4421
  function minimum (
    l : UNRESOLVED_ufixed;
    r : REAL)
    return UNRESOLVED_ufixed is
  begin
    return minimum (l, to_ufixed (r, l'high, l'low));
  end function minimum;
fn

"="

lines 4422–4430
  -- real and ufixed
  function "=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) = r);
  end function "=";
fn

"/="

lines 4431–4438
  function "/=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) /= r);
  end function "/=";
fn

">="

lines 4439–4446
  function ">=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) >= r);
  end function ">=";
fn

"<="

lines 4447–4454
  function "<=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) <= r);
  end function "<=";
fn

">"

lines 4455–4462
  function ">" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) > r);
  end function ">";
fn

"<"

lines 4463–4470
  function "<" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_ufixed (l, r'high, r'low) < r);
  end function "<";
fn

"?="

lines 4471–4478
  function "?=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?= r);
  end function "?=";
fn

"?/="

lines 4479–4486
  function "?/=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?/= r);
  end function "?/=";
fn

"?>="

lines 4487–4494
  function "?>=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?>= r);
  end function "?>=";
fn

"?<="

lines 4495–4502
  function "?<=" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?<= r);
  end function "?<=";
fn

"?>"

lines 4503–4510
  function "?>" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?> r);
  end function "?>";
fn

"?<"

lines 4511–4518
  function "?<" (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_ufixed (l, r'high, r'low) ?< r);
  end function "?<";
fn

maximum

lines 4519–4526
  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;
fn

minimum

lines 4527–4534
  function minimum (
    l : REAL;
    r : UNRESOLVED_ufixed)              -- fixed point input
    return UNRESOLVED_ufixed is
  begin
    return minimum (to_ufixed (l, r'high, r'low), r);
  end function minimum;
fn

"="

lines 4535–4543
  -- overloaded sfixed compare functions with integer
  function "=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return BOOLEAN is
  begin
    return (l = to_sfixed (r, l'high, l'low));
  end function "=";
fn

"/="

lines 4544–4551
  function "/=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return BOOLEAN is
  begin
    return (l /= to_sfixed (r, l'high, l'low));
  end function "/=";
fn

">="

lines 4552–4559
  function ">=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return BOOLEAN is
  begin
    return (l >= to_sfixed (r, l'high, l'low));
  end function ">=";
fn

"<="

lines 4560–4567
  function "<=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return BOOLEAN is
  begin
    return (l <= to_sfixed (r, l'high, l'low));
  end function "<=";
fn

">"

lines 4568–4575
  function ">" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return BOOLEAN is
  begin
    return (l > to_sfixed (r, l'high, l'low));
  end function ">";
fn

"<"

lines 4576–4583
  function "<" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return BOOLEAN is
  begin
    return (l < to_sfixed (r, l'high, l'low));
  end function "<";
fn

"?="

lines 4584–4591
  function "?=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return STD_ULOGIC is
  begin
    return (l ?= to_sfixed (r, l'high, l'low));
  end function "?=";
fn

"?/="

lines 4592–4599
  function "?/=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return STD_ULOGIC is
  begin
    return (l ?/= to_sfixed (r, l'high, l'low));
  end function "?/=";
fn

"?>="

lines 4600–4607
  function "?>=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return STD_ULOGIC is
  begin
    return (l ?>= to_sfixed (r, l'high, l'low));
  end function "?>=";
fn

"?<="

lines 4608–4615
  function "?<=" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return STD_ULOGIC is
  begin
    return (l ?<= to_sfixed (r, l'high, l'low));
  end function "?<=";
fn

"?>"

lines 4616–4623
  function "?>" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return STD_ULOGIC is
  begin
    return (l ?> to_sfixed (r, l'high, l'low));
  end function "?>";
fn

"?<"

lines 4624–4631
  function "?<" (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return STD_ULOGIC is
  begin
    return (l ?< to_sfixed (r, l'high, l'low));
  end function "?<";
fn

maximum

lines 4632–4639
  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;
fn

minimum

lines 4640–4647
  function minimum (
    l : UNRESOLVED_sfixed;
    r : INTEGER)
    return UNRESOLVED_sfixed is
  begin
    return minimum (l, to_sfixed (r, l'high, l'low));
  end function minimum;
fn

"="

lines 4648–4656
  -- integer and sfixed
  function "=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) = r);
  end function "=";
fn

"/="

lines 4657–4664
  function "/=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) /= r);
  end function "/=";
fn

">="

lines 4665–4672
  function ">=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) >= r);
  end function ">=";
fn

"<="

lines 4673–4680
  function "<=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) <= r);
  end function "<=";
fn

">"

lines 4681–4688
  function ">" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) > r);
  end function ">";
fn

"<"

lines 4689–4696
  function "<" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) < r);
  end function "<";
fn

"?="

lines 4697–4704
  function "?=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?= r);
  end function "?=";
fn

"?/="

lines 4705–4712
  function "?/=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?/= r);
  end function "?/=";
fn

"?>="

lines 4713–4720
  function "?>=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?>= r);
  end function "?>=";
fn

"?<="

lines 4721–4728
  function "?<=" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?<= r);
  end function "?<=";
fn

"?>"

lines 4729–4736
  function "?>" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?> r);
  end function "?>";
fn

"?<"

lines 4737–4744
  function "?<" (
    l : INTEGER;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?< r);
  end function "?<";
fn

maximum

lines 4745–4752
  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;
fn

minimum

lines 4753–4760
  function minimum (
    l : INTEGER;
    r : UNRESOLVED_sfixed)
    return UNRESOLVED_sfixed is
  begin
    return minimum (to_sfixed (l, r'high, r'low), r);
  end function minimum;
fn

"="

lines 4761–4769
  -- overloaded sfixed compare functions with real
  function "=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l = to_sfixed (r, l'high, l'low));
  end function "=";
fn

"/="

lines 4770–4777
  function "/=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l /= to_sfixed (r, l'high, l'low));
  end function "/=";
fn

">="

lines 4778–4785
  function ">=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l >= to_sfixed (r, l'high, l'low));
  end function ">=";
fn

"<="

lines 4786–4793
  function "<=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l <= to_sfixed (r, l'high, l'low));
  end function "<=";
fn

">"

lines 4794–4801
  function ">" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l > to_sfixed (r, l'high, l'low));
  end function ">";
fn

"<"

lines 4802–4809
  function "<" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return BOOLEAN is
  begin
    return (l < to_sfixed (r, l'high, l'low));
  end function "<";
fn

"?="

lines 4810–4817
  function "?=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?= to_sfixed (r, l'high, l'low));
  end function "?=";
fn

"?/="

lines 4818–4825
  function "?/=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?/= to_sfixed (r, l'high, l'low));
  end function "?/=";
fn

"?>="

lines 4826–4833
  function "?>=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?>= to_sfixed (r, l'high, l'low));
  end function "?>=";
fn

"?<="

lines 4834–4841
  function "?<=" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?<= to_sfixed (r, l'high, l'low));
  end function "?<=";
fn

"?>"

lines 4842–4849
  function "?>" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?> to_sfixed (r, l'high, l'low));
  end function "?>";
fn

"?<"

lines 4850–4857
  function "?<" (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return STD_ULOGIC is
  begin
    return (l ?< to_sfixed (r, l'high, l'low));
  end function "?<";
fn

maximum

lines 4858–4865
  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;
fn

minimum

lines 4866–4873
  function minimum (
    l : UNRESOLVED_sfixed;
    r : REAL)
    return UNRESOLVED_sfixed is
  begin
    return minimum (l, to_sfixed (r, l'high, l'low));
  end function minimum;
fn

"="

lines 4874–4882
  -- REAL and sfixed
  function "=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) = r);
  end function "=";
fn

"/="

lines 4883–4890
  function "/=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) /= r);
  end function "/=";
fn

">="

lines 4891–4898
  function ">=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) >= r);
  end function ">=";
fn

"<="

lines 4899–4906
  function "<=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) <= r);
  end function "<=";
fn

">"

lines 4907–4914
  function ">" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) > r);
  end function ">";
fn

"<"

lines 4915–4922
  function "<" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return BOOLEAN is
  begin
    return (to_sfixed (l, r'high, r'low) < r);
  end function "<";
fn

"?="

lines 4923–4930
  function "?=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?= r);
  end function "?=";
fn

"?/="

lines 4931–4938
  function "?/=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?/= r);
  end function "?/=";
fn

"?>="

lines 4939–4946
  function "?>=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?>= r);
  end function "?>=";
fn

"?<="

lines 4947–4954
  function "?<=" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?<= r);
  end function "?<=";
fn

"?>"

lines 4955–4962
  function "?>" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?> r);
  end function "?>";
fn

"?<"

lines 4963–4970
  function "?<" (
    l : REAL;
    r : UNRESOLVED_sfixed)              -- fixed point input
    return STD_ULOGIC is
  begin
    return (to_sfixed (l, r'high, r'low) ?< r);
  end function "?<";
fn

maximum

lines 4971–4978
  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;
fn

minimum

lines 4979–4986
  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;
ty

MVL9plus

lines 4987–4988
  -- copied from std_logic_textio
  type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
ty

char_indexed_by_MVL9

lines 4989–4989
  type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
ty

MVL9_indexed_by_char

lines 4990–4990
  type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
ty

MVL9plus_indexed_by_char

lines 4991–4992
  type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
co

MVL9_to_char

lines 4993–4993
  constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
co

char_to_MVL9

lines 4994–4996
  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');
co

char_to_MVL9plus

lines 4997–4999
  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);
co

NBSP

lines 5000–5000
  constant NBSP : CHARACTER      := CHARACTER'val(160);  -- space character
co

NUS

lines 5001–5002
  constant NUS  : STRING(2 to 1) := (others => ' ');
pr

skip_whitespace

lines 5003–5019
  -- 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;
pr

write 2 procedures

lines 5020–5061
  -- 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;
pr

READ 4 procedures

lines 5062–5270
  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;
pr

owrite 2 procedures

lines 5271–5295
  -- 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;
pr

Char2TriBits

lines 5296–5325
  -- 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;
pr

OREAD_common

lines 5326–5417
  -- 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;
pr

OREAD 4 procedures

lines 5418–5556
  -- 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;
pr

hwrite 2 procedures

lines 5557–5582
  -- 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;
pr

Char2QuadBits

lines 5583–5620
  -- 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;
pr

HREAD_common

lines 5621–5712
  -- 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;
pr

HREAD 4 procedures

lines 5713–5848
  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;
fn

TO_STRING 2 functions

lines 5849–5920
  -- 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;
fn

TO_OSTRING

lines 5921–5957
  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;
fn

TO_HSTRING

lines 5958–5994
  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;
fn

TO_OSTRING

lines 5995–6030
  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;
fn

TO_HSTRING

lines 6031–6066
  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;
fn

from_string

lines 6067–6092
  -- 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;
fn

from_ostring

lines 6093–6114
  -- 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;
fn

from_hstring

lines 6115–6133
  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;
fn

from_string

lines 6134–6152
  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;
fn

from_ostring

lines 6153–6171
  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;
fn

from_hstring

lines 6172–6190
  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;
fn

from_string

lines 6191–6199
  -- 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;
fn

from_ostring

lines 6200–6207
  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;
fn

from_hstring

lines 6208–6215
  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;
fn

from_string

lines 6216–6223
  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;
fn

from_ostring

lines 6224–6231
  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;
fn

from_hstring

lines 6232–6239
  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;
pr

calculate_string_boundry

lines 6240–6290
  -- 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;
fn

from_string

lines 6291–6305
  -- 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;
fn

from_ostring

lines 6306–6319
  -- 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;
fn

from_hstring

lines 6320–6329
  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;
fn

from_string

lines 6330–6339
  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;
fn

from_ostring

lines 6340–6349
  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;
fn

from_hstring

lines 6350–6358
  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;