Latches & Flip-Flops
Every circuit up to this point has been combinational: its output is a pure function of its current inputs, with no memory of anything that came before. That's a real limitation — a circuit that can only react to what's on its inputs right now can't count, can't remember a previous state, and can't sequence a multi-step operation. Sequential logic breaks that limitation by feeding a circuit's output back into its own input, creating memory — the ability to hold a value even after the inputs that produced it have changed.
The SR latch: the simplest memory element
The most basic memory element is built from nothing but two cross-coupled NOR gates (or, equivalently, two cross-coupled NAND gates) — each gate's output feeds the other gate's input:
S | R | Q(next) Behavior
0 | 0 | Q (hold) no change — remembers previous state
0 | 1 | 0 Reset
1 | 0 | 1 Set
1 | 1 | invalid both outputs forced to same value — avoid
S (Set) and R (Reset) are the inputs; Q and its complement Q' are the outputs. The behavior that makes this circuit interesting is the S=0, R=0 row: the output holds whatever value it last had, because each gate's output is feeding back into the other gate as one of its inputs, and that feedback loop is what a truth table for a purely combinational circuit could never express — there is no S, R input combination alone that determines Q; the current Q is itself part of the answer. The S=1, R=1 case is normally forbidden: it forces both Q and Q' to the same value, breaking the assumption that they're always complements, and which state the latch falls into when S and R both drop back to 0 simultaneously is a race with no defined winner.
This circuit is called a latch because it has no clock — it responds to its inputs immediately and continuously, the way a light switch responds the instant you flip it.
The D latch: fixing the "invalid state" problem
The SR latch's forbidden input combination is awkward to guarantee against in practice. The D latch (also called a transparent latch) sidesteps the problem entirely by deriving S and R from a single data input D, gated by an enable signal EN:
EN | D | Q(next)
0 | x | Q (hold — enable low, latch is opaque)
1 | 0 | 0
1 | 1 | 1
Internally this is just an SR latch with S = D·EN and R = D'·EN — which structurally guarantees S and R are never both 1, eliminating the invalid state by construction rather than by convention. When EN=1 the latch is transparent: Q follows D immediately, exactly like a piece of combinational wire. When EN=0 the latch is opaque: Q freezes at whatever value it held the instant EN fell, regardless of what D does afterward.
That transparency is exactly the D latch's weakness for building anything more complex than a single storage bit. If you chain two D latches together to build a two-stage pipeline, and both share the same enable signal, data can race straight through both stages in one transparent window instead of advancing one stage per cycle — the second stage's input is still moving while its output is supposed to be settling. Digital systems need something that updates once per clock cycle, not continuously whenever a level happens to be high. That's exactly the gap the flip-flop closes.
The edge-triggered D flip-flop
A flip-flop samples its input only at a clock edge — the instant the clock transitions from 0 to 1 (positive edge-triggered) or from 1 to 0 (negative edge-triggered) — and holds that sampled value for the entire rest of the clock cycle, completely ignoring D in between edges.
CLK edge | D | Q(next)
↑ 0 | 0
↑ 1 | 1
(no edge) | Q (hold, regardless of D)
The standard way to build one is the master-slave construction: two D latches in series, with complementary enable signals — the first ("master") latch is transparent while the clock is low and opaque while it's high; the second ("slave") latch is the reverse. While the clock is low, the master latch tracks D and the slave holds its previous output, isolating the flip-flop's output from whatever the input is doing. The instant the clock rises, the master latch closes (freezing whatever D was at that exact instant) and the slave latch opens, passing the master's just-frozen value through to Q. Because the two latches are never transparent at the same time, there is no path from D straight through to Q at any point — the only thing that reaches the output is the single value the master captured right at the rising edge. That's what "edge-triggered" means at the circuit level: not that the flip-flop is magically instantaneous, but that its two internal latches are deliberately never open together.
The D flip-flop is the fundamental building block of essentially all modern synchronous digital design: every register, every pipeline stage, every counter in this section is built from arrays of D flip-flops sharing a common clock.
JK and T flip-flops
Two other flip-flop types show up in textbooks and in some standard-cell libraries, both derivable from a D flip-flop with extra input logic in front of it:
JK flip-flop — behaves like an SR latch's inputs but with the forbidden case turned into something useful:
J | K | Q(next)
0 | 0 | Q (hold)
0 | 1 | 0 (reset)
1 | 0 | 1 (set)
1 | 1 | Q' (toggle)
J=K=1 toggles the output on every clock edge instead of being forbidden — the JK flip-flop's defining feature. It's built from a D flip-flop by feeding D = J·Q' + K'·Q into the D input.
That J=K=1 toggle behavior is also the reason a JK latch — a level-sensitive JK element built directly from cross-coupled gates, without the master-slave/edge-triggered discipline described above — is dangerous to use directly. If J and K are both held at 1 for the entire time the enable/clock is high, the latch's own output feeds back into its own toggle logic, so it keeps flipping Q again and again, once per gate-propagation delay, for as long as the enable stays asserted — an uncontrolled, timing-dependent number of toggles known as the race-around condition, because the fed-back output is racing the enable pulse. The final value of Q when the enable finally falls depends on exactly how many of those propagation-delay-sized toggles fit inside the pulse width, which is not something a designer can reliably predict or control. This is precisely the failure mode the master-slave construction (or true single-instant edge-triggering) eliminates: because the master and slave latches are never transparent at the same time, J and K are only ever sampled once per clock cycle — there is no window during which the output can loop back into its own input and re-toggle itself.
T flip-flop — a single-input toggle element: T=0 holds, T=1 toggles (Q(next) = Q ⊕ T, another appearance of the XOR "difference" pattern from Boolean Algebra & Logic Gates). It's the JK flip-flop with J and K tied together, or equivalently a D flip-flop with D = Q ⊕ T. T flip-flops are the natural building block for ripple counters, covered later in this section, because a divide-by-2 frequency behavior is exactly what a chain of toggling elements produces.
In modern ASIC and FPGA design, the D flip-flop is overwhelmingly the one actually instantiated in silicon — JK and T flip-flops are mostly a conceptual/textbook tool now, useful for reasoning about toggle behavior, but standard-cell libraries center on D flip-flops (often with added enable and reset pins) rather than stocking JK cells directly.
What's next
Flip-flops sample their input at a clock edge — but a real clock edge isn't instantaneous in physical silicon, and a real signal takes real time to become stable and stay stable around that edge. The next page covers the timing rules — setup time, hold time, clock-to-Q delay, and metastability — that determine when a flip-flop is guaranteed to sample its input correctly, and what happens when those guarantees are violated.