Foundationsaddercarryhalf adderfull addercritical path

Building an Adder: Where Arithmetic Comes From

XOR gives you the sum bit, AND gives you the carry, and that is a half adder. Chain them and you can add any width — but the carry has to travel through every stage in turn, and that dependency is the reason adder design is a real engineering problem.

Follow the mechanism

Software view, hardware view

The gap between what you wrote and what the machine does is where this whole domain lives.

The question
How does arithmetic emerge from logic gates, and what limits how fast an addition can be?
What you wrote
Addition is a primitive. The `+` operator maps to an instruction, the instruction takes a cycle, and there is nothing underneath worth thinking about.
What the hardware does
A network of gates. Each bit position computes its sum from two operand bits and an incoming carry, and produces a carry for the next position. The naive arrangement makes position N wait for position N−1, so the delay grows with width unless the design does something cleverer.
It is the concrete demonstration that arithmetic is built rather than given, and it introduces the dependency-chain problem in its simplest form. The carry chain is the same shape of constraint as a data hazard in a pipeline or a pointer chase in memory: each step needs the previous one's result, so nothing can be overlapped.
SourceCompilerInstructionsFront EndExecutionRegistersCachesMemoryI/OBehavior

The half adder is two gates

Add two single bits and there are four cases. 0+0 is 0. 0+1 and 1+0 are 1. 1+1 is 2, which does not fit in one bit — it is 0 with a carry of 1. Write out the two output columns and they are recognisable immediately: the sum column is exactly XOR, and the carry column is exactly AND.

So a half adder is one XOR and one AND, sharing the same two inputs. That is the whole construction, and it is worth sitting with for a moment: the arithmetic operation everyone treats as primitive turns out to be two Boolean functions that were already available from Boolean Logic: The Four Operations Hardware Actually Has.

It is called a *half* adder because it cannot accept a carry coming in. That is fine for the lowest bit position, where there is nothing to carry from, and useless for every other position.

Half adder: the sum column is XOR, the carry column is AND
ABSum (A XOR B)Carry (A AND B)Decimal
00000 + 0 = 0
01100 + 1 = 1
10101 + 0 = 1
11011 + 1 = 2, i.e. 0 carry 1

The full adder, and chaining it

Every position above the lowest needs three inputs: two operand bits and the carry from below. That is a full adder, and it is built from two half adders plus an OR — add A and B, then add the carry-in to that result, and a carry is produced if either addition generated one.

Chain N full adders, wiring each carry-out to the next carry-in, and you have an N-bit ripple-carry adder. It is correct, it is the minimum gate count, and it is how addition is explained. It is also slow in a specific and instructive way.

The problem is visible in the timing below. Bit 0 settles quickly, but bit 7 cannot produce its final sum until the carry has rippled through all seven positions beneath it. Delay grows linearly with width, so a 64-bit ripple-carry adder would have a critical path of well over a hundred gate delays — which, per Logic Gates: Where Software Stops and Physics Starts, would force a clock period nobody would accept.

When each bit of an 8-bit ripple-carry adder produces its final value (in gate delays)
waiting for carrysettlingstableSIMPLIFIED
12345678
bit 0ssssssss
bit 1wsssssss
bit 2wwssssss
bit 3wwwsssss
bit 4wwwwssss
bit 5wwwwwsss
bit 6wwwwwwss
bit 7wwwwwwws
bit 0No carry-in to wait for; settles immediately.
bit 1Waits for bit 0's carry.
bit 7The critical path: the whole addition is only done when this settles.

Breaking the dependency by computing ahead

The fix is to stop waiting for the carry and compute it directly instead. Each bit position can say two things about carries without knowing the incoming one: it generates a carry if both its operand bits are 1, and it propagates an incoming carry if either is 1. Generate is AND; propagate is OR or XOR depending on the formulation.

From generate and propagate signals, the carry into any position can be expressed as a formula over all the positions below it, and evaluated in constant depth rather than by rippling. That is carry-look-ahead, and it converts linear delay into roughly logarithmic delay at the cost of substantially more gates. Real designs use hybrids that split the width into blocks, because a full look-ahead across 64 bits would be enormous.

The generalisable lesson is the trade in the last row of the table: more parallel hardware to shorten a dependency chain. That is precisely the trade Out-of-Order Execution makes with instructions, Prefetching: The Hardware Guesses What You Will Read Next makes with memory, and Branch Prediction: Guessing Well Enough to Matter makes with control flow. The carry chain is where the pattern is easiest to see, because the dependency is a single wire.

