Processor Datapath & Pipelining
Level 3 — Production (from-scratch derivations, code/logic from memory, explain-out-loud) Time limit: 45 minutes Total marks: 60
Question 1 — Single-cycle clock period derivation (10 marks)
A single-cycle MIPS datapath has the following component latencies:
| Component | Latency (ps) |
|---|---|
| Instruction memory | 200 |
| Register file (read or write) | 100 |
| ALU | 200 |
| Data memory | 200 |
| Sign-extend, muxes, control | 0 |
(a) Derive the critical-path delay and hence the minimum clock period for a design that must support lw. Show the sequence of components traversed. (5 marks)
(b) A colleague proposes clocking the design at the delay of the add instruction instead. Explain out loud why a single-cycle machine cannot do this, and state the CPI of a single-cycle machine. (3 marks)
(c) If the instruction mix is 25% lw, 10% sw, 45% R-type (add-path = 600 ps), 15% beq, 5% j, compute the average time per instruction for an ideal multi-cycle design that only spends as long as each instruction needs, versus the single-cycle time. State the speedup. (2 marks)
Question 2 — Forwarding logic from memory (12 marks)
Consider the classic 5-stage pipeline (IF/ID/EX/MEM/WB) with a forwarding unit.
(a) Write, from memory, the Boolean conditions for the EX-hazard forwarding of the ALU's first operand (ForwardA = 10). Use signal names EX/MEM.RegWrite, EX/MEM.RegisterRd, ID/EX.RegisterRs. (4 marks)
(b) Write the MEM-hazard condition for ForwardA = 01, including the term that prevents it from firing when EX-hazard already handles the operand. Explain why that extra term is needed. (5 marks)
(c) Why must every forwarding condition include a RegisterRd ≠ 0 check? (3 marks)
Question 3 — Load-use hazard detection & stalls (10 marks)
(a) Write the hazard-detection-unit condition that detects a load-use hazard and forces a stall. Use ID/EX.MemRead, ID/EX.RegisterRt, IF/ID.RegisterRs, IF/ID.RegisterRt. (4 marks)
(b) Explain out loud what three actions the control logic performs in the cycle a stall is inserted. (3 marks)
(c) For the code below, show a pipeline diagram (cycle-by-cycle) and state how many stall cycles are needed with forwarding enabled:
lw $t0, 0($t1)
add $t2, $t0, $t3
sub $t4, $t2, $t0
(3 marks)
Question 4 — Control hazards & throughput (10 marks)
A pipeline resolves branches in the MEM stage and flushes on a taken branch. Branch penalty is therefore 3 cycles.
(a) Given 20% branches, 60% taken, derive the average CPI (ignore data hazards; assume flushes only on taken branches). (4 marks)
(b) The architects move branch resolution to the ID stage (penalty 1 cycle). Recompute CPI and give the speedup over part (a). (3 marks)
(c) Explain out loud the cost of resolving branches earlier in ID, and one hazard it can introduce. (3 marks)
Question 5 — Deep pipelining trade-off derivation (10 marks)
An unpipelined datapath does work ps per instruction. Splitting into equal stages adds a register overhead of ps per stage.
(a) Write the expression for the clock period and for ideal throughput as functions of . (3 marks)
(b) Assuming ideal (hazard-free) pipelining, does throughput keep rising with ? Derive the throughput at and and comment. (4 marks)
(c) Real pipelines see CPI grow with depth (more hazards, higher branch penalty). If effective CPI , find the (integer) that maximises throughput; work by evaluating . (3 marks)
Question 6 — Precise exceptions (8 marks)
(a) Define a precise exception in the context of a pipeline. (2 marks)
(b) Explain out loud why out-of-order completion in a deep pipeline threatens precise exceptions, and describe how a reorder buffer / in-order commit restores precision. (4 marks)
(c) In the in-order 5-stage pipeline, why must an exception detected in an earlier instruction (further down the pipe) take priority over one detected in a later instruction in the same cycle? (2 marks)
Answer keyMark scheme & solutions
Question 1
(a) lw traverses: I-Mem → Reg read → ALU (address) → Data Mem → Reg write.
Critical path = 800 ps, so minimum clock period = 800 ps. (3 marks path, 2 marks total)
(b) In a single-cycle machine every instruction completes in exactly one clock cycle, so the clock period must accommodate the slowest instruction (lw, 800 ps). Clocking at the add delay (600 ps) would truncate lw before data memory + write-back complete → incorrect results. CPI = 1 (by definition, one cycle per instruction). (3 marks)
(c) Ideal per-instruction times: lw=800, sw=700 (I-Mem+Reg+ALU+DMem = 200+100+200+200), R-type=600, beq=500 (200+100+200), j=200.
Speedup vs single-cycle (800 ps) = . (2 marks)
Question 2
(a) EX hazard, ForwardA = 10:
if (EX/MEM.RegWrite
and (EX/MEM.RegisterRd ≠ 0)
and (EX/MEM.RegisterRd = ID/EX.RegisterRs))
ForwardA = 10
(4 marks; 1 each for RegWrite, Rd≠0, Rd=Rs match, correct output code)
(b) MEM hazard, ForwardA = 01:
if (MEM/WB.RegWrite
and (MEM/WB.RegisterRd ≠ 0)
and NOT(EX/MEM.RegWrite and (EX/MEM.RegisterRd ≠ 0)
and (EX/MEM.RegisterRd = ID/EX.RegisterRs))
and (MEM/WB.RegisterRd = ID/EX.RegisterRs))
ForwardA = 01
The NOT(...) term ensures the most recent (closer, EX/MEM) result is forwarded when both a MEM/WB and an EX/MEM instruction write the same register; without it, the stale older value from MEM/WB could override the newer one. (3 marks logic, 2 marks explanation)
(c) Register $0 is hardwired to zero and can never be written. If we forwarded on Rd = 0, an instruction whose destination is $0 (used as a no-op / discard) would incorrectly forward a garbage/computed value in place of the constant zero. The ≠ 0 guard prevents false forwarding. (3 marks)
Question 3
(a) Load-use hazard detection:
if (ID/EX.MemRead
and ((ID/EX.RegisterRt = IF/ID.RegisterRs)
or (ID/EX.RegisterRt = IF/ID.RegisterRt)))
stall the pipeline
(4 marks; MemRead + Rt match against both source regs)
(b) In the stall cycle the control unit:
- Freezes the PC (do not fetch next instruction).
- Freezes the IF/ID register (hold the dependent instruction).
- Inserts a bubble: zero the control signals in ID/EX (turn the EX/MEM/WB controls into a nop). (1 mark each)
(c) Pipeline diagram (F=IF, D=ID, X=EX, M=MEM, W=WB, *=stall bubble):
Cyc: 1 2 3 4 5 6 7 8
lw F D X M W
add F D * X M W
sub F * D X M W
The lw result is available after its MEM (cycle 4) and forwarded into add's EX (cycle 5); one stall cycle is required. 1 stall cycle. (sub gets $t2 and $t0 by normal EX/MEM and MEM/WB forwarding, no extra stall.) (3 marks)
Question 4
(a) Fraction of taken branches = . Each taken branch costs 3 penalty cycles. (4 marks)
(b) Penalty now 1 cycle: Speedup = (≈ 1.21×). (3 marks)
(c) Resolving in ID requires moving the comparator and target-address adder into the ID stage, lengthening the ID-stage critical path (may raise clock period). It also introduces a data hazard: a branch that depends on a result still in EX/MEM cannot get its operand by normal forwarding in time, forcing an extra branch-comparison stall (or dedicated forwarding into ID). (3 marks)
Question 5
(a) Clock period: Ideal throughput (instructions/ps), one instr completes per cycle in steady state: (3 marks)
(b) : ps → throughput /ps. : ps → throughput /ps. Throughput keeps rising with but with diminishing returns — the fixed ps overhead dominates as ; the asymptotic ceiling is /ps. (4 marks)
(c) Effective throughput .
| throughput () | ||||
|---|---|---|---|---|
| 5 | 1.25 | 240 | 300 | 3.33 |
| 8 | 1.40 | 165 | 231 | 4.33 |
| 10 | 1.50 | 140 | 210 | 4.76 |
| 12 | 1.60 | 123.3 | 197.3 | 5.07 |
Throughput is still rising at among the sampled values; of the evaluated points gives the highest throughput. (Continuous optimum is near ; among tested integers, 12 wins.) (3 marks)
Question 6
(a) A precise exception is one where, when the exception is taken, all instructions before the faulting instruction have completed and updated architectural state, and no instruction at or after the faulting instruction has modified architectural state — so the saved PC and register/memory state correspond to a single well-defined point in the sequential program order. (2 marks)
(b) In a deep/out-of-order pipeline, a later instruction may finish (write results) before an earlier instruction that then faults; architectural state is thus corrupted out of program order, making the exception imprecise. A reorder buffer holds results in program order and commits (retires) instructions in order: results are written to architectural state only at commit. If a faulting instruction reaches the head of the ROB, all earlier instructions have committed and all later ones are squashed before committing — restoring a precise state. (4 marks)
(c) Instructions must be handled in program order for a precise exception. The earlier instruction (further down the pipe) precedes the later one in program order; if the later one's exception were taken first, the earlier instruction would be abandoned, and the state would not correspond to a precise, in-order point. Priority to the oldest instruction guarantees the exception is reported at the correct architectural PC. (2 marks)
[
{"claim":"Q1a lw critical path = 800 ps","code":"result = (200+100+200+200+100)==800"},
{"claim":"Q1c average multicycle time = 625 ps and speedup 1.28","code":"avg=0.25*800+0.10*700+0.45*600+0.15*500+0.05*200; result = (avg==625) and (abs(800/avg-1.28)<0.005)"},
{"claim":"Q4a CPI = 1.36 with 3-cycle penalty","code":"result = abs((1+0.20*0.60*3)-1.36)<1e-9"},
{"claim":"Q4b CPI 1.12 and speedup ~1.214","code":"cpi=1+0.20*0.60*1; result = abs(cpi-1.12)<1e-9 and abs(1.36/1.12-1.2143)<0.001"},
{"claim":"Q5b throughput k=10 = 1/140","code":"result = abs(1/(1000/10+40) - 1/140)<1e-12"},
{"claim":"Q5c k=12 gives lowest CPI*Tclk among 5,8,10,12","code":"f=lambda k:(1+0.05*k)*(1000/k+40); vals={k:f(k) for k in [5,8,10,12]}; result = min(vals,key=vals.get)==12"}
]