-- ----------------------------------------------------------------------------
--   Title      : NUMERIC_STD arithmetic package for synthesis
--              : Rev. 1.2 (Aug. 19 1994)
--              :
--   Library    : This package shall be compiled into a library symbolically
--              : named IEEE.
--              :
--   Developers : IEEE DASC Synthesis Working Group, PAR 1076.3 
--              :
--   Purpose    : This package defines numeric types and arithmetic functions 
--              : for use with synthesis tools. Two numeric types are defined: 
--              :     --> UNSIGNED : represents unsigned number in vector form
--              :     --> SIGNED   : represents a signed number in vector form
--              : The base element type is type STD_LOGIC.
--              : The leftmost bit is treated as the most significant bit.
--              : Signed numbers are represented in two's complement form.
--              : This package contains overloaded arithmetic operators on 
--              : the SIGNED and UNSIGNED types. The package also contains
--              : useful type conversions functions.
--              :
--              : If any argument to a function is a null array, a null array is
--              : returned (exceptions, if any, are noted individually).
--              :
--   Limitations: None.
--              :
--   Note       : No declarations or definitions shall be included in, or
--              : excluded from, this package. The package declaration declares
--              : the functions that can be used by a user. The package body
--              : shall be considered the formal definition of the semantics of
--              : this package. Tool developers may choose to implement the 
--              : package body in the most efficient manner available to them.
--              :
-- ----------------------------------------------------------------------------
--   Modification history:
--
--   REA: July 24 1994 Initial version from numeric_bit.vhd Rev 1.1
--   REA: August 9 1994 improved to_01 message, fixed to_integer bug
--   REA: August 19 1994
--                asserts made similar
--                to_01: time zero excepted in assert
--                to_01: alias used to force normalization
--
-- ----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

