>
section 7 of 138 min read

7. Sequential Logic: Adding Memory

Combinational logic is enough for adders, multiplexers, and decoders. But many systems need to remember: count, track state, hold data between clock cycles, implement protocols. That requires sequential logic, where outputs depend not only on current inputs but also on past history through some stored state.

7.1 Synchronous vs asynchronous

Synchronous circuits change state only on a clock edge. Simple to design, predictable timing, easy to verify. Used in 99%+ of modern digital circuits. The clock is the heartbeat that keeps everything in step.

Asynchronous circuits change state whenever inputs change, with no global clock. Faster in principle (no waiting for the next clock edge) but plagued by race conditions, hazards, and difficulty of formal verification. Used only in niche applications: some arbiters, asynchronous SRAM interfaces, ultra-low-power sub-threshold logic, GALS systems.

Almost everything from here on is synchronous.

7.2 The latch: simplest memory

The simplest sequential element is the SR latch, built from a pair of cross-coupled NOR (or NAND) gates.

plaintext
   S ──┬─[NOR1]──┬── Q
       │         │
       │         ▼
       │    ┌────────┐
       │    │        │
       └────┤        │
            │        │
       ┌────┤  NOR2  │── Q'
       │    │        │
       │    └────────┘
       │         ▲
       │         │
   R ──┘         │

The two outputs Q and Q' (Q-not) feed back to each other's inputs.

  • Set (S=1,R=0S = 1, R = 0): NOR1 forces Q' to 0; NOR2 then sees both inputs at 0, so Q' goes to 1. Q is now stable at 1. (Hmm, let me redo, since gate outputs depend on the topology. With the cross-coupled NOR pair, S = 1 drives one NOR output low, R = 1 drives the other low; the convention is Q = 1 when set.)

The key behaviors:

  • S=1,R=0S=1, R=0: QQ goes to 1 (set).
  • S=0,R=1S=0, R=1: QQ goes to 0 (reset).
  • S=0,R=0S=0, R=0: QQ holds its previous value (memory!).
  • S=1,R=1S=1, R=1: invalid in NOR-based SR latches; both QQ and QQ' would go to 0, and on release the next state is unpredictable.

The SR latch is bistable: two stable states (Q=0 or Q=1), with a third metastable state in between that real circuits avoid.

Toggle-switch analogy. A wall light switch is bistable: it sits stable in either ON or OFF. There is a brief unstable middle position when you flip it, but it does not stay there. The SR latch is a switch you can flip via electrical signals on S and R.

7.3 Gated latches

A pure SR latch is transparent: any change on S or R immediately propagates. This is hard to use in big circuits because the latch is always listening. So we add an enable signal:

  • The gated SR latch has S and R inputs that only matter when enable is high. Otherwise the outputs hold.
  • The gated D latch simplifies further: a single D ("data") input. When enable is high, Q tracks D; when enable is low, Q holds.

The gated D latch is the workhorse memory cell of older designs. It is level-sensitive: while enable is high, the output tracks the input. While enable is low, it holds.

7.4 Edge-triggered flip-flops

Level-sensitive latches are awkward in feedback paths because while enable is high, outputs can race ahead and re-enter the same latch through combinational logic, causing oscillation. The fix is edge-triggered flip-flops, which only sample their input on a single clock edge (rising or falling).

Two ways to build edge triggering:

  1. Master-slave flip-flop: cascade two level-sensitive latches with opposite-phase enables. The master samples while clock is low; the slave forwards while clock is high. The output changes only at the rising edge when the slave forwards what the master last captured.
  2. True edge-triggered flip-flop: a more efficient circuit with three latches arranged so that only the rising clock edge produces a change. Modern CMOS uses transmission-gate-based versions for efficiency.

The most-used flip-flop:

D flip-flop. One data input D, one clock input CLK. On the rising edge of CLK, Q takes the value of D. Between edges, Q holds.

plaintext
   D ──┬─[D-FF]── Q
       │           │
       │           └── Q'
   CLK ─┘

