-- ---------------------------------------------------------------------------- -- Title : NUMERIC_STD arithmetic package for synthesis -- : Rev. 1.7 (Nov. 23 1994) -- : -- Library : This package shall be compiled into a library symbolically -- : named IEEE. -- : -- Developers : IEEE DASC Synthesis Working Group, PAR 1076.3 -- : -- Purpose : This package defines numeric types and arithmetic functions -- : for use with synthesis tools. Two numeric types are defined: -- : --> UNSIGNED : represents UNSIGNED number in vector form -- : --> SIGNED : represents a SIGNED number in vector form -- : The base element type is type STD_LOGIC. -- : The leftmost bit is treated as the most significant bit. -- : Signed 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). -- : -- Note : No declarations or definitions shall be included in, or -- : excluded from, this package. The package declaration declares -- : the functions that can be used by a user. The package body -- : shall be considered the formal definition of the semantics of -- : this package. Tool developers may choose to implement the -- : package body in the most efficient manner available to them. -- : -- ---------------------------------------------------------------------------- library ieee; use ieee.STD_LOGIC_1164.all; Package numeric_std is --=========================================================================== -- Numeric array type definitions --=========================================================================== type UNSIGNED is array ( NATURAL range <> ) of STD_LOGIC; type SIGNED is array ( NATURAL range <> ) of STD_LOGIC; --=========================================================================== -- Arithmetic Operators: --=========================================================================== -- Id: A.1 function "abs" ( X : SIGNED) return SIGNED; -- Result subtype: SIGNED(X'LENGTH-1 downto 0). -- Result: Returns the absolute value of a SIGNED vector X. -- 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, then R 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, then L 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, then R 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, then L is truncated to R'LENGTH. --============================================================================ -- -- NOTE: If second argument is zero for "rem" operator, a severity level -- of ERROR is issued. -- Id: A.27 function "rem" (L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED(L'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(L'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, then R 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, then L 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, then R 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, then L is truncated to R'LENGTH. --============================================================================ -- -- NOTE: If second argument is zero for "mod" operator, a severity level -- of ERROR is issued. -- Id: A.33 function "mod" (L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED(L'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(L'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, then R 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, then L 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, then R 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, then L 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 Bit '0'. -- The COUNT leftmost bits 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 Bit '0'. -- The COUNT rightmost bits 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. -- All bits of ARG, except ARG'LEFT, are shifted left COUNT times. -- The vacated positions are filled with Bit '0'. -- The COUNT leftmost bits, except ARG'LEFT, are lost. -- Id: S.4 function shift_right ( 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 bit,ARG'LEFT. -- The COUNT rightmost bits 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. --============================================================================ -- RESIZE Functions --============================================================================ -- Id: R.1 function RESIZE ( ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED; -- Result subtype: SIGNED(ARG'LENGTH-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(ARG'LENGTH-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. -- Id: D.5 function TO_UNSIGNED ( ARG: STD_LOGIC_VECTOR) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input ARG -- Result: Converts STD_LOGIC_VECTOR to UNSIGNED. -- Id: D.6 function TO_SIGNED ( ARG: STD_LOGIC_VECTOR) return SIGNED; -- Result subtype: SIGNED, same range as input ARG -- Result: Converts STD_LOGIC_VECTOR to SIGNED. -- Id: D.7 function TO_STDLOGICVECTOR ( ARG: UNSIGNED) return STD_LOGIC_VECTOR; -- Result subtype: STD_LOGIC_VECTOR, same range as input ARG -- Result: Converts UNSIGNED to STD_LOGIC_VECTOR. -- Id: D.8 function TO_STDLOGICVECTOR ( ARG: SIGNED) return STD_LOGIC_VECTOR; -- Result subtype: STD_LOGIC_VECTOR, same range as input ARG -- Result: Converts SIGNED to STD_LOGIC_VECTOR. --============================================================================ -- Logical Operators --============================================================================ -- Id: L.1 function "not" ( L: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input L -- Result: Termwise inversion -- Id: L.2 function "and" ( L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input L -- Result: Vector AND operation -- Id: L.3 function "or" ( L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input L -- Result: Vector OR operation -- Id: L.4 function "nand" ( L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input L -- Result: Vector NAND operation -- Id: L.5 function "nor" ( L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input L -- Result: Vector NOR operation -- Id: L.6 function "xor" ( L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input L -- Result: Vector XOR operation -- ----------------------------------------------------------------------- -- Note : The declaration and implementation of the "xnor" function is -- specifically commented until at which time the VHDL language has been -- officially adopted as containing such a function. At such a point, -- the following comments may be removed along with this notice without -- further "official" ballotting of this 1076.3 package. It is -- the intent of this effort to provide such a function once it becomes -- available in the VHDL standard. -- ----------------------------------------------------------------------- -- Id: L.7 -- function "xnor" ( L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input L -- Result: Vector XNOR operation -- Id: L.8 function "not" ( L: SIGNED) return SIGNED; -- Result subtype: SIGNED, same range as input L -- Result: Termwise inversion -- Id: L.9 function "and" ( L,R: SIGNED ) return SIGNED; -- Result subtype: SIGNED, same range as input L -- Result: Vector AND operation -- Id: L.10 function "or" ( L,R: SIGNED ) return SIGNED; -- Result subtype: SIGNED, same range as input L -- Result: Vector OR operation -- Id: L.11 function "nand" ( L,R: SIGNED ) return SIGNED; -- Result subtype: SIGNED, same range as input L -- Result: Vector NAND operation -- Id: L.12 function "nor" ( L,R: SIGNED ) return SIGNED; -- Result subtype: SIGNED, same range as input L -- Result: Vector NOR operation -- Id: L.13 function "xor" ( L,R: SIGNED ) return SIGNED; -- Result subtype: SIGNED, same range as input L -- Result: Vector XOR operation -- ----------------------------------------------------------------------- -- Note : The declaration and implementation of the "xnor" function is -- specifically commented until at which time the VHDL language has been -- officially adopted as containing such a function. At such a point, -- the following comments may be removed along with this notice without -- further "official" ballotting of this 1076.3 package. It is -- the intent of this effort to provide such a function once it becomes -- available in the VHDL standard. -- ----------------------------------------------------------------------- -- Id: L.14 -- function "xnor" ( L,R: SIGNED ) return SIGNED; -- Result subtype: SIGNED, same range as input L -- Result: Vector XNOR operation --============================================================================ -- Match Functions --============================================================================ -- Id: M.1 function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN; -- Result: terms compared per STD_LOGIC_1164 intent -- Id: M.2 function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN; -- Result: termwise comparison per STD_LOGIC_1164 intent end numeric_std; --============================================================================= --======================= Package Body =============================== --============================================================================= Package body numeric_std is -- null range array constants constant NAU : UNSIGNED (0 downto 1) := (others => '0'); constant NAS : SIGNED (0 downto 1) := (others => '0'); -- implementation controls constant NO_WARNING : boolean := FALSE; -- default to emit warnings --=========================Local Subprograms================================= function MAX(LEFT, RIGHT: INTEGER) return INTEGER is begin if LEFT > RIGHT then return LEFT; else return RIGHT; end if; end; function MIN(LEFT, RIGHT: INTEGER) return INTEGER is begin if LEFT < RIGHT then return LEFT; else return RIGHT; end if; end; function Signed_NUM_BITS ( ARG: INTEGER) return natural is variable nBits: natural; variable N: natural; begin if ARG>=0 then N:=ARG; else N:=-(ARG+1); end if; nBits:=1; while N>0 loop nBits:=nBits+1; N:= N / 2; end loop; return nBits; end; function UNSIGNED_NUM_BITS (ARG: natural) return natural is variable nBits: natural; variable N: natural; begin N:=ARG; nBits:=1; while N>1 loop nBits:=nBits+1; N:= N / 2; end loop; return nBits; end; ------------------------------------------------------------------------ -- this internal function computes the addition of two UNSIGNED -- with input CARRY -- * the two arguments are of the same length function ADD_UNSIGNED ( L,R: UNSIGNED; C: STD_LOGIC ) return UNSIGNED is constant L_left:INTEGER:= L'length-1; alias XL: UNSIGNED(L_left downto 0) is L; alias XR: UNSIGNED(L_left downto 0) is R; variable RESULT: UNSIGNED(L_left downto 0); variable CBIT : STD_LOGIC:= C; begin for i in 0 to L_left loop RESULT(i) := CBIT xor XL(i) xor XR(i); CBIT := (CBIT and XL(i)) or (CBIT and XR(i)) or (XL(i) and XR(i)); end loop; return RESULT; end ADD_UNSIGNED; -- this internal function computes the addition of two SIGNED -- with input CARRY -- * the two arguments are of the same length function ADD_SIGNED ( L,R: SIGNED; C: STD_LOGIC ) return SIGNED is constant L_left:INTEGER:= L'length-1; alias XL: SIGNED(L_left downto 0) is L; alias XR: SIGNED(L_left downto 0) is R; variable RESULT: SIGNED(L_left downto 0); variable CBIT: STD_LOGIC:= C; begin for i in 0 to L_left loop RESULT(i) := CBIT xor XL(i) xor XR(i); CBIT := (CBIT and XL(i)) or (CBIT and XR(i)) or (XL(i) and XR(i)); end loop; return RESULT; end ADD_SIGNED; ------------------------------------------------------------------------ -- this internal procedure computes UNSIGNED division -- giving the quotient and remainder. procedure divMod (num, XDENOM: UNSIGNED; xquot, xremain: out UNSIGNED) is variable TEMP: UNSIGNED(num'length-1 downto 0); variable quot: UNSIGNED(MAX(num'length,XDENOM'length)-1 downto 0); variable diff: UNSIGNED(XDENOM'length downto 0); alias DENOM : UNSIGNED (XDENOM'length-1 downto 0) is XDENOM; variable CARRY: STD_LOGIC; variable TOPBIT: natural; variable isZero: boolean; begin isZero:=TRUE; for j in XDENOM'range loop CARRY:=DENOM(j); if CARRY/='0' then isZero:=FALSE; end if; end loop; assert not isZero report "DIV,MOD,or REM by zero" severity error; TEMP:=num; quot:= (others =>'0'); TOPBIT:=0; for j in DENOM'range loop if DENOM(j)='1' then TOPBIT:=j; exit; end if; end loop; CARRY:='0'; for j in num'length-(TOPBIT+1) downto 0 loop -- lexical ordering works okay for this comparison, no overloaded -- function is needed. if CARRY&TEMP(TOPBIT+j downto j) >= "0"&DENOM(TOPBIT downto 0) then diff(TOPBIT+1 downto 0) := (CARRY&TEMP(TOPBIT+j downto j)) -("0"&DENOM(TOPBIT downto 0)); assert diff(TOPBIT+1)='0' report "internal error in the division algorithm" severity error; CARRY:=diff(TOPBIT); if TOPBIT+j+1<=TEMP'left then TEMP(TOPBIT+j+1):='0'; end if; TEMP(TOPBIT+j downto j):=diff(TOPBIT downto 0); quot(j):='1'; else assert CARRY='0' report "internal error in the division algorithm" severity error; CARRY:=TEMP(TOPBIT+j); end if; end loop; xquot:=quot(num'length-1 downto 0); xremain:=TEMP(num'length-1 downto 0); end divMod; -----------------Local Subprograms - shift/rotate ops------------------------- function XSLL(ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR is constant ARG_L:INTEGER:= ARG'length-1; alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG; variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := (others=>'0'); begin if COUNT <= ARG_L then RESULT(ARG_L downto COUNT):=XARG(ARG_L-COUNT downto 0); end if; return RESULT; end; function XSRL(ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR is constant ARG_L:INTEGER:= ARG'length-1; alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG; variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := (others=>'0'); begin if COUNT <= ARG_L then RESULT(ARG_L-COUNT downto 0):=XARG(ARG_L downto COUNT); end if; return RESULT; end; function XSRA(ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR is constant ARG_L:INTEGER:= ARG'length-1; alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG; variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0); variable XCOUNT: natural := COUNT; begin if ((ARG'length <= 1) or (xCOUNT = 0)) then return ARG; else if (XCOUNT > ARG_L) then xCOUNT:= ARG_L; end if; RESULT(ARG_L-XCOUNT downto 0):=XARG(ARG_L downto XCOUNT); RESULT(ARG_L downto (ARG_L - XCOUNT + 1)) := (others=>XARG(ARG_L)); end if; return RESULT; end; function XROL(ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR is constant ARG_L:INTEGER:= ARG'length-1; alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG; variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := XARG; variable COUNTM: INTEGER; begin COUNTM:= COUNT mod (ARG_L + 1); if COUNTM /= 0 then RESULT(ARG_L downto COUNTM):=XARG(ARG_L-COUNTM downto 0); RESULT(COUNTM-1 downto 0):=XARG(ARG_L downto ARG_L-COUNTM+1); end if; return RESULT; end; function XROR(ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR is constant ARG_L:INTEGER:= ARG'length-1; alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG; variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := XARG; variable COUNTM: INTEGER; begin COUNTM:= COUNT mod (ARG_L + 1); if COUNTM /= 0 then RESULT(ARG_L-COUNTM downto 0):=XARG(ARG_L downto COUNTM); RESULT(ARG_L downto ARG_L-COUNTM+1):=XARG(COUNTM-1 downto 0); end if; return RESULT; end; -----------------Local Subprograms - Relational ops-------------------------- -- -- General "=" for UNSIGNED vectors, same length -- function UNSIGNED_equal ( L,R: UNSIGNED) return BOOLEAN is begin return STD_LOGIC_VECTOR (L) = STD_LOGIC_VECTOR (R) ; end; -- -- General "=" for SIGNED vectors, same length -- function SIGNED_equal ( L,R: SIGNED) return BOOLEAN is begin return STD_LOGIC_VECTOR (L) = STD_LOGIC_VECTOR (R) ; end; -- -- General "<" for UNSIGNED vectors, same length -- function UNSIGNED_LESS ( L,R: UNSIGNED) return BOOLEAN is begin return STD_LOGIC_VECTOR (L) < STD_LOGIC_VECTOR (R) ; end UNSIGNED_LESS ; -- -- General "<" function for SIGNED vectors, same length -- function SIGNED_LESS ( L,R: SIGNED) return BOOLEAN is variable intern_l : SIGNED (0 to L'LENGTH-1); variable intern_r : SIGNED (0 to R'LENGTH-1); begin intern_l:=l; intern_r:=r; intern_l(0):=not intern_l(0); intern_r(0):=not intern_r(0); return STD_LOGIC_VECTOR (intern_L) < STD_LOGIC_VECTOR (intern_R) ; end; -- -- General "<=" function for UNSIGNED vectors, same length -- function UNSIGNED_LESS_OR_EQUAL ( L,R: UNSIGNED) return BOOLEAN is begin return STD_LOGIC_VECTOR (L) <= STD_LOGIC_VECTOR (R) ; end; -- -- General "<=" function for SIGNED vectors, same length -- function SIGNED_LESS_OR_EQUAL ( L,R: SIGNED) return BOOLEAN is -- Need aliasses to assure index direction variable intern_l : SIGNED (0 to L'LENGTH-1); variable intern_r : SIGNED (0 to R'LENGTH-1); begin intern_l:=l; intern_r:=r; intern_l(0):=not intern_l(0); intern_r(0):=not intern_r(0); return STD_LOGIC_VECTOR (intern_L) <= STD_LOGIC_VECTOR (intern_R) ; end; -- function TO_01 is used to convert vectors to the -- correct form for exported functions, -- and to report if there is an element which -- is not in (0,1,h,l). -- Assume the vector is normalized and non-null. -- The function is duplicated for SIGNED and UNSIGNED types. function TO_01(S : SIGNED ; xmap : STD_LOGIC:= '0') return SIGNED is variable RESULT: SIGNED(S'length-1 downto 0); variable bad_element : boolean := FALSE; alias xs : SIGNED(s'length-1 downto 0) is S; begin for i in RESULT'range loop case xs(i) is when '0' | 'L' => RESULT(i):='0'; when '1' | 'H' => RESULT(i):='1'; when others => bad_element := TRUE; end case; end loop; if bad_element then assert NO_WARNING report "numeric_std.TO_01: Array Element not in {0,1,H,L}" severity warning; for i in RESULT'range loop RESULT(i) := xmap; -- standard fixup end loop; end if; return RESULT; end TO_01; function TO_01(S : UNSIGNED ; xmap : STD_LOGIC:= '0') return UNSIGNED is variable RESULT: UNSIGNED(S'length-1 downto 0); variable bad_element : boolean := FALSE; alias xs : UNSIGNED(S'length-1 downto 0) is S; begin for i in RESULT'range loop case xs(i) is when '0' | 'L' => RESULT(i):='0'; when '1' | 'H' => RESULT(i):='1'; when others => bad_element := TRUE; end case; end loop; if bad_element then assert NO_WARNING report "numeric_std.TO_01: Array Element not in {0,1,H,L}" severity warning; for i in RESULT'range loop RESULT(i) := xmap; -- standard fixup end loop; end if; return RESULT; end TO_01; --=========================Exported Functions================================= -- Id: A.1 function "abs" ( X : SIGNED) return SIGNED is constant ARG_LEFT:INTEGER:= X'length-1; alias XX : SIGNED(ARG_LEFT downto 0) is X; variable RESULT: SIGNED (ARG_LEFT downto 0); begin if X'length<1 then return NAS; end if; RESULT:=TO_01(xx,'X'); if (RESULT(RESULT'left)='X') then return RESULT; end if; if RESULT(RESULT'left) = '1' then RESULT:= -RESULT; end if; return RESULT; end; -- "abs" -- Id: A.2 function "-" ( ARG: SIGNED) return SIGNED is constant ARG_LEFT:INTEGER:= ARG'length-1; alias XARG: SIGNED(ARG_LEFT downto 0) is ARG; variable RESULT,XARG01 : SIGNED(ARG_LEFT downto 0); variable CBIT : STD_LOGIC:= '1'; begin if ARG'length<1 then return NAS; end if; XARG01 := TO_01(ARG,'X'); if (XARG01(XARG01'left)='X') then return XARG01; end if; for i in 0 to RESULT'left loop RESULT(i) := not(XARG01(i)) xor CBIT; CBIT := CBIT and not(XARG01(i)); end loop; return RESULT; end; -- "-" --============================================================================= -- Id: A.3 function "+" ( L,R: UNSIGNED ) return UNSIGNED is constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : UNSIGNED(SIZE-1 downto 0); variable R01 : UNSIGNED(SIZE-1 downto 0); begin if ((L'length<1) or (R'length<1)) then return NAU; end if; L01 := TO_01(RESIZE(L,SIZE),'X'); if (L01(L01'left)='X') then return L01; end if; R01 := TO_01(RESIZE(R,SIZE),'X'); if (R01(R01'left)='X') then return R01; end if; return ADD_UNSIGNED (L01, R01, '0') ; end; -- Id: A.4 function "+" ( L,R: SIGNED ) return SIGNED is constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : SIGNED(SIZE-1 downto 0); variable R01 : SIGNED(SIZE-1 downto 0); begin if ((L'length<1) or (R'length<1)) then return NAS; end if; L01 := TO_01(RESIZE(L,SIZE),'X'); if (L01(L01'left)='X') then return L01; end if; R01 := TO_01(RESIZE(R,SIZE),'X'); if (R01(R01'left)='X') then return R01; end if; return ADD_SIGNED (L01, R01, '0') ; end; -- Id: A.5 function "+" ( L: UNSIGNED; R: NATURAL) return UNSIGNED is begin return L + TO_UNSIGNED( R , L'length); end; -- Id: A.6 function "+" ( L: NATURAL; R: UNSIGNED) return UNSIGNED is begin return TO_UNSIGNED( L , R'length) + R; end; -- Id: A.7 function "+" ( L: SIGNED; R: INTEGER) return SIGNED is begin return L + TO_SIGNED( R , L'length); end; -- Id: A.8 function "+" ( L: INTEGER; R: SIGNED) return SIGNED is begin return TO_SIGNED( L , R'length) + R; end; --============================================================================= -- Id: A.9 function "-" ( L,R: UNSIGNED) return UNSIGNED is constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : UNSIGNED(SIZE-1 downto 0); variable R01 : UNSIGNED(SIZE-1 downto 0); begin if ((L'length<1) or (R'length<1)) then return NAU; end if; L01 := TO_01(RESIZE(L,SIZE),'X'); if (L01(L01'left)='X') then return L01; end if; R01 := TO_01(RESIZE(R,SIZE),'X'); if (R01(R01'left)='X') then return R01; end if; return ADD_UNSIGNED (L01,not(R01),'1'); end; -- Id: A.10 function "-" ( L,R: SIGNED) return SIGNED is constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : SIGNED(SIZE-1 downto 0); variable R01 : SIGNED(SIZE-1 downto 0); begin if ((L'length<1) or (R'length<1)) then return NAS; end if; L01 := TO_01(RESIZE(L,SIZE),'X'); if (L01(L01'left)='X') then return L01; end if; R01 := TO_01(RESIZE(R,SIZE),'X'); if (R01(R01'left)='X') then return R01; end if; return ADD_SIGNED (L01,not(R01),'1'); end; -- Id: A.11 function "-" ( L: UNSIGNED; R: NATURAL) return UNSIGNED is begin return L - TO_UNSIGNED( R , L'length); end; -- Id: A.12 function "-" ( L: NATURAL; R: UNSIGNED) return UNSIGNED is begin return TO_UNSIGNED( L , R'length) - R; end; -- Id: A.13 function "-" ( L: SIGNED; R: INTEGER) return SIGNED is begin return L - TO_SIGNED( R , L'length); end; -- Id: A.14 function "-" ( L: INTEGER; R: SIGNED) return SIGNED is begin return TO_SIGNED( L , R'length) - R ; end; --============================================================================= -- Id: A.15 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 RESULT: UNSIGNED((L'length+R'length-1) downto 0) :=(others=>'0'); variable adval : UNSIGNED((L'length+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 RESULT:= (others=>'X'); return RESULT; end if; adval := RESIZE(xr,RESULT'length); for i in 0 to L_left loop if xl(i)='1' then RESULT:= RESULT + adval; end if; adval := shift_left(adval,1); end loop; return RESULT; end; -- Id: A.16 function "*" ( 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 RESULT: SIGNED((L'length+R'length-1) downto 0) :=(others=>'0'); variable adval : SIGNED((L'length+R'length-1) downto 0); variable invt : STD_LOGIC:= '0'; begin if ((L'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 RESULT:= (others=>'X'); return RESULT; end if; adval := RESIZE(xr,RESULT'length); if xl(xl'left)='1' then adval := -(adval); invt := '1'; end if; for i in 0 to L_left loop if (invt xor xl(i))='1' then RESULT:= RESULT + adval; end if; adval := shift_left(adval,1); end loop; return RESULT; end; -- Id: A.17 function "*" ( L: UNSIGNED; R: NATURAL) return UNSIGNED is begin return L * TO_UNSIGNED( R , L'length); end; -- Id: A.18 function "*" ( L: NATURAL; R: UNSIGNED) return UNSIGNED is begin return TO_UNSIGNED( L , R'length) * R; end; -- Id: A.19 function "*" ( L: SIGNED; R: INTEGER) return SIGNED is begin return L * TO_SIGNED( R , L'length); end; -- Id: A.20 function "*" ( L: INTEGER; R: SIGNED) return SIGNED is begin return TO_SIGNED( L , R'length) * R ; end; --============================================================================= -- 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,fremain : UNSIGNED(L'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,fremain : UNSIGNED(L'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 XR := TO_UNSIGNED(R, R_Length); Quot := L / XR; if R_Length>L'Length and Quot(0)/='X' and Quot(R_Length-1 downto L'Length)/=(R_Length-1 downto L'Length => '0') then ASSERT no_warning report "Numeric_std.""/"": Quotient Truncated" severity warning; end if; return Quot(L'Length-1 downto 0); 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 XL := TO_UNSIGNED(L,L_LENGTH); QUOT := XL / R; 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 Quot(R'Length-1 downto 0); 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 XR := TO_SIGNED(R, R_Length); Quot := L / XR; if R_Length>L'Length and Quot(0)/='X' and Quot(R_Length-1 downto L'Length) /= (R_Length-1 downto L'Length => Quot(L'Length-1)) then ASSERT no_warning report "Numeric_std.""/"": Quotient Truncated" severity warning; end if; return Quot(L'Length-1 downto 0); 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 XL := TO_SIGNED(L,L_LENGTH); QUOT := XL / R; 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 Quot(R'Length-1 downto 0); 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,fremain : UNSIGNED(l'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; -- 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,fremain : UNSIGNED(l'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(xnum'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; -- 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 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 XRem(L'Length-1 downto 0); end; -- 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 XRem(R'Length-1 downto 0); end; -- 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 XR := TO_SIGNED(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 => XRem(L'Length-1)) then ASSERT no_warning report "Numeric_std.""rem"": Remainder Truncated" severity warning; end if; return XRem(L'Length-1 downto 0); end; -- 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 XL := TO_SIGNED(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 => XRem(R'Length-1)) then ASSERT no_warning report "Numeric_std.""rem"": Remainder Truncated" severity warning; end if; return XRem(R'Length-1 downto 0); end; --============================================================================= -- 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,fremain : UNSIGNED(l'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; -- 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,fremain : UNSIGNED(l'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 then fremain:=fremain-XDENOM; elsif l(l'left)='1' then fremain:=XDENOM-fremain; end if; return SIGNED(fremain); end; -- 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 XR := TO_UNSIGNED(R, R_Length); XRem := L mod 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.""mod"": Modulus Truncated" severity warning; end if; return XRem(L'Length-1 downto 0); end; -- 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 XL := TO_UNSIGNED(L, L_Length); XRem := XL mod 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.""mod"": Modulus Truncated" severity warning; end if; return XRem(R'Length-1 downto 0); end; -- 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 XR := TO_SIGNED(R, R_Length); XRem := L mod XR; 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 XRem(L'Length-1 downto 0); end; -- 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 XL := TO_SIGNED(L, L_Length); XRem := XL mod R; 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 XRem(R'Length-1 downto 0); end; --============================================================================= -- Id: C.1 function ">" ( L,R: UNSIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: UNSIGNED(L_left downto 0) is L; alias XR: UNSIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : UNSIGNED(L_left downto 0); variable R01 : UNSIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return not UNSIGNED_LESS_OR_EQUAL (RESIZE(L01,SIZE), RESIZE(R01,SIZE)) ; end ">" ; -- Id: C.2 function ">" ( L,R: SIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: SIGNED(L_left downto 0) is L; alias XR: SIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : SIGNED(L_left downto 0); variable R01 : SIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return not SIGNED_LESS_OR_EQUAL (RESIZE(L01,SIZE), RESIZE(R01,SIZE)) ; end ">" ; -- Id: C.3 function ">" ( L: NATURAL; R: UNSIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: UNSIGNED(R_left downto 0) is R; variable R01 : UNSIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(l)>R'length then return TRUE; end if; return not UNSIGNED_LESS_OR_EQUAL (TO_UNSIGNED (L,R01'LENGTH), R01) ; end ">" ; -- Id: C.4 function ">" ( L: INTEGER; R: SIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: SIGNED(R_left downto 0) is R; variable R01 : SIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if Signed_NUM_BITS(l)>R'length then return L>0; end if; return not SIGNED_LESS_OR_EQUAL (TO_SIGNED(L,R01'LENGTH), R01) ; end ">" ; -- Id: C.5 function ">" ( L: UNSIGNED; R: NATURAL) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: UNSIGNED(L_left downto 0) is L; variable L01 : UNSIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL,'X'); if (L01(L01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(R)>L'length then return FALSE; end if; return not UNSIGNED_LESS_OR_EQUAL (L01, TO_UNSIGNED (R,L01'LENGTH)) ; end ">" ; -- Id: C.6 function ">" ( L: SIGNED; R: INTEGER) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: SIGNED(L_left downto 0) is L; variable L01 : SIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL,'X'); if (L01(L01'left)='X') then return FALSE; end if; if Signed_NUM_BITS(R)>L'length then return 0>R; end if; return not SIGNED_LESS_OR_EQUAL (L01, TO_SIGNED(R,L01'LENGTH)) ; end ">" ; --============================================================================= -- Id: C.7 function "<" ( L,R: UNSIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: UNSIGNED(L_left downto 0) is L; alias XR: UNSIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : UNSIGNED(L_left downto 0); variable R01 : UNSIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return UNSIGNED_LESS (RESIZE(L01,SIZE), RESIZE(R01,SIZE)) ; end "<" ; -- Id: C.8 function "<" ( L,R: SIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: SIGNED(L_left downto 0) is L; alias XR: SIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : SIGNED(L_left downto 0); variable R01 : SIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return SIGNED_LESS (RESIZE(L01,SIZE), RESIZE(R01,SIZE)) ; end "<" ; -- Id: C.9 function "<" ( L: NATURAL; R: UNSIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: UNSIGNED(R_left downto 0) is R; variable R01 : UNSIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(L)>R'length then return L<0; end if; return UNSIGNED_LESS (TO_UNSIGNED(L,R01'LENGTH), R01) ; end "<" ; -- Id: C.10 function "<" ( L: INTEGER; R: SIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: SIGNED(R_left downto 0) is R; variable R01 : SIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if Signed_NUM_BITS(L)>R'length then return L<0; end if; return SIGNED_LESS (TO_SIGNED(L,R01'LENGTH), R01) ; end "<" ; -- Id: C.11 function "<" ( L: UNSIGNED; R: NATURAL) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: UNSIGNED(L_left downto 0) is L; variable L01 : UNSIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL,'X'); if (L01(L01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(R)>L'length then return 0L'length then return 0=" ( L,R: UNSIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: UNSIGNED(L_left downto 0) is L; alias XR: UNSIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : UNSIGNED(L_left downto 0); variable R01 : UNSIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return not UNSIGNED_LESS (RESIZE(L01,SIZE), RESIZE(R01,SIZE)) ; end ">=" ; -- Id: C.20 function ">=" ( L,R: SIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: SIGNED(L_left downto 0) is L; alias XR: SIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : SIGNED(L_left downto 0); variable R01 : SIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return not SIGNED_LESS (RESIZE(L01,SIZE), RESIZE(R01,SIZE)) ; end ">=" ; -- Id: C.21 function ">=" ( L: NATURAL; R: UNSIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: UNSIGNED(R_left downto 0) is R; variable R01 : UNSIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(L)>R'length then return L>0; end if; return not UNSIGNED_LESS (TO_UNSIGNED(L,R01'LENGTH), R01) ; end ">=" ; -- Id: C.22 function ">=" ( L: INTEGER; R: SIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: SIGNED(R_left downto 0) is R; variable R01 : SIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if Signed_NUM_BITS(L)>R'length then return L>0; end if; return not SIGNED_LESS (TO_SIGNED (L,R01'LENGTH), R01) ; end ">=" ; -- Id: C.23 function ">=" ( L: UNSIGNED; R: NATURAL) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: UNSIGNED(L_left downto 0) is L; variable L01 : UNSIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL,'X'); if (L01(L01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(R)>L'length then return 0>R; end if; return not UNSIGNED_LESS(L01, TO_UNSIGNED(R,L01'LENGTH)) ; end ">=" ; -- Id: C.24 function ">=" ( L: SIGNED; R: INTEGER) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: SIGNED(L_left downto 0) is L; variable L01 : SIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL,'X'); if (L01(L01'left)='X') then return FALSE; end if; if Signed_NUM_BITS(R)>L'length then return 0>R; end if; return not SIGNED_LESS (L01, TO_SIGNED(R,L01'LENGTH)) ; end ">=" ; --============================================================================= -- Id: C.25 function "=" ( L,R: UNSIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: UNSIGNED(L_left downto 0) is L; alias XR: UNSIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : UNSIGNED(L_left downto 0); variable R01 : UNSIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return UNSIGNED_equal (RESIZE(L01,SIZE),RESIZE(R01,SIZE)) ; end "=" ; -- Id: C.26 function "=" ( L,R: SIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: SIGNED(L_left downto 0) is L; alias XR: SIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : SIGNED(L_left downto 0); variable R01 : SIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL,'X'); R01 := TO_01(XR,'X'); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return FALSE; end if; return SIGNED_equal (RESIZE(L01,SIZE), RESIZE(R01,SIZE)) ; end "=" ; -- Id: C.27 function "=" ( L: NATURAL; R: UNSIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: UNSIGNED(R_left downto 0) is R; variable R01 : UNSIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(L)>R'Length then return FALSE; end if; return UNSIGNED_equal ( TO_UNSIGNED(L,R01'LENGTH), R01); end "=" ; -- Id: C.28 function "=" ( L: INTEGER; R: SIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: SIGNED(R_left downto 0) is R; variable R01 : SIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR,'X'); if (R01(R01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(L)>R'Length then return FALSE; end if; return SIGNED_equal ( TO_SIGNED(L,R01'LENGTH), R01) ; end "=" ; -- Id: C.29 function "=" ( L: UNSIGNED; R: NATURAL) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: UNSIGNED(L_left downto 0) is L; variable L01 : UNSIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL,'X'); if (L01(L01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(R)>L'length then return FALSE; end if; return UNSIGNED_equal (L01, TO_UNSIGNED (R,L01'LENGTH)) ; end "=" ; -- Id: C.30 function "=" ( L: SIGNED; R: INTEGER) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: SIGNED(L_left downto 0) is L; variable L01 : SIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL,'X'); if (L01(L01'left)='X') then return FALSE; end if; if UNSIGNED_NUM_BITS(R)>L'length then return FALSE; end if; return SIGNED_equal (L01, TO_SIGNED (R,L01'LENGTH)) ; end "=" ; --============================================================================= -- Id: C.31 function "/=" ( L,R: UNSIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: UNSIGNED(L_left downto 0) is L; alias XR: UNSIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : UNSIGNED(L_left downto 0); variable R01 : UNSIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL); R01 := TO_01(XR); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return TRUE; end if; return not(UNSIGNED_equal (RESIZE(L01,SIZE),RESIZE(R01,SIZE))) ; end "/=" ; -- Id: C.32 function "/=" ( L,R: SIGNED) return BOOLEAN is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; alias XL: SIGNED(L_left downto 0) is L; alias XR: SIGNED(R_left downto 0) is R; constant SIZE: NATURAL:= MAX (L'LENGTH, R'LENGTH) ; variable L01 : SIGNED(L_left downto 0); variable R01 : SIGNED(R_left downto 0); begin if ((L'length<1) or (R'length<1)) then return FALSE; end if; L01 := TO_01(XL); R01 := TO_01(XR); if ((L01(L01'left)='X') or (R01(R01'left)='X')) then return TRUE; end if; return not(SIGNED_equal (RESIZE(L01,SIZE), RESIZE(R01,SIZE))) ; end "/=" ; -- Id: C.33 function "/=" ( L: NATURAL; R: UNSIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: UNSIGNED(R_left downto 0) is R; variable R01 : UNSIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR); if (R01(R01'left)='X') then return TRUE; end if; if UNSIGNED_NUM_BITS(L)>R'Length then return TRUE; end if; return not(UNSIGNED_equal ( TO_UNSIGNED(L,R01'LENGTH), R01)); end "/=" ; -- Id: C.34 function "/=" ( L: INTEGER; R: SIGNED) return BOOLEAN is constant R_left:INTEGER:= R'length-1; alias XR: SIGNED(R_left downto 0) is R; variable R01 : SIGNED(R_left downto 0); begin if (R'length<1) then return FALSE; end if; R01 := TO_01(XR); if (R01(R01'left)='X') then return TRUE; end if; if Signed_NUM_BITS(L)>R'Length then return TRUE; end if; return not(SIGNED_equal ( TO_SIGNED(L,R01'LENGTH), R01)) ; end "/=" ; -- Id: C.35 function "/=" ( L: UNSIGNED; R: NATURAL) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: UNSIGNED(L_left downto 0) is L; variable L01 : UNSIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL); if (L01(L01'left)='X') then return TRUE; end if; if UNSIGNED_NUM_BITS(R)>L'Length then return TRUE; end if; return not(UNSIGNED_equal (L01, TO_UNSIGNED (R,L01'LENGTH))) ; end "/=" ; -- Id: C.36 function "/=" ( L: SIGNED; R: INTEGER) return BOOLEAN is constant L_left:INTEGER:= L'length-1; alias XL: SIGNED(L_left downto 0) is L; variable L01 : SIGNED(L_left downto 0); begin if (L'length<1) then return FALSE; end if; L01 := TO_01(XL); if (L01(L01'left)='X') then return TRUE; end if; if Signed_NUM_BITS(R)>L'Length then return TRUE; end if; return not(SIGNED_equal (L01, TO_SIGNED (R,L01'LENGTH))) ; end "/=" ; --============================================================================= -- Id: S.1 function shift_left(ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is begin if (ARG'length<1) then return NAU; end if; return UNSIGNED(XSLL(STD_LOGIC_VECTOR(ARG),COUNT)); end; -- Id: S.2 function shift_right(ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is begin if (ARG'length<1) then return NAU; end if; return UNSIGNED(XSRL(STD_LOGIC_VECTOR(ARG),COUNT)); end; -- Id: S.3 function shift_left(ARG: SIGNED; COUNT: NATURAL) return SIGNED is begin if (ARG'length<1) then return NAS; end if; return SIGNED(XSLL(STD_LOGIC_VECTOR(ARG),COUNT)); end; -- Id: S.4 function shift_right(ARG: SIGNED; COUNT: NATURAL) return SIGNED is begin if (ARG'length<1) then return NAS; end if; return SIGNED(XSRA(STD_LOGIC_VECTOR(ARG),COUNT)); end; --============================================================================= -- Id: S.5 function rotate_left(ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is begin if (ARG'length<1) then return NAU; end if; return UNSIGNED(XROL(STD_LOGIC_VECTOR(ARG),COUNT)); end; -- Id: S.6 function rotate_right(ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is begin if (ARG'length<1) then return NAU; end if; return UNSIGNED(XROR(STD_LOGIC_VECTOR(ARG),COUNT)); end; -- Id: S.7 function rotate_left(ARG: SIGNED; COUNT: NATURAL) return SIGNED is begin if (ARG'length<1) then return NAS; end if; return SIGNED(XROL(STD_LOGIC_VECTOR(ARG),COUNT)); end; -- Id: S.8 function rotate_right(ARG: SIGNED; COUNT: NATURAL) return SIGNED is begin if (ARG'length<1) then return NAS; end if; return SIGNED(XROR(STD_LOGIC_VECTOR(ARG),COUNT)); end; --============================================================================= -- Id: D.1 function TO_INTEGER(ARG: UNSIGNED) return NATURAL is constant ARG_LEFT:INTEGER:= ARG'length-1; alias XXARG:UNSIGNED(ARG_LEFT downto 0) is ARG; variable XARG:UNSIGNED(ARG_LEFT downto 0); variable RESULT: NATURAL:= 0; variable w : INTEGER:= 1; -- weight factor begin if (ARG'length<1) then assert NO_WARNING report "numeric_std.TO_INTEGER: null arg" severity warning; return 0; end if; XARG:= TO_01(XXARG); if (XARG(XARG'left)='X') then assert NO_WARNING report "numeric_std.TO_INTEGER: metavalue arg set to 0" severity warning; return 0; end if; for i in XARG'reverse_range loop if XARG (i) = '1' then RESULT:= RESULT + w; end if; if (i /= XARG'left) then w := w + w; end if; end loop; return RESULT; end TO_INTEGER; -- Id: D.2 function TO_INTEGER(ARG: SIGNED) return INTEGER is begin if ARG(ARG'left) = '0' then return TO_INTEGER( UNSIGNED (ARG)) ; else return (- (TO_INTEGER( UNSIGNED ( - (ARG + 1)))) -1); end if; end TO_INTEGER; -- Id: D.3 function TO_UNSIGNED(ARG,SIZE: NATURAL) return UNSIGNED is variable RESULT: UNSIGNED (SIZE-1 downto 0) ; variable i_val:natural := ARG; begin if (SIZE < 1) then return NAU; end if; for i in 0 to RESULT'left loop if (i_val MOD 2) = 0 then RESULT(i) := '0'; else RESULT(i) := '1' ; end if; i_val := i_val/2 ; end loop; if not(i_val=0) then assert NO_WARNING report "numeric_std.TO_UNSIGNED : vector truncated" severity WARNING ; end if; return RESULT ; end TO_UNSIGNED; -- Id: D.4 function TO_SIGNED(ARG: INTEGER; SIZE: NATURAL) return SIGNED is variable RESULT: SIGNED (SIZE-1 downto 0) ; variable b_val : STD_LOGIC:= '0' ; variable i_val : INTEGER:= ARG ; begin if (SIZE < 1) then return NAS; end if; if (ARG<0) then b_val := '1' ; i_val := -(ARG+1) ; end if ; for i in 0 to RESULT'left loop if (i_val MOD 2) = 0 then RESULT(i) := b_val; else RESULT(i) := not b_val ; end if; i_val := i_val/2 ; end loop; if ((i_val/=0) or (b_val/=RESULT(RESULT'left))) then assert NO_WARNING report "numeric_std.TO_SIGNED : vector truncated" severity WARNING ; end if; return RESULT; end TO_SIGNED; -- Id: D.5 function TO_UNSIGNED(ARG: STD_LOGIC_VECTOR) return UNSIGNED is begin return UNSIGNED(ARG); end TO_UNSIGNED; -- Id: D.6 function TO_SIGNED(ARG: STD_LOGIC_VECTOR) return SIGNED is begin return SIGNED(ARG); end TO_SIGNED; -- Id: D.7 function TO_STDLOGICVECTOR(ARG: UNSIGNED) return STD_LOGIC_VECTOR is begin return STD_LOGIC_VECTOR(ARG); end TO_STDLOGICVECTOR; -- Id: D.8 function TO_STDLOGICVECTOR(ARG: SIGNED) return STD_LOGIC_VECTOR is begin return STD_LOGIC_VECTOR(ARG); end TO_STDLOGICVECTOR; --============================================================================= -- Id: R.1 function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED is alias invec : SIGNED (ARG'length-1 downto 0) is ARG ; variable RESULT: SIGNED (NEW_SIZE-1 downto 0) ; constant bound : NATURAL:= MIN(ARG'length,RESULT'length)-2 ; begin if (NEW_SIZE<1) then return NAS; end if; RESULT:= (others=>ARG(ARG'left)) ; if bound >= 0 then RESULT(bound downto 0) := invec(bound downto 0) ; end if; return RESULT; end RESIZE ; -- Id: R.2 function RESIZE ( ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED is constant ARG_LEFT:INTEGER:= ARG'length-1; alias XARG: UNSIGNED(ARG_LEFT downto 0) is ARG; variable RESULT: UNSIGNED(NEW_SIZE-1 downto 0) := (others=>'0'); begin if (NEW_SIZE<1) then return NAU; end if; if XARG'length=0 then return RESULT; end if; if (RESULT'length < ARG'length) then RESULT(RESULT'left downto 0) := XARG(RESULT'left downto 0); else RESULT(RESULT'left downto XARG'left+1) := (others => '0'); RESULT(XARG'left downto 0) := XARG; end if; return RESULT; end RESIZE; --============================================================================ -- Id: L.1 function "not" ( L: UNSIGNED) return UNSIGNED is variable RESULT: UNSIGNED (L'range); begin RESULT:= UNSIGNED(not(STD_LOGIC_VECTOR(L))); return RESULT; end "not"; -- Id: L.2 function "and" ( L,R: UNSIGNED ) return UNSIGNED is variable RESULT: UNSIGNED (L'range); begin RESULT:= UNSIGNED(STD_LOGIC_VECTOR(L) and STD_LOGIC_VECTOR(R)); return RESULT; end "and"; -- Id: L.3 function "or" ( L,R: UNSIGNED ) return UNSIGNED is variable RESULT: UNSIGNED (L'range); begin RESULT:= UNSIGNED(STD_LOGIC_VECTOR(L) or STD_LOGIC_VECTOR(R)); return RESULT; end "or"; -- Id: L.4 function "nand" ( L,R: UNSIGNED ) return UNSIGNED is variable RESULT: UNSIGNED (L'range); begin RESULT:= UNSIGNED(STD_LOGIC_VECTOR(L) nand STD_LOGIC_VECTOR(R)); return RESULT; end "nand"; -- Id: L.5 function "nor" ( L,R: UNSIGNED ) return UNSIGNED is variable RESULT: UNSIGNED (L'range); begin RESULT:= UNSIGNED(STD_LOGIC_VECTOR(L) nor STD_LOGIC_VECTOR(R)); return RESULT; end "nor"; -- Id: L.6 function "xor" ( L,R: UNSIGNED ) return UNSIGNED is variable RESULT: UNSIGNED (L'range); begin RESULT:= UNSIGNED(STD_LOGIC_VECTOR(L) xor STD_LOGIC_VECTOR(R)); return RESULT; end "xor"; -- ----------------------------------------------------------------------- -- Note : The declaration and implementation of the "xnor" function is -- specifically commented until at which time the VHDL language has been -- officially adopted as containing such a function. At such a point, -- the following comments may be removed along with this notice without -- further "official" ballotting of this 1076.3 package. It is -- the intent of this effort to provide such a function once it becomes -- available in the VHDL standard. -- ----------------------------------------------------------------------- -- Id: L.7 --function "xnor" ( L,R: UNSIGNED ) return UNSIGNED is --variable RESULT: UNSIGNED (L'range); --begin -- RESULT:= UNSIGNED(STD_LOGIC_VECTOR(L) xnor STD_LOGIC_VECTOR(R)); -- return RESULT; -- end "xnor"; -- Id: L.8 function "not" ( L: SIGNED) return SIGNED is variable RESULT: SIGNED (L'range); begin RESULT:= SIGNED(not(STD_LOGIC_VECTOR(L))); return RESULT; end "not"; -- Id: L.9 function "and" ( L,R: SIGNED ) return SIGNED is variable RESULT: SIGNED (L'range); begin RESULT:= SIGNED(STD_LOGIC_VECTOR(L) and STD_LOGIC_VECTOR(R)); return RESULT; end "and"; -- Id: L.10 function "or" ( L,R: SIGNED ) return SIGNED is variable RESULT: SIGNED (L'range); begin RESULT:= SIGNED(STD_LOGIC_VECTOR(L) or STD_LOGIC_VECTOR(R)); return RESULT; end "or"; -- Id: L.11 function "nand" ( L,R: SIGNED ) return SIGNED is variable RESULT: SIGNED (L'range); begin RESULT:= SIGNED(STD_LOGIC_VECTOR(L) nand STD_LOGIC_VECTOR(R)); return RESULT; end "nand"; -- Id: L.12 function "nor" ( L,R: SIGNED ) return SIGNED is variable RESULT: SIGNED (L'range); begin RESULT:= SIGNED(STD_LOGIC_VECTOR(L) nor STD_LOGIC_VECTOR(R)); return RESULT; end "nor"; -- Id: L.13 function "xor" ( L,R: SIGNED ) return SIGNED is variable RESULT: SIGNED (L'range); begin RESULT:= SIGNED(STD_LOGIC_VECTOR(L) xor STD_LOGIC_VECTOR(R)); return RESULT; end "xor"; -- ----------------------------------------------------------------------- -- Note : The declaration and implementation of the "xnor" function is -- specifically commented until at which time the VHDL language has been -- officially adopted as containing such a function. At such a point, -- the following comments may be removed along with this notice without -- further "official" ballotting of this 1076.3 package. It is -- the intent of this effort to provide such a function once it becomes -- available in the VHDL standard. -- ----------------------------------------------------------------------- -- Id: L.14 --function "xnor" ( L,R: SIGNED ) return SIGNED is --variable RESULT: SIGNED (L'range); --begin -- RESULT:= SIGNED(STD_LOGIC_VECTOR(L) xnor STD_LOGIC_VECTOR(R)); -- return RESULT; -- end "xnor"; --============================================================================= -- support constants for STD_MATCH: type STDULOGIC_TABLE is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC; -- truth table for "and" function constant AND_TABLE : STDULOGIC_TABLE := ( -- ---------------------------------------------------- -- | U X 0 1 Z W L H - | | -- ---------------------------------------------------- ( 'U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U' ), -- | U | ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | X | ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | 0 | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 1 | ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | Z | ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | W | ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | L | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | H | ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ) -- | - | ); -- truth table for STD_MATCH function constant MATCH_TABLE : STDULOGIC_TABLE := ( -- ---------------------------------------------------- -- | U X 0 1 Z W L H - | | -- ---------------------------------------------------- ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '1' ), -- | U | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1' ), -- | X | ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', '1' ), -- | 0 | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', '1' ), -- | 1 | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1' ), -- | Z | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1' ), -- | W | ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', '1' ), -- | L | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', '1' ), -- | H | ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ) -- | - | ); -- Id: M.1 function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN is variable VALUE : STD_ULOGIC; begin VALUE := MATCH_TABLE(L, R); return VALUE = '1'; end STD_MATCH; -- Id: M.2 function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN is alias LV: STD_LOGIC_VECTOR ( 1 to L'LENGTH ) is L; alias RV: STD_LOGIC_VECTOR ( 1 to R'LENGTH ) is R; variable VALUE: STD_ULOGIC:= '1'; begin -- Check that both input vectors are the same length. if LV'LENGTH /= RV'LENGTH then assert NO_WARNING report "STD_MATCH input arguments are not of equal length" severity warning; return FALSE; else for i in LV'LOW to LV'HIGH loop VALUE := AND_TABLE(MATCH_TABLE(LV(i), RV(i)), VALUE); end loop; return VALUE = '1'; end if; end STD_MATCH; --============================================================================= end numeric_std;