08The Edge-Triggered Register
Chapter 7 left us holding a bit — and a complaint. We built the gated D latch, a real one-bit memory you write on command. Then we caught it doing something we can't live with. While its enable is high it goes transparent: it echoes whatever is on its D input live, the whole time. It's a door propped open for a stretch, when what we actually needed was a camera shutter — one clean click. Wire it to the ALU and it doesn't capture the answer. It captures the ALU thinking, every half-formed carry rippling straight through to the output. So here's the question this chapter turns on: how do you build a memory that changes only in a single, razor-thin instant — and stays frozen the rest of the time? The answer sounds fancier than it is: the edge-triggered flip-flop. It's built from parts you already own — two of last chapter's latches, stacked, with one of them fed an upside-down copy of the same control signal. We give that control signal a name and a shape here: the clock, a plain square wave that ticks like a metronome. Take it as a given for now, a beat we can count. Where the beat physically comes from we'll open up in Chapter 12, in exactly one place. From there it's a short climb. Stack the latches into a flip-flop that snaps only on the clock's edge. Put eight of them shoulder to shoulder on one shared clock to hold a whole word. Finally, loop that register back through the ALU so one tick per beat makes it count. No magic — just a latch, doubled, listening to a metronome.
01The flaw, and the metronome
Let's stand on last chapter's crime scene for a moment, because the whole design we're about to build is a reaction to it. Here is the gated D latch with its enable C held 1 — the door propped open. In that state it is transparent. The output Q isn't holding a stored value at all; it's tracking D live, following every wiggle like a bare wire. Grab D below and watch Q chase it, helplessly, for as long as the enable stays up. Now drop the enable and look at what happened. Q froze on whatever value was in front of it the moment C fell. That moment, and no other. So this device doesn't decide across a stretch. It already decides in an instant — the instant C falls — then blabs for the rest of the window. Hold onto that. We aren't about to invent instant-sensitivity out of nothing. We're going to isolate the one instant the latch was always deciding in.
And here's why that "transparent for a while" behaviour is genuinely dangerous, not just untidy. Picture the latch's D input wired to the ALU's output. Now imagine we hold the enable high to "capture" a sum. But an ALU doesn't answer instantly. Its carries ripple, and its bits flicker through half-formed intermediate values before they settle. Because the latch is transparent that whole time, all of that churn pours straight into Q. We didn't store a number; we stored a live feed of a circuit mid-thought. Watch the ALU output smear across the open window below.
So the diagnosis is sharp. The enable is held for a duration, but the thing worth keeping is a single trustworthy instant — the moment the ALU has finished settling. Your first fix is probably the one I reached for too: just make the enable pulse shorter. Drag that window above narrower and the smear does shrink. It looks like it works. Here's why it loses. A narrow pulse is still a duration, so its width is now a number your whole machine's correctness rests on. Too wide and the churn leaks in. Too narrow and the latch can't capture at all. And that width has to stay right on every chip, at every temperature and voltage, while the ALU's settling time drifts underneath it. An edge has no width to get wrong. And there's a sting. To make a pulse that narrow, landing exactly where you want it, you'd need a circuit that fires on an instant — the very thing we don't have. So what we want is a control signal that doesn't say "listen for this whole stretch" but "listen at exactly this tick, and ignore everything else." That signal has a name and a shape, and it's the heartbeat of every computer ever built: the clock. It's nothing exotic — just a voltage that marches up and down forever in a steady square wave, 1 for half the beat and 0 for the other half, over and over. For now, take it as a given — a metronome we can count. We'll crack open what physically generates it a few chapters from here. Watch it tick below.
Now look closer at that square wave, because the trick of the whole chapter lives not in the flat tops and bottoms but in the near-vertical walls between them. Each time the clock jumps from 0 up to 1, that upward wall is the rising edge. Each time it drops from 1 back to 0, that's the falling edge. These edges are the "instants" we were hunting for. In a real chip they last well under a nanosecond — a genuine slice of a moment rather than a held window. The plan from here is to build a memory that wakes up only on one chosen edge, grabs the value in front of it, and then goes deaf again until the next one. Point out the two kinds of edge below.
02Two latches, oppositely clocked
Here's the first move toward an edge, and it costs us nothing but an inverter. Our gated latch is transparent while its control is 1 — call that a positive latch, one that listens on the high half of the clock. But feed that same latch an inverted clock — run the clock wire through a NOT gate first — and you flip its whole schedule. Now it's sealed while the clock is high and transparent while the clock is 0. That's a negative latch, listening on the low half. Same circuit, one inverter, opposite timing. Set the two side by side below and watch them take turns: whenever one is transparent, the other is shut.
So we have two latches taking turns, and we want an instant. Here's the wall. Every part in our box responds to a level. A gate watches how high a voltage is sitting right now. A latch watches whether its enable is up or down. None of them can see a wall of zero width go past. There is no edge-detector in the parts bin. We can't buy this. We have to arrange it. Here's the puzzle. Take thirty seconds before you read on. You have two doors that are never open at the same time. You want a corridor a value can cross in one instant only. Where do you put the doors? Side by side and you've built nothing: each door opens onto its own room. Put them in series, one behind the other, and everything changes. Now the only path from input to output runs through both, and there is no moment when both are passable. Put a negative latch first — call it the master — and feed its output into a positive latch behind it, the slave. Both run off the same clock. Now trace who's awake when. While the clock is 0, the master is transparent and drinks in D, but the slave is sealed, so nothing reaches the output. While the clock is 1, the master seals — freezing whatever it last saw — and only now does the slave open and pass that frozen value out. Wired to opposite halves of one clock, they are never open at the same time. This two-latch sandwich is the master-slave D flip-flop. Study its guts below — the two latches, oppositely clocked, only ever one of them see-through.
Notice what actually happens at the swap, because that is the invention. The value never flows through the pair. At the instant the clock rises, the master's door is closing on the value it holds at the same moment the slave's door is opening onto it. The bit isn't passed along a corridor; it is handed over. And a handover has nowhere to live except the single instant of the swap. So the only moment this device can change is the moment the clock's wall goes past — which is exactly what edge-triggered means. Look at what it's made of, too. The master's closing is that one honest decision a latch was always making, the instant its enable fell. The slave is there for one job: to make sure nothing else gets out.
Follow a single bit on its journey through that sandwich and the edge behaviour falls right out. Put a fresh value on D while the clock is low. It soaks into the master but stalls at the sealed slave, held in the antechamber, invisible at the output. Nothing happens at Q no matter how you jiggle D. Then the clock rises — and in that one instant the master slams shut, capturing the value that was on D right then, while the slave swings open and releases it to Q. The bit crosses the whole device on the strength of a single edge. Step the value through master and slave across one clock cycle below.
And here's the cheapest test of whether you own this rather than the drawing. We made the master a negative latch and the slave a positive one, and we got a device that fires on the rising edge. So, before you read on: what do you get if you swap them? Make the master positive and the slave negative — move the one inverter to the other latch. Now the master drinks while the clock is high and seals when the clock falls, and the slave opens onto it right then. The handover moves to the way down. That's a falling-edge flip-flop. Same corridor, mirrored schedule. Nothing about the mechanism changed; you moved one inverter.
Now put it on a timing diagram and see the payoff plainly, because this is the exact behaviour we were begging for two sections ago. Let D thrash — change it as often and as wildly as you like across the beat. The output Q ignores all of it and moves once, cleanly, at the rising edge. It adopts whatever D happened to be at that razor moment, then holds flat until the next rising edge comes around. Input racing, output advancing by exactly one edge per cycle. Watch Q step, and only step, on the edges below.
It's worth naming why this beats the plain latch in one clean comparison, since "edge-triggered" can sound like a buzzword until you see the window shrink. A gated latch's vulnerable window — the stretch during which a glitch on D can corrupt the stored bit — is the entire high half of the clock, maybe tens of nanoseconds. You can account for that half yourself: the clock is up for half of every beat, so the latch is exposed for half of every beat. The flip-flop's vulnerable window is only the sliver right around the edge itself. Which raises a fair question, so hold it for two paragraphs: if an edge is an instant, why isn't the sliver zero wide? Because the master's capture takes real time, and we're about to put names and numbers on exactly how much. So read the percentage under the widget below as that sliver measured against that widget's clock, not as a law of flip-flops. Run the clock slower and the same sliver becomes a thinner slice of a longer beat. Everywhere else, D can do whatever it wants and the stored value simply doesn't care. Edge-triggering doesn't add magic; it maximizes the stable window by collapsing "listen" from a duration down to an instant. Compare the wide transparent window against the razor edge below.
03The edge-triggered flip-flop
We're never going to want to redraw two internal latches every time we use one of these, so let's do what we did with the adder and the ALU — black-box it. Sealed inside one symbol, the master-slave flip-flop shows just four terminals. There's D, the data you want to store. There's the clock input, drawn as a little triangle notched into the box to mean "this pin triggers on an edge, not a level." There's Q, the stored bit coming out. And there's Q̄, its permanent opposite, free for the taking. That's the whole interface — present data on D, tick the clock, read the sample on Q. Meet the D flip-flop as you'll actually draw it from now on, below.
Every real datasheet carries a piece of fine print here, and it's not pedantry — it's the physical price of that razor edge. But we don't have to take it on faith, because we built the guts. One fact sits underneath all of it: gates take time. Now watch the master's door close. The master latch takes a real, if tiny, moment to capture its value, because the value must travel all the way around the master's own feedback loop before that loop can hold itself up. So D has to be already steady for a short spell before the edge — the setup time. The door is also still sealing after the edge has gone by, so D has to stay steady for a short spell after it — the hold time. Miss that window — let D still be moving as the edge lands — and the flip-flop hasn't got a settled value to grab. Then, once it does capture, the fresh Q doesn't appear the same instant. It emerges a hair later, after the gates inside settle. That lag is the propagation delay. Three names, one cause. Setup, hold, and propagation delay are the three real numbers that will one day set how fast a clock can safely run. That same cause makes me walk back an absolute from earlier. Our inverter takes a moment too, so on a rising clock the slave starts opening a hair before the master has finished shutting. For that hair, both doors are passable. It's small, it's real, and real designs are sized so the master wins that race. Slide D's transition around the edge below and watch the capture succeed or fail. Land right on it and the flip-flop is left mid-decision, hanging at neither a clean 0 nor a clean 1. That state has a name, and it gets the next paragraph.
And I owe you the one ugly corner honestly, the way we owed you the latch's forbidden input last chapter. What if D changes at precisely the edge, violating both setup and hold at once? Then the master is caught mid-decision. Q can momentarily hang at neither a clean 0 nor a clean 1, but somewhere in the murk between, taking an unpredictable extra while to topple to one side. That's metastability again — the ball balanced on the hilltop. It's not a flaw in our drawing but a genuine physical hazard that real designs must budget for. In practice you keep D stable across the window and it never bites. Nudge the transition onto the exact edge below and watch the output hesitate.
04Eight in a row — the register
One flip-flop holds one bit — but we never deal in single bits, we deal in bytes. So do the obvious thing. Line up eight D flip-flops side by side, hand each its own D input, and — here's the key move — wire all eight clock pins to the same clock wire. Now a single rising edge captures all eight bits simultaneously, freezing a whole byte in one synchronized snap. That parallel bundle of flip-flops sharing one clock is a register, and it is the first device in this course that stores a full number instead of a lone bit. Load a byte into the eight-wide register on one edge below.
This is the right place to coin a word for what a register holds, because it's a unit that will follow us for the rest of the book. An N-bit value moved and stored as one unit is a word — here, eight bits, a byte-wide word. The width of the register, the width of the ALU, and soon the width of every RAM slot are all the same N, and that shared width is exactly what "word" names. A word isn't a new kind of thing. It's just "how many wires we agree to read together as one number." Widen and narrow the word below and watch its ceiling climb.
Now we can finally close the wound we opened in section one. Wire the eight-bit ALU output to the register's eight D inputs, and drive the register from a clock whose rising edge we place after the ALU has had time to settle. During the churn — carries rippling, bits flickering — the register is deaf. It holds its old value and utterly ignores the mess. Then, at the edge, one clean snapshot: the settled sum lands in the register and stays. This is the whole reason edge-triggering was worth building. A latch would have swallowed the churn; the flip-flop takes only the finished answer. Latch the settled ALU result on the rising edge below.
A+B is computing the bus churns — carries ripple, so the byte flickers through garbage values (0xF7, 0x1C, 0xA5…) before it settles to 0x87. Hit Run: the register stays deaf, holding its old contents through the whole churn, and takes exactly one snapshot on the rising clock edge. Slide that edge into the churn zone and it latches a glitch; slide it past the settle point and it latches the clean 0x87. Same wires, same ALU — the only thing you changed is when the edge falls.05Feed it back — the accumulator
Here's where a held word stops being storage and starts being machinery. We just wired the ALU's output into a register. Now do the daring thing: take that register's output and wire it straight back to one of the ALU's inputs. First, though, hold the ALU picture fresh in your hands — the black box with two operands in, one op-select line, one result out, from Chapter 6. That result is what we're about to route home. Here it is again below.
Now close the loop and watch what a register plus an ALU plus a clock become together. The register's stored value feeds an ALU input. The ALU's other input is a fixed 1, and the ALU is set to add. The ALU's output — the old value plus one — feeds back to the register's D. That feedback-through-the-ALU structure is an accumulator: a register that operates on its own contents each tick. Now stop, before you tick anything, and answer this honestly: what does this loop do if the register is just a transparent latch? Commit to an answer first. Here it is. A transparent latch has Q following D live, so the sum reaches the output the instant it reaches the input. It races back round through the ALU, gets one added to it, appears again, races round again. The loop never steps. It tears away in a blur, as fast as the gates can carry it, and lands wherever it happens to land. So feedback isn't the daring part of this circuit. Feedback is trivial. The edge is the entire difference between counting and chaos: every rising edge, the register latches "itself plus one" and holds it until the next edge. The flip-flop's one-snapshot-per-edge discipline is the only thing that makes a clean, controlled step possible. Trace the loop below: output, into the ALU, plus one, back to D.
Set that accumulator ticking and it does something you've been waiting eight chapters to see a circuit do on its own: it counts. Zero, then one, then two, three, four — one clean increment per clock edge, marching upward with no human touching a switch. This is a binary counter, and it is the seed of the thing that will eventually walk a computer through its program, one instruction at a time. Hit the clock below and watch the register climb, edge by edge.
And for a closing flourish, flip that one control line from add to subtract and let the counter run down from zero — because what happens next is two's complement made visible in the wires. Subtract one from 00000000 and the register doesn't error or stop. It rolls straight to 11111111, all ones — which, read as a signed number, is exactly −1. The counter counting backward past zero is the wrap-around arithmetic we derived back in Chapter 5, now happening physically, once per tick. Remember these landmarks — 00000000 is 0, all-ones is −1 — and watch them light below as the count crosses zero.
And that's Chapter 8 — the chapter where memory learned to keep time. The whole climb was one flaw and its cure. The gated latch listens for a window, so it swallows a circuit mid-thought, and the fix is to make it listen for an instant. We found that instant in the clock — a plain square wave with two edges hiding in its walls. We caught it by stacking two of last chapter's latches on opposite halves of that clock, a master and a slave, so only one is ever transparent and a value can cross only at the edge. That's the edge-triggered D flip-flop: D in, a clock triangle, Q and Q̄ out, honest about its setup and hold window, its propagation delay, and the sliver of metastability at the exact edge. Eight of them on a shared clock became a register — a machine word that captures a whole byte in one synchronized snap — which finally let us latch the ALU's settled answer without swallowing its churn. And then, in one move, we looped that register back through the ALU and watched a held word turn into a running one. It became an accumulator that adds to itself each tick, a counter that climbs 0, 1, 2, 3 on its own — and rolls down through all-ones to show us two's complement live. But notice what we don't have: one register holds exactly one number, and a real program needs to juggle hundreds. We need not one word but a whole bank of them, with the power to say "give me number 617" and get that one back. That's bulk, addressable storage. Building it out of the registers we just made, plus a circuit that picks exactly one, is where we go next.