The problem: gates have no past
In the last two guides we built powerful things out of gates: a multiplexer that picks one input, a full adder that sums bits, whole combinational blocks whose output depends only on the inputs present right now. That 'right now' is the catch. Stop the inputs and the output holds, sure — but change them and the old answer vanishes instantly, leaving no trace. A combinational circuit is like a calculator with no memory key: it can compute, but it cannot remember what it just computed.
But a computer is useless without memory. A counter must know what number it reached last tick; a program must remember the address of the next instruction; a register must hold a value while the adder chews on it. We need a circuit whose output can depend not only on its inputs but on its own history — what happened before. Circuits with that property earn a new name: sequential logic, because their behaviour follows a sequence in time, not just a snapshot.
The trick that remembers: feedback
How can a circuit made of forgetful gates remember? With one daring move: take a gate's output and wire it back to its own input. This loop, called feedback, lets a signal chase its own tail and settle into a stable value that then holds itself up — the circuit becomes its own memory. The classic example is the SR latch built from two cross-coupled NOR gates: each gate's output feeds the other's input, forming a tiny ring that can rest in one of two stable states.
Recall from guide 1 that any gate can be built from NAND alone (NAND completeness) — so a latch is still nothing but the switches you already understand, just wired in a ring instead of a line. The two outputs are labelled Q and its complement (often written Q-bar). Pulse the Set input and Q locks to 1; pulse Reset and Q locks to 0; release both and the ring simply holds whatever it last settled on, indefinitely, with no clock and no further input. That held value is one stored bit.
SR latch (cross-coupled NOR), behaviour table S R | Q (next) meaning -----+---------------------- 0 0 | Q (hold) remember the old value <-- this is the memory 1 0 | 1 set 0 1 | 0 reset 1 1 | --- forbidden (Q and Q-bar both 0; race on release) The 'hold' row is the whole point: with no command, the bit stays put.
Notice the forbidden row. Raising Set and Reset together drives both outputs to 0, and when you release them the ring can settle either way at random — a coin flip you cannot predict. This is our first taste of an awkward truth: sequential circuits have timing rules and illegal moves that combinational circuits never had. Tame the latch and you tame the whole machine; mishandle it and you get glitches that no truth table can explain.
Adding a clock: the gated latch
A bare latch reacts the instant its inputs wiggle — too eager for a real machine where signals ripple through long combinational paths and are briefly garbage before they settle. We want the latch to ignore its data input until we say 'now'. So we add an enable wire and AND it with the inputs: when enable is high the latch is transparent (it follows the data input); when enable is low it is opaque (it freezes, holding the last value). That enable signal will become the clock — a steady metronome that tells every memory element exactly when it is allowed to look.
This gated D latch (D for Data) is a real improvement, but it carries a subtle flaw. As long as the clock is high it stays transparent, so if the data input changes mid-pulse, that change flows straight through. In a loop — like a counter that feeds its own output back as next input — a single long clock pulse could let the value race around the loop several times in one tick. We want exactly one update per tick, not a free-for-all while the clock is high. The fix is to make the element react not to a clock level but to a clock edge.
The flip-flop: one bit, one tick
Chain two gated latches in series — a master and a slave — driven by opposite clock phases, and you get the edge-triggered D flip-flop, the workhorse memory cell of essentially every modern chip. While the clock is low the master is transparent and quietly tracks the data input; the slave is frozen and shows the world the old value. At the rising edge the roles flip in one instant: the master snaps shut, capturing whatever D was at that knife-edge, and the slave opens just long enough to copy it out. The net effect is gorgeously clean — the flip-flop samples D once, exactly at the clock edge, and holds it steady for the entire rest of the cycle.
- Clock low: the master latch is transparent and follows D as it wanders; the slave is closed and outputs the value stored last edge.
- The rising edge arrives: in that instant the master closes, freezing the exact value of D at the edge — this is the 'sample'.
- Just after the edge: the slave opens and copies the master's frozen value to the output Q, where it now stays rock-steady all cycle.
- Because master and slave are never transparent at the same moment, no signal can race through end to end — exactly one update per tick.
From one bit to registers and counters
A single flip-flop holds one bit, which is not very interesting on its own. But lay 32 of them side by side, wire all their clock inputs to the same line, and you have a 32-bit register: at every clock edge it snapshots 32 wires at once and holds the whole word for a cycle. Bundle many registers into a register file addressed by number and you have the CPU's tiny on-chip notepad — the registers that hold the values an instruction is actually working on. Every architectural register you will meet later, including the program counter, is just a row of flip-flops sharing a clock.
Now wire a register's output through a little combinational logic and back to its own input, and the magic compounds. Feed the output through a +1 adder and you have a counter: each tick it stores its own value plus one, so Q marches 0, 1, 2, 3, ... in lockstep with the clock — exactly the engine that drives a program counter forward instruction by instruction. This compute-then-store loop, combinational logic computing the next value and flip-flops remembering it across the edge, is the universal skeleton of sequential logic and the seed of next guide's finite state machine.
There is one honest catch hiding in that loop, and it is the bridge to the next guide. The new value computed by the combinational logic must reach the flip-flop's input and stop wiggling before the next clock edge samples it. The flip-flop demands the data be stable for a tiny window before the edge (its setup time) and just after (its hold time); violate that window and it can store garbage or even hang halfway between 0 and 1. Honouring this rule everywhere is the discipline called synchronous design, and the longest such compute path — the critical path — is what ultimately caps how fast you can run the clock. That is exactly where guide 4 begins.