From one big step to five small ones
In the last guide we saw pipelining as a laundry line: while one load dries, the next is already washing, so loads finish back-to-back even though each still takes the full wash-dry-fold time. Now we make that real for a CPU. The classic teaching design — the one used by RISC-V and MIPS textbooks — slices the work of running one instruction into exactly five stages, each doing one tidy job in one clock cycle. The five are named IF, ID, EX, MEM, WB, and once you know what each does, the whole pipeline reads like an assembly line you could walk along.
- IF — Instruction Fetch: read the instruction from instruction memory at the address in the program counter, and bump the PC to point at the next one.
- ID — Instruction Decode: work out what the instruction is and read its source operands out of the register file.
- EX — Execute: the ALU does the arithmetic — an add, a compare, or computing a memory address.
- MEM — Memory access: for a load or store, read or write data memory; instructions that touch no memory simply pass through.
- WB — Write Back: write the result back into the destination register, so a later instruction can read it.
Why exactly these five? Because they fall out naturally from the instruction cycle you met earlier — fetch, decode, execute — once you split off the slow bits of memory and the final register write into their own steps. A plain register-to-register add still walks all five stages even though its MEM stage does nothing; keeping every instruction the same length is what lets them march in lock-step. That uniformity is a deliberate gift of a load-store RISC design, and it is exactly why these ISAs pipeline so cleanly.
The pipeline registers: latches between the stages
Here is the part that makes the laundry line actually work in silicon. Between every pair of stages sits a bank of latches called a pipeline register. At each rising clock edge, the work of one stage is captured into the pipeline register in front of it, and that frozen snapshot becomes the input to the next stage on the following cycle. So the registers are the dividers in the laundry — the trays that hold a half-finished load so the previous washer is free to start the next one.
Each pipeline register has to carry everything the later stages will still need, not just the data. The IF/ID register holds the fetched instruction bits. The ID/EX register holds the two operand values, the decoded control signals, and the destination register number. The EX/MEM register carries the ALU result, and the MEM/WB register carries the value about to be written back. The destination register number is the easy thing to forget — it has to ride all the way from ID to WB so that, four cycles later, the result lands in the right place.
Tracing five instructions down the line
Picture five independent instructions entering one per cycle. By cycle 5 the pipeline is full: all five stages are busy at once, each on a different instruction. That is the whole point — the steady state of a full pipeline retires one finished instruction every cycle. Drawing it as a diagram makes the staircase obvious, and it is worth staring at until the diagonal clicks into place.
cycle: 1 2 3 4 5 6 7 8 9
---------------------------------------------
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 WB
steady state (cycles 5..5): all 5 stages busy at once.
latency of one instruction : still 5 cycles (unchanged)
throughput once full : 1 instruction finished per cycleRead two numbers off this picture, because confusing them is the classic beginner mistake. The latency of any single instruction is still five cycles — pipelining made i1 not one bit faster to finish; it never improves single-instruction latency. What changed is throughput (pipeline throughput): after the line fills, a result pops out every cycle instead of every five. Run a long program of N instructions and you take roughly N + 4 cycles instead of 5N — almost a fivefold speedup, with the +4 being the one-time cost of filling the pipe.
But instructions are rarely so polite
That clean staircase assumed every instruction was independent of the others. Real programs are not so kind: an instruction often needs a value that an earlier one has not finished producing yet. These collisions are called hazards (pipeline hazards), and they are the reason the next three guides exist. There are three families, and it is worth meeting them by name now even though we cure them later.
A structural hazard is two instructions wanting the same piece of hardware in the same cycle — like one washing machine and two loads needing it at once. A control hazard comes from branches: until a branch resolves in EX, the pipeline does not truly know which instruction to fetch next, so it may have started fetching down the wrong road. And the everyday troublemaker, a data hazard, is a read-after-write dependence: an instruction tries to read a register in ID while the instruction that writes it is still only at EX or MEM and has not reached WB. The needed value exists, but it is still stuck mid-pipeline.
Look at one tiny, painful case you will meet constantly — the load-use hazard. Suppose `lw x1, 0(x2)` is immediately followed by `add x3, x1, x4`. The load only has its value back from data memory at the end of its MEM stage, but the add wants x1 in its EX stage, which lands one cycle too early. No amount of clever wiring can hand over a value that does not exist yet, so this one hazard cannot be fully hidden — the pipeline must insert at least one wasted cycle, a stall, and we will see in guide 4 exactly why this load is the stubborn exception.
What this does to CPI — and the honest tradeoff
Recall the iron law of performance: run time is instruction count x CPI x cycle time. The dream of a five-stage pipeline is a CPI of 1 — one instruction finished per cycle in steady state. Hazards spoil that dream a little. Every stall the hardware inserts adds a wasted cycle, nudging the real, observed CPI above 1. We call that the effective CPI: the ideal 1 plus the average number of stall cycles each instruction causes. If 20 percent of instructions are loads and a quarter of those force a one-cycle stall, you pay an extra 0.05 cycles per instruction on average — effective CPI 1.05.
So why not chop the work into ten stages, or twenty, for an even higher clock? This is the pipeline-depth tradeoff, and it is genuinely two-sided. Deeper pipelines have less work per stage, so each stage is faster and the clock can tick higher — that is real. But the gains shrink and the penalties grow. The fixed latch overhead becomes a bigger fraction of each shorter stage, so you do not get the full speedup from a higher clock rate. Worse, a mispredicted branch or a stall now wastes more in-flight cycles, because there are more half-done instructions to throw away.