Digital Design 2: Sequential Logic¶
Overview¶
This lecture picks up from combinational logic and builds the first digital circuits that can remember. We review the combinational vs. sequential distinction, then construct the SR latch from cross-coupled NOR gates, a clock-gated D latch, a rising-edge-triggered D flip-flop, and a 1-bit register with synchronous enable and clear. Along the way we introduce the multiplexer (MUX) as a data selector and use two MUXes in series to add enable and clear controls on top of a plain D flip-flop. We close by combining a 4-bit register with a 4-bit ripple-carry adder to build a 4-bit counter.
Learning Objectives¶
- Distinguish combinational from sequential logic and explain why processors need sequential circuits
- Describe the role of a clock signal and the difference between rising and falling edges
- Analyze the operation of the SR latch built from cross-coupled NOR gates
- Build a D latch from an SR latch by gating S and R with the clock
- Explain master–slave construction of a D flip-flop and why edge-triggering is preferred
- Use multiplexers to select between data sources in a register
- Design a 1-bit register with synchronous enable (hold vs. load) and synchronous clear (pass vs. zero) using two MUXes
- Compose N flip-flops into an N-bit register and an N-bit register plus an adder into a counter
Prerequisites¶
- Digital Design — combinational logic, gates, truth tables, sum-of-products, ripple-carry adder
- Binary and Bases — binary representation
- Truth tables and Boolean expressions
From Combinational to Sequential¶
Why We Need State¶
Combinational circuits compute outputs strictly from their current inputs — they cannot remember anything. A processor obviously does have memory: the register file, the program counter, condition flags, and RAM all hold values across time. To build a processor we need circuits that can store bits.
Goal for this lecture: build an N-bit register, and then combine a register with an adder to build a counter.
Combinational vs Sequential Logic¶
| Property | Combinational Logic | Sequential Logic |
|---|---|---|
| Output depends on | Current inputs only | Current inputs and previous state |
| Memory | None | Storage elements |
| Clock | Not required | Required to synchronize updates |
| Feedback | No feedback paths | Contains feedback loops |
| Examples | Adders, MUXes, decoders | Latches, flip-flops, registers |
The key mechanism that turns a combinational circuit into a sequential one is feedback: the output of a gate is wired back to an earlier gate's input. Without feedback, outputs depend only on current inputs; with feedback, the circuit can hold a value.
Building-Block Hierarchy¶
flowchart LR
SR[SR Latch] --> DL[D Latch]
DL --> DFF[D Flip-Flop<br/>master-slave]
DFF --> REG1[1-bit Register<br/>EN + CLR via MUXes]
REG1 --> REGN[N-bit Register]
REGN --> CNT[4-bit Counter<br/>register + adder]
The SR Latch¶
Cross-Coupled NOR Gates¶
The SR latch is the simplest storage element. It uses two NOR gates wired so that each gate's output feeds back as an input to the other:
R ───┬─── NOR ───┬─── Q
│ │
│ ┌──────┘ (feedback)
│ │
│ └──────┐
│ │
S ───┴─── NOR ───┴─── Q̄
│ │
└───────────┘ (feedback)
NOR gate truth table (reminder):
| A | B | A NOR B |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 0 |
How the SR Latch Behaves¶
- S = 1, R = 0 (Set): drives Q to 1 and Q̄ to 0.
- S = 0, R = 1 (Reset): drives Q to 0 and Q̄ to 1.
- S = 0, R = 0 (Hold): Q holds its last value — this is the stored state.
- S = 1, R = 1 (Forbidden): both Q and Q̄ would be forced to 0; when S and R return to 0 the final state is undefined. This combination must be avoided.
SR Latch Truth Table¶
| R | S | Q | Q̄ | State |
|---|---|---|---|---|
| 0 | 0 | Q | Q̄ | Hold (no change) |
| 0 | 1 | 1 | 0 | Set |
| 1 | 0 | 0 | 1 | Reset |
| 1 | 1 | X | X | Forbidden |
SR Latch as Static RAM¶
Each SR latch can hold a single bit as long as power is applied — this is the defining property of static RAM (SRAM). SRAM is fast but low density because each cell needs several transistors (a 6T cell is typical). DRAM stores each bit as charge on a tiny capacitor (1 transistor + 1 cap), which is dense but slow and needs periodic refresh. CPU caches are built from SRAM; main memory is DRAM.
| Technology | How It Stores a Bit | Speed | Density | Refresh |
|---|---|---|---|---|
| SRAM | Cross-coupled latch (~6 transistors) | Fast | Low | Not needed while powered |
| DRAM | Capacitor charge (1T + 1C) | Slower | High | Periodic refresh required |
Clock Signals¶
What Is a Clock?¶
A clock is a periodic signal that alternates between 0 and 1 at a fixed frequency. It provides the timing reference that tells every sequential circuit when to update. In real hardware the clock comes from a crystal oscillator.
Clock Terminology¶
| Term | Definition |
|---|---|
| Rising edge | Transition from 0 to 1 |
| Falling edge | Transition from 1 to 0 |
| Cycle / period | Time for one complete high-low sequence |
| Frequency | Number of cycles per second (Hz) |
Level-Triggered vs Edge-Triggered¶
- Level-triggered (latch): state can change at any time while the clock is at a particular level (high or low).
- Edge-triggered (flip-flop): state changes only at a clock edge (usually the rising edge).
Edge-triggered circuits give predictable timing and are used throughout modern processors.
The D Latch¶
Motivation¶
The SR latch has two problems: it takes two separate inputs to store one bit, and the S = R = 1 combination is forbidden. The D latch solves both by using a single data input D plus a clock/enable input C. The latch only updates when C is high.
Circuit¶
Gate D and its complement with the clock, and feed the results into the SR latch's S and R inputs:
flowchart LR
D[D] --> AND1[AND]
D --> NOT[NOT]
NOT --> AND2[AND]
C[C] --> AND1
C --> AND2
AND1 --> |S| SR[SR Latch]
AND2 --> |R| SR
SR --> Q[Q]
SR --> QB[Q̄]
Because S comes from D AND C and R comes from (NOT D) AND C, S and R can never both be 1. And when C = 0, both S and R are 0 so the latch holds.
D Latch Behavior¶
| C (Clock) | D (Data) | Q (Output) |
|---|---|---|
| 0 | X | No change (hold) |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Key insight: while C = 1, Q follows D; when C = 0, Q holds its last value. This is level-triggered behavior.
Digital Tool Demo¶
In class we built this D latch in the Digital simulator starting from two NOR gates, added the clock-gated inputs, saved the result as a custom component for reuse, and used the data-graph view to visualize D, C, and Q over time.
Multiplexers¶
What Is a Multiplexer?¶
A multiplexer (MUX) is a data selector: it routes one of several inputs to a single output based on a select signal. Think of it as a software-controlled switch.
2:1 MUX¶
Truth table (compact form):
| s | r |
|---|---|
| 0 | a |
| 1 | b |
Boolean expression: r = (a · s̄) + (b · s)
Gate-Level Implementation¶
flowchart LR
S[s] --> NOT[NOT]
NOT --> AND1[AND]
A[a] --> AND1
S --> AND2[AND]
B[b] --> AND2
AND1 --> OR[OR]
AND2 --> OR
OR --> R[r]
This is a direct sum-of-products implementation of r = (a · s̄) + (b · s).
4:1 MUX from Three 2:1 MUXes¶
Larger MUXes are built by composition. A 4:1 MUX uses a 2-bit selector s₁s₀:
| s₁ | s₀ | r |
|---|---|---|
| 0 | 0 | a |
| 0 | 1 | b |
| 1 | 0 | c |
| 1 | 1 | d |
flowchart LR
A[a] --> M1[2:1 MUX]
B[b] --> M1
S0[s₀] --> M1
C[c] --> M2[2:1 MUX]
D[d] --> M2
S0 --> M2
M1 --> M3[2:1 MUX]
M2 --> M3
S1[s₁] --> M3
M3 --> R[r]
MUXes scale to N-bit data by replicating the selector logic across each bit line.
Why MUXes Matter¶
Multiplexers are everywhere in a processor:
- Register file read: select which register's value flows to the ALU
- ALU input: choose between a register value and an immediate
- PC update: choose between PC + 4 and a branch target
- Write-back: choose between the ALU result and a memory value
And — as we'll see next — MUXes let us add enable and clear controls to a register.
The D Flip-Flop¶
Problem with the D Latch¶
While the clock is high, a D latch is transparent: any change on D passes through to Q. If the output feeds back (as it will in a register), the circuit can race through multiple updates in a single clock cycle. Timing becomes unpredictable.
Master–Slave Construction¶
A D flip-flop is built from two D latches in series, with inverted clocks:
flowchart LR
D[D] --> M[D Latch<br/>Master]
C[CLK] --> NOT[NOT]
NOT --> M
M --> S[D Latch<br/>Slave]
C --> S
S --> Q[Q]
- CLK = 0: master is transparent (follows D), slave is locked.
- CLK = 1: master is locked, slave is transparent — so Q now reflects whatever the master captured.
- Rising edge (0 → 1): master freezes its current D value, and the slave immediately publishes it.
The net effect is that Q only changes at the rising edge of the clock, picking up whatever D was at that instant.
Timing Diagram¶
CLK: ____┌─────┐_____┌─────┐_____┌─────┐____
│ │ │ │ │ │
D: ──XX─┤XXXXX├─────┤XXXXX├─XXXX┤XXXXX├────
│ │ │ │ │ │
Q: ─────┤ ├─────┤ ├─────┤ ├────
↑ ↑ ↑
Q captures Q captures Q captures
D on edge D on edge D on edge
Between rising edges Q is stable, regardless of what D does.
1-Bit Register: D Flip-Flop + Two MUXes¶
A bare D flip-flop updates Q to D on every rising edge. For a useful register we want two extra controls:
- Enable (EN): when EN = 0, the register holds its current value; when EN = 1, it loads the new D value on the next rising edge.
- Clear (CLR): when CLR = 1, force the next stored value to 0 (synchronous clear — happens on the rising edge, not instantly).
We add both controls synchronously by placing two MUXes in front of the flip-flop:
flowchart LR
D[D] --> ENMUX[2:1 MUX<br/>EN]
QFB[Q fed back] --> ENMUX
EN[EN] --> ENMUX
ENMUX --> CLRMUX[2:1 MUX<br/>CLR]
ZERO[0] --> CLRMUX
CLR[CLR] --> CLRMUX
CLRMUX --> DFF[D Flip-Flop]
CLK[CLK] --> DFF
DFF --> Q[Q]
Q --> QFB
- The EN MUX selects between the current stored value Q (fed back) and the new input D. Selector = EN.
- EN = 0 → output is Q (hold)
- EN = 1 → output is D (load)
- The CLR MUX selects between the EN MUX's output and a hardwired 0. Selector = CLR.
- CLR = 0 → output is whatever the EN MUX produced
- CLR = 1 → output is 0 (forces Q to 0 on the next rising edge)
- The flip-flop samples the final MUX output on the rising edge of CLK.
Both controls are synchronous: nothing changes until the next clock edge.
Register Control Table¶
| CLR | EN | Next Q on rising edge |
|---|---|---|
| 1 | X | 0 (clear) |
| 0 | 0 | Q (hold) |
| 0 | 1 | D (load) |
N-Bit Register¶
An N-bit register is simply N D flip-flops in parallel, sharing the same CLK, EN, and CLR signals. Each flip-flop has its own EN MUX and CLR MUX in front of it, wired to the corresponding bit of D.
D[N-1:0] (N-bit input)
│
▼
┌───────────────────────────────────┐
│ FF FF FF FF ... FF FF FF │ each with its
│ │ own EN MUX and
│ Q[N-1:0] (N-bit output) │ CLR MUX
└───────────────────────────────────┘
│ │ │
CLK EN CLR (shared)
Register Interface¶
Inputs: D[N-1:0], CLK, EN, CLR
Outputs: Q[N-1:0]
A 1-bit register is just the N = 1 case. A 4-bit register is what we need to build a 4-bit counter.
Building a 4-Bit Counter¶
Combine a 4-bit register with a 4-bit ripple-carry adder and wire the adder's second input to the constant value 1:
flowchart LR
REG["4-bit Register"] -->|"Q"| ADD["4-bit Adder"]
ONE["constant 1"] --> ADD
ADD -->|"sum"| REG
CLK["CLK"] --> REG
CLR["CLR"] --> REG
REG -->|"count"| OUT["count"]
Operation on each rising edge:
- The adder computes
current_value + 1. - The register stores that new value on the rising edge of CLK.
- CLR = 1 forces the count back to 0 on the next rising edge.
A 4-bit counter wraps around after 15 (0xF), because 15 + 1 = 16 = 0x10 and only the low 4 bits are stored — this is overflow.
Practice Problems¶
Problem 1 — SR Latch Trace¶
An SR latch has Q = 0 initially. Trace Q after each step:
- S = 1, R = 0
- S = 0, R = 0
- S = 0, R = 1
- S = 0, R = 0
Solution
1. S = 1, R = 0: **Q becomes 1** (Set) 2. S = 0, R = 0: **Q stays 1** (Hold) 3. S = 0, R = 1: **Q becomes 0** (Reset) 4. S = 0, R = 0: **Q stays 0** (Hold)Problem 2 — MUX Design¶
Write the Boolean expression for a 2:1 MUX in sum-of-products form, and sketch the gate-level circuit.
Solution
r = (a · s̄) + (b · s) Gates: one NOT (for s̄), two ANDs, one OR.Problem 3 — Flip-Flop vs Latch¶
Why do we prefer a D flip-flop (edge-triggered) over a D latch (level-triggered) in processor design?
Solution
- A D latch is **transparent** while the clock is high, so any input change propagates immediately and the output can change multiple times per cycle. - A D flip-flop only updates at the **rising edge**, giving each cycle exactly one well-defined update point. - Edge-triggering also makes **feedback** safe: a register's Q can legally feed its own D input because Q is stable except for an instant at the edge. This is essential for building counters, state machines, and pipelines.Problem 4 — Register Control¶
A 1-bit register uses the EN MUX + CLR MUX design described above. Currently Q = 1 and D = 0. What is the next value of Q on the rising edge for each of the following control settings?
(a) CLR = 0, EN = 0 (b) CLR = 0, EN = 1 (c) CLR = 1, EN = 0 (d) CLR = 1, EN = 1
Solution
(a) CLR = 0, EN = 0 → **hold**. Q stays 1. (b) CLR = 0, EN = 1 → **load D**. Q becomes 0. (c) CLR = 1, EN = 0 → **clear** wins (CLR MUX selects 0). Q becomes 0. (d) CLR = 1, EN = 1 → **clear** still wins. Q becomes 0. CLR is wired after the EN MUX, so it overrides EN.Problem 5 — Counter Sizing¶
How many bits are needed for a counter that counts from 0 to 255, and what happens after the counter reaches 255?
Solution
**Bits**: 8 (2⁸ = 256 values, 0 through 255). **After 255**: the adder computes 255 + 1 = 256 = 0x100, but only 8 bits are stored, so the register latches 0x00. The counter **wraps around** to 0 — this is overflow.Key Concepts¶
| Concept | Definition |
|---|---|
| Sequential Logic | Outputs depend on inputs and stored state; contains feedback |
| Clock | Periodic 0/1 signal; provides timing reference for state changes |
| Rising / Falling Edge | 0→1 and 1→0 transitions of the clock |
| SR Latch | Cross-coupled NOR gates; simplest 1-bit storage |
| D Latch | Level-triggered: while C = 1, Q follows D |
| D Flip-Flop | Edge-triggered; master–slave; updates only on the rising edge |
| MUX | Data selector: picks one of several inputs based on a select signal |
| Enable (EN) | Control that chooses between hold and load on the next edge |
| Clear (CLR) | Control that forces the next stored value to 0 |
| Register | N flip-flops in parallel sharing CLK / EN / CLR |
| Counter | Register + adder + constant-1, updates on each rising edge |
| SRAM / DRAM | Latch-based vs. capacitor-based memory technologies |
Summary¶
-
Sequential logic adds feedback and storage to combinational logic. Outputs depend on both the current inputs and the previous state — the ingredient every processor needs.
-
The SR latch built from cross-coupled NOR gates is the simplest storage element. Set (S=1) forces Q to 1, Reset (R=1) forces Q to 0, Hold (S=R=0) keeps the last value, and S=R=1 is forbidden.
-
Clock signals synchronize when state changes occur. Level-triggered circuits (latches) change while the clock is at a level; edge-triggered circuits (flip-flops) change only at a clock edge. Edge-triggering gives predictable timing.
-
The D flip-flop (master–slave) uses two D latches with inverted clocks so that Q only updates on the rising edge. This makes feedback safe and is the standard building block for registers.
-
MUXes select between data sources. Two MUXes in series add synchronous enable (hold vs. load) and synchronous clear (pass vs. 0) on top of a plain D flip-flop, giving us a proper 1-bit register.
-
N-bit registers and counters are built by composition: N flip-flops in parallel give an N-bit register, and a register plus an adder plus the constant 1 gives a counter.
Further Reading¶
- Digital simulator — https://github.com/hneemann/Digital — the schematic-entry tool used in class.
- Computer Organization and Design: RISC-V Edition (Patterson & Hennessy) — sequential logic, latches, flip-flops, and register files.
- Next lecture — Processor Components (Apr 9) — register file, ALU, and control, built from the components introduced today.