This package provides generic binary adders.
function add
(A, B : in std_ulogic_vector)
return std_ulogic_vector;
function add
(A, B : in std_ulogic_vector;
Ci : in std_ulogic)
return std_ulogic_vector;
calculate the modulo-n sum of two operands A and B (and, in the second version, a carry-input bit C). Both operands must have the same size.
The result type is std_ulogic_vector(A'length-1 downto 0).
procedure add
(A, B : in std_ulogic_vector;
Ci : in std_ulogic;
Y : out std_ulogic_vector;
Co : out std_ulogic);
calculates the modulo-n sum of A, B and Ci. Both operands and the result must have the same size. Co provides a carry-out bit.
procedure CSAdd
(A, B : in std_ulogic_vector;
Y, Z : out std_ulogic_vector;
G, P : out std_ulogic);
This is the main workhorse of the package. It calculates the modulo-2**n sum of A and B and returns the result in Y. The secondary output Z provides the sum incremented by 1 (also modulo 2**n). All vectors must have the same size n.
G and P can be used to generate a carry-out bit (or to chain several instances of the adder). The G bit is active whenever the adder generates a carry -- that is, when A + B >= 2**n. P indicates that a carry-in may propagate to the carry-out -- i.e. when A + B = 2**n - 1. A carry-out bit Co can be calculated as
Co := G or (P and Ci);
Note: Depending on the implementation, G and P may be active simultaneously; therefore it is an error to use the formula Co := G xor (P and Ci);.
procedure CIAdd
(A, B : in std_ulogic_vector;
Y, C : out std_ulogic_vector;
G, P : out std_ulogic);
Use of this function is deprecated; please use CSAdd instead.
CIAdd calculates the modulo-2**n sum of A and B and returns the result in Y. All vectors must have the same size n.
C is what I call an `increment vector': If you calculate Y xor C, the result will equal (A + B + 1) mod 2**n. That is, a carry-in bit Ci will be wired this way:
Real_Y := Y xor (C and (C'range => Ci));
G and P can be used to generate a carry-out bit (or to chain several instances of the adder). The G bit is active whenever the adder generates a carry -- that is, when A + B >= 2**n. P indicates that a carry-in may propagate to the carry-out -- i.e. when A + B = 2**n - 1. A carry-out bit Co can be calculated as
Co := G or (P and Ci);
Note: Depending on the implementation, G and P may be active simultaneously; therefore it is an error to use the formula Co := G xor (P and Ci);.
The rest of the package contains implementation details of the CSAdd and CIAdd procedures. It is subject to change, and therefore currently undocumented. Please refer to the source code for details.
In order to build a subtractor, you can exploit one of the formulae:
A - B = A + ¬B + 1
A - B = ¬(¬A + B)
An incrementer or decrementer is better built using functions from package work.Bit_Manipulation:
function incr (A : in std_ulogic_vector) return std_ulogic_vector is
begin
return A xor lshift(cascade_and(A), 1, '1');
end incr;
function decr (A : in std_ulogic_vector) return std_ulogic_vector is
begin
return not incr(not A);
end decr;
A negation can be done with Y := incr(not A);.
Wallace trees and other tree adders use rows of full adders. There is no procedure that implements a full adder, but its components are available: package work.Misc provides the xor3 and maj23 functions that calculate the Y and carry outputs, respectively.