Package numeric_std is
 
  --===========================================================================
  -- Numeric array type definitions
  --===========================================================================
 
  type UNSIGNED is array ( NATURAL range <> ) of STD_LOGIC;
  type SIGNED is array ( NATURAL range <> ) of STD_LOGIC;
 
  --===========================================================================
  -- Arithmetic Operators:
  --===========================================================================
 
     -- Id: A.1
  function "abs" ( constant x : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(X'LENGTH-1 downto 0).
     -- Result: Returns the absolute value of a signed number X.
 
     -- Id: A.2
  function "-" ( constant arg : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0).
     -- Result: Returns the value of the unary minus operation on a
     --         signed number ARG.
 
  --============================================================================

     -- Id: A.3
  function "+" ( constant L : UNSIGNED;  constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED(max(L'LENGTH, R'LENGTH)-1 downto 0).
     -- Result: Adds two unsigned numbers that may be of different lengths.
 
     -- Id: A.4
  function "+" ( constant L : SIGNED;    constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(max(L'LENGTH, R'LENGTH)-1 downto 0).
     -- Result: Adds two signed numbers that may be of different lengths.
 
     -- Id: A.5
  function "+" ( constant L : UNSIGNED;  constant R : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
     -- Result: Adds an unsigned number, L, with a non-negative integer, R.
 
     -- Id: A.6
  function "+" ( constant L : NATURAL;   constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
     -- Result: Adds a non-negative integer, L, with an unsigned number, R.
 
     -- Id: A.7
  function "+" ( constant L : INTEGER;   constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED (R'LENGTH-1 downto 0).
     -- Result: Adds an integer, L (may be positive or negative), to a signed
     --         number, R.
 
     -- Id: A.8
  function "+" ( constant L : SIGNED;     constant R : INTEGER ) return SIGNED;
     -- Result subtype: SIGNED (L'LENGTH-1 downto 0).
     -- Result: Adds a signed number, L, to an integer, R.
 
  --============================================================================
 
     -- Id: A.9
  function "-" ( constant L : UNSIGNED;  constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED(max(L'LENGTH, R'LENGTH)-1 downto 0).
     -- Result: Subtracts two unsigned numbers that may be of different lengths.
 
     -- Id: A.10
  function "-" ( constant L : SIGNED;       constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(max(L'LENGTH, R'LENGTH)-1 downto 0).
     -- Result: Subtracts a signed number, R, from another signed number, L,
     --         that may possibly be of different lengths.
 
     -- Id: A.11
  function "-" ( constant L : UNSIGNED;   constant R : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED (L'LENGTH-1 downto 0).
     -- Result: Subtracts a non-negative integer, R, from an unsigned number, L.
 
     -- Id: A.12
  function "-" ( constant L : NATURAL;   constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
     -- Result: Subtracts an unsigned number, R, from a non-negative integer, L.
 
     -- Id: A.13
  function "-" ( constant L : SIGNED;    constant R : INTEGER ) return SIGNED;
     -- Result subtype: SIGNED (L'LENGTH-1 downto 0).
     -- Result: Subtracts an integer, R, from a signed number, L.
 
     -- Id: A.14
  function "-" ( constant L : INTEGER;     constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(R'LENGTH-1 downto 0).
     -- Result: Subtracts a signed number, R, from an integer, L.
 
  --============================================================================
 
     -- Id: A.15
  function "*" ( constant L : UNSIGNED;  constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED((L'length+R'length-1) downto 0).
     -- Result: Performs the multiplication operation on two unsigned numbers
     --         that may possibly be of different lengths.
 
     -- Id: A.16
  function "*" ( constant L : SIGNED;    constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED((L'length+R'length-1) downto 0)
     -- Result: Multiplies two signed numbers that may possibly be of
     --         different lengths.
 
     -- Id: A.17
  function "*" ( constant L : UNSIGNED;  constant R : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED((L'length+L'length-1) downto 0).
     -- Result: Multiplies an unsigned number, L, with a non-negative 
     --         integer, R. R is converted to an unsigned number of 
     --         size L'length before multiplication.
 
     -- Id: A.18
  function "*" ( constant L : NATURAL;  constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED((R'length+R'length-1) downto 0).
     -- Result: Multiplies an unsigned number, R, with a non-negative 
     --         integer, L. L is converted to an unsigned number of 
     --         size R'length before multiplication.
 
     -- Id: A.19
  function "*" ( constant L : SIGNED;     constant R : INTEGER ) return SIGNED;
     -- Result subtype: SIGNED((L'length+L'length-1) downto 0)
     -- Result: Multiplies a signed number, L, with an integer, R. R is
     --         converted to a signed number of size L'length before 
     --         multiplication.
 
     -- Id: A.20
  function "*" ( constant L : INTEGER;     constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED((R'length+R'length-1) downto 0)
     -- Result: Multiplies a signed number, R, with an integer, L. L is
     --         converted to a signed number of size R'length before 
     --         multiplication.
 
  --============================================================================
  --
  --  NOTE: If second argument is zero for "/" operator, a severity level
  --        of ERROR is issued.
 
     -- Id: A.21
  function "/" ( constant L : UNSIGNED; constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED (L'LENGTH-1 downto 0)
     -- Result: Divides an unsigned number, L, by another unsigned number, R.
 
     -- Id: A.22
  function "/" ( constant L : SIGNED;       constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED (L'LENGTH-1 downto 0)
     -- Result: Divides an signed number, L, by another signed number, R.
 
     -- Id: A.23
  function "/" ( constant L : UNSIGNED;  constant R : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED (L'LENGTH-1 downto 0)
     -- Result: Divides an unsigned number, L, by a non-negative integer, R.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: A.24
  function "/" ( constant L : NATURAL;  constant R : UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED (R'LENGTH-1 downto 0)
     -- Result: Divides a non-negative integer, L, by an unsigned number, R.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: A.25
  function "/" ( constant L : SIGNED;      constant R : INTEGER ) return SIGNED;
     -- Result subtype: SIGNED (L'LENGTH-1 downto 0)
     -- Result: Divides a signed number, L, by an integer, R.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: A.26
  function "/" ( constant L : INTEGER;     constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED (R'LENGTH-1 downto 0)
     -- Result: Divides an integer, L, by a signed number, R.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
  --============================================================================
  --
  --  NOTE: If second argument is zero for "rem" operator, a severity level
  --        of ERROR is issued.
 
     -- Id: A.27
  function "rem" ( constant L : UNSIGNED; constant R: UNSIGNED )return UNSIGNED;
     -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L rem R" where L and R are unsigned numbers.
 
     -- Id: A.28
  function "rem" ( constant L : SIGNED;   constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L rem R" where L and R are signed numbers.
 
     -- Id: A.29
  function "rem" ( constant L : UNSIGNED; constant R: NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L rem R" where L is an unsigned number and R is a 
     --         non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: A.30
  function "rem" ( constant L : NATURAL; constant R: UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
     -- Result: Computes "L rem R" where R is an unsigned number and L is a 
     --         non-negative integer.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: A.31
  function "rem" ( constant L : SIGNED;  constant R : INTEGER ) return SIGNED;
     -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L rem R" where L is signed number and R is an integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: A.32
  function "rem" ( constant L : INTEGER;  constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
     -- Result: Computes "L rem R" where R is signed number and L is an integer.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
  --============================================================================
  --
  --  NOTE: If second argument is zero for "mod" operator, a severity level
  --        of ERROR is issued.
 
     -- Id: A.33
  function "mod" ( constant L : UNSIGNED; constant R: UNSIGNED )return UNSIGNED;
     -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L mod R" where L and R are unsigned numbers.
 
     -- Id: A.34
  function "mod" ( constant L : SIGNED;   constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L mod R" where L and R are signed numbers.
 
     -- Id: A.35
  function "mod" ( constant L : UNSIGNED; constant R: NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L mod R" where L is an unsigned number and R 
     --         is a non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: A.36
  function "mod" ( constant L : NATURAL; constant R: UNSIGNED ) return UNSIGNED;
     -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
     -- Result: Computes "L mod R" where R is an unsigned number and L 
     --         is a non-negative integer.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: A.37
  function "mod" ( constant L : SIGNED;  constant R : INTEGER ) return SIGNED;
     -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
     -- Result: Computes "L mod R" where L is a signed number and
     --         R is an integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: A.38
  function "mod" ( constant L : INTEGER;  constant R : SIGNED ) return SIGNED;
     -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
     -- Result: Computes "L mod R" where L is an integer and
     --         R is a signed number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
  --============================================================================
  -- Comparison Operators
  --============================================================================
 
     -- Id: C.1
  function ">"  ( constant L : UNSIGNED; constant R : UNSIGNED ) return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L > R" where L and R are unsigned numbers possibly
     --         of different lengths.
 
     -- Id: C.2
  function ">"  ( constant L : SIGNED; constant R : SIGNED )     return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L > R" where L and R are signed numbers possibly
     --         of different lengths.
 
     -- Id: C.3
  function ">"  ( constant L : NATURAL; constant R : UNSIGNED )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L > R" where L is a non-negative integer and
     --         R is an unsigned number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.4
  function ">"  ( constant L : INTEGER; constant R : SIGNED )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L > R" where L is a integer and
     --         R is a signed number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.5
  function ">"  ( constant L : UNSIGNED; constant R : NATURAL )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L > R" where L is an unsigned number and
     --         R is a non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.

     -- Id: C.6
  function ">"  ( constant L : SIGNED; constant R : INTEGER )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L > R" where L is a signed number and
     --         R is a integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
  --============================================================================
 
     -- Id: C.7
  function "<"  ( constant L : UNSIGNED; constant R : UNSIGNED ) return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L < R" where L and R are unsigned numbers possibly
     --         of different lengths.
 
     -- Id: C.8
  function "<"  ( constant L : SIGNED; constant R : SIGNED )     return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L < R" where L and R are signed numbers possibly
     --         of different lengths.
 
     -- Id: C.9
  function "<"  ( constant L : NATURAL; constant R : UNSIGNED )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L < R" where L is a non-negative integer and
     --         R is an unsigned number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.10
  function "<"  ( constant L : INTEGER; constant R : SIGNED )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L < R" where L is an integer and
     --         R is a signed number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.11
  function "<"  ( constant L : UNSIGNED; constant R : NATURAL )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L < R" where L is an unsigned number and
     --         R is a non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: C.12
  function "<"  ( constant L : SIGNED; constant R : INTEGER )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L < R" where L is a signed number and
     --         R is an integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
  --============================================================================
 
     -- Id: C.13
  function "<=" ( constant L : UNSIGNED; constant R : UNSIGNED ) return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L <= R" where L and R are unsigned numbers possibly
     --         of different lengths.
 
     -- Id: C.14
  function "<=" ( constant L : SIGNED; constant R : SIGNED )     return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L <= R" where L and R are signed numbers possibly
     --         of different lengths.
 
     -- Id: C.15
  function "<=" ( constant L : NATURAL; constant R : UNSIGNED )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L <= R" where L is a non-negative integer and
     --         R is an unsigned number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.16
  function "<=" ( constant L : INTEGER; constant R : SIGNED )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L <= R" where L is an integer and
     --         R is a signed number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.17
  function "<=" ( constant L : UNSIGNED; constant R : NATURAL )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L <= R" where L is an unsigned number and
     --         R is a non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.

     -- Id: C.18
  function "<=" ( constant L : SIGNED; constant R : INTEGER )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L <= R" where L is a signed number and
     --         R is an integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
  --============================================================================
 
     -- Id: C.19
  function ">=" ( constant L : UNSIGNED; constant R : UNSIGNED ) return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L >= R" where L and R are unsigned numbers possibly
     --         of different lengths.
 
     -- Id: C.20
  function ">=" ( constant L : SIGNED; constant R : SIGNED )     return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L >= R" where L and R are signed numbers possibly
     --         of different lengths.
 
     -- Id: C.21
  function ">=" ( constant L : NATURAL; constant R : UNSIGNED )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L >= R" where L is a non-negative integer and
     --         R is an unsigned number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.22
  function ">=" ( constant L : INTEGER; constant R : SIGNED )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L >= R" where L is an integer and
     --         R is a signed number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.23
  function ">=" ( constant L : UNSIGNED; constant R : NATURAL )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L >= R" where L is an unsigned number and
     --         R is a non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: C.24
  function ">=" ( constant L : SIGNED; constant R : INTEGER )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L >= R" where L is a signed number and
     --         R is an integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.

  --============================================================================
 
     -- Id: C.25
  function "=" ( constant L : UNSIGNED; constant R : UNSIGNED ) return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L = R" where L and R are unsigned numbers possibly
     --         of different lengths.
 
     -- Id: C.26
  function "=" ( constant L : SIGNED; constant R : SIGNED )     return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L = R" where L and R are signed numbers possibly
     --         of different lengths.
 
     -- Id: C.27
  function "=" ( constant L : NATURAL; constant R : UNSIGNED )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L = R" where L is a non-negative integer and
     --         R is an unsigned number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.28
  function "=" ( constant L : INTEGER; constant R : SIGNED )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L = R" where L is an integer and
     --         R is a signed number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.29
  function "=" ( constant L : UNSIGNED; constant R : NATURAL )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L = R" where L is an unsigned number and
     --         R is a non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: C.30
  function "=" ( constant L : SIGNED; constant R : INTEGER )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L = R" where L is a signed number and
     --         R is an integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
  --============================================================================
 
     -- Id: C.31
  function "/=" ( constant L : UNSIGNED; constant R : UNSIGNED ) return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L /= R" where L and R are unsigned numbers possibly
     --         of different lengths.
 
     -- Id: C.32
  function "/=" ( constant L : SIGNED; constant R : SIGNED )     return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L /= R" where L and R are signed numbers possibly
     --         of different lengths.
 
     -- Id: C.33
  function "/=" ( constant L : NATURAL; constant R : UNSIGNED )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L /= R" where L is a non-negative integer and
     --         R is an unsigned number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.34
  function "/=" ( constant L : INTEGER; constant R : SIGNED )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L /= R" where L is an integer and
     --         R is a signed number.
     --         If NO_OF_BITS(L) > R'LENGTH, then L is truncated to R'LENGTH.
 
     -- Id: C.35
  function "/=" ( constant L : UNSIGNED; constant R : NATURAL )  return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L /= R" where L is an unsigned number and
     --         R is a non-negative integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
     -- Id: C.36
  function "/=" ( constant L : SIGNED; constant R : INTEGER )    return BOOLEAN;
     -- Result subtype: BOOLEAN
     -- Result: Computes "L /= R" where L is a signed number and
     --         R is an integer.
     --         If NO_OF_BITS(R) > L'LENGTH, then R is truncated to L'LENGTH.
 
  --============================================================================
  -- Shift and Rotate Functions
  --============================================================================
 
     -- Id: S.1
  function shift_left  ( constant  arg  : UNSIGNED;
                       constant count : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a shift-left on an unsigned number COUNT times.
     --         The vacated positions are filled with Bit '0'.
     -- The COUNT leftmost bits are lost.
 
     -- Id: S.2
  function shift_right ( constant  arg  : UNSIGNED;
                       constant count : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a shift-right on an unsigned number COUNT times.
     --         The vacated positions are filled with Bit '0'.
     --         The COUNT rightmost bits are lost.
 
     -- Id: S.3
  function shift_left  ( constant  arg  : SIGNED;
                       constant count : NATURAL ) return SIGNED;
     -- Result subtype: SIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a shift-left on a signed number COUNT times.
     --         All bits of ARG, except ARG'LEFT, are shifted left COUNT times.
     --         The vacated positions are filled with Bit '0'. 
     --         The COUNT leftmost bits, except ARG'LEFT, are lost.
 
     -- Id: S.4
  function shift_right ( constant  arg  : SIGNED;
                       constant count : NATURAL ) return SIGNED;
     -- Result subtype: SIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a shift-right on a signed number COUNT times.
     --         The vacated positions are filled with the leftmost bit,ARG'LEFT.
     --         The COUNT rightmost bits are lost.
 
  --============================================================================
 
  --============================================================================
 
     -- Id: S.5
  function rotate_left  ( constant  arg  : UNSIGNED;
                        constant count : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a rotate_left of an unsigned number COUNT times.

     -- Id: S.6
  function rotate_right ( constant  arg  : UNSIGNED;
                        constant count : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a rotate_right of an unsigned number COUNT times.
 
     -- Id: S.7
  function rotate_left  ( constant  arg  : SIGNED;
                        constant count : NATURAL ) return SIGNED;
     -- Result subtype: SIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a logical rotate-left of a signed 
     --         number COUNT times.
 
     -- Id: S.8
  function rotate_right ( constant  arg  : SIGNED;
                        constant count : NATURAL ) return SIGNED;
     -- Result subtype: SIGNED (ARG'LENGTH-1 downto 0)
     -- Result: Performs a logical rotate-right of a signed 
     --         number COUNT times.
 
  --============================================================================
  --  resize Functions
  --============================================================================

     -- Id: R.1
  function resize ( constant arg : SIGNED;
          constant new_size : NATURAL ) return SIGNED;
     -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
     -- Result: Resizes the signed number ARG to the specified size. 
     --         Resize always happen at the left.
     --         If size is being extended, the new bit positions are filled
     --         with the sign bit (ARG'LEFT). If size is being reduced,
     --         the sign bit is retained.
 
     -- Id: R.2
  function resize ( constant arg : UNSIGNED;
          constant new_size : NATURAL ) return UNSIGNED;
     -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
     -- Result: Resizes the unsigned number ARG to the specified size. 
     --         Resize always happen at the left.
     --         If size is being extended, the new bit positions are filled
     --         with '0'. If size is being reduced, the leftmost bits are
     --         truncated.

 
  --============================================================================
  -- Conversion Functions
  --============================================================================
 
     -- Id: D.1
  function to_integer ( constant arg : UNSIGNED ) return NATURAL;
     -- Result subtype: NATURAL. Value cannot be negative since parameter is an
     --                 unsigned number.
     -- Result: Converts the unsigned number to an integer.
 
     -- Id: D.2
  function to_integer ( constant arg : SIGNED ) return INTEGER;
     -- Result subtype: INTEGER
     -- Result: Converts a signed number to an integer.
 
     -- Id: D.3
  function to_unsigned ( constant  arg : NATURAL;
                       constant size : NATURAL) return UNSIGNED;
     -- Result subtype: UNSIGNED (SIZE-1 downto 0)
     -- Result: Converts a non-negative integer to an unsigned number with
     --         the specified size.
 
     -- Id: D.4
  function to_signed ( constant  arg : INTEGER;
                     constant size : NATURAL ) return SIGNED;
     -- Result subtype: SIGNED (SIZE-1 downto 0)
     -- Result: Converts an integer to a signed number of the specified size.

end numeric_std;
 
--=============================================================================
--=======================    Package    Body    ===============================
--=============================================================================


Package body numeric_std is


   -- null range array constants
 
   constant nau : UNSIGNED (0 downto 1) := (others => '0');
   constant nas : SIGNED (0 downto 1) := (others => '0');
 


--=========================Local Subprograms=================================

    function Max(LEFT, RIGHT : integer) return integer is
    begin
        if left > right then
            return left;
        else
            return right;
        end if;
    end;

    function Min(LEFT, RIGHT : integer) return integer is
    begin
        if left < right then
            return left;
        else
            return right;
        end if;
    end;


------------------------------------------------------------------------
   -- this internal function computes the addition of two UNSIGNED
   -- with input carry
   -- * the two arguments are of the same length

function ADD_UNSIGNED ( constant L : UNSIGNED;
                  constant R : UNSIGNED;
                  constant C : std_logic ) return UNSIGNED  is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias XL : UNSIGNED(L_left downto 0) is L;
  alias XR : UNSIGNED(R_left downto 0) is R;
  variable RESULT : UNSIGNED(L_left downto 0);
  variable cbit : std_logic := C;
begin
   if (L_left /= R_left) then
     assert (L_left = R_left) 
     report "numeric_std.ADD_UNSIGNED : vector sizes should be equal"
     severity ERROR ;
     end if;
   if (R_left<0) then return NAU; -- not a vector
   end if;
   for i in 0 to L_left loop
     RESULT(i) := Cbit xor XL(i) xor XR(i);
     Cbit := (Cbit and XL(i)) or (Cbit and XR(i)) or (XL(i) and XR(i));
   end loop;
   return RESULT;
end ADD_UNSIGNED;

   -- this internal function computes the addition of two SIGNED
   -- with input carry
   -- * the two arguments are of the same length

function ADD_SIGNED ( constant L : SIGNED;
                  constant R : SIGNED;
                  constant C : std_logic ) return SIGNED  is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias XL : SIGNED(L_left downto 0) is L;
  alias XR : SIGNED(R_left downto 0) is R;
  variable RESULT : SIGNED(L_left downto 0);
  variable Cbit : std_logic := C;
begin
   if (L_left /= R_left) then
     assert (L_left = R_left) 
     report "numeric_std.ADD_SIGNED : vector sizes should be equal"
     severity ERROR ;
     end if;
   if (R_left<0) then return NAS; -- not a vector
   end if;
   for i in 0 to L_left loop
     RESULT(i) := Cbit xor XL(i) xor XR(i);
     Cbit := (Cbit and XL(i)) or (Cbit and XR(i)) or (XL(i) and XR(i));
   end loop;
   return RESULT;
end ADD_SIGNED;

------------------------------------------------------------------------

function "-" ( constant L : std_logic_vector;
               constant R : std_logic_vector ) return std_logic_vector  is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias XL : std_logic_vector(L_left downto 0) is L;
  alias XR : std_logic_vector(R_left downto 0) is R;
  variable RESULT : std_logic_vector(max(L_left,R_left) downto 0);
  variable cbit : std_logic := '1';
begin
  if ((L_left<0) or (R_left<0)) then return std_logic_vector(nau); -- not a vector
    end if;
  for i in 0 to result'left loop
    result(i) := cbit;
    if i<=xl'left then
      result(i) := result(i) xor xl(i);
      if i>xr'left then cbit := cbit and xl(i);
        end if;
      end if;
    if i<=xr'left then
      result(i) := result(i) xor not(xr(i));
      if i>xl'left then cbit := cbit and not(xr(i));
        else cbit := cbit and (xl(i) or not(xr(i)));
        end if;
      end if;
    end loop;
  return result;
end;



    -- this internal procedure computes unsigned division of a std_logic_Vector
    -- giving the quotient and remainder.
    procedure divMod (num, xdenom: std_logic_vector;
                      xquot, xremain: out std_logic_vector) is
       variable temp: std_logic_vector(num'length-1 downto 0);
       variable quot: std_logic_vector(max(num'length,xdenom'length)-1 downto 0);
       variable diff: std_logic_vector(xdenom'length downto 0);
       alias denom : std_logic_vector (xdenom'length-1 downto 0) is xdenom;
       variable carry: std_logic;
       variable topBit: natural;
       variable isZero: boolean;
    begin
       isZero:=true;
       for j in xdenom'range loop
          carry:=denom(j);
          if carry/='0' then
             isZero:=false;
          end if;
       end loop;
       ASSERT not isZero   report "DIV,MOD,or REM by zero"   severity error;
       temp:=num;
       quot:= (others =>'0');
       topBit:=0;
       for j in denom'range loop
          if denom(j)='1' then
             topBit:=j;
             exit;
          end if;
       end loop;

       carry:='0';
       for j in num'length-(topBit+1) downto 0 loop
          -- lexical ordering works okay for this comparison, no overloaded
          -- function is needed.
          if carry&temp(topBit+j downto j) >= "0"&denom(topBit downto 0) then
             diff(topBit+1 downto 0) := (carry&temp(topBit+j downto j))
                                       -("0"&denom(topBit downto 0));

             ASSERT diff(topBit+1)='0'
                   report "internal error in the division algorithm"
                   severity error;
             carry:=diff(topBit);
             if topBit+j+1<=temp'left then
                temp(topBit+j+1):='0';
             end if;
             temp(topBit+j downto j):=diff(topBit downto 0);
             quot(j):='1';
          else
             ASSERT carry='0'
                   report "internal error in the division algorithm"
                   severity error;
             carry:=temp(topBit+j);
          end if;
       end loop;
       xquot:=quot(num'length-1 downto 0);
       xremain:=temp(num'length-1 downto 0);
    end;

-----------------Local Subprograms - shift/rotate ops-------------------------

function xsll ( constant  ARG  : std_logic_vector;
               constant count : NATURAL ) return std_logic_vector is
  constant ARG_l:integer := ARG'length-1;
  alias XARG : std_logic_vector(ARG_l downto 0) is ARG;
  variable result : std_logic_vector(ARG_l downto 0) := (others=>'0');
begin
  if count <= ARG_l then
    result(ARG_l downto count):=XARG(ARG_l-count downto 0);
    end if;
  return result;
end;

function xsrl ( constant  ARG  : std_logic_vector;
               constant count : NATURAL ) return std_logic_vector is
  constant ARG_l:integer := ARG'length-1;
  alias XARG : std_logic_vector(ARG_l downto 0) is ARG;
  variable result : std_logic_vector(ARG_l downto 0) := (others=>'0');
begin
  if count <= ARG_l then
    result(ARG_l-count downto 0):=XARG(ARG_l downto count);
    end if;
  return result;
end;

function xsra ( constant  ARG  : std_logic_vector;
               constant count : NATURAL ) return std_logic_vector is
  constant ARG_l:integer := ARG'length-1;
  alias XARG : std_logic_vector(ARG_l downto 0) is ARG;
  variable result : std_logic_vector(ARG_l downto 0);
  variable xcount : natural := count;
begin
  if ((ARG'length <= 1) or (xcount = 0)) then return ARG;
  else 
    if (xcount > ARG_l) then xcount := ARG_l; end if;
    result(ARG_l-xcount downto 0):=XARG(ARG_l downto xcount);
    result(ARG_l downto (ARG_l - xcount + 1)) := (others=>XARG(ARG_l));
    end if;
  return result;
end;

function xrol ( constant  ARG  : std_logic_vector;
               constant count : NATURAL ) return std_logic_vector is
  constant ARG_l:integer := ARG'length-1;
  alias XARG : std_logic_vector(ARG_l downto 0) is ARG;
  variable result : std_logic_vector(ARG_l downto 0) := XARG;
  variable countm : integer;
begin
  countm := count mod (ARG_l + 1);
  if countm /= 0 then
    result(ARG_l downto countm):=XARG(ARG_l-countm downto 0);
    result(countm-1 downto 0):=XARG(ARG_l downto ARG_l-countm+1);
    end if;
  return result;
end;

function xror ( constant  ARG  : std_logic_vector;
               constant count : NATURAL ) return std_logic_vector is
  constant ARG_l:integer := ARG'length-1;
  alias XARG : std_logic_vector(ARG_l downto 0) is ARG;
  variable result : std_logic_vector(ARG_l downto 0) := XARG;
  variable countm : integer;
begin
  countm := count mod (ARG_l + 1);
  if countm /= 0 then
    result(ARG_l-countm downto 0):=XARG(ARG_l downto countm);
    result(ARG_l downto ARG_l-countm+1):=XARG(countm-1 downto 0);
    end if;
  return result;
end;


-----------------Local Subprograms - Relational ops--------------------------

--
-- to_signed : From unsigned to signed does zero-extension 
--
function to_signed ( constant ARG : UNSIGNED;
                     constant SIZE : NATURAL ) return SIGNED is
begin
    return SIGNED(UNSIGNED'(resize(ARG,SIZE))) ;
end to_signed;

--
-- to_signed : From signed to signed does sign extension
--
function to_signed ( constant ARG : SIGNED;
                     constant SIZE : NATURAL ) return SIGNED is
begin
    return resize(ARG,SIZE) ;
end to_signed;


--
-- General "=" for UNSIGNED vectors, same length
--
function unsigned_equal ( constant L : UNSIGNED;
	                  constant R : UNSIGNED ) return BOOLEAN is
begin
  if (L'LENGTH /= R'LENGTH) then
    assert (L'LENGTH = R'LENGTH) 
    report "numeric_std.unsigned_equal : vector sizes should be equal"
    severity ERROR ;
    end if;
  return std_logic_vector (L) = std_logic_vector (R) ;
  end unsigned_equal ;

--
-- General "=" for SIGNED vectors, same length
--
function signed_equal ( constant L : SIGNED;
	                constant R : SIGNED ) return BOOLEAN is
begin
  if (L'LENGTH /= R'LENGTH) then
    assert (L'LENGTH = R'LENGTH) 
    report "numeric_std.signed_equal : vector sizes should be equal"
    severity ERROR ;
    end if;
  return std_logic_vector (L) = std_logic_vector (R) ;
end signed_equal ;



--
-- General "<" for UNSIGNED vectors, same length
--
function unsigned_less ( constant L : UNSIGNED; 
                         constant R : UNSIGNED ) return BOOLEAN is
begin
  if (L'LENGTH /= R'LENGTH) then
    assert (L'LENGTH = R'LENGTH) 
    report "numeric_std.unsigned_less : vector sizes should be equal"
    severity ERROR ;
    end if;
  return std_logic_vector (L) < std_logic_vector (R) ;
  end unsigned_less ;

--
-- General "<" function for SIGNED vectors, same length 
--
function signed_less ( constant L : SIGNED; 
                       constant R : SIGNED ) return BOOLEAN is
  -- Need aliasses to assure index direction
  alias intern_l : SIGNED (0 to L'LENGTH-1) is L ;
  alias intern_r : SIGNED (0 to R'LENGTH-1) is R ;
begin
  if (L'LENGTH /= R'LENGTH) then
    assert (L'LENGTH = R'LENGTH) 
    report "numeric_std.signed_less : vector sizes should be equal"
    severity ERROR ;
    end if;
  if (intern_l(0) /= intern_r(0)) then
    -- One is positive, One is negative
    return intern_l(0)='1' ;
  else 
    -- Both are either negative or positive
    if (intern_l(0)='0') then
      -- Both are positive
      -- Return Default "<" for remaining bits 
      return std_logic_vector(intern_l(1 to intern_l'RIGHT)) < 
	     std_logic_vector(intern_r(1 to intern_r'RIGHT)) ;
    else 
      -- Both are negative
      -- Return Default ">" for remaining bits
      return std_logic_vector(intern_l(1 to intern_l'RIGHT)) > 
             std_logic_vector(intern_r(1 to intern_r'RIGHT)) ;
      end if ;
    end if ;
  end signed_less ; 

--
-- General "<=" function for UNSIGNED vectors, same length 
--
function unsigned_less_or_equal ( constant L : UNSIGNED; 
                                  constant R : UNSIGNED ) return BOOLEAN is
begin
  if (L'LENGTH /= R'LENGTH) then
    assert (L'LENGTH = R'LENGTH) 
    report "numeric_std.unsigned_less_or_equal : vector sizes should be equal"
    severity ERROR ;
    end if;
  return std_logic_vector (L) <= std_logic_vector (R) ;
  end unsigned_less_or_equal ;

--
-- General "<=" function for SIGNED vectors, same length 
--
function signed_less_or_equal ( constant L : SIGNED; 
                                constant R : SIGNED ) return BOOLEAN is
  -- Need aliasses to assure index direction
  alias intern_l : SIGNED (0 to L'LENGTH-1) is L ;
  alias intern_r : SIGNED (0 to R'LENGTH-1) is R ;
begin
  if (L'LENGTH /= R'LENGTH) then
    assert (L'LENGTH = R'LENGTH) 
    report "numeric_std.signed_less_or_equal : vector sizes should be equal"
    severity ERROR ;
    end if;
  -- The actual compare
  if (intern_l(0) /= intern_r(0)) then
    -- One is positive, One is negative
    return intern_l(0)='1' ;
  else 
    -- Both are either negative or positive
    if (intern_l(0)='0') then
      -- Both are positive
      -- Return Default "<=" for remaining bits 
      return std_logic_vector(intern_l (1 to intern_l'RIGHT)) <= 
	     std_logic_vector(intern_r (1 to intern_r'RIGHT)) ;
    else 
      -- Both are negative
      -- Return Default ">=" for remaining bits
      return std_logic_vector(intern_l (1 to intern_l'RIGHT)) >= 
	     std_logic_vector(intern_r (1 to intern_r'RIGHT)) ;
      end if ;
    end if ;
  end signed_less_or_equal ;

-- function to_01 is used to convert vectors to the
--          correct form for exported functions,
--          and to report if there is an element which
--          is not in (0,1,h,l).
--    Assume the vector is normalized and non-null.
--    The function is duplicated for signed and unsigned types.

function to_01(s : signed ; xmap : std_logic := '0') return signed is
  variable result : signed(s'length-1 downto 0);
  variable bad_element : boolean := false;
  alias xs : signed(s'length-1 downto 0) is s;
  begin
    for i in result'range loop
      case xs(i) is
        when '0' | 'L' => result(i):='0';
        when '1' | 'H' => result(i):='1';
        when others => bad_element := true;
        end case;
      end loop;
    if (bad_element and (now /= 0 ns)) then
      assert bad_element
        report "numeric_std.to_01: Element not in {0,1,H,L} result:=(others=>0)"
        severity error;
      for i in result'range loop
        result(i) := xmap;        -- standard fixup
        end loop;
      end if;
    return result;
  end; -- to_01
       
function to_01(s : unsigned ; xmap : std_logic := '0') return unsigned is
  variable result : unsigned(s'length-1 downto 0);
  variable bad_element : boolean := false;
  alias xs : unsigned(s'length-1 downto 0) is s;
  begin
    for i in result'range loop
      case xs(i) is
        when '0' | 'L' => result(i):='0';
        when '1' | 'H' => result(i):='1';
        when others => bad_element := true;
        end case;
      end loop;
    if (bad_element and (now /= 0 ns)) then
      assert bad_element
        report "numeric_std.to_01: Element not in {0,1,H,L} result:=(others=>0)"
        severity error;
      for i in result'range loop
        result(i) := xmap;        -- standard fixup
        end loop;
      end if;
    return result;
  end; -- to_01
         
--=========================Exported Functions=================================

     -- Id: A.1
function "abs" ( constant x : SIGNED ) return SIGNED is
    constant arg_left:integer := x'length-1;
    alias xx : signed(arg_left downto 0) is x;
    variable result : SIGNED (arg_left downto 0);
begin
  if result'length>0 then
    result:=to_01(xx);
    if result(result'left) = '1' then
      result := -result;
      end if;
    return result;
  else return nas;
    end if;
  end; -- "abs"


     -- Id: A.2
function "-" ( constant arg : SIGNED ) return SIGNED is
  constant arg_left:integer := arg'length-1;
  alias xarg : signed(arg_left downto 0) is arg;
  variable result,xarg01 : SIGNED(arg_left downto 0);
  variable cbit : std_logic := '1';
begin
  if result'length>0 then
    xarg01 := to_01(arg);
    for i in 0 to result'length loop
      result(i) := not(xarg01(i)) xor cbit;
      cbit := cbit and xarg01(i);
      end loop;
    return result;
  else return nas;
    end if;
  end; -- "-"


--=============================================================================


     -- Id: A.3
function "+" ( constant L : UNSIGNED;
               constant R : UNSIGNED ) return UNSIGNED is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
  
begin
  if ((L_left<0) or (R_left<0)) then return nau; -- not a vector
    end if;
  
  L01 := to_01(L);
  R01 := to_01(R);
  return ADD_UNSIGNED (resize(L01,SIZE), resize(R01,SIZE), '0') ;
end;

     -- Id: A.4
function "+" ( constant L : SIGNED;
               constant R : SIGNED ) return SIGNED is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return nas; -- not a vector
    end if;
  L01 := to_01(L);
  R01 := to_01(R);
  return ADD_SIGNED (resize(L01,SIZE), resize(R01,SIZE), '0') ;
end;

     -- Id: A.5
function "+" ( constant L : UNSIGNED;
               constant R : NATURAL ) return UNSIGNED is
begin
  return L + to_unsigned( R , L'length);
end;

     -- Id: A.6
function "+" ( constant L : NATURAL;
               constant R : UNSIGNED ) return UNSIGNED is
begin
  return to_unsigned( L , R'length) + R;
end;

     -- Id: A.7
function "+" ( constant L : SIGNED;
               constant R : INTEGER ) return SIGNED is
begin
  return L + to_signed( R , L'length);
end;

     -- Id: A.8
function "+" ( constant L : INTEGER;
               constant R : SIGNED ) return SIGNED is
begin
  return to_signed( L , R'length) + R;
end;

--=============================================================================

     -- Id: A.9
function "-" ( constant L : UNSIGNED;
               constant R : UNSIGNED ) return UNSIGNED  is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return nau; -- not a vector
    end if;
  L01 := to_01(L);
  R01 := to_01(R);
  return ADD_UNSIGNED (resize(L01,SIZE), 
                       resize(UNSIGNED(not std_logic_vector(R01)),SIZE), 
                       '1') ;
end;

     -- Id: A.10
function "-" ( constant L : SIGNED;
               constant R : SIGNED ) return SIGNED is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return nas; -- not a vector
    end if;
  L01 := to_01(L);
  R01 := to_01(R);
  return ADD_SIGNED (resize(L01,SIZE), 
                       resize(SIGNED(not std_logic_vector(R01)),SIZE), 
                       '1') ;
end;



     -- Id: A.11
function "-" ( constant L : UNSIGNED;
               constant R : NATURAL ) return UNSIGNED is
begin
  return L -  to_unsigned( R , L'length);
end;

     -- Id: A.12
function "-" ( constant L : NATURAL;
               constant R : UNSIGNED ) return UNSIGNED is
begin
  return to_unsigned( L , R'length) - R;
end;

     -- Id: A.13
function "-" ( constant L : SIGNED;
               constant R : INTEGER ) return SIGNED is
begin
  return L - to_signed( R , L'length);
end;

     -- Id: A.14
function "-" ( constant L : INTEGER;
               constant R : SIGNED ) return SIGNED is
begin
  return  to_signed( L , R'length) - R ;
end;


--=============================================================================

     -- Id: A.15
function "*" ( constant L : UNSIGNED;
               constant R : UNSIGNED ) return UNSIGNED is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xxl : UNSIGNED(L_left downto 0) is L;
  alias xxr : UNSIGNED(R_left downto 0) is R;
  variable xl : UNSIGNED(L_left downto 0);
  variable xr : UNSIGNED(R_left downto 0);
  variable result : UNSIGNED((L'length+R'length-1) downto 0) :=(others=>'0');
  variable adval : UNSIGNED((L'length+R'length-1) downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return nau; -- not a vector
    end if;
  xl := to_01(xxl);
  xr := to_01(xxr);
  adval := resize(xr,result'length);
  for i in 0 to L_left loop
    if xl(i)='1' then result := result + adval;
    end if;
    adval := shift_left(adval,1);  
    end loop;
  return result;
end;

     -- Id: A.16
function "*" ( constant L : SIGNED;
               constant R : SIGNED ) return SIGNED is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xxl : SIGNED(L_left downto 0) is L;
  alias xxr : SIGNED(R_left downto 0) is R;
  variable xl : SIGNED(L_left downto 0);
  variable xr : SIGNED(R_left downto 0);
  variable result : SIGNED((L'length+R'length-1) downto 0) :=(others=>'0');
  variable adval : SIGNED((L'length+R'length-1) downto 0);
  variable invt : std_logic := '0';
begin
  if ((L_left<0) or (R_left<0)) then return nas; -- not a vector
    end if;
  xl := to_01(xxl);
  xr := to_01(xxr);
  adval := resize(xr,result'length);
  if xl(xl'left)='1' then
    adval := -(adval);
    invt := '1';
    end if;
  for i in 0 to L_left loop
    if (invt xor xl(i))='1' then result := result + adval;
    end if;
    adval := shift_left(adval,1);  
    end loop;
  return result;
end;


     -- Id: A.17
function "*" ( constant L : UNSIGNED;
               constant R : NATURAL ) return UNSIGNED is
begin
  return L *  to_unsigned( R , L'length);
end;

     -- Id: A.18
function "*" ( constant L : NATURAL;
               constant R : UNSIGNED ) return UNSIGNED is
begin
  return to_unsigned( L , R'length) * R;
end;

     -- Id: A.19
function "*" ( constant L : SIGNED;
               constant R : INTEGER ) return SIGNED is
begin
  return L * to_signed( R , L'length);
end;

     -- Id: A.20
function "*" ( constant L : INTEGER;
               constant R : SIGNED ) return SIGNED is
begin
  return  to_signed( L , R'length) * R ;
end;

--=============================================================================

     -- Id: A.21
function "/" ( constant L : UNSIGNED;
               constant R : UNSIGNED ) return UNSIGNED is
    constant L_left:integer := L'length-1;
    constant R_left:integer := R'length-1;
    alias xxl : UNSIGNED(L_left downto 0) is L;
    alias xxr : UNSIGNED(R_left downto 0) is R;
    variable xl : UNSIGNED(L_left downto 0);
    variable xr : UNSIGNED(R_left downto 0);
    variable fquot,fremain : std_logic_Vector(L'length-1 downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return nau; -- not a vector
    end if;
  xl := to_01(xxl);
  xr := to_01(xxr);
  divMod(std_logic_vector(xl),std_logic_vector(xr),fquot,fremain);
  return UNSIGNED(fquot);
end;

     -- Id: A.22
function "/" ( constant L : SIGNED;
               constant R : SIGNED ) return SIGNED is
    constant L_left:integer := L'length-1;
    constant R_left:integer := R'length-1;
    alias xxl : SIGNED(L_left downto 0) is L;
    alias xxr : SIGNED(R_left downto 0) is R;
    variable xl : SIGNED(L_left downto 0);
    variable xr : SIGNED(R_left downto 0);
    variable fquot,fremain : std_logic_Vector(L'length-1 downto 0);
    variable xnum: std_logic_vector(L'length-1 downto 0);
    variable xdenom: std_logic_vector(R'length-1 downto 0);
    variable qneg: boolean := false;
begin
    if ((L_left<0) or (R_left<0)) then return nas; -- not a vector
      end if;
    xl := to_01(xxl);
    xr := to_01(xxr);
    if xl(xl'left)='1' then
       xnum:=std_logic_vector(-xl);
       qNeg:=true;
    else
       xNum:=std_logic_vector(xl);
    end if;
    if xr(xr'left)='1' then
       xdenom:=std_logic_vector(-xr);
       qNeg:=not qNeg;
    else
       xdenom:=std_logic_vector(xr);
    end if;
    divMod(xnum,xdenom,fquot,fremain);
    if qNeg then fquot:="00"-fquot;  end if;
    return SIGNED(fquot);
end;

     -- Id: A.23
function "/" ( constant L : UNSIGNED;
               constant R : NATURAL ) return UNSIGNED is
begin
  return L /  to_unsigned( R , L'length);
end;

     -- Id: A.24
function "/" ( constant L : NATURAL;
               constant R : UNSIGNED ) return UNSIGNED is
begin
  return to_unsigned( L , R'length) / R;
end;

     -- Id: A.25
function "/" ( constant L : SIGNED;
               constant R : INTEGER ) return SIGNED is
begin
  return L / to_signed( R , L'length);
end;

     -- Id: A.26
function "/" ( constant L : INTEGER;
               constant R : SIGNED ) return SIGNED is
begin
  return  to_signed( L , R'length) / R ;
end;

--=============================================================================

     -- Id: A.27
function "rem" ( constant L : UNSIGNED;
                 constant R : UNSIGNED ) return UNSIGNED is
    constant L_left:integer := L'length-1;
    constant R_left:integer := R'length-1;
    alias xxl : UNSIGNED(L_left downto 0) is L;
    alias xxr : UNSIGNED(R_left downto 0) is R;
    variable xl : UNSIGNED(L_left downto 0);
    variable xr : UNSIGNED(R_left downto 0);
    variable fquot,fremain : std_logic_Vector(l'length-1 downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return nau; -- not a vector
    end if;
  xl := to_01(xxl);
  xr := to_01(xxr);
  divMod(std_logic_vector(xl),std_logic_vector(xr),fquot,fremain);
  return UNSIGNED(fremain);
end;

     -- Id: A.28
function "rem" ( constant L : SIGNED;
                 constant R : SIGNED ) return SIGNED is
    constant L_left:integer := L'length-1;
    constant R_left:integer := R'length-1;
    alias xxl : SIGNED(L_left downto 0) is L;
    alias xxr : SIGNED(R_left downto 0) is R;
    variable fquot,fremain : std_logic_Vector(l'length-1 downto 0);
    variable xnum: std_logic_vector(l'length-1 downto 0);
    variable xdenom: std_logic_vector(r'length-1 downto 0);
    variable rneg: boolean := false;
begin
    xnum := std_logic_vector(to_01(xxl));
    xdenom := std_logic_vector(to_01(xxr));
    if xnum(xnum'left)='1' then
       xnum:=std_logic_vector(-SIGNED(xnum));
       rNeg:=true;
    else
       xNum:=std_logic_vector(xnum);
    end if;
    if xdenom(xdenom'left)='1' then
       xdenom:=std_logic_vector(-SIGNED(xdenom));
    else
       xdenom:=std_logic_vector(xdenom);
    end if;
    divMod(xnum,xdenom,fquot,fremain);
    if rNeg then
       fremain:="00"-fremain;
    end if;
    return SIGNED(fremain);
end;

     -- Id: A.29
function "rem" ( constant L : UNSIGNED;
               constant R : NATURAL ) return UNSIGNED is
begin
  return L rem  to_unsigned( R , L'length);
end;

     -- Id: A.30
function "rem" ( constant L : NATURAL;
               constant R : UNSIGNED ) return UNSIGNED is
begin
  return to_unsigned( L , R'length) rem R;
end;

     -- Id: A.31
function "rem" ( constant L : SIGNED;
               constant R : INTEGER ) return SIGNED is
begin
  return L rem to_signed( R , L'length);
end;

     -- Id: A.32
function "rem" ( constant L : INTEGER;
               constant R : SIGNED ) return SIGNED is
begin
  return  to_signed( L , R'length) rem R ;
end;

--=============================================================================

     -- Id: A.33
function "mod" ( constant L : UNSIGNED;
                 constant R : UNSIGNED ) return UNSIGNED is
    constant L_left:integer := L'length-1;
    constant R_left:integer := R'length-1;
    alias xxl : UNSIGNED(L_left downto 0) is L;
    alias xxr : UNSIGNED(R_left downto 0) is R;
    variable xl : UNSIGNED(L_left downto 0);
    variable xr : UNSIGNED(R_left downto 0);
    variable fquot,fremain : std_logic_Vector(l'length-1 downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return nau; -- not a vector
    end if;
  xl := to_01(xxl);
  xr := to_01(xxr);
  divMod(std_logic_Vector(xl),std_logic_Vector(xr),fquot,fremain);
  return UNSIGNED(fremain);
end;

     -- Id: A.34
function "mod" ( constant L : SIGNED;
                 constant R : SIGNED ) return SIGNED is
    constant L_left:integer := L'length-1;
    constant R_left:integer := R'length-1;
    alias xxl : SIGNED(L_left downto 0) is L;
    alias xxr : SIGNED(R_left downto 0) is R;
    variable xl : SIGNED(L_left downto 0);
    variable xr : SIGNED(R_left downto 0);
    variable fquot,fremain : std_logic_Vector(l'length-1 downto 0);
    variable xnum: std_logic_Vector(l'length-1 downto 0);
    variable xdenom: std_logic_Vector(r'length-1 downto 0);
    variable rneg: boolean := false;
begin
    if ((L_left<0) or (R_left<0)) then return nas; -- not a vector
      end if;
    xl := to_01(xxl);
    xr := to_01(xxr);
    if xl(xl'left)='1' then
       xnum:=std_logic_Vector(-xl);
    else
       xNum:=std_logic_Vector(xl);
    end if;
    if xr(xr'left)='1' then
       xdenom:=std_logic_Vector(-xr);
       rNeg:=true;
    else
       xdenom:=std_logic_Vector(xr);
    end if;
    divMod(xnum,xdenom,fquot,fremain);
    if rNeg and l(l'left)='1' then
       fremain:="00"-fremain;
    elsif rNeg then
       fremain:=fremain-xdenom;
    elsif l(l'left)='1' then
       fremain:=xdenom-fremain;
    end if;
    return SIGNED(fremain);
end;

     -- Id: A.35
function "mod" ( constant L : UNSIGNED;
               constant R : NATURAL ) return UNSIGNED is
begin
  return L mod  to_unsigned( R , L'length);
end;

     -- Id: A.36
function "mod" ( constant L : NATURAL;
               constant R : UNSIGNED ) return UNSIGNED is
begin
  return to_unsigned( L , R'length) mod R;
end;

     -- Id: A.37
function "mod" ( constant L : SIGNED;
               constant R : INTEGER ) return SIGNED is
begin
  return L mod to_signed( R , L'length);
end;

     -- Id: A.38
function "mod" ( constant L : INTEGER;
               constant R : SIGNED ) return SIGNED is
begin
  return  to_signed( L , R'length) mod R ;
end;

--=============================================================================

     -- Id: C.1
function ">"  ( constant L : UNSIGNED;
                constant R : UNSIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  alias xR : unsigned(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return not unsigned_less_or_equal (resize(L01,SIZE), resize(R01,SIZE)) ;
end ">" ;

     -- Id: C.2
function ">"  ( constant L : SIGNED;
                constant R : SIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : signed(L_left downto 0) is L;
  alias xR : signed(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return not signed_less_or_equal (to_signed(L01,SIZE), to_signed(R01,SIZE)) ;
end ">" ;

     -- Id: C.3
function ">"  ( constant L : NATURAL;
                constant R : UNSIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : unsigned(R_left downto 0) is R;
  variable R01 : unsigned(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return not unsigned_less_or_equal (to_unsigned (L,R01'LENGTH), R01) ;
end ">" ;

     -- Id: C.4
function ">"  ( constant L : INTEGER;
                constant R : SIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : signed(R_left downto 0) is R;
  variable R01 : signed(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return not signed_less_or_equal (to_signed(L,R01'LENGTH), R01) ;
end ">" ;

     -- Id: C.5
function ">"  ( constant L : UNSIGNED;
                constant R : NATURAL ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  variable L01 : unsigned(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
    return not unsigned_less_or_equal (L01, to_unsigned (R,L01'LENGTH)) ;
end ">" ;

     -- Id: C.6
function ">"  ( constant L : SIGNED;
                constant R : INTEGER ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : signed(L_left downto 0) is L;
  variable L01 : signed(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return not signed_less_or_equal (L01, to_signed(R,L01'LENGTH)) ;
end ">" ;

--=============================================================================

     -- Id: C.7
function "<"  ( constant L : UNSIGNED;
                constant R : UNSIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  alias xR : unsigned(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return unsigned_less (resize(L01,SIZE), resize(R01,SIZE)) ;
end "<" ;

     -- Id: C.8
function "<"  ( constant L : SIGNED;
                constant R : SIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : signed(L_left downto 0) is L;
  alias xR : signed(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return signed_less (to_signed(L01,SIZE), to_signed(R01,SIZE)) ;
end "<" ;

     -- Id: C.9
function "<"  ( constant L : NATURAL;
                constant R : UNSIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : unsigned(R_left downto 0) is R;
  variable R01 : unsigned(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return unsigned_less (to_unsigned(L,R01'LENGTH), R01) ;
end "<" ;

     -- Id: C.10
function "<"  ( constant L : INTEGER;
                constant R : SIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : signed(R_left downto 0) is R;
  variable R01 : signed(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return signed_less (to_signed(L,R01'LENGTH), R01) ;
end "<" ;

     -- Id: C.11
function "<"  ( constant L : UNSIGNED;
                constant R : NATURAL ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  variable L01 : unsigned(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return unsigned_less (L01, to_unsigned (R,L01'LENGTH)) ;
end "<" ;

     -- Id: C.12
function "<"  ( constant L : SIGNED;
                constant R : INTEGER ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : signed(L_left downto 0) is L;
  variable L01 : signed(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return signed_less (L01, to_signed (R,L01'LENGTH)) ;
end "<" ;

--=============================================================================

     -- Id: C.13
function "<=" ( constant L : UNSIGNED;
                constant R : UNSIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  alias xR : unsigned(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
    return unsigned_less_or_equal (resize(L01,SIZE), resize(R01,SIZE)) ;
end "<=" ;

     -- Id: C.14
function "<=" ( constant L : SIGNED;
                constant R : SIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : signed(L_left downto 0) is L;
  alias xR : signed(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return signed_less_or_equal (to_signed(L01,SIZE), to_signed(R01,SIZE)) ;
end "<=" ;

     -- Id: C.15
function "<=" ( constant L : NATURAL;
                constant R : UNSIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : unsigned(R_left downto 0) is R;
  variable R01 : unsigned(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return unsigned_less_or_equal (to_unsigned(L,R01'LENGTH), R01) ;
end "<=" ;

     -- Id: C.16
function "<=" ( constant L : INTEGER;
                constant R : SIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : signed(R_left downto 0) is R;
  variable R01 : signed(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return signed_less_or_equal (to_signed(L,R01'LENGTH), R01) ;
end "<=" ;

     -- Id: C.17
function "<=" ( constant L : UNSIGNED;
                constant R : NATURAL ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  variable L01 : unsigned(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return unsigned_less_or_equal (L01, to_unsigned(R,L01'LENGTH)) ;
end "<=" ;

     -- Id: C.18
function "<=" ( constant L : SIGNED;
                constant R : INTEGER ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : signed(L_left downto 0) is L;
  variable L01 : signed(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return signed_less_or_equal (L01, to_signed(R,L01'LENGTH)) ;
end "<=" ;

--=============================================================================

     -- Id: C.19
function ">=" ( constant L : UNSIGNED;
                constant R : UNSIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  alias xR : unsigned(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return not unsigned_less (resize(L01,SIZE), resize(R01,SIZE)) ;
end ">=" ;

     -- Id: C.20
function ">=" ( constant L : SIGNED;
                constant R : SIGNED ) return BOOLEAN is 
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : signed(L_left downto 0) is L;
  alias xR : signed(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
    return not signed_less (to_signed(L01,SIZE), to_signed(R01,SIZE)) ;
end ">=" ;

     -- Id: C.21
function ">=" ( constant L : NATURAL;
                constant R : UNSIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : unsigned(R_left downto 0) is R;
  variable R01 : unsigned(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return not unsigned_less (to_unsigned(L,R01'LENGTH), R01) ;
end ">=" ;

     -- Id: C.22
function ">=" ( constant L : INTEGER;
                constant R : SIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : signed(R_left downto 0) is R;
  variable R01 : signed(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return not signed_less (to_signed (L,R01'LENGTH), R01) ;
end ">=" ;

     -- Id: C.23
function ">=" ( constant L : UNSIGNED;
                constant R : NATURAL ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  variable L01 : unsigned(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return not unsigned_less (L01, to_unsigned(R,L01'LENGTH)) ;
end ">=" ;

     -- Id: C.24
function ">=" ( constant L : SIGNED;
                constant R : INTEGER ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : signed(L_left downto 0) is L;
  variable L01 : signed(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return not signed_less (L01, to_signed(R,L01'LENGTH)) ; 
end ">=" ;

--=============================================================================

     -- Id: C.25
function "="  ( constant L : UNSIGNED;
               constant R : UNSIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  alias xR : unsigned(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return unsigned_equal (resize(L01,SIZE),resize(R01,SIZE)) ;
end "=" ;

     -- Id: C.26
function "="  ( constant L : SIGNED;
                constant R : SIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : signed(L_left downto 0) is L;
  alias xR : signed(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return signed_equal (to_signed(L01,SIZE), to_signed(R01,SIZE)) ;
end "=" ;

     -- Id: C.27
function "="  ( constant L : NATURAL;
                constant R : UNSIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : unsigned(R_left downto 0) is R;
  variable R01 : unsigned(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return unsigned_equal ( to_unsigned(L,R01'LENGTH), R01);
end "=" ;

     -- Id: C.28
function "="  ( constant L : INTEGER;
                constant R : SIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : signed(R_left downto 0) is R;
  variable R01 : signed(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return signed_equal ( to_signed(L,R01'LENGTH), R01) ;
end "=" ;

     -- Id: C.29
function "="  ( constant L : UNSIGNED;
                constant R : NATURAL ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  variable L01 : unsigned(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return unsigned_equal (L01, to_unsigned (R,L01'LENGTH)) ;
end "=" ;

     -- Id: C.30
function "="  ( constant L : SIGNED;
                constant R : INTEGER ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : signed(L_left downto 0) is L;
  variable L01 : signed(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return signed_equal (L01, to_signed (R,L01'LENGTH)) ;
end "=" ;


--=============================================================================

     -- Id: C.31
function "/="  ( constant L : UNSIGNED;
               constant R : UNSIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  alias xR : unsigned(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : unsigned(L_left downto 0);
  variable R01 : unsigned(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return not(unsigned_equal (resize(L01,SIZE),resize(R01,SIZE))) ;
end "/=" ;

     -- Id: C.32
function "/="  ( constant L : SIGNED;
                constant R : SIGNED ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  constant R_left:integer := R'length-1;
  alias xL : signed(L_left downto 0) is L;
  alias xR : signed(R_left downto 0) is R;
  constant SIZE : NATURAL := max (L'LENGTH, R'LENGTH) ;
  variable L01 : signed(L_left downto 0);
  variable R01 : signed(R_left downto 0);
begin
  if ((L_left<0) or (R_left<0)) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  R01 := to_01(xR);
  return not(signed_equal (to_signed(L01,SIZE), to_signed(R01,SIZE))) ;
end "/=" ;

     -- Id: C.33
function "/="  ( constant L : NATURAL;
                constant R : UNSIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : unsigned(R_left downto 0) is R;
  variable R01 : unsigned(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return not(unsigned_equal ( to_unsigned(L,R01'LENGTH), R01));
end "/=" ;

     -- Id: C.34
function "/="  ( constant L : INTEGER;
                constant R : SIGNED ) return BOOLEAN is
  constant R_left:integer := R'length-1;
  alias xR : signed(R_left downto 0) is R;
  variable R01 : signed(R_left downto 0);
begin
  if (R_left<0) then return false; -- not a vector
    end if;
  R01 := to_01(xR);
  return not(signed_equal ( to_signed(L,R01'LENGTH), R01)) ;
end "/=" ;

     -- Id: C.35
function "/="  ( constant L : UNSIGNED;
                constant R : NATURAL ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : unsigned(L_left downto 0) is L;
  variable L01 : unsigned(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return not(unsigned_equal (L01, to_unsigned (R,L01'LENGTH))) ;
end "/=" ;

     -- Id: C.36
function "/="  ( constant L : SIGNED;
                constant R : INTEGER ) return BOOLEAN is
  constant L_left:integer := L'length-1;
  alias xL : signed(L_left downto 0) is L;
  variable L01 : signed(L_left downto 0);
begin
  if (L_left<0) then return false; -- not a vector
    end if;
  L01 := to_01(xL);
  return not(signed_equal (L01, to_signed (R,L01'LENGTH))) ;
end "/=" ;


--=============================================================================

     -- Id: S.1
function shift_left ( constant  ARG  : UNSIGNED;
               constant count : NATURAL ) return UNSIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : unsigned(arg_left downto 0) is arg;
  variable xarg : unsigned(arg_left downto 0);
begin
  if (arg_left<0) then return nau; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return UNSIGNED(xsll(std_logic_vector(xarg),count));
end;

     -- Id: S.2
function shift_right ( constant  ARG  : UNSIGNED;
               constant count : NATURAL ) return UNSIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : unsigned(arg_left downto 0) is arg;
  variable xarg : unsigned(arg_left downto 0);
begin
  if (arg_left<0) then return nau; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return UNSIGNED(xsrl(std_logic_vector(xarg),count));
end;

     -- Id: S.3
function shift_left ( constant  ARG  : SIGNED;
               constant count : NATURAL ) return SIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : signed(arg_left downto 0) is arg;
  variable xarg : signed(arg_left downto 0);
begin
  if (arg_left<0) then return nas; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return SIGNED(xsll(std_logic_vector(xarg),count));
end;

     -- Id: S.4
function shift_right ( constant  ARG  : SIGNED;
               constant count : NATURAL ) return SIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : signed(arg_left downto 0) is arg;
  variable xarg : signed(arg_left downto 0);
begin
  if (arg_left<0) then return nas; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return SIGNED(xsra(std_logic_vector(xarg),count));
end;

--=============================================================================

     -- Id: S.5
function rotate_left ( constant  ARG  : UNSIGNED;
               constant count : NATURAL ) return UNSIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : unsigned(arg_left downto 0) is arg;
  variable xarg : unsigned(arg_left downto 0);
begin
  if (arg_left<0) then return nau; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return UNSIGNED(xrol(std_logic_vector(xarg),count));
end;

     -- Id: S.6
function rotate_right ( constant  ARG  : UNSIGNED;
               constant count : NATURAL ) return UNSIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : unsigned(arg_left downto 0) is arg;
  variable xarg : unsigned(arg_left downto 0);
begin
  if (arg_left<0) then return nau; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return UNSIGNED(xror(std_logic_vector(xarg),count));
end;


     -- Id: S.7
function rotate_left ( constant  ARG  : SIGNED;
               constant count : NATURAL ) return SIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : signed(arg_left downto 0) is arg;
  variable xarg : signed(arg_left downto 0);
begin
  if (arg_left<0) then return nas; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return SIGNED(xrol(std_logic_vector(xarg),count));
end;

     -- Id: S.8
function rotate_right ( constant  ARG  : SIGNED;
               constant count : NATURAL ) return SIGNED is
  constant arg_left:integer := arg'length-1;
  alias xxarg : signed(arg_left downto 0) is arg;
  variable xarg : signed(arg_left downto 0);
begin
  if (arg_left<0) then return nas; -- not a vector
    end if;
  xarg := to_01(xxarg);
  return SIGNED(xror(std_logic_vector(xarg),count));
end;

--=============================================================================


     -- Id: D.1
function to_integer ( constant ARG : UNSIGNED ) return NATURAL is
   constant arg_left:integer := arg'length-1;
   alias xxarg :unsigned(arg_left downto 0) is arg;
   variable xarg :unsigned(arg_left downto 0); 
   variable result : NATURAL := 0;
   variable w : INTEGER := 1;  -- weight factor
begin
   -- null range abort.
   if not(ARG'length > 0) then
     assert ARG'length > 0   
     report "numeric_std.to_integer : null argument"
     severity failure;
     end if;
   -- integer truncation warning       
   if not(ARG'length < 32) then
     assert ARG'length < 32 
     report "numeric_std.to_integer : integer truncated"
     severity warning;
     end if;
   xarg := to_01(xxarg);
   for i in xarg'reverse_range loop
     if xarg (i) = '1' then
       result := result + w;
       end if;
     if (i /= xarg'left) then w := w + w;
       end if;
     end loop;
   return result;
end to_integer;

     -- Id: D.2
function to_integer ( constant ARG : SIGNED ) return INTEGER is
begin
    if ARG(ARG'left) = '0' then
       return to_integer( UNSIGNED (ARG)) ;
    else
       return (- to_integer( UNSIGNED ( - ARG)) );
    end if;
end to_integer;

     -- Id: D.3
function to_unsigned ( constant ARG : NATURAL;
                       constant SIZE : NATURAL ) return UNSIGNED is
  VARIABLE result : UNSIGNED (SIZE-1 downto 0) ;
  variable i_val:natural := arg;
  begin
  for i in 0 to SIZE-1 loop
    if (i_val MOD 2) = 0 then
       result(i) := '0';
    else result(i) := '1' ;
      end if;
    i_val := i_val/2 ;
    end loop;
  if not(i_val=0) then
    assert (i_val=0) 
    report "numeric_std.to_unsigned : number truncated"
    severity WARNING ;
    end if;
  return result ;
  end to_unsigned;

     -- Id: D.4
function to_signed ( constant ARG : INTEGER;
                     constant SIZE : NATURAL ) return SIGNED is
  VARIABLE result : SIGNED (SIZE-1 downto 0) ;
  VARIABLE b_val : std_logic := '0' ;
  VARIABLE i_val : INTEGER := ARG ;
  begin
  if (ARG<0) then
    b_val := '1' ;
    i_val := -(ARG+1) ;
    end if ;
  for i in 0 to SIZE-1 loop
    if (i_val MOD 2) = 0 then
      result(i) := b_val;
    else 
      result(i) := not b_val ;
      end if;
    i_val := i_val/2 ;
    end loop;
  if not(i_val=0) then
    assert (i_val=0) 
    report "numeric_std.to_signed : number truncated"
    severity WARNING ;
    end if;
  return result;
  end to_signed;

--=============================================================================


     -- Id: R.1
function resize (constant ARG : SIGNED;
              constant new_size : NATURAL) return SIGNED is
    alias invec : SIGNED (ARG'length-1 downto 0) is ARG ;
    VARIABLE result : SIGNED (new_size-1 downto 0) ;
    constant bound : NATURAL := min(ARG'length,new_size)-1 ;
begin
    if (arg'length < 1) then 
      return nas;
      end if;
    result := (others=>ARG(ARG'left)) ; 
    result(bound downto 0) := invec(bound downto 0) ;
    return result;
end resize ;


     -- Id: R.2
function resize ( constant ARG : UNSIGNED;
          constant new_size : NATURAL ) return UNSIGNED is
  constant ARG_left:integer := ARG'length-1;
  alias XARG : UNSIGNED(ARG_left downto 0) is ARG;
  variable result : UNSIGNED(new_size-1 downto 0) := (others=>'0');
begin
  if result'length=0 then return nau;
    end if;
  if XARG'length=0 then return result;
    end if;
  if (result'length < arg'length) then
    result(result'left downto 0) := xarg(result'left downto 0);
  else
    result(result'left downto XARG'left+1) := (others => '0');
    result(XARG'left downto 0) := XARG;
    end if;
  return result;
  end resize;

       
--=============================================================================
end numeric_std;




