Adding Memory: Combinational, Sequential and the Clock
Combinational logic has no memory — the output is a function of the inputs right now. Add feedback and you can store a bit; add a clock and you can control when stored values change. That step is what turns a calculator into a machine that executes programs.
Software view, hardware view
The gap between what you wrote and what the machine does is where this whole domain lives.
Two kinds of circuit
A combinational circuit's output depends only on its current inputs. The adder from Building an Adder: Where Arithmetic Comes From is one: give it the same operands and it produces the same sum, always, with no notion of what came before. It has no memory and needs no clock.
A sequential circuit's output depends on its inputs *and* on stored state. That is what lets a counter know what it counted to, a program counter know where execution reached, and a cache know what it holds. The difference is not complexity — it is the presence of feedback.
The mechanism is simple in principle. Cross-couple two gates so each drives the other, and the pair has two stable configurations. It will sit in whichever one it was pushed into, indefinitely, as long as power is applied. That bistability *is* the stored bit — no capacitor, no magnetism, just a circuit that holds its own position.
| Property | Combinational | Sequential |
|---|---|---|
| Output depends on | Current inputs only | Current inputs and stored state |
| Memory | None | Yes, via feedback |
| Needs a clock | No | Usually, to control when state changes |
| Examples | Adder, multiplexer, decoder, ALU datapath | Register, program counter, pipeline stage, cache |
| Analogy in software | A pure function | An object with mutable fields |
| Where it appears | The ALU: Where Arithmetic Actually Happens, Building an Adder: Where Arithmetic Comes From | Registers: The Fastest Storage, and There Is Almost None of It, The Program Counter: Deciding What Happens Next, Pipelining: Throughput Without Making Anything Faster |
The clock imposes a discipline, not a speed
A bistable pair can store a bit but says nothing about *when* it should change. Left alone, storage elements would update whenever their inputs happened to settle, and different paths settle at different times — the result is a circuit whose behaviour depends on physical delays, which is unworkable.
The clock solves it by defining moments. State changes only at a clock edge, so between edges the combinational logic has the entire period to settle, and every storage element captures its input simultaneously. That is what makes the design analysable: correctness reduces to a single check, that the longest combinational path fits within one clock period.
It follows that clock frequency is bounded by the critical path, exactly as Logic Gates: Where Software Stops and Physics Starts describes. It also follows that if you *shorten* the paths — by splitting deep logic into several shorter stages separated by registers — you can raise the frequency. That is precisely what Pipelining: Throughput Without Making Anything Faster is, and it is why the clock discipline is a prerequisite rather than an implementation detail.
From one stored bit to a machine
Widen a single storage element to N bits in parallel and you have a register — the fastest storage in the machine, and the subject of Registers: The Fastest Storage, and There Is Almost None of It. Registers are why arithmetic instructions name registers rather than memory: the value is physically adjacent to the ALU, so it arrives within the cycle.
Two particular registers turn the circuit into a computer. The program counter holds which instruction to execute next (The Program Counter: Deciding What Happens Next), and updating it each cycle is what makes execution a sequence rather than a single evaluation. An instruction register holds the instruction being decoded, so control signals stay stable while it is interpreted.
That is the whole progression, and it is worth stating explicitly because everything after this module assumes it: gates compute, feedback stores, the clock schedules, registers hold, and a program counter sequences. Everything above — pipelines, caches, cores, coherence — is elaboration on those five ideas.
transistors | v arranged into gates NAND is enough for all of them | v composed into combinational logic adders, multiplexers, the ALU datapath | v plus feedback storage elements a bistable pair holds one bit | v plus a clock registers N bits captured together on an edge | v plus a program counter a machine that executes a sequence Everything above this line -- pipelines, caches, cores, coherence -- is elaboration on these five steps.
Key points
- Combinational logic is a pure function of its current inputs and has no memory.
- Sequential logic adds feedback, so a circuit can hold its own state indefinitely while powered.
- The clock defines when state may change, so combinational logic has a full period to settle.
- Correctness reduces to one check: the longest combinational path must fit inside the clock period.
- Registers, the program counter and pipeline stages are all applications of this single mechanism.
Follow the mechanism
The path through the machine, hop by hop — and the conclusions it invites that are wrong.
- 1Gates → feedback: cross-coupling two gates creates two stable configurations, one of which the circuit holds.
- 2Clock edge → capture: at the edge, storage elements sample their inputs simultaneously and hold the value.
- 3Register → combinational logic: the stored state drives the logic, which computes the next state during the period.
- 4Combinational logic → register input: the result must settle before the next edge arrives, or the captured value is invalid.
- 5Program counter → instruction sequence: updating one register each cycle turns evaluation into execution of a program.
- • Assuming clock speed is an independent dial rather than a consequence of circuit depth.
- • Believing a longer pipeline is straightforwardly better; it raises frequency but makes each misprediction more costly.
- • Treating registers as a kind of very fast memory rather than as storage elements physically inside the datapath.
Consequences, controls and cost
- • Clock frequency is bounded by the longest combinational path between two storage elements.
- • Splitting deep logic into shorter clocked stages raises the achievable frequency, which is what pipelining exploits.
- • State is preserved only while powered; registers and caches are volatile by construction.
- • Every synchronous element sees the same clock, so distributing that signal with minimal skew becomes a design problem of its own at scale.
- • Nothing directly at this level; the clock discipline is fixed in silicon.
- • Understand that a "cycle" is a real physical interval bounded by settling time, not an arbitrary accounting unit ([[the-clock]]).
- • Reason about instruction cost in cycles and throughput rather than in wall-clock time, since frequency itself varies ([[frequency-scaling]]).
- • Not observable from software directly. Cycle counts and instruction latency tables are the visible consequences.
- • Compare cycles against instructions retired to see how much of each period is doing useful work ([[ipc]]).
- • More pipeline stages allow a higher clock but increase misprediction cost and design complexity.
- • Storage elements cost area and power; a large register file competes with cache for the same budget.
- • Clock distribution consumes a significant share of a chip's power, which is one motivation for clock gating idle blocks.
Scope
§224 — what these claims are specific to.
- SIMPLIFIEDReal designs distinguish latches from edge-triggered flip-flops and must satisfy setup and hold constraints; both are elided here. Some high-performance blocks are deliberately asynchronous.
- MICROARCH-SPECIFICPipeline depth, and therefore how much combinational logic sits between registers, varies substantially between designs and is a major factor in a core's frequency and misprediction cost.