FIGURE 6.7
Full Adder From Two Half Adders
FIGURE 6.8
Example 6.18
Full Adder
6.6 • Binary Adders and Subtractors 243
d. COUT _ (1 _ 1) _ 0 _ 1 _ 1
_ 0 _ 0 _ 1
_ 0 _ 1 _ 1
_ _ (1 _ 1) _ 0
_ 0 _ 0 _ 0 (Binary equivalent: COUT _ _ 10)
In each case, the binary equivalent is the same as the number of HIGH inputs, regardless
of which inputs they are.
❘❙❚ EXAMPLE 6.19 Combine a half adder and a full adder to make a circuit that will add two 2-bit numbers.
Check that the circuit will work by adding the following numbers and writing the binary
equivalents of the inputs and outputs:
a. A2 A1 _ 01, B2 B1 _ 01
b. A2 A1 _ 11, B2 B1 _ 10
SOLUTION The 2-bit adder is shown in Figure 6.9. The half adder combines A1 and B1;
A2, B2, and C1 are added in the full adder. The carry output, C1, of the half adder is connected
to the carry input of the full adder. (A half adder can be used only in the LSB of a
multiple-bit addition.)
FIGURE 6.9
Example 6.19
2-Bit Adder
Sums:
a. 01 _ 01 _ 010
A1 _ 1, B1 _ 1 C1 _ 1, _1 _ 0
A2 _ 0, B2 _ 0, C1 _ 1 C2 _ 0, _2 _ 1
(Binary equivalent: A2 A1 _ B2 B1 _ C2 _2 _1 _ 010)
b. 11 _ 10 _ 101
A1 _ 1, B1 _ 0 C1 _ 0, _1 _ 1
A2 _ 1, B2 _ 1, C1 _ 0 C2 _ 1, _2 _ 0
(Binary equivalent: A2 A1 _ B2 B1 _ C2 _2_1 _ 101) ❘❙❚
244 C H A P T E R 6 • Digital Arithmetic and Arithmetic Circuits
Parallel Binary Adder/Subtractor
Parallel binary adder A circuit, consisting of n full adders, that will add two
n-bit binary numbers. The output consists of n sum bits and a carry bit.
Ripple carry A method of passing carry bits from one stage of a parallel adder to
the next by connecting COUT of one full adder to CIN of the following stage.
Cascade To connect an output of one device to an input of another, often for the
purpose of expanding the number of bits available for a particular function.
As Example 6.19 implies, a binary adder can be expanded to any number of bits by using
a full adder for each bit addition and connecting their carry inputs and outputs in
cascade. Figure 6.10 shows four full adders connected as a 4-bit parallel binary
adder.
K E Y T E R M S
FIGURE 6.10
4-Bit Parallel Binary Adder
The first stage (LSB) can be either a full adder with its carry input forced to logic 0 or
a half adder, since there is no previous stage to provide a carry. The addition is done one bit
at a time, with the carry from each adder propagating to the next stage.
❘❙❚ EXAMPLE 6.20 Verify the summing operation of the circuit in Figure 6.10 by calculating the output for the
following sets of inputs:
a. A4 A3 A2 A1 _ 0101, B4 B3 B2 B1 _ 1001
b. A4 A3 A2 A1 _ 1111, B4 B3 B2 B1 _ 0001
SOLUTION At each stage, A _ B _ CIN _ COUT _.
a. 0101 _ 1001 _ 1110
(510 _ 910 _ 1410)
A1 _ 1, B1 _ 1, C0 _ 0; C1 _ 1, _1 _ 0
A2 _ 0, B2 _ 0, C1 _ 1; C2 _ 0, _2 _ 1
A3 _ 1, B3 _ 0, C2 _ 0; C3 _ 0, _3 _ 1
A4 _ 0, B4 _ 1, C3 _ 0; C4 _ 0, _4 _ 1
(Binary equivalent: C4 _4 _3 _2 _1 _ 01110)
www.electronictech.com
6.6 • Binary Adders and Subtractors 245
b. 1111 _ 0001 _ 10000
(1510 _ 110 _ 1610)
A1 _ 1, B1 _ 1, C0 _ 0; C1 _ 1, _1 _ 0
A2 _ 1, B2 _ 0, C1 _ 1; C2 _ 1, _2 _ 0
A3 _ 1, B3 _ 0, C2 _ 1; C3 _ 1, _3 _ 0
A4 _ 1, B4 _ 0, C3 _ 1; C4 _ 1, _4 _ 0
(Binary equivalent: C4 _4 _3 _2 _1 _ 10000)
❘❙❚
The internal carries in the parallel binary adder in Figure 6.10 are achieved by a system
called ripple carry. The carry output of one full adder cascades directly to the carry
input of the next. Every time a carry bit changes, it “ripples” through some or all of the following
stages. A sum is not complete until the carry from another stage has arrived. The
equivalent circuit of a 4-bit ripple carry is shown in Figure 6.11.
C0
C1
C2
C3
C4
A1 _ B1
A1B1
A2 _ B2
A2B2
A3 _ B3
A3B3
A4 _ B4 A4B4
FIGURE 6.11
4-bit Ripple Carry Chain
A potential problem with this design is that the adder circuitry does not switch instantaneously.
A carry propagating through a ripple adder adds delays to the summation time
and, more importantly, can introduce unwanted intermediate states.
Examine the sum (1111 _ 0001 _ 10000). For a parallel adder having a ripple carry,
the output goes through the following series of changes as the carry bit propagates through
the circuit:
C4 _4 _3 _2 _1 _ 01111
01110
01100
01000
10000
If the output of the full adder is being used to drive another circuit, these unwanted intermediate
states may cause erroneous operation of the load circuit.
Fast Carry
Fast carry (or look-ahead carry) A gate network that generates a carry bit directly
from all incoming operand bits, independent of the operation of each full
adder stage.
An alternative carry circuit is called fast carry or look-ahead carry. The idea behind fast
carry is that the circuit will examine all the A and B bits simultaneously and produce an
output carry that uses fewer levels of gating than a ripple carry circuit. Also, since there is
K E Y T E R M
246 C H A P T E R 6 • Digital Arithmetic and Arithmetic Circuits
INPUT
OUTPUT
a1
c1
c1
b1 INPUT
AND2
AND2
OR2
OR2
a2 INPUT
b2 INPUT
AND2
OR2
a3 INPUT
b3 INPUT
AND2
OR2
a4 INPUT
b4 INPUT
AND2
OR2
c0 INPUT
AND2 c2 OUTPUT c2
OR3
AND3
AND2
OR4
OR6
GND
VCC
AND3
AND4
c3 OUTPUT c3
AND2
AND3
AND4
AND6
c4 OUTPUT c4
FIGURE 6.12
4-bit Fast Carry Circuit
a carry bit gate network for each internal stage, the propagation delay is the same for each
full adder, regardless of the input operands.
The algebraic relation between operand bits and fast carry output is presented below,
without proof. It can be developed from the fast carry circuit of Figure 6.12 by tracing the
logic of the gates in the circuit.
C4 _ A4 B4 _ A3 B3 (A4 _ B4) _ A2 B2 (A4 _ B4)(A3 _ B3)
_ A1 B1 (A4 _ B4)(A3 _ B3)(A2 _ B2)
_ C0 (A4 _ B4)(A3 _ B3)(A2 _ B2)(A1 _ B1)
6.6 • Binary Adders and Subtractors 247
We can make some intuitive sense of the above expression by examining it a term at a
time. The first term says if the MSBs of both operands are 1, there will be a carry (e.g.,
1000 _ 1000 _ 10000; carry generated).
The second term says if both second bits are 1 AND at least one MSB is 1, there will
be a carry (e.g., 0100 _ 1100 _ 10000, or 1100 _ 1100 _ 11000; carry generated in either
case). This pattern can be followed logically through all the terms.
The internal carry bits are generated by similar circuits that drive the carry input of
each full adder stage in the parallel adder. In general, we can generate each internal carry
by expanding the following expression:
Cn _ AnBn _ Cn _ 1 (An _ Bn)
The algebraic expressions for the remaining carry bits are:
C1 _ A1B1 _ C0 (A1 _ B1)
C2 _ A2B2 _ A1 B1 (A2 _ B2) _ C0 (A2 _ B2)(A1 _ B1)
C3 _ A3B3 _ A2 B2 (A3 _ B3) _ A1 B1 (A3 _ B3)(A2 _ B2)
_ C0 (A3 _ B3)(A2 _ B2)(A1 _ B1)
❘❙❚ SECTION 6.6A REVIEW PROBLEM
6.9 Refer to the logic diagrams for the ripple carry and fast carry circuits (Figures 6.11 and
6.12). How many gates must a carry bit propagate through in each device if the effect
of the carry input ripples through to the _4 bit? (See Figure 6.32 on page 273 and Figure
6.33 on page 273.)
Using VHDL Components to Implement a Parallel Adder
Hierarchy A group of design entities associated in a series of levels or layers in
which complete designs form portions of another, more general design entity. The
more general design is considered to be the higher level of the hierarchy.
Component A complete VHDL design entity that can be used as a part of a
higher-level file in a hierarchical design.
Port An input or output of a VHDL design entity or component.
Component declaration statement A statement that defines the input and output
port names of a component used in a VHDL design entity.
Instantiate To use an instance of a component.
Component instantiation statement A statement that maps port names of a
VHDL component to the port names, internal signals, or variables of a higher-level
VHDL design entity.
VHDL designs can be created using a hierarchy of design entities. Certain functions, such
as full adders, decoders, and so on, can be created once and used in many designs or multiple
times in a single design.
We can create a parallel adder in VHDL by using multiple instances of a full adder
component in the top-level file of a VHDL design hierarchy. Figure 6.13 shows a graphical
illustration of this concept. Each full adder shown is an instance of a component written
in VHDL, as shown in the following.
—— full_add.vhd
—— Full adder: adds two bits, a and b, plus input carry
—— to yield sum bit and output carry.
K E Y T E R M S
➥ Full_add.vhd
248 C H A P T E R 6 • Digital Arithmetic and Arithmetic Circuits
ENTITY full_add IS
PORT (
a, b, c_in : IN BIT;
c_out, sum : OUT BIT);
END full_add;
ARCHITECTURE adder OF full_add IS
BEGIN
c_out __ ((a xor b) and c_in) or (a and b) ;
sum __ (a xor b) xor c_in;
END adder;
INPUT
FULL_ADD
a1
b1 INPUT
c0 INPUT
OUTPUT c1
OUTPUT sum1
a
b
c_out
sum
c_in
INPUT
FULL_ADD
a2
b2 INPUT
OUTPUT c2
OUTPUT sum2
a
b
c_out
sum
c_in
INPUT
FULL_ADD
a3
b3 INPUT
OUTPUT c3
OUTPUT sum3
a
b
c_out
sum
c_in
INPUT
FULL_ADD
a4
b4 INPUT
OUTPUT c4
OUTPUT sum4
a
b
c_out
sum
c_in
FIGURE 6.13
4-bit Parallel Adder with Ripple
Carry
We can create the same design as in Figure 6.13 using VHDL only. To make this hierarchical
design we require:
1. A separate component file for a full adder (full_add.vhd), saved in a folder where the
compiler can find it (i.e., on a library path)
2. A component declaration statement in the top-level file of the design hierarchy
3. A component instantiation statement for each instance of the full adder component
The general form of a design entity using components is:
ENTITY entity_name IS
PORT ( input and output definitions);
END entity_name;
ARCHITECTURE arch_name OF entity_name IS
component declaration(s);
signal declaration(s);
6.6 • Binary Adders and Subtractors 249
BEGIN
Component instantiation(s);
Other statements;
END arch_name;
The VHDL file for a 4-bit parallel adder using full adder components is shown next.
—— add4par.vhd
—— 4-bit parallel adder, using 4 instances
—— of the component full_add
ENTITY add4par IS
PORT(
c0 : IN BIT;
a, b : IN BIT_VECTOR (4 downto 1);
c4 : OUT BIT;
sum : OUT BIT_VECTOR (4 downto 1));
END add4par;
ARCHITECTURE adder OF add4par IS
—— Component declaration
COMPONENT full_add
PORT (
a, b, c_in : IN BIT;
c_out, sum : OUT BIT);
END COMPONENT;
—— Define a signal for internal carry bits
SIGNAL c : BIT_VECTOR (3 downto 1);
BEGIN
—— Four Component Instantiation Statements
adder1: full_add
PORT MAP ( a __ a(1),
b __ b(1),
c_in __ c0,
c_out __ c(1),
sum __ sum (1));
adder2: full_add
PORT MAP ( a __ a(2),
b __ b(2),
c_in __ c(1),
c_out __ c(2),
sum __ sum (2));
adder3: full_add
PORT MAP ( a __ a(3),
b __ b(3),
c_in __ c(2),
c_out __ c(3),
sum __ sum (3));
adder4: full_add
PORT MAP ( a __ a(4),
b __ b(4),
c_in __ c(3),
c_out __ c4,
sum __ sum (4));
END adder;
➥ add4par.vhd
250 C H A P T E R 6 • Digital Arithmetic and Arithmetic Circuits
The component declaration statement defines the ports of the component with the
same names as in the full_add.vhd. Note that the form of the component declaration statement
is almost the same as that of the component’s entity declaration. In effect, we are redefining
the component entity in the top-level file of the design hierarchy.
The component instantiation statement is of the following form:
__instance_name: __component_name
GENERIC MAP (__parameter_name __ __parameter_value ,
__parameter_name __ __parameter_value)
PORT MAP (__component_port __ __connect_port,
__component_port __ __connect_port);
In the generic map, a generalized parameter name can be mapped to a specific value
when the component is instantiated. For example, a parameter name can be given a value
that specifies the number of component output bits. We will not use this feature in our present
examples.
In the port map, component ports are the names of the ports used in the component file
and connect ports are the names of the ports, variables, or signals used in the higher-level
design entity. For example, the component ports of the full adder component are a, b, c
in, c_out, and sum. The connect ports for the instance adder1 are a(1), b(1), c0, c(1), and
sum(1). The ripple carry from adder1 to adder2 is achieved by mapping the port c_in of
adder2 to c(1), which is also mapped to the port c_out of adder1.
We can write the component instantiation statements more efficiently if we decide to
use all ports of the component in the order they are defined. In this case, we can simply list
the connect ports in the port map in the correct order, as follows:
adder1: full_add PORT MAP (a(1),b(1),c0, c(1),sum(1));
adder2: full_add PORT MAP (a(2),b(2),c(1),c(2),sum(2));
adder3: full_add PORT MAP (a(3),b(3),c(2),c(3),sum(3));
adder4: full_add PORT MAP (a(4),b(4),c(3),c4, sum(4));
If we only wish to use some of the component ports or use them in a different order
than the order in which theywere originally defined, we must use the previous form of port
map (i.e., a __ a(1), etc.).
GENERATE Statements
GENERATE statement A VHDL construct that is used to create repetitive portions
of hardware.
The four component instantiation statements shown previously can be written in a more
general form:
adder(i): full_add PORT MAP (a(i), b(i), c(i-1), c(i), sum(i));
A statement that can be written in this indexed form can be implemented using a
GENERATE statement, which has the form:
label:
FOR index IN range GENERATE
statements;
END GENERATE;
The VHDL code that follows shows how to use the statement to create a 4-bit adder.
—— add4gen.vhd
—— 4-bit parallel adder, using a generate statement
—— and components
K E Y T E R M
➥ add4gen.vhd
6.6 • Binary Adders and Subtractors 251
ENTITY add4gen IS
PORT (
c0 : IN BIT;
a, b : IN BIT_VECTOR (4 downto 1);
c4 : OUT BIT;
sum : OUT BIT_VECTOR (4 downto 1));
END add4gen;
ARCHITECTURE adder OF add4gen IS
——Component declaration
COMPONENT full_add
PORT (
a, b, c_in : IN BIT;
c_out, sum : OUT BIT);
END COMPONENT;
—— Define a signal for internal carry bits
SIGNAL c : BIT_VECTOR (4 downto 0);
BEGIN
c(0) __ c0;
adders:
FOR i IN 1 to 4 GENERATE
adder: full_add PORT MAP (a(i),b(i),c(i-1),c(i),sum(i));
END GENERATE;
c4 __ c(4);
END adder;
The GENERATE statement will create hardware that corresponds to the range of the
index variable, i. In this case i goes from 1 to 4, so the statement instantiates four instances
of the full adder. Since we have an input carry, an output carry and three internal carries,
we must use a 5-bit signal (BIT_VECTOR (4 downto 0)) if we are to include all carry
bits in indexed form. The input carry, c0, defined in the entity declaration, is assigned to the
vector element c(0). Similarly, the output, c4, is assigned the value of the element c(4).
It is easy to expand the adder width by changing the range of the FOR GENERATE
statement. For example, to make an 8-bit adder, we change the vectors to have a width of
eight bits. The required VHDL code, shown next, requires the same number of lines of
code as the 4-bit adder.
—— add8gen.vhd
—— 8-bit parallel adder, using a generate statement
—— and components
ENTITY add8gen IS
PORT (
C0 : IN BIT;
a, b : IN BIT_VECTOR (8 downto 1);
c8 : OUT BIT;
sum : OUT BIT_VECTOR (8 downto 1));
END add8gen;
ARCHITECTURE adder OF add8gen IS
—— Component declaration
COMPONENT full_add
PORT (
a, b, c_in : IN BIT;
c_out, sum : OUT BIT);
➥ add8gen.vhd
252 C H A P T E R 6 • Digital Arithmetic and Arithmetic Circuits
END COMPONENT;
—— Define a signal for internal carry bits
SIGNAL c : BIT_VECTOR (8 downto 0);
BEGIN
c(0) __ c0;
adders:
FOR i IN 1 to 8 GENERATE
adder: full_add PORT MAP (a(i), b(i), c(i-1), c(i),
sum(i));
END GENERATE;
c8 __ c(8);
END adder;
2’s Complement Subtractor
Recall the technique for subtracting binary numbers in 2’s complement notation. For example,
to find the difference 0101 _ 0011 by 2’s complement subtraction:
1. Find the 2’s complement of 0011:
0011
1100 (1’s complement)
_1
1101 (2’s complement)
2. Add the 2’s complement of the subtrahend to the minuend:
0101 (_5)
_ 1101 (_3)
1 0010 (_2)
(Discard carry)
We can easily build a circuit to perform 2’s complement subtraction, using a parallel
binary adder and an inverter for each bit of one of the operands. The circuit shown in Figure
6.14 performs the operation (A _ B).
FIGURE 6.14
2’s Complement Subtractor
The four inverters generate the 1’s complement of B. The parallel adder generates the
2’s complement by adding the carry bit (held at logic 1) to the 1’s complement at the B inputs.
Algebraically, this is expressed as:
A _ B _ A _ (_B) _ A _ B_ _ 1
where B_ is the 1’s complement of B, and (B_ _ 1) is the 2’s complement of B.
6.6 • Binary Adders and Subtractors 253
❘❙❚ EXAMPLE 6.21 Verify the operation of the 2’s complement subtractor in Figure 6.14 by subtracting:
a. 1001 _ 0011 (unsigned)
b. 0100 _ 0111 (signed)
SOLUTION Let B_ be the 1’s complement of B.
a. Inverter inputs (B): 0011
Inverter outputs (B_): 1100
Sum (A _ B_ _ 1): 1001 (_9)
1100 _ (_3)
_ 1
1 0110 (_6)
(Discard carry)
b. Inverter inputs (B): 0111
Inverter outputs (B_): 1000
Sum (A _ B_ _ 1): 0100 (_4)
1000 _ (_7)
_ 1
Negative result: 1101 (_3)
1’s complement of 1101: 0010
_ 1
2’s complement of 1101: 0011 (_3)
❘❙❚
Parallel Binary Adder/Subtractor
Figure 6.15 shows a parallel binary adder configured as a programmable adder/subtractor.
The Exclusive OR gates work as programmable inverters to pass B to the parallel adder in
either true or complement form, as shown in Figure 6.16.
←
FIGURE 6.15
2’s Complement Adder/Subtractor
254 C H A P T E R 6 • Digital Arithmetic and Arithmetic Circuits
The A_D_D_/SUB input is tied to the XOR inverter/buffers and to the carry input of the
parallel adder. When A_D_D_/SUB _ 1, B is complemented and the 1 from the carry input is
added to the complement sum. The effect is to subtract (A _ B). When A_D_D_/SUB _ 0, the
B inputs are presented to the adder in true form and the carry input is 0. This produces an
output equivalent to (A _ B).
This circuit can add or subtract 4-bit signed or unsigned binary numbers.
❘❙❚ EXAMPLE 6.22 Write a VHDL file to implement the 4-bit adder/subtractor shown in Figure 6.15. Also
create a simulation file to test a representative selection of addition and subtraction
operations.
Share with your friends: |