The Fetch-Decode-Execute Cycle, One Clock Edge at a Time
We've spent four lessons taking the CPU apart piece by piece: reset forces a known starting address, a decoder turns opcode bits into control wires, the ALU computes everything in parallel and a mux picks the winner, and a control unit — microcoded or hardwired — sequences all of this across however many cycles an instruction needs. Now it's time to put the pieces back together and watch them work as one machine, on one real instruction, one clock edge at a time. By the end of this lesson, "the CPU executed an instruction" should stop sounding abstract and start sounding like exactly what it is: a tightly choreographed sequence of wires flipping in a specific order, driven by nothing more than a clock and some combinational logic.
Our Subject: AVR ADD R1, R2
We'll trace the AVR instruction ADD R1, R2 — add register R2 into register R1, store the result back in R1. Its 16-bit encoding, straight out of lesson 2:
Break the encoding into fields:
- Fixed opcode prefix:
0000 11. - Destination bits:
0 00001, selectingR1. - Source bits:
0010, combined with the extra source bit, selectingR2. - Decoder result: read
R1andR2, add them, and write the result back toR1.
On AVR, this single instruction executes in exactly one clock cycle — a direct payoff of the hardwired control philosophy from lesson 4. (We'll also glance at the 8085 equivalent, which needs multiple T-states, to highlight the contrast.)
Learning Objectives
By the end of this lesson, you should be able to:
- Trace a simple instruction from fetch through writeback.
- Identify which CPU events are clocked and which are combinational settling.
- Explain why setup time, propagation delay, and clock period constrain instruction timing.
- Compare a single-cycle AVR register operation with a multi-T-state 8085 memory operation.
- Use timing diagrams to debug incorrect register writes, stale opcodes, or missed flag updates.
The Datapath We're About to Watch
Every box here is something you've already met. This lesson is purely about timing — which wires assert on which edge.
Step-by-Step Across the Clock Cycle
Notice everything between T0 and T1 — fetch, decode, register read, ALU compute — happens as combinational logic settling, not as separate clocked steps. The clock only marks two moments: "start this instruction" (T0) and "commit the results" (T1). Inside that window, signal propagation through the decoder and ALU just needs to finish before T1 arrives, which is exactly why lesson 3's "constant ALU delay regardless of operation" property matters: the clock period has to be long enough for the slowest possible combinational path, every single cycle.
Worked Example: Minimum Clock Period
A simplified single-cycle CPU has these worst-case delays for an ADD path:
| Path segment | Delay |
|---|---|
| PC clock-to-output | 0.5 ns |
| Instruction memory access | 4.0 ns |
| Instruction decode | 1.5 ns |
| Register file read | 1.0 ns |
| ALU add and flag logic | 3.0 ns |
| Register setup time | 0.5 ns |
The clock period must cover the whole path from one clocked state element to the next:
Tclk_min = 0.5 + 4.0 + 1.5 + 1.0 + 3.0 + 0.5 ns.Tclk_min = 10.5 ns.fmax = 1 / Tclk_min.fmaxis approximately95.2 MHz.
Real CPUs include clock skew, routing delay, memory wait states, and margin, so the production maximum frequency would be lower. The calculation still shows the core rule: one instruction per cycle is only safe when every required signal arrives before the next capture edge.
Waveform View: Which Wire Fires When
The timing sketch below is explanatory, not a gate-level simulation. It shows valid windows and latch pulses within one AVR-style ADD R1, R2 cycle.
title "AVR ADD R1, R2 timing"
time start=0 end=10 unit=ns divisions=10
CLK: square label="clock" low=0 high=1 duty=50 cycles=1 unit=logic color=#ca8a04
ADDR: step label="PC address valid" low=0 high=1 at=1 unit=logic color=#2563eb
OP: step label="opcode valid" low=0 high=1 at=2 unit=logic color=#16a34a
DEC: step label="decode settled" low=0 high=1 at=4 unit=logic color=#9333ea
ALU: step label="ALU result valid" low=0 high=1 at=7 unit=logic color=#dc2626
WE: pulse label="write enable" low=0 high=1 at=9 width=0.5 unit=logic color=#0f766e
marker T0 at=0 label="T0 edge"
marker T1 at=10 label="T1 edge"
Read this left to right: the opcode bus has valid data almost immediately, the decoder output settles a little later (it has to wait for the IR latch), the register file read happens once addresses are known, and the ALU result is the last thing to settle — because it's waiting on everything upstream. RF_WE (register file write-enable), SREG_latch, and PC_inc all fire together, right at the end of the cycle, because writing back early — before the ALU result is guaranteed stable — would corrupt the register file with a half-settled value.
Contrast: The 8085's Multi-T-State Version
The 8085 (microcoded, lesson 4) needs multiple T-states even for a simple accumulator operation, because its bus and ALU aren't built for everything to happen in one combinational sweep. A representative ADD M (add memory operand pointed to by HL into the accumulator) takes several T-states:
| T-state | What happens |
|---|---|
| T1 | Opcode fetch begins; PC drives address bus |
| T2 | Opcode latched into instruction register; decode starts |
| T3 | HL register pair drives address bus to fetch memory operand |
| T4 | Memory operand read onto data bus, latched into temp register |
| T5 | ALU adds accumulator + temp register; result stored in accumulator, flags updated |
This is the microcode sequencer from lesson 4 in action: each T-state corresponds to one row read out of the 8085's internal microcode-driven control logic, asserting a different subset of control wires each time, because the operand has to travel from memory to the ALU across a shared, narrower internal bus rather than AVR's direct register-file-to-ALU wiring.
ARM Cortex-M Thumb Encoding, For Comparison
A roughly equivalent ARM Thumb instruction, ADDS R1, R1, R2 (add R2 into R1, set flags), also uses a compact 16-bit Thumb encoding. In the Thumb T1 form, the fixed 0001100 pattern identifies register add, while the remaining rrr, rrr, and ddd fields select the source and destination registers.
Cortex-M's pipeline overlaps fetch/decode/execute across instructions rather than completing everything in a single isolated cycle — but the combinational decode-to-control-signal mapping inside each stage is the same principle as AVR's: opcode bits matched by hardwired logic (lesson 2), function-select bits routed straight into the ALU mux (lesson 3), all driven by a clock that — because control is hardwired, not microcoded (lesson 4) — has predictable per-stage timing, which is precisely what makes the pipeline overlap safe to build in the first place.
Everything At Once: The Full Picture
This loop — fetch, decode, execute, writeback, increment, repeat — is the entire reason a CPU appears to "run a program." There is no higher-level interpreter, no hidden intelligence. It's reset's fixed starting point, the decoder's mechanical bit-matching, the ALU's parallel-compute-then-select trick, and the control unit's cycle-sequencing strategy, looping at clock speed, forever, until power is removed.
Common Mistakes
- Treating fetch, decode, and execute as always separate clock cycles. In a single-cycle datapath they are phases of settling inside one cycle.
- Writing the register file before the ALU result and flags are stable.
- Ignoring memory wait states; flash or external memory can stretch the fetch path.
- Assuming pipeline overlap changes the architectural result. It changes timing, not instruction semantics.
- Forgetting that flags are part of writeback and must correspond to the same selected result as the destination register.
Summary
Everything from lesson 1 onward converges right here: reset gave the CPU a starting address, the decoder turned that address's opcode into wires, the ALU computed every possible result and let the mux pick one, and the control philosophy (hardwired or microcoded) determined whether that all happened in one clock cycle or five. "The fetch-decode-execute cycle" isn't a separate new concept to memorize — it's simply the name for watching all four previous mechanisms run together, on schedule, clock edge after clock edge, for as long as the chip has power.
This is the last lesson in the Internals series — you now have the complete chain from "power applied" to "instruction executed," wire by wire.
Further Reading
- Patterson and Hennessy, Computer Organization and Design, single-cycle and pipelined datapath chapters.
- Microchip, AVR Instruction Set Manual, instruction cycle counts and status flag behavior.
- Intel, 8085 Microprocessor User Manual, machine cycles and T-state timing.
- Arm, Cortex-M Technical Reference Manuals, fetch/decode/execute pipeline descriptions.