An adder/subtractor is an arithmetic combinational logic circuit which can add/subtract two N-bit binary numbers and output their N-bit binary sum/difference, a carry/borrow status bit, and if needed an overflow status bit. If we choose to represent signed numbers using 2's complement, then we can build an adder/subtractor from a basic adder circuit, e.g. a ripple carry adder.

In the case of addition, the adder/subtractor would behave exactly as the basic adder circuit.
Subtraction, however, is different. Here the number to be subtracted is negated, i.e we make use of the algebraic rule `A-B = A+(-B)`

.
The negation of a number `B`

in 2's complement is `not(B)+1`

.
We can achieve this computation by giving the basic adder the numbers `A`

and `not(B)`

then setting the initial
carry input to the basic adder to be `1`

.

When adding, the carry output of the basic adder circuit is used directly. For subtraction, the borrow is the negation of the carry.

The detection of an overflow is the same for both addition and subtraction: an overflow has occurred if and only if the basic adder's two most significant carry outputs are different.

As an example imagine we have four full adders.
With these we can easily build a 4-bit ripple carry adder to calculate `A+B`

— we just link up the four half adders, the carry out of one becomes the carry in of another, and set the first carry in to `0`

.
Now, if we want to calculate `A+(-B)`

then we can use the same half adders if we invert the bits of `B`

and set the
first carry in to `1`

.
This would add `A`

and the 2's complement of `B`

giving us our subtraction.

To build our 4-bit adder/subtractor circuit using a 4-bit ripple carry adder we need,
along with the two input numbers to add/subtract (`A`

and `B`

), an input telling us if we are to perform an addition or subtraction operation which we can call `Op`

.
Now, if we look at the definition of the XOR gate we see that
`B xor 0 = B`

and
`B xor 1 = not(B)`

.
We can use this in our negation of `B`

if we set `Op`

to `0`

when adding and
to `1`

when subtracting.
This in conjunction with setting the initial carry input of the ripple carry adder to `Op`

gives us what we need.
The following table shows how this works:

`Op` |
`Operand 1` |
`Operand 2` |
`Initial carry` |
`Result` |
---|---|---|---|---|

`0` |
`A` |
`B` |
`0` |
`A+B` |

`1` |
`A` |
`not(B)` |
`1` |
`A-B` |

The carry/borrow status bit output can also make use of the XOR gate.
If `C`

is the carry output of the ripple carry adder, then we can set the carry/borrow output of
the adder/subtractor to be `C xor Op`

.
The overflow status bit output is handled easily, as it is `C3 xor C4`

when `C3`

and `C4`

are the respective
carry outputs of the third and fourth half adder respectively.

The following Verilog code shows a 4-bit adder/subtractor that uses the ripple carry method. The code for the full adder is also shown for completeness.

` ````
module ripple_carry_adder_subtractor(S, C, V, A, B, Op);
output [3:0] S; // The 4-bit sum/difference.
output C; // The 1-bit carry/borrow status.
output V; // The 1-bit overflow status.
input [3:0] A; // The 4-bit augend/minuend.
input [3:0] B; // The 4-bit addend/subtrahend.
input Op; // The operation: 0 => Add, 1=>Subtract.
wire C0; // The carry out bit of fa0, the carry in bit of fa1.
wire C1; // The carry out bit of fa1, the carry in bit of fa2.
wire C2; // The carry out bit of fa2, the carry in bit of fa3.
wire C3; // The carry out bit of fa2, used to generate final carry/borrrow.
wire B0; // The xor'd result of B[0] and Op
wire B1; // The xor'd result of B[1] and Op
wire B2; // The xor'd result of B[2] and Op
wire B3; // The xor'd result of B[3] and Op
// Looking at the truth table for xor we see that
// B xor 0 = B, and
// B xor 1 = not(B).
// So, if Op==1 means we are subtracting, then
// adding A and B xor Op alog with setting the first
// carry bit to Op, will give us a result of
// A+B when Op==0, and A+not(B)+1 when Op==1.
// Note that not(B)+1 is the 2's complement of B, so
// this gives us subtraction.
xor(B0, B[0], Op);
xor(B1, B[1], Op);
xor(B2, B[2], Op);
xor(B3, B[3], Op);
xor(C, C3, Op); // Carry = C3 for addition, Carry = not(C3) for subtraction.
xor(V, C3, C2); // If the two most significant carry output bits differ, then we have an overflow.
full_adder fa0(S[0], C0, A[0], B0, Op); // Least significant bit.
full_adder fa1(S[1], C1, A[1], B1, C0);
full_adder fa2(S[2], C2, A[2], B2, C1);
full_adder fa3(S[3], C3, A[3], B3, C2); // Most significant bit.
endmodule // ripple_carry_adder_subtractor
module full_adder(S, Cout, A, B, Cin);
output S;
output Cout;
input A;
input B;
input Cin;
wire w1;
wire w2;
wire w3;
wire w4;
xor(w1, A, B);
xor(S, Cin, w1);
and(w2, A, B);
and(w3, A, Cin);
and(w4, B, Cin);
or(Cout, w2, w3, w4);
endmodule // full_adder
```

When given test inputs, the 4-bit adder/subtractor generated the following waveform:

Mano, M. Morris, and Kime, Charles R. *Logic and Computer Design Fundamentals. 2nd Edition.* Prentice Hall, 2000.

Copyright © 2014 Barry Watson. All rights reserved.