Standard VHDL Synthesis Package (1076.3,NUMERIC_BIT)
: an excerpt
Purpose : This package defines
numeric types and arithmetic functions for use with synthesis tools.
Two numeric types are defined:
: -- > UNSIGNED: represents an UNSIGNED number in vector form
: -- > SIGNED: represents a SIGNED number in vector form
The base element type is type BIT.
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,
clock detection functions, and other utility functions.
If any argument to a function is a null array, a null array is returned
(exceptions, if any, are noted individually).
-------------------------------------------------------------------------------
package NUMERIC_BIT is
constant CopyRightNotice: STRING
:= "Copyright 1995 IEEE. All rights reserved.";
--============================================================
-- Numeric array type definitions
--============================================================
type UNSIGNED is array (NATURAL range <> ) of BIT;
type SIGNED is array (NATURAL range <> ) of BIT;
--============================================================
-- Arithmetic Operators: overloaded "+" operators
--============================================================
-- 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.
..
end NUMERIC_BIT;
--===============================================================
--======================= Package Body ==========================
--===============================================================
package body NUMERIC_BIT 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 MAX;
function MIN (LEFT, RIGHT: INTEGER) return INTEGER is
begin
if LEFT < RIGHT then return LEFT;
else return RIGHT;
end if;
end MIN;
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 SIGNED_NUM_BITS;
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 UNSIGNED_NUM_BITS;
----------------------------------------------------------------------
-- 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: BIT) 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: BIT := 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: BIT) 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: BIT := 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;
..
--=========================================================
function "+" (L, R: UNSIGNED) return UNSIGNED is
constant L_LEFT: INTEGER := L'LENGTH-1;
constant R_LEFT: INTEGER := R'LENGTH-1;
constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
begin
if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
end if;
return ADD_UNSIGNED(RESIZE(L, SIZE), RESIZE(R, SIZE), '0');
end "+";
function "+" (L, R: SIGNED) return SIGNED is
constant L_LEFT: INTEGER := L'LENGTH-1;
constant R_LEFT: INTEGER := R'LENGTH-1;
constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
begin
if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
end if;
return ADD_SIGNED(RESIZE(L, SIZE), RESIZE(R, SIZE), '0');
end "+";
function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
begin
return L + TO_UNSIGNED(R, L'LENGTH);
end "+";
function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
begin
return TO_UNSIGNED(L, R'LENGTH) + R;
end "+";
function "+" (L: SIGNED; R: INTEGER) return SIGNED is
begin
return L + TO_SIGNED(R, L'LENGTH);
end "+";
function "+" (L: INTEGER; R: SIGNED) return SIGNED is
begin
return TO_SIGNED(L, R'LENGTH) + R;
end "+";
..