The D flip-flop is the backbone of synchronous design. A typical FPGA has hundreds of thousands of them. A modern CPU has hundreds of thousands more inside its register file, pipelines, caches, and TLBs. Every reset-domain crossing, every clock-domain crossing, every pipeline register is a D flip-flop.

7.5 JK flip-flop

Like the SR flip-flop but resolves the illegal state. With JJ and KK inputs:

JKQ (next)
00Q (hold)
010 (reset)
101 (set)
11Qˉ\bar Q (toggle)

The toggle behavior makes JK perfect for ripple counters, which is why early TTL counters (74LS73, 74LS76) were JK-based. Modern designs almost always use D flip-flops with explicit toggle logic in front.

7.6 T flip-flop

Stripped-down JK with J=KJ = K tied together, called T (for "toggle"). Toggles on each clock edge if T = 1, holds if T = 0. Used in counters where you just want the bit to flip.

7.7 Characteristic equations

The "next-state" behavior of each flip-flop can be written as a single Boolean equation:

Flip-flopQ+Q^+ (next state)
SRQ+=S+RˉQQ^+ = S + \bar{R}Q (with SR=0SR = 0)
DQ+=DQ^+ = D
JKQ+=JQˉ+KˉQQ^+ = J\bar{Q} + \bar{K}Q
TQ+=TQQ^+ = T \oplus Q

These come up when you derive the next-state logic for a state machine: you write what you want Q+Q^+ to be in terms of inputs and current state, then compare against the flip-flop's characteristic equation to pick what to feed into D, J, K, or T.

7.8 Excitation tables

The inverse: given current Q and desired Q+, what should you feed the flip-flop?

QQ+DJKT
0000/X0
0111/X1
100X/11
111X/00

(X means "don't care," which gives JK its flexibility for minimization.)

D is dead simple: D = Q+. JK has don't-cares that can yield smaller next-state logic when minimized with K-maps. T is good when you want to express "should we toggle?" directly.

7.9 Setup and hold time

A flip-flop needs the data input to be stable for some time before the clock edge (setup time, tsut_{su}) and remain stable for some time after (hold time, tht_h). If either is violated, the flip-flop may go metastable: its output hovers between 0 and 1 for an unpredictable duration before resolving.

Modern flip-flops have setup times on the order of tens to hundreds of picoseconds. The synthesis tool's job is to ensure that, for every flip-flop, the worst-case path from the previous flip-flop completes within the clock period minus the setup time. The constraint is

tcq+tcombinational+tsuTclk.t_{cq} + t_{combinational} + t_{su} \leq T_{clk}.

This is timing closure, and a CPU shipping at 5 GHz means every path between flip-flops fits in 200 ps, including all the gate delays and wire delays.

7.10 Metastability and synchronizers

When an asynchronous signal (a button press, a signal from another clock domain) is sampled by a flip-flop, the timing is uncontrolled, and setup/hold violations can occur. The flip-flop output then sits in a metastable state, neither cleanly 0 nor 1, for some unpredictable time before resolving.

The cure is a synchronizer: a chain of two (or more) flip-flops in the destination clock domain, each giving the previous one's output time to settle.

rendering diagram...

Each additional flip-flop multiplies the mean time between failures (MTBF) of the synchronizer by the resolution time. A two-flop synchronizer is enough for typical 1 MHz button presses; four flops or more for sub-nanosecond inter-domain crossings at GHz clocks.

Hardware-security note: glitch attacks. Voltage glitches (briefly drop the supply) or clock glitches (a single short clock cycle) are deliberately designed to violate setup/hold time on critical flip-flops, pushing them into metastability so the next-state logic loads garbage. With careful timing, an attacker can corrupt exactly the right flip-flop, for instance the one storing "user authenticated" or the one storing the current state of an FSM that gates secure-boot. Countermeasures include duplicated flip-flops with comparison, dual-rail logic that detects unbalanced transitions, and dedicated glitch detectors that trip the chip into reset on anomalous clock or power. We will revisit glitch attacks in detail in Chapter 24.