Adder designs: the same trade at increasing scale
DesignDelay with width NGate costWhere it is used
Ripple-carryLinear in NMinimalNarrow additions; teaching
Carry-look-aheadRoughly logarithmic in NSubstantially higherWide adders, usually in blocks
Carry-selectRoughly square root of NRoughly doubleComputes both possible results, then selects
Hybrid block designsClose to logarithmicTuned per targetWhat production ALUs actually use
The patternShorter dependency chainMore parallel hardwareRecurs at every level of this domain

Key points

  • A half adder is one XOR (sum) and one AND (carry) — arithmetic composed from Boolean logic.
  • A full adder accepts a carry-in, which is what allows positions to be chained.
  • Ripple-carry is minimal in gates but its delay grows linearly with width, because each position waits for the one below.
  • Carry-look-ahead computes generate and propagate signals to break the chain, trading many more gates for roughly logarithmic delay.
  • Spending parallel hardware to shorten a dependency chain is the recurring pattern of the entire domain.

Follow the mechanism

The path through the machine, hop by hop — and the conclusions it invites that are wrong.

  1. 1
    Operand bits → XOR: the sum bit for each position is produced from the two operand bits and the carry-in.
  2. 2
    Operand bits → AND/OR: generate and propagate signals are computed for each position independently.
  3. 3
    Carry → next position: in a ripple design the carry must physically settle before the position above can finish.
  4. 4
    Look-ahead logic → all carries: alternatively, every carry is computed in parallel from the generate and propagate signals.
  5. 5
    Final sum → register: once the slowest bit settles, the complete result is available to be latched at the next clock edge.
What people conclude from this — wrongly
  • Assuming addition takes constant time regardless of width; latency depends on the design and the operand width.
  • Believing hardware is fast because it is "closer to the metal" rather than because it is massively parallel.
  • Thinking carry-look-ahead is free; it costs a great deal of area and power to buy the shorter path.

Consequences, controls and cost

What it causes
  • • Addition latency depends on operand width and on the adder design, not on the values being added.
  • • Adder depth is a major contributor to the critical path, and therefore to achievable clock frequency.
  • • Wide additions cost disproportionately more hardware than narrow ones, which is one reason narrow types can be cheaper in silicon.
  • • The same dependency-chain problem reappears at instruction and memory level, with the same class of solution.
What you can do
  • • Nothing directly — adder design is fixed long before software runs.
  • • Recognise the dependency-chain shape when it appears in your own code: a serial chain of dependent operations cannot be overlapped, whether it is carries, instructions or pointer loads ([[pointer-chasing]]).
  • • Expect the hardware to spend parallelism to hide latency, and structure code so that parallelism is available to spend.
How to see it
  • • Not directly observable from software. Instruction latency tables published by vendors show the result — typically one cycle for integer addition on contemporary cores.
  • • Compare a long chain of dependent additions against the same number of independent ones; the difference exposes the dependency limit, not the adder ([[instruction-level-parallelism]]).
What it costs
  • • Faster adders cost area and power, which competes with cache and cores for the same silicon budget.
  • • Deeper arithmetic logic can force a longer clock period unless it is pipelined across stages.
  • • Narrow arithmetic is cheaper in hardware but requires more instructions when the data is wider.

Scope

§224 — what these claims are specific to.

What these claims are specific to
  • SIMPLIFIEDReal ALUs use hybrid multi-level schemes tuned to a specific process and target frequency, not the textbook ripple or full look-ahead shown here.
  • MICROARCH-SPECIFICInteger addition is single-cycle on most contemporary cores, but multiplication, division and floating-point operations have longer and quite different latencies that vary by microarchitecture.

Misconceptions

Claim
“Addition is a hardware primitive with no internal structure.”
Reality
It is a network of gates, and its depth is a real design constraint. That structure is why wide multiplication and division cost several times more than addition.
Claim
“All arithmetic instructions take one cycle.”
Reality
Integer addition typically does. Multiplication takes several, division takes many more and is often not pipelined, and floating-point operations differ again. Vendor latency tables exist because these numbers vary.
Claim
“The carry chain is a historical curiosity.”
Reality
It is the clearest instance of a pattern that dominates the whole domain: a serial dependency that cannot be parallelised, worked around by spending hardware to compute ahead. Branch prediction and prefetching are the same trade at larger scale.