----------------------------------------------------------------------------------- -- -- Copyright (c) 199X by IEEE. All rights reserved. -- -- Copyright (c) 1998 by Synopsys, Inc. All rights reserved. -- -- This source file is an essential part of IEEE Standard P1076.3, -- Standard VHDL Synthesis Packages. -- -- Title : Standard VHDL Synthesis Packages (1076.3, NUMERIC_STD) -- -- Library : This package has been 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 vectors 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). -- -- --------------------------------------------------------------------------------- -- modification history : -- --------------------------------------------------------------------------------- -- Version: 2.4 -- Date : 12 April 1995 -- ----------------------------------------------------------------------------------- -- -- Author: Dongxiang Wu May 11, 1998. -- -- Modified: Dongxiang Wu Jun 5, 1998. -- Implement xnor, sll, srl, rol, ror operators -- -- Modified: Dongxiang Wu Jun 8, 1998 -- Implement TO_01, STD_MATCH. ----------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; package numeric_std is constant CopyRightNotice: STRING := "Copyright (c) 199X IEEE. All rights reserved."; --============================================================================ -- 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" (ARG: SIGNED) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0). -- Result: Returns the absolute value of a SIGNED vector ARG. -- Id: A.2 function "-" (ARG: SIGNED) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0). -- Result: Returns the value of the unary minus operation on a -- SIGNED vector ARG. --============================================================================ -- Id: A.3 function "+" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). -- Result: Adds two UNSIGNED vectors that may be of different lengths. -- Id: A.4 function "+" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). -- Result: Adds two SIGNED vectors that may be of different lengths. -- Id: A.5 function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0). -- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R. -- Id: A.6 function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0). -- Result: Adds a non-negative INTEGER, L, with an UNSIGNED vector, R. -- Id: A.7 function "+" (L: INTEGER; 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 -- vector, R. -- Id: A.8 function "+" (L: SIGNED; R: INTEGER) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0). -- Result: Adds a SIGNED vector, L, to an INTEGER, R. --============================================================================ -- Id: A.9 function "-" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). -- Result: Subtracts two UNSIGNED vectors that may be of different lengths. -- Id: A.10 function "-" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). -- Result: Subtracts a SIGNED vector, R, from another SIGNED vector, L, -- that may possibly be of different lengths. -- Id: A.11 function "-" (L: UNSIGNED;R: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0). -- Result: Subtracts a non-negative INTEGER, R, from an UNSIGNED vector, L. -- Id: A.12 function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0). -- Result: Subtracts an UNSIGNED vector, R, from a non-negative INTEGER, L. -- Id: A.13 function "-" (L: SIGNED; R: INTEGER) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0). -- Result: Subtracts an INTEGER, R, from a SIGNED vector, L. -- Id: A.14 function "-" (L: INTEGER; R: SIGNED) return SIGNED; -- Result subtype: SIGNED(R'LENGTH-1 downto 0). -- Result: Subtracts a SIGNED vector, R, from an INTEGER, L. --============================================================================ -- Id: A.15 function "*" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0). -- Result: Performs the multiplication operation on two UNSIGNED vectors -- that may possibly be of different lengths. -- Id: A.16 function "*" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED((L'LENGTH+R'LENGTH-1) downto 0) -- Result: Multiplies two SIGNED vectors that may possibly be of -- different lengths. -- Id: A.17 function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0). -- Result: Multiplies an UNSIGNED vector, L, with a non-negative -- INTEGER, R. R is converted to an UNSIGNED vector of -- SIZE L'LENGTH before multiplication. -- Id: A.18 function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0). -- Result: Multiplies an UNSIGNED vector, R, with a non-negative -- INTEGER, L. L is converted to an UNSIGNED vector of -- SIZE R'LENGTH before multiplication. -- Id: A.19 function "*" (L: SIGNED; R: INTEGER) return SIGNED; -- Result subtype: SIGNED((L'LENGTH+L'LENGTH-1) downto 0) -- Result: Multiplies a SIGNED vector, L, with an INTEGER, R. R is -- converted to a SIGNED vector of SIZE L'LENGTH before -- multiplication. -- Id: A.20 function "*" (L: INTEGER; R: SIGNED) return SIGNED; -- Result subtype: SIGNED((R'LENGTH+R'LENGTH-1) downto 0) -- Result: Multiplies a SIGNED vector, R, with an INTEGER, L. L is -- converted to a SIGNED vector 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 "/" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R. -- Id: A.22 -- function "/" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Divides an SIGNED vector, L, by another SIGNED vector, R. -- Id: A.23 -- function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Divides an UNSIGNED vector, L, by a non-negative INTEGER, R. -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. -- Id: A.24 -- function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) -- Result: Divides a non-negative INTEGER, L, by an UNSIGNED vector, R. -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. -- Id: A.25 -- function "/" (L: SIGNED; R: INTEGER) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Divides a SIGNED vector, L, by an INTEGER, R. -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. -- Id: A.26 -- function "/" (L: INTEGER; R: SIGNED) return SIGNED; -- Result subtype: SIGNED(R'LENGTH-1 downto 0) -- Result: Divides an INTEGER, L, by a SIGNED vector, R. -- If NO_OF_BITS(L) > R'LENGTH, result 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" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) -- Result: Computes "L rem R" where L and R are UNSIGNED vectors. -- Id: A.28 -- function "rem" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(R'LENGTH-1 downto 0) -- Result: Computes "L rem R" where L and R are SIGNED vectors. -- Id: A.29 -- function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Computes "L rem R" where L is an UNSIGNED vector and R is a -- non-negative INTEGER. -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. -- Id: A.30 -- function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) -- Result: Computes "L rem R" where R is an UNSIGNED vector and L is a -- non-negative INTEGER. -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. -- Id: A.31 -- function "rem" (L: SIGNED; R: INTEGER) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Computes "L rem R" where L is SIGNED vector and R is an INTEGER. -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. -- Id: A.32 -- function "rem" (L: INTEGER; R: SIGNED) return SIGNED; -- Result subtype: SIGNED(R'LENGTH-1 downto 0) -- Result: Computes "L rem R" where R is SIGNED vector and L is an INTEGER. -- If NO_OF_BITS(L) > R'LENGTH, result 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" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) -- Result: Computes "L mod R" where L and R are UNSIGNED vectors. -- Id: A.34 -- function "mod" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(R'LENGTH-1 downto 0) -- Result: Computes "L mod R" where L and R are SIGNED vectors. -- Id: A.35 -- function "mod" (L: UNSIGNED; R: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Computes "L mod R" where L is an UNSIGNED vector and R -- is a non-negative INTEGER. -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. -- Id: A.36 -- function "mod" (L: NATURAL; R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0) -- Result: Computes "L mod R" where R is an UNSIGNED vector and L -- is a non-negative INTEGER. -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. -- Id: A.37 -- function "mod" (L: SIGNED; R: INTEGER) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Computes "L mod R" where L is a SIGNED vector and -- R is an INTEGER. -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH. -- Id: A.38 -- function "mod" (L: INTEGER; 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 vector. -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH. --============================================================================ -- Comparison Operators --============================================================================ -- Id: C.1 function ">" (L, R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly -- of different lengths. -- Id: C.2 function ">" (L, R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L > R" where L and R are SIGNED vectors possibly -- of different lengths. -- Id: C.3 function ">" (L: NATURAL; R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L > R" where L is a non-negative INTEGER and -- R is an UNSIGNED vector. -- Id: C.4 function ">" (L: INTEGER; R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L > R" where L is a INTEGER and -- R is a SIGNED vector. -- Id: C.5 function ">" (L: UNSIGNED; R: NATURAL) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L > R" where L is an UNSIGNED vector and -- R is a non-negative INTEGER. -- Id: C.6 function ">" (L: SIGNED; R: INTEGER) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L > R" where L is a SIGNED vector and -- R is a INTEGER. --============================================================================ -- Id: C.7 function "<" (L, R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly -- of different lengths. -- Id: C.8 function "<" (L, R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L < R" where L and R are SIGNED vectors possibly -- of different lengths. -- Id: C.9 function "<" (L: NATURAL; R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L < R" where L is a non-negative INTEGER and -- R is an UNSIGNED vector. -- Id: C.10 function "<" (L: INTEGER; R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L < R" where L is an INTEGER and -- R is a SIGNED vector. -- Id: C.11 function "<" (L: UNSIGNED; R: NATURAL) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L < R" where L is an UNSIGNED vector and -- R is a non-negative INTEGER. -- Id: C.12 function "<" (L: SIGNED; R: INTEGER) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L < R" where L is a SIGNED vector and -- R is an INTEGER. --============================================================================ -- Id: C.13 function "<=" (L, R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly -- of different lengths. -- Id: C.14 function "<=" (L, R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L <= R" where L and R are SIGNED vectors possibly -- of different lengths. -- Id: C.15 function "<=" (L: NATURAL; R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L <= R" where L is a non-negative INTEGER and -- R is an UNSIGNED vector. -- Id: C.16 function "<=" (L: INTEGER; R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L <= R" where L is an INTEGER and -- R is a SIGNED vector. -- Id: C.17 function "<=" (L: UNSIGNED; R: NATURAL) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L <= R" where L is an UNSIGNED vector and -- R is a non-negative INTEGER. -- Id: C.18 function "<=" (L: SIGNED; R: INTEGER) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L <= R" where L is a SIGNED vector and -- R is an INTEGER. --============================================================================ -- Id: C.19 function ">=" (L, R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly -- of different lengths. -- Id: C.20 function ">=" (L, R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L >= R" where L and R are SIGNED vectors possibly -- of different lengths. -- Id: C.21 function ">=" (L: NATURAL; R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L >= R" where L is a non-negative INTEGER and -- R is an UNSIGNED vector. -- Id: C.22 function ">=" (L: INTEGER; R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L >= R" where L is an INTEGER and -- R is a SIGNED vector. -- Id: C.23 function ">=" (L: UNSIGNED; R: NATURAL) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L >= R" where L is an UNSIGNED vector and -- R is a non-negative INTEGER. -- Id: C.24 function ">=" (L: SIGNED; R: INTEGER) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L >= R" where L is a SIGNED vector and -- R is an INTEGER. --============================================================================ -- Id: C.25 function "=" (L, R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly -- of different lengths. -- Id: C.26 function "=" (L, R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L = R" where L and R are SIGNED vectors possibly -- of different lengths. -- Id: C.27 function "=" (L: NATURAL; R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L = R" where L is a non-negative INTEGER and -- R is an UNSIGNED vector. -- Id: C.28 function "=" (L: INTEGER; R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L = R" where L is an INTEGER and -- R is a SIGNED vector. -- Id: C.29 function "=" (L: UNSIGNED; R: NATURAL) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L = R" where L is an UNSIGNED vector and -- R is a non-negative INTEGER. -- Id: C.30 function "=" (L: SIGNED; R: INTEGER) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L = R" where L is a SIGNED vector and -- R is an INTEGER. --============================================================================ -- Id: C.31 function "/=" (L, R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly -- of different lengths. -- Id: C.32 function "/=" (L, R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L /= R" where L and R are SIGNED vectors possibly -- of different lengths. -- Id: C.33 function "/=" (L: NATURAL; R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L /= R" where L is a non-negative INTEGER and -- R is an UNSIGNED vector. -- Id: C.34 function "/=" (L: INTEGER; R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L /= R" where L is an INTEGER and -- R is a SIGNED vector. -- Id: C.35 function "/=" (L: UNSIGNED; R: NATURAL) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L /= R" where L is an UNSIGNED vector and -- R is a non-negative INTEGER. -- Id: C.36 function "/=" (L: SIGNED; R: INTEGER) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: Computes "L /= R" where L is a SIGNED vector and -- R is an INTEGER. --============================================================================ -- Shift and Rotate Functions --============================================================================ -- Id: S.1 function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a shift-left on an UNSIGNED vector COUNT times. -- The vacated positions are filled with '0'. -- The COUNT leftmost elements are lost. -- Id: S.2 function SHIFT_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a shift-right on an UNSIGNED vector COUNT times. -- The vacated positions are filled with '0'. -- The COUNT rightmost elements are lost. -- Id: S.3 function SHIFT_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a shift-left on a SIGNED vector COUNT times. -- The vacated positions are filled with '0'. -- The COUNT leftmost elements are lost. -- Id: S.4 function SHIFT_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a shift-right on a SIGNED vector COUNT times. -- The vacated positions are filled with the leftmost -- element, ARG'LEFT. The COUNT rightmost elements are lost. --============================================================================ -- Id: S.5 function ROTATE_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a rotate-left of an UNSIGNED vector COUNT times. -- Id: S.6 function ROTATE_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a rotate-right of an UNSIGNED vector COUNT times. -- Id: S.7 function ROTATE_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a logical rotate-left of a SIGNED -- vector COUNT times. -- Id: S.8 function ROTATE_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: Performs a logical rotate-right of a SIGNED -- vector COUNT times. --============================================================================ --============================================================================ ------------------------------------------------------------------------------ -- Note : Function S.9 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.9 function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: SHIFT_LEFT(ARG, COUNT) ------------------------------------------------------------------------------ -- Note : Function S.10 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.10 function "sll" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: SHIFT_LEFT(ARG, COUNT) ------------------------------------------------------------------------------ -- Note : Function S.11 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.11 function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: SHIFT_RIGHT(ARG, COUNT) ------------------------------------------------------------------------------ -- Note : Function S.12 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.12 function "srl" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT)) ------------------------------------------------------------------------------ -- Note : Function S.13 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.13 function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: ROTATE_LEFT(ARG, COUNT) ------------------------------------------------------------------------------ -- Note : Function S.14 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.14 function "rol" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: ROTATE_LEFT(ARG, COUNT) ------------------------------------------------------------------------------ -- Note : Function S.15 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.15 function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: ROTATE_RIGHT(ARG, COUNT) ------------------------------------------------------------------------------ -- Note : Function S.16 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.16 function "ror" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0) -- Result: ROTATE_RIGHT(ARG, COUNT) --============================================================================ -- RESIZE Functions --============================================================================ -- Id: R.1 function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED; -- Result subtype: SIGNED(NEW_SIZE-1 downto 0) -- Result: Resizes the SIGNED vector ARG to the specified size. -- To create a larger vector, the new [leftmost] bit positions -- are filled with the sign bit (ARG'LEFT). When truncating, -- the sign bit is retained along with the rightmost part. -- Id: R.2 function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(NEW_SIZE-1 downto 0) -- Result: Resizes the SIGNED vector ARG to the specified size. -- To create a larger vector, the new [leftmost] bit positions -- are filled with '0'. When truncating, the leftmost bits -- are dropped. --============================================================================ -- Conversion Functions --============================================================================ -- Id: D.1 function TO_INTEGER (ARG: UNSIGNED) return NATURAL; -- Result subtype: NATURAL. Value cannot be negative since parameter is an -- UNSIGNED vector. -- Result: Converts the UNSIGNED vector to an INTEGER. -- Id: D.2 function TO_INTEGER (ARG: SIGNED) return INTEGER; -- Result subtype: INTEGER -- Result: Converts a SIGNED vector to an INTEGER. -- Id: D.3 function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(SIZE-1 downto 0) -- Result: Converts a non-negative INTEGER to an UNSIGNED vector with -- the specified SIZE. -- Id: D.4 function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED; -- Result subtype: SIGNED(SIZE-1 downto 0) -- Result: Converts an INTEGER to a SIGNED vector of the specified SIZE. --============================================================================ -- Logical Operators --============================================================================ -- Id: L.1 function "not" (L: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Termwise inversion -- Id: L.2 function "and" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Vector AND operation -- Id: L.3 function "or" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Vector OR operation -- Id: L.4 function "nand" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Vector NAND operation -- Id: L.5 function "nor" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Vector NOR operation -- Id: L.6 function "xor" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Vector XOR operation -- --------------------------------------------------------------------------- -- Note : Function L.7 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. -- --------------------------------------------------------------------------- -- Id: L.7 function "xnor" (L, R: UNSIGNED) return UNSIGNED; -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0) -- Result: Vector XNOR operation -- Id: L.8 function "not" (L: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Termwise inversion -- Id: L.9 function "and" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Vector AND operation -- Id: L.10 function "or" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Vector OR operation -- Id: L.11 function "nand" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Vector NAND operation -- Id: L.12 function "nor" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Vector NOR operation -- Id: L.13 function "xor" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- --------------------------------------------------------------------------- -- Note : Function L.14 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. -- --------------------------------------------------------------------------- -- Id: L.14 function "xnor" (L, R: SIGNED) return SIGNED; -- Result subtype: SIGNED(L'LENGTH-1 downto 0) -- Result: Vector XNOR operation --============================================================================ -- Match Functions --============================================================================ -- Id: M.1 function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: terms compared per STD_LOGIC_1164 intent -- Id: M.2 function STD_MATCH (L, R: UNSIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: terms compared per STD_LOGIC_1164 intent -- Id: M.3 function STD_MATCH (L, R: SIGNED) return BOOLEAN; -- Result subtype: BOOLEAN -- Id: M.4 function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: terms compared per STD_LOGIC_1164 intent -- Id: M.5 function STD_MATCH (L, R: STD_ULOGIC_VECTOR) return BOOLEAN; -- Result subtype: BOOLEAN -- Result: terms compared per STD_LOGIC_1164 intent --============================================================================ -- Translation Functions --============================================================================ -- Id: T.1 function TO_01 (S: UNSIGNED; XMAP: STD_LOGIC := '0') return UNSIGNED; -- Result subtype: UNSIGNED(S'RANGE) -- Result: Termwise, 'H' is translated to '1', and 'L' is translated -- to '0'. If a value other than '0'|'1'|'H'|'L' is found, -- the array is set to (others => XMAP), and a warning is -- issued. -- Id: T.2 function TO_01 (S: SIGNED; XMAP: STD_LOGIC := '0') return SIGNED; -- Result subtype: SIGNED(S'RANGE) -- Result: Termwise, 'H' is translated to '1', and 'L' is translated -- to '0'. If a value other than '0'|'1'|'H'|'L' is found, -- the array is set to (others => XMAP), and a warning is -- issued. end numeric_std; library IEEE; use IEEE.std_logic_1164.all; package body numeric_std is function max(L, R: INTEGER) return INTEGER is begin if L > R then return L; else return R; end if; end; function min(L, R: INTEGER) return INTEGER is begin if L < R then return L; else return R; end if; end; -- synopsys synthesis_off type tbl_type is array (STD_ULOGIC) of STD_ULOGIC; constant tbl_BINARY : tbl_type := ('X', 'X', '0', '1', 'X', 'X', '0', '1', 'X'); -- synopsys synthesis_on -- synopsys synthesis_off type tbl_mvl9_boolean is array (STD_ULOGIC) of boolean; constant IS_X : tbl_mvl9_boolean := (true, true, false, false, true, true, false, false, true); -- synopsys synthesis_on function MAKE_BINARY(A : STD_ULOGIC) return STD_ULOGIC is -- synopsys built_in SYN_FEED_THRU begin -- synopsys synthesis_off if (IS_X(A)) then assert false report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." severity warning; return ('X'); end if; return tbl_BINARY(A); -- synopsys synthesis_on end; function MAKE_BINARY(A : UNSIGNED) return UNSIGNED is -- synopsys built_in SYN_FEED_THRU variable one_bit : STD_ULOGIC; variable result : UNSIGNED (A'range); begin -- synopsys synthesis_off for i in A'range loop if (IS_X(A(i))) then assert false report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." severity warning; result := (others => 'X'); return result; end if; result(i) := tbl_BINARY(A(i)); end loop; return result; -- synopsys synthesis_on end; function MAKE_BINARY(A : SIGNED) return SIGNED is -- synopsys built_in SYN_FEED_THRU variable one_bit : STD_ULOGIC; variable result : SIGNED (A'range); begin -- synopsys synthesis_off for i in A'range loop if (IS_X(A(i))) then assert false report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." severity warning; result := (others => 'X'); return result; end if; result(i) := tbl_BINARY(A(i)); end loop; return result; -- synopsys synthesis_on end; -- Type propagation function which returns a signed type with the -- size of the left arg. function LEFT_SIGNED_ARG(A,B: SIGNED) return SIGNED is variable Z: SIGNED (A'left downto 0); -- pragma return_port_name Z begin return(Z); end; -- Type propagation function which returns an unsigned type with the -- size of the left arg. function LEFT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is variable Z: UNSIGNED (A'left downto 0); -- pragma return_port_name Z begin return(Z); end; -- Type propagation function which returns a signed type with the -- size of the result of a signed multiplication function MULT_SIGNED_ARG(A,B: SIGNED) return SIGNED is variable Z: SIGNED ((A'length+B'length-1) downto 0); -- pragma return_port_name Z begin return(Z); end; -- Type propagation function which returns an unsigned type with the -- size of the result of a unsigned multiplication function MULT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is variable Z: UNSIGNED ((A'length+B'length-1) downto 0); -- pragma return_port_name Z begin return(Z); end; function SHL(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED is -- synopsys subpgm_id 358 constant control_msb: INTEGER := COUNT'length - 1; variable control: UNSIGNED (control_msb downto 0); constant result_msb: INTEGER := ARG'length-1; subtype rtype is UNSIGNED (result_msb downto 0); variable result, temp: rtype; begin control := MAKE_BINARY(COUNT); -- synopsys synthesis_off if (control(0) = 'X') then result := rtype'(others => 'X'); return result; end if; -- synopsys synthesis_on result := ARG; for i in 0 to control_msb loop if control(i) = '1' then temp := rtype'(others => '0'); if 2**i <= result_msb then temp(result_msb downto 2**i) := result(result_msb - 2**i downto 0); end if; result := temp; end if; end loop; return result; end; function SHL(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED is -- synopsys subpgm_id 359 constant control_msb: INTEGER := COUNT'length - 1; variable control: UNSIGNED (control_msb downto 0); constant result_msb: INTEGER := ARG'length-1; subtype rtype is SIGNED (result_msb downto 0); variable result, temp: rtype; begin control := MAKE_BINARY(COUNT); -- synopsys synthesis_off if (control(0) = 'X') then result := rtype'(others => 'X'); return result; end if; -- synopsys synthesis_on result := ARG; for i in 0 to control_msb loop if control(i) = '1' then temp := rtype'(others => '0'); if 2**i <= result_msb then temp(result_msb downto 2**i) := result(result_msb - 2**i downto 0); end if; result := temp; end if; end loop; return result; end; function SHR(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED is -- synopsys subpgm_id 360 constant control_msb: INTEGER := COUNT'length - 1; variable control: UNSIGNED (control_msb downto 0); constant result_msb: INTEGER := ARG'length-1; subtype rtype is UNSIGNED (result_msb downto 0); variable result, temp: rtype; begin control := MAKE_BINARY(COUNT); -- synopsys synthesis_off if (control(0) = 'X') then result := rtype'(others => 'X'); return result; end if; -- synopsys synthesis_on result := ARG; for i in 0 to control_msb loop if control(i) = '1' then temp := rtype'(others => '0'); if 2**i <= result_msb then temp(result_msb - 2**i downto 0) := result(result_msb downto 2**i); end if; result := temp; end if; end loop; return result; end; function SHR(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED is -- synopsys subpgm_id 361 constant control_msb: INTEGER := COUNT'length - 1; variable control: UNSIGNED (control_msb downto 0); constant result_msb: INTEGER := ARG'length-1; subtype rtype is SIGNED (result_msb downto 0); variable result, temp: rtype; variable sign_bit: STD_ULOGIC; begin control := MAKE_BINARY(COUNT); -- synopsys synthesis_off if (control(0) = 'X') then result := rtype'(others => 'X'); return result; end if; -- synopsys synthesis_on result := ARG; sign_bit := ARG(ARG'left); for i in 0 to control_msb loop if control(i) = '1' then temp := rtype'(others => sign_bit); if 2**i <= result_msb then temp(result_msb - 2**i downto 0) := result(result_msb downto 2**i); end if; result := temp; end if; end loop; return result; end; -- convert an integer to a unsigned STD_ULOGIC_VECTOR function CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER) return UNSIGNED is variable result: UNSIGNED(SIZE-1 downto 0); variable temp: integer; -- synopsys built_in SYN_INTEGER_TO_UNSIGNED -- synopsys subpgm_id 371 begin -- synopsys synthesis_off temp := ARG; for i in 0 to SIZE-1 loop if (temp mod 2) = 1 then result(i) := '1'; else result(i) := '0'; end if; if temp > 0 then temp := temp / 2; else temp := (temp - 1) / 2; -- simulate ASR end if; end loop; return result; -- synopsys synthesis_on end; function CONV_UNSIGNED(ARG: UNSIGNED; SIZE: INTEGER) return UNSIGNED is constant msb: INTEGER := min(ARG'length, SIZE) - 1; subtype rtype is UNSIGNED (SIZE-1 downto 0); variable new_bounds: UNSIGNED (ARG'length-1 downto 0); variable result: rtype; -- synopsys built_in SYN_ZERO_EXTEND -- synopsys subpgm_id 372 begin -- synopsys synthesis_off new_bounds := MAKE_BINARY(ARG); if (new_bounds(0) = 'X') then result := rtype'(others => 'X'); return result; end if; result := rtype'(others => '0'); result(msb downto 0) := new_bounds(msb downto 0); return result; -- synopsys synthesis_on end; -- convert an integer to a 2's complement STD_ULOGIC_VECTOR function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) return SIGNED is variable result: SIGNED (SIZE-1 downto 0); variable temp: integer; -- synopsys built_in SYN_INTEGER_TO_SIGNED -- synopsys subpgm_id 376 begin -- synopsys synthesis_off temp := ARG; for i in 0 to SIZE-1 loop if (temp mod 2) = 1 then result(i) := '1'; else result(i) := '0'; end if; if temp > 0 then temp := temp / 2; elsif (temp > integer'low) then temp := (temp - 1) / 2; -- simulate ASR else temp := temp / 2; -- simulate ASR end if; end loop; return result; -- synopsys synthesis_on end; function CONV_SIGNED(ARG: SIGNED; SIZE: INTEGER) return SIGNED is constant msb: INTEGER := min(ARG'length, SIZE) - 1; subtype rtype is SIGNED (SIZE-1 downto 0); variable new_bounds : SIGNED (ARG'length-1 downto 0); variable result: rtype; -- synopsys built_in SYN_SIGN_EXTEND -- synopsys subpgm_id 378 begin -- synopsys synthesis_off new_bounds := MAKE_BINARY(ARG); if (new_bounds(0) = 'X') then result := rtype'(others => 'X'); return result; end if; result := rtype'(others => new_bounds(new_bounds'left)); result(msb downto 0) := new_bounds(msb downto 0); return result; -- synopsys synthesis_on end; function mult(A,B: SIGNED) return SIGNED is variable BA: SIGNED((A'length+B'length-1) downto 0); variable PA: SIGNED((A'length+B'length-1) downto 0); variable AA: SIGNED(A'length downto 0); variable neg: STD_ULOGIC; constant one : UNSIGNED(1 downto 0) := "01"; -- pragma map_to_operator MULT_TC_OP -- pragma type_function MULT_SIGNED_ARG -- pragma return_port_name Z begin if (A(A'left) = 'X' or B(B'left) = 'X') then PA := (others => 'X'); return(PA); end if; PA := (others => '0'); neg := B(B'left) xor A(A'left); BA := CONV_SIGNED(('0' & abs(B)),(A'length+B'length)); AA := '0' & abs(A); for i in 0 to A'length-1 loop if AA(i) = '1' then PA := PA+BA; end if; BA := SHL(BA,one); end loop; if (neg= '1') then return(-PA); else return(PA); end if; end; function mult(A,B: UNSIGNED) return UNSIGNED is variable BA: UNSIGNED((A'length+B'length-1) downto 0); variable PA: UNSIGNED((A'length+B'length-1) downto 0); constant one : UNSIGNED(1 downto 0) := "01"; -- pragma map_to_operator MULT_UNS_OP -- pragma type_function MULT_UNSIGNED_ARG -- pragma return_port_name Z begin if (A(A'left) = 'X' or B(B'left) = 'X') then PA := (others => 'X'); return(PA); end if; PA := (others => '0'); BA := CONV_UNSIGNED(B,(A'length+B'length)); for i in 0 to A'length-1 loop if A(i) = '1' then PA := PA+BA; end if; BA := SHL(BA,one); end loop; return(PA); end; -- subtract two signed numbers of the same length -- both arrays must have range (msb downto 0) function minus(A, B: SIGNED) return SIGNED is variable carry: STD_ULOGIC; variable BV: STD_ULOGIC_VECTOR (A'left downto 0); variable sum: SIGNED (A'left downto 0); -- pragma map_to_operator SUB_TC_OP -- pragma type_function LEFT_SIGNED_ARG -- pragma return_port_name Z begin if (A(A'left) = 'X' or B(B'left) = 'X') then sum := (others => 'X'); return(sum); end if; carry := '1'; BV := not STD_ULOGIC_VECTOR(B); for i in 0 to A'left loop sum(i) := A(i) xor BV(i) xor carry; carry := (A(i) and BV(i)) or (A(i) and carry) or (carry and BV(i)); end loop; return sum; end; -- add two signed numbers of the same length -- both arrays must have range (msb downto 0) function plus(A, B: SIGNED) return SIGNED is variable carry: STD_ULOGIC; variable BV, sum: SIGNED (A'left downto 0); -- pragma map_to_operator ADD_TC_OP -- pragma type_function LEFT_SIGNED_ARG -- pragma return_port_name Z begin if (A(A'left) = 'X' or B(B'left) = 'X') then sum := (others => 'X'); return(sum); end if; carry := '0'; BV := B; for i in 0 to A'left loop sum(i) := A(i) xor BV(i) xor carry; carry := (A(i) and BV(i)) or (A(i) and carry) or (carry and BV(i)); end loop; return sum; end; -- subtract two unsigned numbers of the same length -- both arrays must have range (msb downto 0) function unsigned_minus(A, B: UNSIGNED) return UNSIGNED is variable carry: STD_ULOGIC; variable BV: STD_ULOGIC_VECTOR (A'left downto 0); variable sum: UNSIGNED (A'left downto 0); -- pragma map_to_operator SUB_UNS_OP -- pragma type_function LEFT_UNSIGNED_ARG -- pragma return_port_name Z begin if (A(A'left) = 'X' or B(B'left) = 'X') then sum := (others => 'X'); return(sum); end if; carry := '1'; BV := not STD_ULOGIC_VECTOR(B); for i in 0 to A'left loop sum(i) := A(i) xor BV(i) xor carry; carry := (A(i) and BV(i)) or (A(i) and carry) or (carry and BV(i)); end loop; return sum; end; -- add two unsigned numbers of the same length -- both arrays must have range (msb downto 0) function unsigned_plus(A, B: UNSIGNED) return UNSIGNED is variable carry: STD_ULOGIC; variable BV, sum: UNSIGNED (A'left downto 0); -- pragma map_to_operator ADD_UNS_OP -- pragma type_function LEFT_UNSIGNED_ARG -- pragma return_port_name Z begin if (A(A'left) = 'X' or B(B'left) = 'X') then sum := (others => 'X'); return(sum); end if; carry := '0'; BV := B; for i in 0 to A'left loop sum(i) := A(i) xor BV(i) xor carry; carry := (A(i) and BV(i)) or (A(i) and carry) or (carry and BV(i)); end loop; return sum; end; -- Id: A.16 function "*"(L, R: SIGNED) return SIGNED is -- pragma label_applies_to mult -- synopsys subpgm_id 296 begin return mult(CONV_SIGNED(L, L'length), CONV_SIGNED(R, R'length)); -- pragma label mult end; -- Id: A.15 function "*"(L, R: UNSIGNED) return UNSIGNED is -- pragma label_applies_to mult -- synopsys subpgm_id 295 begin return mult(CONV_UNSIGNED(L, L'length), CONV_UNSIGNED(R, R'length)); -- pragma label mult end; -- Id: A.3 function "+"(L, R: UNSIGNED) return UNSIGNED is -- pragma label_applies_to plus -- synopsys subpgm_id 236 constant length: INTEGER := max(L'length, R'length); begin return unsigned_plus(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label plus end; -- Id: A.4 function "+"(L, R: SIGNED) return SIGNED is -- pragma label_applies_to plus -- synopsys subpgm_id 237 constant length: INTEGER := max(L'length, R'length); begin return plus(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label plus end; -- Id: A.7 function "+"(L: SIGNED; R: INTEGER) return SIGNED is -- pragma label_applies_to plus -- synopsys subpgm_id 242 constant length: INTEGER := L'length; begin return plus(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label plus end; -- Id: A.8 function "+"(L: INTEGER; R: SIGNED) return SIGNED is -- pragma label_applies_to plus -- synopsys subpgm_id 243 constant length: INTEGER := R'length; begin return plus(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label plus end; -- Id: A.9 function "-"(L, R: UNSIGNED) return UNSIGNED is -- pragma label_applies_to minus -- synopsys subpgm_id 248 constant length: INTEGER := max(L'length, R'length); begin return unsigned_minus(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label minus end; -- Id: A.10 function "-"(L, R: SIGNED) return SIGNED is -- pragma label_applies_to minus -- synopsys subpgm_id 249 constant length: INTEGER := max(L'length, R'length); begin return minus(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label minus end; -- Id: A.13 function "-"(L: SIGNED; R: INTEGER) return SIGNED is -- pragma label_applies_to minus -- synopsys subpgm_id 254 constant length: INTEGER := L'length; begin return minus(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label minus end; -- Id: A.14 function "-"(L: INTEGER; R: SIGNED) return SIGNED is -- pragma label_applies_to minus -- synopsys subpgm_id 255 constant length: INTEGER := R'length; begin return minus(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label minus end; -- Id: A.2 function "-"(ARG: SIGNED) return SIGNED is -- pragma label_applies_to minus -- synopsys subpgm_id 286 begin return 0 - ARG; -- pragma label minus end; -- Id: A.1 function "abs"(ARG: SIGNED) return SIGNED is -- synopsys subpgm_id 287 begin if (ARG(ARG'left) = '0' or ARG(ARG'left) = 'L') then return ARG; else return 0 - ARG; end if; end; -- Type propagation function which returns the type BOOLEAN function UNSIGNED_RETURN_BOOLEAN(A,B: UNSIGNED) return BOOLEAN is variable Z: BOOLEAN; -- pragma return_port_name Z begin return(Z); end; -- Type propagation function which returns the type BOOLEAN function SIGNED_RETURN_BOOLEAN(A,B: SIGNED) return BOOLEAN is variable Z: BOOLEAN; -- pragma return_port_name Z begin return(Z); end; -- compare two signed numbers of the same length -- both arrays must have range (msb downto 0) function is_less(A, B: SIGNED) return BOOLEAN is constant sign: INTEGER := A'left; variable a_is_0, b_is_1, result : boolean; -- pragma map_to_operator LT_TC_OP -- pragma type_function SIGNED_RETURN_BOOLEAN -- pragma return_port_name Z begin if A(sign) /= B(sign) then result := A(sign) = '1'; else result := FALSE; for i in 0 to sign-1 loop a_is_0 := A(i) = '0'; b_is_1 := B(i) = '1'; result := (a_is_0 and b_is_1) or (a_is_0 and result) or (b_is_1 and result); end loop; end if; return result; end; -- compare two signed numbers of the same length -- both arrays must have range (msb downto 0) function is_less_or_equal(A, B: SIGNED) return BOOLEAN is constant sign: INTEGER := A'left; variable a_is_0, b_is_1, result : boolean; -- pragma map_to_operator LEQ_TC_OP -- pragma type_function SIGNED_RETURN_BOOLEAN -- pragma return_port_name Z begin if A(sign) /= B(sign) then result := A(sign) = '1'; else result := TRUE; for i in 0 to sign-1 loop a_is_0 := A(i) = '0'; b_is_1 := B(i) = '1'; result := (a_is_0 and b_is_1) or (a_is_0 and result) or (b_is_1 and result); end loop; end if; return result; end; -- compare two unsigned numbers of the same length -- both arrays must have range (msb downto 0) function unsigned_is_less(A, B: UNSIGNED) return BOOLEAN is constant sign: INTEGER := A'left; variable a_is_0, b_is_1, result : boolean; -- pragma map_to_operator LT_UNS_OP -- pragma type_function UNSIGNED_RETURN_BOOLEAN -- pragma return_port_name Z begin result := FALSE; for i in 0 to sign loop a_is_0 := A(i) = '0'; b_is_1 := B(i) = '1'; result := (a_is_0 and b_is_1) or (a_is_0 and result) or (b_is_1 and result); end loop; return result; end; -- compare two unsigned numbers of the same length -- both arrays must have range (msb downto 0) function unsigned_is_less_or_equal(A, B: UNSIGNED) return BOOLEAN is constant sign: INTEGER := A'left; variable a_is_0, b_is_1, result : boolean; -- pragma map_to_operator LEQ_UNS_OP -- pragma type_function UNSIGNED_RETURN_BOOLEAN -- pragma return_port_name Z begin result := TRUE; for i in 0 to sign loop a_is_0 := A(i) = '0'; b_is_1 := B(i) = '1'; result := (a_is_0 and b_is_1) or (a_is_0 and result) or (b_is_1 and result); end loop; return result; end; -- Id: C.7 function "<"(L, R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to lt -- synopsys subpgm_id 305 constant length: INTEGER := max(L'length, R'length); begin return unsigned_is_less(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label lt end; -- Id: C.8 function "<"(L, R: SIGNED) return BOOLEAN is -- pragma label_applies_to lt -- synopsys subpgm_id 306 constant length: INTEGER := max(L'length, R'length); begin return is_less(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label lt end; -- Id: C.12 function "<"(L: SIGNED; R: INTEGER) return BOOLEAN is -- pragma label_applies_to lt -- synopsys subpgm_id 311 constant length: INTEGER := max(L'length, 32); begin return is_less(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label lt end; -- Id: C.10 function "<"(L: INTEGER; R: SIGNED) return BOOLEAN is -- pragma label_applies_to lt -- synopsys subpgm_id 312 constant length: INTEGER := max(32, R'length); begin return is_less(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label lt end; -- Id: C.13 function "<="(L, R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to leq -- synopsys subpgm_id 314 constant length: INTEGER := max(L'length, R'length); begin return unsigned_is_less_or_equal(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label leq end; -- Id: C.14 function "<="(L, R: SIGNED) return BOOLEAN is -- pragma label_applies_to leq -- synopsys subpgm_id 315 constant length: INTEGER := max(L'length, R'length); begin return is_less_or_equal(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label leq end; -- Id: C.18 function "<="(L: SIGNED; R: INTEGER) return BOOLEAN is -- pragma label_applies_to leq -- synopsys subpgm_id 320 constant length: INTEGER := max(L'length, 32); begin return is_less_or_equal(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label leq end; -- Id: C.16 function "<="(L: INTEGER; R: SIGNED) return BOOLEAN is -- pragma label_applies_to leq -- synopsys subpgm_id 321 constant length: INTEGER := max(32, R'length); begin return is_less_or_equal(CONV_SIGNED(L, length), CONV_SIGNED(R, length)); -- pragma label leq end; -- Id: C.1 function ">"(L, R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to gt -- synopsys subpgm_id 323 constant length: INTEGER := max(L'length, R'length); begin return unsigned_is_less(CONV_UNSIGNED(R, length), CONV_UNSIGNED(L, length)); -- pragma label gt end; -- Id: C.2 function ">"(L, R: SIGNED) return BOOLEAN is -- pragma label_applies_to gt -- synopsys subpgm_id 324 constant length: INTEGER := max(L'length, R'length); begin return is_less(CONV_SIGNED(R, length), CONV_SIGNED(L, length)); -- pragma label gt end; -- Id: C.6 function ">"(L: SIGNED; R: INTEGER) return BOOLEAN is -- pragma label_applies_to gt -- synopsys subpgm_id 329 constant length: INTEGER := max(L'length, 32); begin return is_less(CONV_SIGNED(R, length), CONV_SIGNED(L, length)); -- pragma label gt end; -- Id: C.4 function ">"(L: INTEGER; R: SIGNED) return BOOLEAN is -- pragma label_applies_to gt -- synopsys subpgm_id 330 constant length: INTEGER := max(32, R'length); begin return is_less(CONV_SIGNED(R, length), CONV_SIGNED(L, length)); -- pragma label gt end; -- Id: C.19 function ">="(L, R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to geq -- synopsys subpgm_id 332 constant length: INTEGER := max(L'length, R'length); begin return unsigned_is_less_or_equal(CONV_UNSIGNED(R, length), CONV_UNSIGNED(L, length)); -- pragma label geq end; -- Id: C.20 function ">="(L, R: SIGNED) return BOOLEAN is -- pragma label_applies_to geq -- synopsys subpgm_id 333 constant length: INTEGER := max(L'length, R'length); begin return is_less_or_equal(CONV_SIGNED(R, length), CONV_SIGNED(L, length)); -- pragma label geq end; -- Id: C.24 function ">="(L: SIGNED; R: INTEGER) return BOOLEAN is -- pragma label_applies_to geq -- synopsys subpgm_id 338 constant length: INTEGER := max(L'length, 32); begin return is_less_or_equal(CONV_SIGNED(R, length), CONV_SIGNED(L, length)); -- pragma label geq end; -- Id: C.22 function ">="(L: INTEGER; R: SIGNED) return BOOLEAN is -- pragma label_applies_to geq -- synopsys subpgm_id 339 constant length: INTEGER := max(32, R'length); begin return is_less_or_equal(CONV_SIGNED(R, length), CONV_SIGNED(L, length)); -- pragma label geq end; -- for internal use only. Assumes SIGNED arguments of equal length. function bitwise_eql(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return BOOLEAN is -- pragma built_in SYN_EQL begin for i in L'range loop if L(i) /= R(i) then return FALSE; end if; end loop; return TRUE; end; -- for internal use only. Assumes SIGNED arguments of equal length. function bitwise_neq(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return BOOLEAN is -- pragma built_in SYN_NEQ begin for i in L'range loop if L(i) /= R(i) then return TRUE; end if; end loop; return FALSE; end; -- Id: C.26 function "="(L, R: UNSIGNED) return BOOLEAN is -- synopsys subpgm_id 341 constant length: INTEGER := max(L'length, R'length); begin return bitwise_eql( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); end; -- Id: C.27 function "="(L, R: SIGNED) return BOOLEAN is -- synopsys subpgm_id 342 constant length: INTEGER := max(L'length, R'length); begin return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); end; -- Id: C.30 function "="(L: SIGNED; R: INTEGER) return BOOLEAN is -- synopsys subpgm_id 347 constant length: INTEGER := max(L'length, 32); begin return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); end; -- Id: C.28 function "="(L: INTEGER; R: SIGNED) return BOOLEAN is -- synopsys subpgm_id 348 constant length: INTEGER := max(32, R'length); begin return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); end; -- Id: C.31 function "/="(L, R: UNSIGNED) return BOOLEAN is -- synopsys subpgm_id 350 constant length: INTEGER := max(L'length, R'length); begin return bitwise_neq( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); end; -- Id: C.32 function "/="(L, R: SIGNED) return BOOLEAN is -- synopsys subpgm_id 351 constant length: INTEGER := max(L'length, R'length); begin return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); end; -- Id: C.36 function "/="(L: SIGNED; R: INTEGER) return BOOLEAN is -- synopsys subpgm_id 356 constant length: INTEGER := max(L'length, 32); begin return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); end; -- Id: C.34 function "/="(L: INTEGER; R: SIGNED) return BOOLEAN is -- synopsys subpgm_id 357 constant length: INTEGER := max(32, R'length); begin return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ), STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) ); end; function CONV_INTEGER(ARG: UNSIGNED) return INTEGER is variable result: INTEGER; variable tmp: STD_ULOGIC; -- synopsys built_in SYN_UNSIGNED_TO_INTEGER -- synopsys subpgm_id 366 begin -- synopsys synthesis_off assert ARG'length <= 31 report "ARG is too large in CONV_INTEGER" severity FAILURE; result := 0; for i in ARG'range loop result := result * 2; tmp := tbl_BINARY(ARG(i)); if tmp = '1' then result := result + 1; elsif tmp = 'X' then assert false report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." severity warning; assert false report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0." severity WARNING; return 0; end if; end loop; return result; -- synopsys synthesis_on end; function CONV_INTEGER(ARG: SIGNED) return INTEGER is variable result: INTEGER; variable tmp: STD_ULOGIC; -- synopsys built_in SYN_SIGNED_TO_INTEGER -- synopsys subpgm_id 367 begin -- synopsys synthesis_off assert ARG'length <= 32 report "ARG is too large in CONV_INTEGER" severity FAILURE; result := 0; for i in ARG'range loop if i /= ARG'left then result := result * 2; tmp := tbl_BINARY(ARG(i)); if tmp = '1' then result := result + 1; elsif tmp = 'X' then assert false report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)." severity warning; assert false report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0." severity WARNING; return 0; end if; end if; end loop; tmp := MAKE_BINARY(ARG(ARG'left)); if tmp = '1' then if ARG'length = 32 then result := (result - 2**30) - 2**30; else result := result - (2 ** (ARG'length-1)); end if; end if; return result; -- synopsys synthesis_on end; -- Id: A.17 function "*"(L: UNSIGNED; R: NATURAL) return UNSIGNED is -- pragma label_applies_to mult -- synopsys subpgm_id 302 ??? constant length: INTEGER := L'length; begin return mult(-- pragma label mult CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); end; -- Id: A.18 function "*"(L: NATURAL; R: UNSIGNED) return UNSIGNED is -- pragma label_applies_to mult -- synopsys subpgm_id 302 ??? constant length: INTEGER := R'length; begin return mult(-- pragma label mult CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); end; -- Id: A.19 function "*"(L: SIGNED; R: INTEGER ) return SIGNED is -- pragma label_applies_to mult -- synopsys subpgm_id 302 ??? constant length: INTEGER := L'length; begin return mult(-- pragma label mult CONV_SIGNED(L, length), CONV_SIGNED(R, length)); end; -- Id: A.20 function "*"(L: INTEGER ; R: SIGNED) return SIGNED is -- pragma label_applies_to mult -- synopsys subpgm_id 302 ??? constant length: INTEGER := R'length; begin return mult(-- pragma label mult CONV_SIGNED(L, length), CONV_SIGNED(R, length)); end; -- Id: A.5 function "+"(L: UNSIGNED; R: NATURAL) return UNSIGNED is -- pragma label_applies_to plus ??? -- synopsys subpgm_id 236 ??? constant length: INTEGER := L'length; begin return unsigned_plus(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label plus end; -- Id: A.6 function "+"(L: NATURAL; R: UNSIGNED) return UNSIGNED is -- pragma label_applies_to plus ??? -- synopsys subpgm_id 236 ??? constant length: INTEGER := R'length; begin return unsigned_plus(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label plus end; -- Id: A.11 function "-"(L: UNSIGNED; R: NATURAL) return UNSIGNED is -- pragma label_applies_to minus -- synopsys subpgm_id 276 ??? constant length: INTEGER := L'length; begin return unsigned_minus( -- pragma label minus CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); end; -- Id: A.12 function "-"(L: NATURAL; R: UNSIGNED) return UNSIGNED is -- pragma label_applies_to minus -- synopsys subpgm_id 276 ??? constant length: INTEGER := R'length; begin return unsigned_minus( -- pragma label minus CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); end; -- Id: C.9 function "<"(L: NATURAL; R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to lt -- synopsys subpgm_id 312 ??? constant length: INTEGER := max(31, R'length); begin return unsigned_is_less(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label lt end; -- Id: C.11 function "<"(L: UNSIGNED; R: NATURAL) return BOOLEAN is -- pragma label_applies_to lt -- synopsys subpgm_id 312 ??? constant length: INTEGER := max(L'length, 31); begin return unsigned_is_less(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label lt end; -- Id: C.15 function "<="(L: NATURAL; R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to leq -- synopsys subpgm_id 321 ??? constant length: INTEGER := max(31, R'length); begin return unsigned_is_less_or_equal(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label leq end; -- Id: C.17 function "<="(L: UNSIGNED; R: NATURAL) return BOOLEAN is -- pragma label_applies_to leq -- synopsys subpgm_id 321 ??? constant length: INTEGER := max(L'length, 31); begin return unsigned_is_less_or_equal(CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)); -- pragma label leq end; -- Id: C.3 function ">"(L: NATURAL; R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to gt -- synopsys subpgm_id 330 ??? constant length: INTEGER := max(31, R'length); begin return unsigned_is_less(CONV_UNSIGNED(R, length), CONV_UNSIGNED(L, length)); -- pragma label gt end; -- Id: C.5 function ">"(L: UNSIGNED; R: NATURAL) return BOOLEAN is -- pragma label_applies_to gt -- synopsys subpgm_id 330 ??? constant length: INTEGER := max(L'length, 31); begin return unsigned_is_less(CONV_UNSIGNED(R, length), CONV_UNSIGNED(L, length)); -- pragma label gt end; -- Id: C.21 function ">="(L: NATURAL; R: UNSIGNED) return BOOLEAN is -- pragma label_applies_to geq -- synopsys subpgm_id 339 ??? constant length: INTEGER := max(31, R'length); begin return unsigned_is_less_or_equal(CONV_UNSIGNED(R, length), CONV_UNSIGNED(L, length)); -- pragma label geq end; -- Id: C.23 function ">="(L: UNSIGNED; R: NATURAL) return BOOLEAN is -- pragma label_applies_to geq -- synopsys subpgm_id 339 ??? constant length: INTEGER := max(31, L'length); begin return unsigned_is_less_or_equal(CONV_UNSIGNED(R, length), CONV_UNSIGNED(L, length)); -- pragma label geq end; -- Id: C.27 function "="(L: NATURAL; R: UNSIGNED) return BOOLEAN is -- synopsys subpgm_id 348 ??? constant length: INTEGER := max(31, R'length); begin return bitwise_eql( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length)), STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); end; -- Id: C.29 function "="(L: UNSIGNED; R: NATURAL) return BOOLEAN is -- synopsys subpgm_id 348 ??? constant length: INTEGER := max(L'length, 31); begin return bitwise_eql( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length)), STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); end; -- Id: C.33 function "/="(L: NATURAL; R: UNSIGNED) return BOOLEAN is -- synopsys subpgm_id 357 constant length: INTEGER := max(31, R'length); begin return bitwise_neq( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length)), STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); end; -- Id: C.35 function "/="(L: UNSIGNED; R: NATURAL) return BOOLEAN is -- synopsys subpgm_id 357 constant length: INTEGER := max(L'length, 31); begin return bitwise_neq( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length)), STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) ); end; function CONTROL_BITS(COUNT:NATURAL) return NATURAL is variable temp : UNSIGNED(30 downto 0); variable result: INTEGER; begin temp := CONV_UNSIGNED(COUNT, 31); if (temp(30) = '1') then result := 31; elsif (temp(29) = '1') then result := 30; elsif (temp(28) = '1') then result := 29; elsif (temp(27) = '1') then result := 28; elsif (temp(26) = '1') then result := 27; elsif (temp(25) = '1') then result := 26; elsif (temp(24) = '1') then result := 25; elsif (temp(23) = '1') then result := 24; elsif (temp(22) = '1') then result := 23; elsif (temp(21) = '1') then result := 22; elsif (temp(20) = '1') then result := 21; elsif (temp(19) = '1') then result := 20; elsif (temp(18) = '1') then result := 19; elsif (temp(17) = '1') then result := 18; elsif (temp(16) = '1') then result := 17; elsif (temp(15) = '1') then result := 16; elsif (temp(14) = '1') then result := 15; elsif (temp(13) = '1') then result := 14; elsif (temp(12) = '1') then result := 13; elsif (temp(11) = '1') then result := 12; elsif (temp(10) = '1') then result := 11; elsif (temp(9) = '1') then result := 10; elsif (temp(8) = '1') then result := 9; elsif (temp(7) = '1') then result := 8; elsif (temp(6) = '1') then result := 7; elsif (temp(5) = '1') then result := 6; elsif (temp(4) = '1') then result := 5; elsif (temp(3) = '1') then result := 4; elsif (temp(2) = '1') then result := 3; elsif (temp(1) = '1') then result := 2; else result := 1; end if; return result; end; -- Id: S.1 function SHIFT_LEFT(ARG:UNSIGNED; COUNT: NATURAL) return UNSIGNED is variable control_length : INTEGER; constant temp :INTEGER := ARG'length; begin control_length := CONTROL_BITS(temp); return SHL(ARG, CONV_UNSIGNED(COUNT, control_length)); end; -- Id: S.2 function SHIFT_RIGHT(ARG:UNSIGNED; COUNT: NATURAL) return UNSIGNED is variable control_length : INTEGER; constant temp :INTEGER := ARG'length; begin control_length := CONTROL_BITS(temp); return SHR(ARG, CONV_UNSIGNED(COUNT, control_length)); end; -- Id: S.3 function SHIFT_LEFT(ARG:SIGNED; COUNT: NATURAL) return SIGNED is variable control_length : INTEGER; constant temp :INTEGER := ARG'length; begin control_length := CONTROL_BITS(temp); return SHL(ARG, CONV_UNSIGNED(COUNT, control_length)); end; -- Id: S.4 function SHIFT_RIGHT(ARG:SIGNED; COUNT: NATURAL) return SIGNED is variable control_length : INTEGER; constant temp :INTEGER := ARG'length; begin control_length := CONTROL_BITS(temp); return SHR(ARG, CONV_UNSIGNED(COUNT, control_length)); end; function SHORT_ROTATE_LEFT(ARG:UNSIGNED; control: UNSIGNED) return UNSIGNED is constant control_msb: INTEGER := control'length-1; constant result_msb: INTEGER := ARG'length-1; variable mycontrol : UNSIGNED ( control_msb downto 0); subtype rtype is UNSIGNED (result_msb downto 0); variable result, temp: rtype; begin result := ARG; mycontrol := control; for i in 0 to control_msb loop if mycontrol(i) = '1' then temp := rtype'(others => '0'); if 2**i <= result_msb then temp(result_msb downto 2**i) := result(result_msb - 2**i downto 0); temp(2**i-1 downto 0) := result(result_msb downto result_msb - 2**i + 1); end if; result := temp; end if; end loop; return result; end; -- Id: S.5 function ROTATE_LEFT(ARG:UNSIGNED; COUNT: NATURAL) return UNSIGNED is variable control_msb: INTEGER; constant temp : INTEGER := ARG'length; variable result: UNSIGNED(temp - 1 downto 0); begin control_msb := CONTROL_BITS(temp - 1); result:= SHORT_ROTATE_LEFT(ARG, MAKE_BINARY(CONV_UNSIGNED(COUNT, control_msb))); return result; end; function SHORT_ROTATE_RIGHT(ARG:UNSIGNED; control: UNSIGNED) return UNSIGNED is constant control_msb: INTEGER := control'length - 1; constant result_msb: INTEGER := ARG'length-1; variable mycontrol: UNSIGNED( control_msb downto 0); subtype rtype is UNSIGNED (result_msb downto 0); variable result, temp: rtype; begin -- synopsys synthesis_off if (control(0) = 'X') then result := rtype'(others => 'X'); return result; end if; -- synopsys synthesis_on result := ARG; mycontrol := control; for i in 0 to control_msb loop if mycontrol(i) = '1' then temp := rtype'(others => '0'); if 2**i <= result_msb then temp(result_msb - 2**i downto 0) := result(result_msb downto 2**i); temp(result_msb downto result_msb - 2**i + 1 ) := result(2**i - 1 downto 0); end if; result := temp; end if; end loop; return result; end; -- Id: S.6 function ROTATE_RIGHT(ARG:UNSIGNED; COUNT: NATURAL) return UNSIGNED is variable control_msb: INTEGER; constant temp : INTEGER := ARG'length; begin control_msb := CONTROL_BITS(temp - 1); return SHORT_ROTATE_RIGHT(ARG, MAKE_BINARY(CONV_UNSIGNED(COUNT, control_msb))); end; function SHORT_ROTATE_LEFT(ARG:SIGNED; control: UNSIGNED) return SIGNED is constant control_msb: INTEGER := control'length - 1; constant result_msb: INTEGER := ARG'length-1; variable mycontrol :UNSIGNED( control_msb downto 0); subtype rtype is SIGNED (result_msb downto 0); variable result, temp: rtype; begin -- synopsys synthesis_off if (control(0) = 'X') then result := rtype'(others => 'X'); return result; end if; -- synopsys synthesis_on result := ARG; mycontrol := control; for i in 0 to control_msb loop if mycontrol(i) = '1' then temp := rtype'(others => '0'); if 2**i <= result_msb then temp(result_msb downto 2**i) := result(result_msb - 2**i downto 0); temp(2**i-1 downto 0) := result(result_msb downto result_msb - 2**i + 1); end if; result := temp; end if; end loop; return result; end; -- Id: S.7 function ROTATE_LEFT(ARG:SIGNED; COUNT: NATURAL) return SIGNED is variable control_msb: INTEGER; constant temp : INTEGER := ARG'length; begin control_msb := CONTROL_BITS(temp - 1); return SHORT_ROTATE_LEFT(ARG, MAKE_BINARY(CONV_UNSIGNED(COUNT, control_msb))); end; function SHORT_ROTATE_RIGHT(ARG:SIGNED; control: UNSIGNED) return SIGNED is constant control_msb: INTEGER := control'length-1; constant result_msb: INTEGER := ARG'length-1; variable mycontrol: UNSIGNED(control_msb downto 0); subtype rtype is SIGNED (result_msb downto 0); variable result, temp: rtype; begin -- synopsys synthesis_off if (control(0) = 'X') then result := rtype'(others => 'X'); return result; end if; -- synopsys synthesis_on result := ARG; mycontrol := control; for i in 0 to control_msb loop if mycontrol(i) = '1' then temp := rtype'(others => '0'); if 2**i <= result_msb then temp(result_msb - 2**i downto 0) := result(result_msb downto 2**i); temp(result_msb downto result_msb - 2**i + 1 ) := result(2**i - 1 downto 0); end if; result := temp; end if; end loop; return result; end; -- Id: S.8 function ROTATE_RIGHT(ARG:SIGNED; COUNT: NATURAL) return SIGNED is variable control_msb: INTEGER; constant temp : INTEGER := ARG'length; begin control_msb := CONTROL_BITS(temp - 1); return SHORT_ROTATE_RIGHT(ARG, MAKE_BINARY(CONV_UNSIGNED(COUNT, control_msb))); end; -- Id: R.1 function RESIZE(ARG:SIGNED; NEW_SIZE: NATURAL) return SIGNED is begin return CONV_SIGNED(ARG, NEW_SIZE); end; -- Id: R.2 function RESIZE(ARG:UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED is begin return CONV_UNSIGNED(ARG, NEW_SIZE); end; -- Id: D.1 function TO_INTEGER(ARG: UNSIGNED) return NATURAL is begin return NATURAL(CONV_INTEGER(ARG)); end; -- Id: D.2 function TO_INTEGER(ARG: SIGNED) return INTEGER is begin return CONV_INTEGER(ARG); end; -- Id: D.3 function TO_UNSIGNED(ARG, SIZE: NATURAL) return UNSIGNED is begin return CONV_UNSIGNED(ARG, SIZE); end; -- Id: D.4 function TO_SIGNED(ARG: INTEGER; SIZE: NATURAL) return SIGNED is begin return CONV_SIGNED(ARG, SIZE); end; -- Id: L.1 function "not"(L: UNSIGNED) return UNSIGNED is variable result : UNSIGNED(L'range); constant length: INTEGER := L'length; begin for i in 0 to length - 1 loop result(i) := not L(i); end loop; return result; end; -- Id: L.2 function "and"(L, R: UNSIGNED) return UNSIGNED is constant length: INTEGER := L'length; variable result : UNSIGNED(0 to length-1); variable tempL : UNSIGNED(0 to length-1); variable tempR : UNSIGNED(0 to length-1); begin tempL := L; tempR := CONV_UNSIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) and tempR(i); end loop; return result; end; -- Id: L.3 function "or"(L, R: UNSIGNED) return UNSIGNED is constant length: INTEGER := L'length; variable result : UNSIGNED(0 to length-1); variable tempL : UNSIGNED(0 to length-1); variable tempR : UNSIGNED(0 to length-1); begin tempL := L; tempR := CONV_UNSIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) or tempR(i); end loop; return result; end; -- Id: L.4 function "nand"(L, R: UNSIGNED) return UNSIGNED is constant length: INTEGER := L'length; variable result : UNSIGNED(0 to length-1); variable tempL : UNSIGNED(0 to length-1); variable tempR : UNSIGNED(0 to length-1); begin tempL := L; tempR := CONV_UNSIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) nand tempR(i); end loop; return result; end; -- Id: L.5 function "nor"(L, R: UNSIGNED) return UNSIGNED is constant length: INTEGER := L'length; variable result : UNSIGNED(0 to length-1); variable tempL : UNSIGNED(0 to length-1); variable tempR : UNSIGNED(0 to length-1); begin tempL := L; tempR := CONV_UNSIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) nor tempR(i); end loop; return result; end; -- Id: L.6 function "xor"(L, R: UNSIGNED) return UNSIGNED is constant length: INTEGER := L'length; variable result : UNSIGNED(0 to length-1); variable tempL : UNSIGNED(0 to length-1); variable tempR : UNSIGNED(0 to length-1); begin tempL := L; tempR := CONV_UNSIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) xor tempR(i); end loop; return result; end; -- Id: L.8 function "not"(L: SIGNED) return SIGNED is variable result : SIGNED(L'range); constant length: INTEGER := L'length; begin for i in 0 to length - 1 loop result(i) := not L(i); end loop; return result; end; -- Id: L.9 function "and"(L, R: SIGNED) return SIGNED is constant length: INTEGER := L'length; variable result : SIGNED(0 to length-1); variable tempL : SIGNED(0 to length-1); variable tempR : SIGNED(0 to length-1); begin tempL := L; tempR := CONV_SIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) and tempR(i); end loop; return result; end; -- Id: L.10 function "or"(L, R: SIGNED) return SIGNED is constant length: INTEGER := L'length; variable result : SIGNED(0 to length-1); variable tempL : SIGNED(0 to length-1); variable tempR : SIGNED(0 to length-1); begin tempL := L; tempR := CONV_SIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) or tempR(i); end loop; return result; end; -- Id: L.11 function "nand"(L, R: SIGNED) return SIGNED is constant length: INTEGER := L'length; variable result : SIGNED(0 to length-1); variable tempL : SIGNED(0 to length-1); variable tempR : SIGNED(0 to length-1); begin tempL := L; tempR := CONV_SIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) nand tempR(i); end loop; return result; end; -- Id: L.12 function "nor"(L, R: SIGNED) return SIGNED is constant length: INTEGER := L'length; variable result : SIGNED(0 to length-1); variable tempL : SIGNED(0 to length-1); variable tempR : SIGNED(0 to length-1); begin tempL := L; tempR := CONV_SIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) nor tempR(i); end loop; return result; end; -- Id: L.13 function "xor"(L, R: SIGNED) return SIGNED is constant length: INTEGER := L'length; variable result : SIGNED(0 to length-1); variable tempL : SIGNED(0 to length-1); variable tempR : SIGNED(0 to length-1); begin tempL := L; tempR := CONV_SIGNED(R, length); for i in 0 to length - 1 loop result(i) := tempL(i) xor tempR(i); end loop; return result; end; --================================================================================ -- Currently Unsupported Functions -- --================================================================================ -- -- Id: A.21 -- function "/" (L, 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: UNSIGNED(L'LENGTH-1 downto 0); -- variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); -- begin -- if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; -- end if; -- XL := TO_01(XXL, 'X'); -- XR := TO_01(XXR, 'X'); -- if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then -- FQUOT := (others => 'X'); -- return FQUOT; -- end if; -- DIVMOD(XL, XR, FQUOT, FREMAIN); -- return FQUOT; -- end "/"; -- -- Id: A.22 -- function "/" (L, 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: UNSIGNED(L'LENGTH-1 downto 0); -- variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); -- variable XNUM: UNSIGNED(L'LENGTH-1 downto 0); -- variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0); -- variable QNEG: BOOLEAN := FALSE; -- begin -- if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS; -- end if; -- XL := TO_01(XXL, 'X'); -- XR := TO_01(XXR, 'X'); -- if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then -- FQUOT := (others => 'X'); -- return SIGNED(FQUOT); -- end if; -- if XL(XL'LEFT)='1' then -- XNUM := UNSIGNED(-XL); -- QNEG := TRUE; -- else -- XNUM := UNSIGNED(XL); -- end if; -- if XR(XR'LEFT)='1' then -- XDENOM := UNSIGNED(-XR); -- QNEG := not QNEG; -- else -- XDENOM := UNSIGNED(XR); -- end if; -- DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); -- if QNEG then FQUOT := "0"-FQUOT; -- end if; -- return SIGNED(FQUOT); -- end "/"; -- -- Id: A.23 -- function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED is -- constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R)); -- variable XR, QUOT: UNSIGNED(R_LENGTH-1 downto 0); -- begin -- if (L'LENGTH < 1) then return NAU; -- end if; -- if (R_LENGTH > L'LENGTH) then -- QUOT := (others => '0'); -- return RESIZE(QUOT, L'LENGTH); -- end if; -- XR := TO_UNSIGNED(R, R_LENGTH); -- QUOT := RESIZE((L / XR), QUOT'LENGTH); -- return RESIZE(QUOT, L'LENGTH); -- end "/"; -- -- Id: A.24 -- function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED is -- constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH); -- variable XL, QUOT: UNSIGNED(L_LENGTH-1 downto 0); -- begin -- if (R'LENGTH < 1) then return NAU; -- end if; -- XL := TO_UNSIGNED(L, L_LENGTH); -- QUOT := RESIZE((XL / R), QUOT'LENGTH); -- if L_LENGTH > R'LENGTH and QUOT(0)/='X' -- and QUOT(L_LENGTH-1 downto R'LENGTH) -- /= (L_LENGTH-1 downto R'LENGTH => '0') -- then -- assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated" -- severity WARNING; -- end if; -- return RESIZE(QUOT, R'LENGTH); -- end "/"; -- -- Id: A.25 -- function "/" (L: SIGNED; R: INTEGER) return SIGNED is -- constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R)); -- variable XR, QUOT: SIGNED(R_LENGTH-1 downto 0); -- begin -- if (L'LENGTH < 1) then return NAS; -- end if; -- if (R_LENGTH > L'LENGTH) then -- QUOT := (others => '0'); -- return RESIZE(QUOT, L'LENGTH); -- end if; -- XR := TO_SIGNED(R, R_LENGTH); -- QUOT := RESIZE((L / XR), QUOT'LENGTH); -- return RESIZE(QUOT, L'LENGTH); -- end "/"; -- -- Id: A.26 -- function "/" (L: INTEGER; R: SIGNED) return SIGNED is -- constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH); -- variable XL, QUOT: SIGNED(L_LENGTH-1 downto 0); -- begin -- if (R'LENGTH < 1) then return NAS; -- end if; -- XL := TO_SIGNED(L, L_LENGTH); -- QUOT := RESIZE((XL / R), QUOT'LENGTH); -- if L_LENGTH > R'LENGTH and QUOT(0)/='X' -- and QUOT(L_LENGTH-1 downto R'LENGTH) -- /= (L_LENGTH-1 downto R'LENGTH => QUOT(R'LENGTH-1)) -- then -- assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated" -- severity WARNING; -- end if; -- return RESIZE(QUOT, R'LENGTH); -- end "/"; --============================================================================ -- -- Id: A.27 -- function "rem" (L, 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: UNSIGNED(L'LENGTH-1 downto 0); -- variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); -- begin -- if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; -- end if; -- XL := TO_01(XXL, 'X'); -- XR := TO_01(XXR, 'X'); -- if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then -- FREMAIN := (others => 'X'); -- return FREMAIN; -- end if; -- DIVMOD(XL, XR, FQUOT, FREMAIN); -- return FREMAIN; -- end "rem"; -- -- Id: A.28 -- function "rem" (L, 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: UNSIGNED(L'LENGTH-1 downto 0); -- variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); -- variable XNUM: UNSIGNED(L'LENGTH-1 downto 0); -- variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0); -- variable RNEG: BOOLEAN := FALSE; -- begin -- if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS; -- end if; -- XNUM := UNSIGNED(TO_01(XXL, 'X')); -- XDENOM := UNSIGNED(TO_01(XXR, 'X')); -- if ((XNUM(XNUM'LEFT)='X') or (XDENOM(XDENOM'LEFT)='X')) then -- FREMAIN := (others => 'X'); -- return SIGNED(FREMAIN); -- end if; -- if XNUM(XNUM'LEFT)='1' then -- XNUM := UNSIGNED(-SIGNED(XNUM)); -- RNEG := TRUE; -- else -- XNUM := UNSIGNED(XNUM); -- end if; -- if XDENOM(XDENOM'LEFT)='1' then -- XDENOM := UNSIGNED(-SIGNED(XDENOM)); -- else -- XDENOM := UNSIGNED(XDENOM); -- end if; -- DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); -- if RNEG then -- FREMAIN := "0"-FREMAIN; -- end if; -- return SIGNED(FREMAIN); -- end "rem"; -- -- Id: A.29 -- function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED is -- constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R)); -- variable XR, XREM: UNSIGNED(R_LENGTH-1 downto 0); -- begin -- if (L'LENGTH < 1) then return NAU; -- end if; -- XR := TO_UNSIGNED(R, R_LENGTH); -- XREM := L rem XR; -- if R_LENGTH > L'LENGTH and XREM(0)/='X' -- and XREM(R_LENGTH-1 downto L'LENGTH) -- /= (R_LENGTH-1 downto L'LENGTH => '0') -- then -- assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, L'LENGTH); -- end "rem"; -- -- Id: A.30 -- function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED is -- constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH); -- variable XL, XREM: UNSIGNED(L_LENGTH-1 downto 0); -- begin -- XL := TO_UNSIGNED(L, L_LENGTH); -- XREM := XL rem R; -- if L_LENGTH > R'LENGTH and XREM(0)/='X' -- and XREM(L_LENGTH-1 downto R'LENGTH) -- /= (L_LENGTH-1 downto R'LENGTH => '0') -- then -- assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, R'LENGTH); -- end "rem"; -- -- Id: A.31 -- function "rem" (L: SIGNED; R: INTEGER) return SIGNED is -- constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R)); -- variable XR, XREM: SIGNED(R_LENGTH-1 downto 0); -- begin -- if (L'LENGTH < 1) then return NAS; -- end if; -- XR := TO_SIGNED(R, R_LENGTH); -- XREM := RESIZE((L rem XR), XREM'LENGTH); -- if R_LENGTH > L'LENGTH and XREM(0)/='X' -- and XREM(R_LENGTH-1 downto L'LENGTH) -- /= (R_LENGTH-1 downto L'LENGTH => XREM(L'LENGTH-1)) -- then -- assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, L'LENGTH); -- end "rem"; -- -- Id: A.32 -- function "rem" (L: INTEGER; R: SIGNED) return SIGNED is -- constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH); -- variable XL, XREM: SIGNED(L_LENGTH-1 downto 0); -- begin -- if (R'LENGTH < 1) then return NAS; -- end if; -- XL := TO_SIGNED(L, L_LENGTH); -- XREM := RESIZE((XL rem R), XREM'LENGTH); -- if L_LENGTH > R'LENGTH and XREM(0)/='X' -- and XREM(L_LENGTH-1 downto R'LENGTH) -- /= (L_LENGTH-1 downto R'LENGTH => XREM(R'LENGTH-1)) -- then -- assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, R'LENGTH); -- end "rem"; --============================================================================ -- -- Id: A.33 -- function "mod" (L, 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: UNSIGNED(L'LENGTH-1 downto 0); -- variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); -- begin -- if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; -- end if; -- XL := TO_01(XXL, 'X'); -- XR := TO_01(XXR, 'X'); -- if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then -- FREMAIN := (others => 'X'); -- return FREMAIN; -- end if; -- DIVMOD(XL, XR, FQUOT, FREMAIN); -- return FREMAIN; -- end "mod"; -- -- Id: A.34 -- function "mod" (L, 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: UNSIGNED(L'LENGTH-1 downto 0); -- variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); -- variable XNUM: UNSIGNED(L'LENGTH-1 downto 0); -- variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0); -- variable RNEG: BOOLEAN := FALSE; -- begin -- if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS; -- end if; -- XL := TO_01(XXL, 'X'); -- XR := TO_01(XXR, 'X'); -- if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then -- FREMAIN := (others => 'X'); -- return SIGNED(FREMAIN); -- end if; -- if XL(XL'LEFT)='1' then -- XNUM := UNSIGNED(-XL); -- else -- XNUM := UNSIGNED(XL); -- end if; -- if XR(XR'LEFT)='1' then -- XDENOM := UNSIGNED(-XR); -- RNEG := TRUE; -- else -- XDENOM := UNSIGNED(XR); -- end if; -- DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); -- if RNEG and L(L'LEFT)='1' then -- FREMAIN := "0"-FREMAIN; -- elsif RNEG and FREMAIN/="0" then -- FREMAIN := FREMAIN-XDENOM; -- elsif L(L'LEFT)='1' and FREMAIN/="0" then -- FREMAIN := XDENOM-FREMAIN; -- end if; -- return SIGNED(FREMAIN); -- end "mod"; -- -- Id: A.35 -- function "mod" (L: UNSIGNED; R: NATURAL) return UNSIGNED is -- constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R)); -- variable XR, XREM: UNSIGNED(R_LENGTH-1 downto 0); -- begin -- if (L'LENGTH < 1) then return NAU; -- end if; -- XR := TO_UNSIGNED(R, R_LENGTH); -- XREM := RESIZE((L mod XR), XREM'LENGTH); -- if R_LENGTH > L'LENGTH and XREM(0)/='X' -- and XREM(R_LENGTH-1 downto L'LENGTH) -- /= (R_LENGTH-1 downto L'LENGTH => '0') -- then -- assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, L'LENGTH); -- end "mod"; -- -- -- Id: A.36 -- function "mod" (L: NATURAL; R: UNSIGNED) return UNSIGNED is -- constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH); -- variable XL, XREM: UNSIGNED(L_LENGTH-1 downto 0); -- begin -- if (R'LENGTH < 1) then return NAU; -- end if; -- XL := TO_UNSIGNED(L, L_LENGTH); -- XREM := RESIZE((XL mod R), XREM'LENGTH); -- if L_LENGTH > R'LENGTH and XREM(0)/='X' -- and XREM(L_LENGTH-1 downto R'LENGTH) -- /= (L_LENGTH-1 downto R'LENGTH => '0') -- then -- assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, R'LENGTH); -- end "mod"; -- -- Id: A.37 -- function "mod" (L: SIGNED; R: INTEGER) return SIGNED is -- constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R)); -- variable XR, XREM: SIGNED(R_LENGTH-1 downto 0); -- begin -- if (L'LENGTH < 1) then return NAS; -- end if; -- XR := TO_SIGNED(R, R_LENGTH); -- XREM := RESIZE((L mod XR), XREM'LENGTH); -- if R_LENGTH > L'LENGTH and XREM(0)/='X' -- and XREM(R_LENGTH-1 downto L'LENGTH) -- /= (R_LENGTH-1 downto L'LENGTH => XREM(L'LENGTH-1)) -- then -- assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, L'LENGTH); -- end "mod"; -- -- Id: A.38 -- function "mod" (L: INTEGER; R: SIGNED) return SIGNED is -- constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH); -- variable XL, XREM: SIGNED(L_LENGTH-1 downto 0); -- begin -- if (R'LENGTH < 1) then return NAS; -- end if; -- XL := TO_SIGNED(L, L_LENGTH); -- XREM := RESIZE((XL mod R), XREM'LENGTH); -- if L_LENGTH > R'LENGTH and XREM(0)/='X' -- and XREM(L_LENGTH-1 downto R'LENGTH) -- /= (L_LENGTH-1 downto R'LENGTH => XREM(R'LENGTH-1)) -- then -- assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated" -- severity WARNING; -- end if; -- return RESIZE(XREM, R'LENGTH); -- end "mod"; --============================================================================ ------------------------------------------------------------------------------ -- Note : Function S.9 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- -- Id: S.9 function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is begin if (COUNT >= 0) then return SHIFT_LEFT(ARG, COUNT); else return SHIFT_RIGHT(ARG, -COUNT); end if; end "sll"; ------------------------------------------------------------------------------ -- Note : Function S.10 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- -- Id: S.10 function "sll" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is begin if (COUNT >= 0) then return SHIFT_LEFT(ARG, COUNT); else return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), -COUNT)); end if; end "sll"; ------------------------------------------------------------------------------ -- Note : Function S.11 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.11 function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is begin if (COUNT >= 0) then return SHIFT_RIGHT(ARG, COUNT); else return SHIFT_LEFT(ARG, -COUNT); end if; end "srl"; ------------------------------------------------------------------------------ -- Note : Function S.12 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.12 function "srl" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is begin if (COUNT >= 0) then return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT)); else return SHIFT_LEFT(ARG, -COUNT); end if; end "srl"; ------------------------------------------------------------------------------ -- Note : Function S.13 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.13 function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is begin if (COUNT >= 0) then return ROTATE_LEFT(ARG, COUNT); else return ROTATE_RIGHT(ARG, -COUNT); end if; end "rol"; ------------------------------------------------------------------------------ -- Note : Function S.14 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.14 function "rol" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is begin if (COUNT >= 0) then return ROTATE_LEFT(ARG, COUNT); else return ROTATE_RIGHT(ARG, -COUNT); end if; end "rol"; ------------------------------------------------------------------------------ -- Note : Function S.15 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.15 function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is begin if (COUNT >= 0) then return ROTATE_RIGHT(ARG, COUNT); else return ROTATE_LEFT(ARG, -COUNT); end if; end "ror"; ------------------------------------------------------------------------------ -- Note : Function S.16 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: S.16 function "ror" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is begin if (COUNT >= 0) then return ROTATE_RIGHT(ARG, COUNT); else return ROTATE_LEFT(ARG, -COUNT); end if; end "ror"; --============================================================================ ------------------------------------------------------------------------------ -- Note : Function L.7 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: L.7 function "xnor" (L, R: UNSIGNED) return UNSIGNED is constant length: INTEGER := L'length; variable result : UNSIGNED(0 to length-1); variable tempL : UNSIGNED(0 to length-1); variable tempR : UNSIGNED(0 to length-1); begin tempL := L; tempR := CONV_UNSIGNED(R, length); for i in 0 to length - 1 loop result(i) := (tempL(i) and tempR(i)) or ((not tempL(i)) and (not tempR(i))); end loop; return result; end; ------------------------------------------------------------------------------ -- Note : Function L.14 is not compatible with VHDL 1076-1987. Comment -- out the function (declaration and body) for VHDL 1076-1987 compatibility. ------------------------------------------------------------------------------ -- Id: L.14 function "xnor" (L, R: SIGNED) return SIGNED is constant length: INTEGER := L'length; variable result : SIGNED(0 to length-1); variable tempL : SIGNED(0 to length-1); variable tempR : SIGNED(0 to length-1); begin tempL := L; tempR := CONV_SIGNED(R, length); for i in 0 to length - 1 loop result(i) := (tempL(i) and tempR(i)) or ((not tempL(i)) and (not tempR(i))); end loop; return result; end; --============================================================================ -- support constants for STD_MATCH -- synopsys synthesis_off type BOOLEAN_TABLE is array(STD_ULOGIC, STD_ULOGIC) of BOOLEAN; constant MATCH_TABLE: BOOLEAN_TABLE := ( -------------------------------------------------------------------------- -- U X 0 1 Z W L H - -------------------------------------------------------------------------- (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | U | (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | X | (FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE), -- | 0 | (FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE), -- | 1 | (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | Z | (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | W | (FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE), -- | L | (FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE), -- | H | ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) -- | - | ); -- synopsys synthesis_on -- Id: M.1 function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN is -- pragma built_in SYN_X_EQL begin -- synopsys synthesis_off return MATCH_TABLE(L, R); -- synopsys synthesis_on end STD_MATCH; -- Id: M.2 function STD_MATCH (L, R: UNSIGNED) return BOOLEAN is -- pragma built_in SYN_X_EQL -- synopsys synthesis_off alias LV: UNSIGNED(1 to L'LENGTH) is L; alias RV: UNSIGNED(1 to R'LENGTH) is R; -- synopsys synthesis_on begin -- synopsys synthesis_off if ((L'LENGTH < 1) or (R'LENGTH < 1)) then assert false report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE" severity warning; return FALSE; end if; if LV'LENGTH /= RV'LENGTH then assert false report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE" severity warning; return FALSE; else for I in LV'LOW to LV'HIGH loop if not (MATCH_TABLE(LV(I), RV(I))) then return FALSE; end if; end loop; return TRUE; end if; -- synopsys synthesis_on end STD_MATCH; -- Id: M.3 function STD_MATCH (L, R: SIGNED) return BOOLEAN is -- pragma built_in SYN_X_EQL -- synopsys synthesis_off alias LV: SIGNED(1 to L'LENGTH) is L; alias RV: SIGNED(1 to R'LENGTH) is R; -- synopsys synthesis_on begin -- synopsys synthesis_off if ((L'LENGTH < 1) or (R'LENGTH < 1)) then assert false report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE" severity warning; return FALSE; end if; if LV'LENGTH /= RV'LENGTH then assert false report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE" severity warning; return FALSE; else for I in LV'LOW to LV'HIGH loop if not (MATCH_TABLE(LV(I), RV(I))) then return FALSE; end if; end loop; return TRUE; end if; -- synopsys synthesis_on end STD_MATCH; -- Id: M.4 function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN is -- pragma built_in SYN_X_EQL -- synopsys synthesis_off alias LV: STD_LOGIC_VECTOR(1 to L'LENGTH) is L; alias RV: STD_LOGIC_VECTOR(1 to R'LENGTH) is R; -- synopsys synthesis_on begin -- synopsys synthesis_off if ((L'LENGTH < 1) or (R'LENGTH < 1)) then assert false report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE" severity WARNING; return FALSE; end if; if LV'LENGTH /= RV'LENGTH then assert false report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE" severity WARNING; return FALSE; else for I in LV'LOW to LV'HIGH loop if not (MATCH_TABLE(LV(I), RV(I))) then return FALSE; end if; end loop; return TRUE; end if; -- synopsys synthesis_on end STD_MATCH; -- Id: M.5 function STD_MATCH (L, R: STD_ULOGIC_VECTOR) return BOOLEAN is -- pragma built_in SYN_X_EQL -- synopsys synthesis_off alias LV: STD_ULOGIC_VECTOR(1 to L'LENGTH) is L; alias RV: STD_ULOGIC_VECTOR(1 to R'LENGTH) is R; -- synopsys synthesis_on begin -- synopsys synthesis_off if ((L'LENGTH < 1) or (R'LENGTH < 1)) then assert false report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE" severity WARNING; return FALSE; end if; if LV'LENGTH /= RV'LENGTH then assert false report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE" severity WARNING; return FALSE; else for I in LV'LOW to LV'HIGH loop if not (MATCH_TABLE(LV(I), RV(I))) then return FALSE; end if; end loop; return TRUE; end if; -- synopsys synthesis_on end STD_MATCH; --============================================================================ -- 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). -- Id: T.1 function TO_01 (S: UNSIGNED ; XMAP: STD_LOGIC := '0') return UNSIGNED is constant length : INTEGER := S'LENGTH; variable RESULT: UNSIGNED(S'LENGTH-1 downto 0); begin for i in 0 to length - 1 loop if (S(i) = '0' or S(i) = '1' or S(i) = 'H' or S(i) = 'L') then RESULT(i) := S(i); else RESULT(i) := XMAP; end if; end loop; return RESULT; end TO_01; -- Id: T.2 function TO_01 (S: SIGNED ; XMAP: STD_LOGIC := '0') return SIGNED is constant length : INTEGER := S'LENGTH; variable RESULT: SIGNED(S'LENGTH-1 downto 0); begin for i in 0 to length - 1 loop if (S(i) = '0' or S(i) = '1' or S(i) = 'H' or S(i) = 'L') then RESULT(i) := S(i); else RESULT(i) := XMAP; end if; end loop; return RESULT; end TO_01; --============================================================================ end numeric_std;