Sequential Logic, the Clock, and Why GHz Lies to You
Part 3 of 15
Lesson 1, Part 3 of the Computer Architecture From First Principles series. Parts 1 and 2 built a combinational ALU out of gates — given inputs, it produces an output, instantly and statelessly. This part is the hinge the entire rest of computer architecture swings on: how does a circuit that has no memory turn into a machine that remembers?
This is one of the most important transitions in Computer Architecture, because this is where we go from:
"A circuit computes something"
to:
"A computer can remember something."
Let's go slowly and build the idea from first principles.
The fundamental distinction is:
Combinational logic has no memory. Sequential logic has state/memory.
But let's understand exactly what that means.
Combinational Logic
Suppose I give you:
Y = A + B
The output is completely determined by the current inputs.
For example:
If I change:
A = 7
B = 3the output becomes:
Y = 10
There is no concept of:
"What was A five seconds ago?"
The circuit only cares about the current inputs.
Mathematically:
Y = f(A, B)
That's combinational logic.
Another Example: AND Gate
Consider:
Y = A ∧ B
The truth table is:
| A | B | Y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
If the inputs are:
A = 1
B = 1then:
Y = 1Change B:
A = 1
B = 0and:
Y = 0The circuit doesn't remember that B was previously 1.
So How Does a Computer Remember?
Now imagine I tell a circuit:
Store the number 42.
Then I change the input to:
100I still want the output to be:
42until I explicitly tell the circuit to update.
That's fundamentally different.
We need something like:
The output now depends not only on the input but also on previous state.
Mathematically:
Combinational
Y_t = f(X_t)
Sequential
S_(t+1) = f(S_t, X_t)
where:
X_t= current inputS_t= current stored stateS_(t+1)= next state
That tiny difference is enormously important.
What Is "State"?
State is simply:
Information about the past that the circuit remembers and can use in the future.
For example, imagine:
S = 42The circuit remembers S = 42 even if its input changes.
In a CPU, there are huge amounts of state:
Program Counter
Registers
Cache contents
Pipeline registers
Branch predictor state
TLB entries
Reorder Buffer
Control registers
etc.So when we say:
"The CPU has state"
we mean the CPU contains physical storage elements that preserve information across clock cycles.
The Simplest Storage: A Latch
Before the flip-flop, let's understand a latch.
Imagine a box:
It has:
D= dataEN= enableQ= stored output
Think of EN as:
"Are you allowed to change?"
If EN = 1, the latch is transparent:
Q = D
If EN = 0, it holds its previous value:
Q = Q_previous
So:
EN = 1
D changes:
0 → 1 → 0 → 1
Q follows:
0 → 1 → 0 → 1But:
EN = 0
D changes:
0 → 1 → 0 → 1
Q remains:
42This is memory.
Why Is a Latch Possible?
This gets into digital logic.
A simple storage element can be constructed using feedback.
Consider two inverters:
The output of one feeds into the other.
Suppose the first node is 0. The inverter makes it 1, which feeds the second inverter, producing 0, which feeds back into the first.
So:
0 → 1 → 0 → 1 → ...The system settles into a stable state.
There are two stable configurations:
Q = 0
Q̄ = 1or:
Q = 1
Q̄ = 0That feedback gives us the ability to retain state.
This is a deep idea:
Memory in digital logic comes from feedback + stable states.
Latch vs Flip-Flop
This distinction is worth understanding.
A latch is generally level-sensitive. A flip-flop is generally edge-triggered.
Think about the clock:
CLK:
____|‾‾‾‾‾|____|‾‾‾‾‾|____A latch might say:
"While the clock is HIGH, I am allowed to track the input."
A flip-flop instead says:
"I only capture the input at a particular clock edge."
For example, a positive-edge-triggered flip-flop captures D at:
↑
CLK: ________|‾‾‾‾‾‾and then holds that value.
Flip-Flop
Conceptually:
The important rule is:
Q_next = Dat the active clock edge.
Suppose D = 42 and the clock edge occurs. Then Q = 42.
Now change D = 100 but don't provide another clock edge. Q remains 42.
At the next clock edge, Q = 100.
That's the fundamental behavior of a flip-flop.
Why Do We Need a Clock?
Now we arrive at something extremely important.
Imagine you had a CPU where every circuit could update whenever it wanted.
You might have:
The changes could propagate continuously.
How would we know when one operation ends and the next begins?
We need synchronization.
The clock gives the system discrete moments where state is allowed to change.
Think:
Time →
Cycle 1 Cycle 2 Cycle 3
CLK ↑ ↑ ↑
│ │ │
│ │ │
State ───●─────────────●─────────────●────At each active edge:
S_(t+1) = F(S_t, X_t)
So a synchronous digital system is essentially:
This pattern is the foundation of a synchronous CPU.
This Is Where the CPU Clock Comes From
Imagine:
Suppose the ALU performs A + B. The general idea is:
At the beginning of the cycle:
Register A = 10
Register B = 20The combinational logic calculates 10 + 20 = 30.
Then at the clock edge:
Destination Register = 30The next cycle starts with the new state.
This gives us a very clean mental model:
Register → Computation → Register
That pattern appears everywhere in CPUs.
Why Can't the CPU Just Update Continuously?
Because real gates aren't instantaneous.
Suppose:
Each gate has a propagation delay.
For example, purely illustratively:
AND 20 ps
XOR 30 ps
MUX 40 ps
ALU 100 psThe signal needs time to propagate.
If the register captures too early:
Bad.
Therefore the clock period needs to be long enough for the worst relevant combinational path to settle. Very roughly:
T_clock ≥ T_(clk→Q) + T_logic + T_setupwhere:
T_(clk→Q)= time for source flip-flop to produce its outputT_logic= combinational logic delayT_setup= time destination flip-flop needs the input stable before the edge
There are also clock skew, jitter, hold-time and other physical effects, which we'll get to later.
This equation is one of the bridges between digital logic and CPU frequency.
Now Let's Understand the Clock Properly
Suppose the clock looks like:
One complete repetition is one clock period, call it T.
Frequency is:
f = 1 / T
Therefore:
T = 1 / f
3 GHz
Suppose f = 3 GHz. Remember 1 GHz = 10^9 Hz, so:
f = 3 × 10^9 cycles/sTherefore:
T = 1 / (3 × 10^9)
T = 333.33 × 10^-12 s
T ≈ 333 pswhere 1 ps = 10^-12 s.
So one clock cycle lasts approximately 0.333 ns.
Does 3 GHz Mean 3 Billion Operations?
No. This is an extremely common misunderstanding.
3 GHz means:
3 billion clock cycles per second.
It does not mean 3 billion instructions/sec, because an instruction and a clock cycle are different concepts.
Example: One Instruction Per Cycle
Suppose a CPU has f = 3 GHz and can sustain 1 instruction/cycle. Then:
3 × 10^9 instructions/secSo in this specific hypothetical CPU, IPC = 1 and:
Instructions/sec = f × IPC
= 3 GHz × 1
= 3G instructions/secBut that's only one possible CPU.
What If IPC = 4?
Suppose a modern CPU can sustain IPC = 4 at 3 GHz. Then:
Instructions/sec = 3 × 10^9 × 4
= 12 × 10^9So:
12 billion instructions/sec
despite the clock being only 3 GHz.
This is why:
Clock frequency alone is a terrible measure of CPU performance.
But What Does IPC Actually Mean?
IPC: Instructions Per Cycle
If over some interval the CPU completes 1000 instructions over 250 cycles:
IPC = 1000 / 250 = 4Another useful metric is:
CPI = Cycles / Instructionand ideally CPI = 1 / IPC.
So IPC = 4 corresponds to an average CPI = 0.25.
This can initially seem strange:
How can an instruction take less than one cycle?
Because we're talking about throughput, not individual instruction latency.
Pipeline Example
Suppose our CPU has five stages:
Imagine each instruction takes five stages.
Without pipelining:
I1: IF ID EX MEM WB
I2: IF ID EX MEM WB
I3: IF ID EX MEM WBOnly one instruction is progressing at a time.
With pipelining:
Cycle → 1 2 3 4 5 6 7
I1 IF ID EX MEM WB
I2 IF ID EX MEM WB
I3 IF ID EX MEM WB
I4 IF ID EX MEM WB
I5 IF ID EX MEM WBAfter the pipeline fills:
I1 → complete
I2 → complete
I3 → complete
I4 → completePotentially one instruction completes every cycle.
Therefore IPC ≈ 1, even though Latency ≈ 5 cycles for an individual instruction.
That's the critical distinction.
Latency vs Throughput
Imagine a washing machine factory.
Each washing machine requires 10 minutes from start to finish.
So Latency = 10 min.
But if you have a pipeline:
you might complete one washing machine every 2.5 minutes after the pipeline fills.
Thus Throughput = 1 / 2.5 machines/minute.
The individual machine didn't become faster. The system became capable of processing more machines concurrently.
CPU pipelines work similarly.
Why Deeper Pipelines Can Increase Frequency
Suppose we have ALU logic = 600 ps and it's one giant combinational block.
The clock can't be much faster than 600 ps.
Now divide it into three stages:
Stage 1 = 200 ps
Stage 2 = 200 ps
Stage 3 = 200 psNow theoretically T_cycle ≈ 200 ps and f ≈ 5 GHz instead of f ≈ 1.67 GHz.
So deeper pipelines can increase clock frequency.
But there's a cost. More pipeline stages mean:
- more registers
- more clock power
- more latency
- more complicated hazard handling
- branch misprediction penalties become larger
- more forwarding paths
- more design complexity
So there is a tradeoff. This is why CPU architecture is fundamentally about tradeoffs, not maximizing one metric.
Why Branches Become Painful
Suppose we have:
BEQ R1,R2,targetThe CPU doesn't immediately know whether the branch is taken.
But the pipeline wants to keep fetching instructions.
Suppose:
Cycle 1: Fetch branch
Cycle 2: Decode branch
Cycle 3: Determine branchWhat should we fetch in cycle 2? The next sequential instruction, or the target instruction? We don't know yet.
So the CPU predicts.
Suppose it predicts Not taken, but discovers Actually taken!
Then instructions fetched along the wrong path have to be discarded. That's a:
Pipeline flush
If the pipeline is 20 stages deep, a branch misprediction can potentially waste many cycles.
Hence branch prediction becomes critical.
The Clock Is Not the CPU
Another subtle point.
A CPU doesn't "do one thing" on every clock edge.
Instead, the clock coordinates state transitions.
Between edges, combinational logic computes. At an edge, state is captured.
Conceptually:
Cycle N
Registers
│
▼
Combinational logic
│
│ computation happens
│
▼
Registers
↑
clock
edge
Cycle N+1So:
Clock = synchronization mechanism, not Clock = instruction execution mechanism.
A More Accurate CPU Mental Model
You can now think of a CPU as:
Mathematically:
S_(t+1) = F(S_t, X_t)
The clock determines when S_(t+1) replaces S_t.
That's the heart of synchronous digital design.
One More Important Concept: Setup and Hold Time
A flip-flop isn't infinitely fast.
For a flip-flop to correctly capture D at a clock edge:
Setup time
D must be stable for some time before the clock edge.
Hold time
D must remain stable for some time after the clock edge.
Conceptually:
setup hold
│ │
▼ ▼
D: ───────████████████──────
↑
clock edgeIf D changes too close to the edge, the flip-flop can enter an unstable condition. This can lead to:
Metastability
This is a very important concept when we later discuss:
- interrupts
- asynchronous inputs
- CDC (clock-domain crossing)
- hardware interfaces
- synchronizers
- embedded systems.
So What Actually Limits Clock Frequency?
At a high level:
T_clock ≥ T_register + T_combinational + T_setup + T_marginTherefore:
f_max ≈ 1 / T_criticalThe slowest/longest register-to-register path determines the maximum achievable clock frequency. This is called the:
Critical path
For example:
If this path takes 400 ps while every other path takes 200 ps, the clock must accommodate the 400-ps path.
Therefore f_max ≲ 2.5 GHz, ignoring other timing overheads.
This concept becomes extremely important when designing hardware.
Now Connect This Back to the CPU
Imagine:
At cycle N:
R1 = 10
R2 = 20ALU computes 10 + 20 = 30.
At the clock edge:
R3 ← 30Then cycle N+1 starts with R3 = 30.
This gives us the basic computational rhythm:
Read state → Compute → Capture new state
And that is essentially what a synchronous CPU does billions of times per second.
One Final Distinction: Register vs Memory
When we say:
"A flip-flop stores one bit."
we shouldn't immediately imagine that all computer memory is made from flip-flops.
Different storage technologies exist. For example:
They have very different:
- density
- latency
- power
- cost
- persistence
- implementation.
We'll eventually derive why an SRAM bit cell is different from a flip-flop, why DRAM uses capacitors, and why caches use SRAM while main memory uses DRAM.
The Big Picture You Should Have Now
You can compress everything we've discussed into this:
The fundamental equation is:
S_(t+1) = F(S_t, X_t)
and the clock determines when S_t → S_(t+1).
The Key Mental Model
If you remember only four things from this section, remember these:
1. Combinational logic
Y = f(X)
No memory.
2. Sequential logic
S_next = f(S, X)
Has memory/state.
3. Flip-flop
Q_next = D
at a clock edge. It stores one bit.
4. CPU
State → Computation → Next State
repeated synchronously.
Further Reading
- MIT OCW 6.004, Sequential Logic — the D-latch, D-register, and timing-constraint material this section builds on.
- GeeksforGeeks, Combinational Circuit vs Sequential Circuit and Introduction of Sequential Circuits.
- Instructions per cycle (Wikipedia) — a concise reference for the GHz-vs-IPC-vs-throughput distinction covered above.
- Ben Eater's "Build an 8-bit computer from scratch" series — watching a real clock signal drive a real breadboard register makes the D flip-flop material in this post tangible in a way no diagram can.
- Patterson & Hennessy, Computer Organization and Design — the standard textbook treatment of clocking methodology and setup/hold timing.
- Harris & Harris, Digital Design and Computer Architecture — a deeper dive into latch/flip-flop circuit-level design (the two-inverter feedback loop) than this post attempts.
And this gives us the perfect bridge to the next layer — Lesson 1, Part 4:
How do we take individual 1-bit storage elements and turn them into a 64-bit register, then 32/64 registers into a register file, and finally connect that register file to an ALU to build an actual CPU datapath?
That's where register files, multiplexers, buses, decoders, the PC, and the actual datapath come in — the subject of the next post.