Intuition The one-sentence idea
A pipeline is an assembly line: each worker (stage) needs the unfinished product plus the instructions of what to do next handed to it. Pipeline registers are the conveyor-belt trays that carry both the data and the control signals from one stage to the next, so every instruction keeps its own paperwork as it moves.
In a single-cycle datapath, one instruction flows through combinational logic (ALU, muxes, adders) from PC to write-back in one long clock. In a pipeline we want 5 instructions in flight at once . But combinational logic has no memory — if instruction B's inputs arrive at the ALU while instruction A's result is still travelling to memory, they collide.
We need a wall with lockers between each stage that latches values on the clock edge. That wall = the pipeline register. It freezes stage-N's output so stage-N+1 can consume it next cycle while stage-N works on a new instruction.
WHAT they are: edge-triggered registers placed between the 5 classic stages. Named after the two stages they sit between:
Register
Between stages
Carries (data)
IF/ID
Fetch → Decode
instruction word, PC+4
ID/EX
Decode → Execute
reg values, sign-ext imm, PC+4, dest reg #
EX/MEM
Execute → Memory
ALU result, branch target, store data, dest reg #
MEM/WB
Memory → Write-back
memory data, ALU result, dest reg #
Note: there is no register after WB — the result is written into the register file, which is the storage.
Intuition The "paperwork travels with the part" principle
Control signals (like RegWrite, MemRead, ALUOp, MemtoReg) are all generated once, in the Decode stage , by the control unit reading the opcode. But some of them are needed later — e.g. RegWrite is only used in WB, four cycles after decode.
If we tried to regenerate them in each stage, stage 5 wouldn't know which instruction it's serving. So instead we compute all control signals in ID, then latch the not-yet-used ones into ID/EX, and let them travel stage-by-stage , dropping off signals where each is consumed.
Definition Control-signal grouping
Control signals are split into three bundles by which stage uses them :
EX bundle: ALUSrc, ALUOp, RegDst (used in Execute)
MEM bundle: MemRead, MemWrite, Branch (used in Memory)
WB bundle: RegWrite, MemtoReg (used in Write-back)
ID/EX holds all three bundles. EX/MEM holds MEM+WB. MEM/WB holds only WB. Each register drops the bundle just consumed.
RegWrite for add $t0,$t1,$t2
Step — ID: Control unit reads opcode 000000 → sets RegWrite=1. Why this step? Because opcode is only visible in ID; decide once.
Step — latch into ID/EX: RegWrite=1 stored in ID/EX at clock edge. Why? WB is 3 cycles away; must be preserved.
Step — EX→EX/MEM: EX doesn't use RegWrite, so it copies it unchanged into EX/MEM. Why? A stage passes along paperwork it doesn't consume.
Step — MEM→MEM/WB: Still unused, copied into MEM/WB.
Step — WB: RegWrite=1 finally drives the register file's write-enable. Why now? This is where the destination register is actually written. Result lands in $t0.
Worked example Why the destination register number must travel too
Consider lw $s0, 0($t0). The write-back writes into $s0. But which register number is $s0? It was decoded in ID (bits 20–16). By WB, four cycles later, the instruction word is long gone from IF/ID.
Step: dest reg # (5 bits) is latched ID/EX → EX/MEM → MEM/WB. Why this step? Without carrying it, WB would write to the wrong register (whatever number happens to be on the bus). This exact bug — using the current instruction's field instead of the pipelined one — is a classic datapath error.
Common mistake "Control signals are regenerated fresh in each stage."
Why it feels right: Each stage has combinational logic, so surely it 'knows' what to do. The flaw: only ID has the opcode; other stages see only data + latched signals. Fix: all signals are computed once in ID and transported via pipeline registers.
Common mistake "The write-back writes to the register named in the current IF/ID instruction."
Why it feels right: In a single-cycle CPU there is only one instruction, so 'the' destination is unambiguous. The flaw: in a pipeline, 5 different instructions occupy the 5 stages; the one in WB was fetched 4 cycles ago. Fix: the destination reg # rides in the pipeline registers so WB writes the correct, older instruction's target.
Common mistake "We need a register after the WB stage too."
Why it feels right: Symmetry — 5 stages, so 5 walls? The flaw: WB's output goes into the register file , which is already stateful storage. Adding another latch would just delay the write by a cycle and worsen hazards. Fix: only 4 pipeline registers (IF/ID, ID/EX, EX/MEM, MEM/WB).
Common mistake "PC+4 only needs to be in IF/ID."
Why it feels right: PC increment happens in fetch. The flaw: branch target = PC+4 + (imm<<2) is computed in EX, so PC+4 must survive to EX/MEM. Fix: carry PC+4 through ID/EX (and to EX/MEM if branch resolves there).
Recall Feynman: explain to a 12-year-old
Imagine a sandwich shop with 5 workers in a line: one gets the bread, one adds cheese, one grills, one wraps, one hands it over. Between each worker there's a little tray . When a worker finishes, they put the half-made sandwich and a sticky note saying what to do next on the tray. The next worker grabs the tray, reads the note, and does their job. The trays are the pipeline registers , and the sticky notes are the control signals . This way 5 sandwiches are being made at the same time, and nobody forgets what to do — because the instructions travel with the sandwich!
"I Decide Everything, My Work." — IF/ID, ID/EX, EX/MEM, MEM/WB (the 4 registers, in order). And for the 3 control bundles: "EX signals eat first, MEM next, WB last leaves the line."
How many pipeline registers are in a classic 5-stage MIPS pipeline, and why not 5? Four (IF/ID, ID/EX, EX/MEM, MEM/WB). No register after WB because WB writes into the register file, which is already stateful storage.
In which stage are ALL control signals generated? In ID (Decode), because that's the only stage that sees the opcode.
Why must control signals travel inside pipeline registers? Because signals like RegWrite are used stages later (WB), but can only be decoded from the opcode in ID; they must be transported forward.
Which three bundles are control signals grouped into? EX bundle (ALUSrc, ALUOp, RegDst), MEM bundle (MemRead, MemWrite, Branch), WB bundle (RegWrite, MemtoReg).
Why does the destination register number ride through the pipeline registers? Because the instruction word is gone by WB; without carrying the 5-bit dest #, WB would write to the wrong register.
What does ID/EX carry that EX/MEM no longer needs? The EX control bundle (ALUSrc, ALUOp, RegDst) — it's consumed in EX and dropped afterward.
Which pipeline register carries the ALU result and store data? EX/MEM.
Why is PC+4 carried past IF/ID? Because the branch target (PC+4 + imm<<2) is computed later in EX, so PC+4 must survive to that stage.
What happens to a control bundle after its stage consumes it? It is dropped and not latched into the next pipeline register (each register is narrower for control than the one before).
Single-cycle datapath — the starting point before we insert registers
Pipeline hazards — data/control hazards arise because signals and results are staggered across these registers
Forwarding and stalling — reads values directly out of EX/MEM and MEM/WB registers
Control unit design — the source that generates all bundles in ID
Clocking and edge-triggered flip-flops — the mechanism that lets registers latch cleanly
combinational logic collides
each stage drops consumed bundle
Freeze stage output each cycle
Reg values, imm, dest reg
ALU result, branch target, store data
Signal used then discarded
Intuition Hinglish mein samjho
Dekho, pipeline ek assembly line jaisa hai — 5 workers (IF, ID, EX, MEM, WB) ek line mein kaam kar rahe hain. Har do workers ke beech ek pipeline register (tray) hota hai. Jab ek stage apna kaam khatam karta hai, wo apna result us tray mein rakh deta hai, aur agla stage clock edge par use utha leta hai. Isliye ek saath 5 instructions "in flight" reh sakti hain bina aapas mein takraaye.
Ab sabse important baat: control signals (jaise RegWrite, MemRead, ALUOp) sirf ID stage mein bante hain, kyunki opcode wahi visible hota hai. Lekin kuch signals baad mein chahiye hote hain — jaise RegWrite to WB stage mein 3 cycle baad use hota hai. To hum saare signals ID mein bana ke unhe pipeline register mein daal dete hain, aur wo instruction ke saath-saath travel karte hain. Har stage jo signal use kar leta hai, use aage nahi bhejta — isko "bundle drop karna" bolte hain (EX, MEM, WB bundles).
Ek badi galti jo students karte hain: wo sochte hain ki har stage apne signals khud bana leta hai. Nahi bhai! Sirf ID banata hai, baaki stages sirf latched signals padhte hain. Doosri galti — destination register number (jaise $s0 ka number) ko bhi carry karna zaroori hai, warna WB galat register mein likh dega, kyunki tab tak instruction word gayab ho chuka hota hai.
Yaad rakho: 4 hi registers hote hain (WB ke baad koi nahi, kyunki register file khud storage hai). Jab tumhe hazards aur forwarding padhna ho, tab yahi EX/MEM aur MEM/WB registers se hi values directly forward hoti hain — isliye yeh concept ki neev hai.