Building Adders from Logic Gates
How can hardware carry out the binary addition procedure?
Signed and Unsigned Value
x = 0110
Unsigned value of x = 6.
Signed value of x = unsigned value of x = 6.
y = 1110
Unsigned value of y = 14.
Signed value of y = unsigned value of y - 2^4 = -2.
Next: connect this view with the flip-and-add-one view.
Equivalence of the Two Views
Consider an n-bit negative number x; that is, the MSB of x is 1. Let y be obtained by flipping all bits of x and adding 1. Then:
signed value of x = unsigned value of x - 2^n = -(unsigned value of y)
1 Let x be an n-bit negative number; that is, the MSB of x is 1.
1 For example, the 4-bit number x = 1110.
2 unsigned value of x + unsigned value of bitflip(x) = 2^n - 1.
2 1110 + 0001 = 1111. That is, 14 + 1 = 16 - 1 = 15.
3 unsigned value of bitflip(x) + 1 = 2^n - unsigned value of x.
3 1 + 1 = 2^4 - 14.
4 - (unsigned value of bitflip(x) + 1) = unsigned value of x - 2^n = signed value of x.
4 -2 = 14 - 2^4.
The proof is complete.
Next: use this to explain signed addition.
Why Unsigned Addition Works for Negative Numbers Too
1 Consider two n-bit negative numbers x and y. That is, the MSB of both numbers is 1.
1 x = 1110, y = 1011.
2 signed value(x) = unsigned value(x) - 2^n.
signed value(y) = unsigned value(y) - 2^n.
2 signed value(x) = -2 = 14 - 16.
signed value(y) = -5 = 11 - 16.
3 signed value(x) + signed value(y) = unsigned value(x) + unsigned value(y) - 2^n - 2^n.
3 signed value(x) + signed value(y) = -2 + -5 = -7.
4 n-bit unsigned value(x+y) + 2^n = unsigned value(x) + unsigned value(y).
So, n-bit unsigned value(x+y) = unsigned value(x) + unsigned value(y) - 2^n.
4 The 4-bit result of x+y is 1001.1001 + 2^4 = 1110 + 1011, after discarding the carry outside 4 bits.
5 From the previous two lines, signed value(x) + signed value(y) = n-bit unsigned value(x+y) - 2^n.
5 signed value(x) + signed value(y) = unsigned value(1001) - 2^4 = 9 - 16 = -7.
Hence, the n-bit number x+y represents the correct signed result, provided the result is within range.
Prove the same result when x is negative and y is positive.
What Must an Adder Remember?
At each position, hardware receives two operand bits.
From the second position onward, it may also receive a carry from the previous position.
We therefore need chips that can add two bits and three bits.Next: Build a hierarchy of increasingly capable adders.
Four Chips, Built One upon Another
For every chip, separate its specification—what it must do—from its implementation—how it is built.
Adding Two Bits
A HalfAdder adds two one-bit inputs. The two-bit result is separated into its least significant bit, sum, and most significant bit, carry.
- Chip name:
- HalfAdder
- Inputs:
a, b- Outputs:
sum, carry- Function:
sumis the LSB andcarryis the MSB ofa+b.
| a | b | carry | sum |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 0 |
Implement the HalfAdder
Use only And, Or, and Not gates. Compare the output columns with Boolean functions you already know, but expand any Xor you recognize.
Write Boolean expressions for sum(a,b) and carry(a,b).
Draw the gate diagram using only And, Or, and Not.
Write the PARTS section of HalfAdder.hdl.
Expressionssum = (a OR b) AND NOT(a AND b)carry = a AND b
PARTS:
Or(a=a, b=b, out=either);
And(a=a, b=b, out=both);
Not(in=both, out=notBoth);
And(a=either, b=notBoth, out=sum);
And(a=a, b=b, out=carry);Adding Three Bits
A FullAdder adds two operand bits and a third bit c, normally the carry from the previous position.
- Chip name:
- FullAdder
- Inputs:
a, b, c- Outputs:
sum, carry- Function:
sumis the LSB andcarryis the MSB ofa+b+c.
| a | b | c | carry | sum |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 1 | 0 | 0 | 1 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | 1 |
Build a FullAdder from HalfAdders
First use two HalfAdders and one additional basic gate. Draw the circuit and name every internal wire. Then expand the HalfAdders to obtain a circuit containing only And, Or, and Not gates.
Add a and b.
Add the first sum to c.
When should the final carry be 1?
PARTS:
HalfAdder(a=a, b=b, sum=s1, carry=c1);
HalfAdder(a=s1, b=c, sum=sum, carry=c2);
Or(a=c1, b=c2, out=carry);And/Or/Not form:sum = (!a&!b&c) | (!a&b&!c) | (a&!b&!c) | (a&b&c)carry = (a&b) | (a&c) | (b&c)
Implement each three-input AND by cascading two And gates.
From One Position to a Sixteen-Bit Adder
Each carry output becomes the next position's carry input. This design is called a ripple-carry adder.
The carry out of the MSB is discarded. Add16 neither detects nor handles overflow.
Sixteen-Bit Adder Specification
- Chip name:
- Add16
- Inputs:
a[16], b[16]- Outputs:
out[16]- Function:
out = a+busing 16-bit two's-complement addition.- Overflow:
- Neither detected nor handled.
| a | b | out | Meaning |
|---|---|---|---|
| 0000...0011 | 0000...0101 | 0000...1000 | 3+5=8 |
| 1111...1110 | 0000...0011 | 0000...0001 | −2+3=1 |
| 1111...1111 | 0000...0001 | 0000...0000 | −1+1=0 |
A complete table would require 232 input rows; the specification defines all of them compactly.
Plan the Add16 Implementation
Which chip should process bit 0? Why does it not need a carry input?
How many FullAdders are required for bits 1 through 15?
Name a consistent sequence of internal carry wires.
Sketch the first three and final two HDL part declarations.
Use one HalfAdder for bit 0 and fifteen FullAdders for bits 1–15. Connect carry0 to the next chip's c input, then carry1, and so on. The final carry has no output pin and may be left unconnected.
Incrementing a Sixteen-Bit Value
An incrementer is a special-purpose adder that adds the constant 1.
- Chip name:
- Inc16
- Inputs:
in[16]- Outputs:
out[16]- Function:
out = in+1using 16-bit two's-complement addition.- Overflow:
- Neither detected nor handled.
| in | out | Meaning |
|---|---|---|
| 0000...0000 | 0000...0001 | 0 becomes 1 |
| 0000...0111 | 0000...1000 | 7 becomes 8 |
| 1111...1111 | 0000...0000 | −1 becomes 0 |
A complete table has 216 rows. These rows illustrate the single rule out=in+1.
Two Ways to Build Inc16
What constant should be connected to Add16's second input?
Starting at the LSB, when must a carry continue to the next bit?
Write HDL for Design A. Then compare the number and type of subchips used by the two designs.
PARTS:
Add16(a=in, b[0]=true, b[1..15]=false, out=out);In the Nand2Tetris HDL, constants may be connected directly to bus subranges.
One Chip, Many Operations
An Arithmetic Logic Unit (ALU) is the processor component that performs arithmetic and logical operations on data.
Instead of constructing a separate external chip for every operation, an ALU contains shared hardware and uses control bits to decide what that hardware does.
The Hack ALU Interface
x[16]→y[16]→zxnxzynyfnoout[16]For now, focus on the two 16-bit inputs, the six control bits, and the 16-bit output. We will add the two status outputs zr and ng in Lecture 7.
Next: Follow the six transformations that make one ALU compute many functions.
From Bit Addition to an Arithmetic Unit
Adds two bits.
Adds two bits and a carry.
Propagates carry across sixteen positions.
Adds the constant one.
Small chips with precise contracts become building blocks for larger chips. The ALU will combine these arithmetic chips with the logic gates built earlier.
Lecture 7: Arithmetic Logic Unit (ALU)
One chip for every operation.