5.2.1 · D5Processor Datapath & Pipelining

Question bank — Single-cycle datapath design

2,110 words10 min readBack to topic

Before you start, make sure these words feel solid; if not, revisit the parent note. The figure below is your map — every question refers to a block or wire on it, so glance back whenever a name feels unfamiliar.

Figure — Single-cycle datapath design
Recall Quick vocabulary refresh — the hardware blocks (open only if unsure)
  • PC (Program Counter) ::: a small register that holds the address of the instruction currently being run; each cycle it either advances to PC+4 (the next instruction, 4 bytes further) or jumps to a branch/jump target.
  • Instruction memory ::: the storage the CPU reads the current instruction out of, using the address held in the PC.
  • Data memory ::: the separate storage that lw (load) reads from and sw (store) writes to; ordinary arithmetic never touches it.
  • Register file ::: the small fast bank of CPU registers with two read ports and one write port.
  • ALU (Arithmetic Logic Unit) ::: the block that adds, subtracts, compares, and computes memory addresses — the "calculator" of the datapath.
  • Sign-extender ::: hardware that copies a 16-bit immediate's top bit upward to make a correct 32-bit value (keeps negatives negative).
Recall Quick vocabulary refresh — the control signals (open only if unsure)
  • RegWrite ::: 1 = write a result into the register file this cycle; 0 = leave the register file untouched.
  • ALUSrc ::: chooses the ALU's second input — 0 = register rt, 1 = sign-extended immediate.
  • MemRead / MemWrite ::: enable reading from / writing to data memory (1 = active).
  • MemToReg ::: chooses the write-back value — 0 = ALU result, 1 = data-memory output.
  • RegDst ::: chooses the destination register field — 0 = rt (I-type), 1 = rd (R-type).
  • Branch ::: 1 only for branch instructions; combined with Zero to decide the next PC.
  • Zero ::: an output from the ALU that is 1 when its result is zero (used to test beq equality).
  • PCSrc ::: chooses the next PC — 0 = PC+4, 1 = branch target; driven by Branch AND Zero.
Recall Quick vocabulary refresh — general terms (open only if unsure)
  • CPI ::: cycles per instruction — how many clock ticks one instruction takes on average.
  • Critical path ::: the longest chain of hardware delays any instruction must travel through in one cycle.
  • Mux ::: a selector switch; it picks one of several input wires to pass through, chosen by a control signal.
  • R-type / I-type / J-type ::: instruction shapes. R-type (add) uses only registers; I-type (lw, sw, beq) carries a 16-bit immediate; J-type (j) carries a 26-bit jump target and unconditionally changes the PC.

True or false — justify

TF1. "Single-cycle" means the CPU can only run one type of instruction.
False — it means each instruction finishes in one clock cycle (CPI = 1); all instruction types coexist and muxes route the data appropriately.
TF2. Because CPI = 1, a single-cycle CPU is automatically the fastest possible design.
False — total time is CPI × clock period × instruction count, and single-cycle pays for CPI = 1 with an enormous clock period set by the slowest instruction.
TF3. In a single-cycle datapath the ALU can be reused to compute PC+4.
False — within the same cycle the ALU is already busy with the instruction's own arithmetic, so PC+4 and the branch target each need their own dedicated adder.
TF4. Every instruction physically passes through all five functional-unit regions each cycle.
True in the sense that the wires and blocks are all present and powered every cycle, but unused results (e.g. data memory for an R-type) are simply ignored by the control signals rather than removed. These are hardware regions, not five clock cycles.
TF5. Adding one slow instruction only slows that instruction down.
False — the clock period is the max over all instructions, so one slow instruction raises the period for every instruction on the machine.
TF6. A beq that is not taken still reads the register file.
True — the register file always reads rs and rt in the decode region regardless of the outcome; only the use of the comparison (the PCSrc mux) changes.
TF7. Setting RegWrite = 0 for a store also requires setting the RegDst mux correctly.
False — if RegWrite = 0 nothing is written, so the destination-select mux is a "don't care" (X); its value is irrelevant because no write happens.
TF8. The sign-extender is only needed for arithmetic immediates, not for branches.
False — branches also sign-extend their 16-bit offset to 32 bits (so negative backward jumps work) before the left-shift by 2.
TF9. A J-type jump (j) uses the ALU's Zero output to decide whether to jump.
False — a jump is unconditional; it ignores Zero entirely and always overrides the PC with its computed target via a dedicated jump-target mux.

Spot the error

SE1. "For a branch, shift the 16-bit immediate left by 2, then sign-extend to 32 bits."
Order is wrong — you must sign-extend first, then shift left 2; shifting first corrupts the high bits and destroys sign correctness for negative offsets.
SE2. "Branch target = PC + (SignExt(imm) << 2)."
The base is wrong — it must be PC+4, the already-incremented PC, not PC; MIPS defines branches relative to the next instruction.
SE3. "The PCSrc mux is controlled by the Branch signal alone."
Incomplete — it needs Branch AND the ALU's Zero output; a branch instruction that compares unequal must not take the branch.
SE4. "For lw, MemToReg = 0 so the ALU result is written back."
Wrong value — a load must write back the data-memory output, so MemToReg = 1 selects memory (the ALU here only computed the address).
SE5. "R-type needs ALUSrc = 1 to feed the immediate into the ALU."
Wrong — R-type has no immediate; ALUSrc = 0 so the ALU's second operand is the register rt. ALUSrc = 1 is for lw/sw.
SE6. "We can drop the RegDst mux if all instructions used the same destination field."
The premise is the whole point — R-type writes rd (bits 15–11) and I-type writes rt (bits 20–16); they disagree, which is exactly why the mux must exist.
SE7. "sw sets MemToReg = 0 to be safe."
Misleading — sw writes no register, so MemToReg is a don't-care (X); assigning it a definite value isn't wrong but implies a meaning that isn't there.
SE8. "The clock period should equal the average instruction delay."
Wrong statistic — it must equal the maximum (worst-case) instruction delay, because a single fixed clock must satisfy even the slowest instruction.
SE9. "The J-type jump target is just SignExt(imm) << 2, exactly like a branch."
Wrong — a jump takes the 26-bit target, shifts it left 2, and concatenates the top 4 bits of PC+4 (PC[31:28]) to fill out 32 bits; it is not a sign-extended PC-relative offset.

Why questions

WHY1. Why does a mux appear at the ALU's second input?
Because instruction types disagree on that input — R-type wants a register value, while load/store/immediate want the sign-extended immediate; a mux (controlled by ALUSrc) resolves the disagreement.
WHY2. Why must sw and beq have RegWrite = 0?
Neither produces a value destined for a register, so writing would overwrite a register with garbage and silently corrupt program state.
WHY3. Why is lw usually the critical path in MIPS single-cycle?
It touches every region — instruction memory, register read, ALU (address), data memory, and register write-back — so its delay chain is the longest.
WHY4. Why does converting a branch offset to bytes require a left-shift by 2?
The offset is counted in instructions (words), and each instruction is 4 bytes, so multiplying by 4 (shift left 2) converts word-count into a byte address.
WHY5. Why is a fast add still forced to be slow in single-cycle?
Every instruction shares one fixed clock period set by the slowest instruction, so the add finishes early and then just wastes the remaining time.
WHY6. Why do the "don't care" (X) entries appear in the control truth table?
Because when an instruction doesn't perform an action (e.g. doesn't write a register), the signals feeding that action have no effect, so their value is free to be anything.
WHY7. Why can multi-cycle designs reuse the ALU for PC+4 but single-cycle cannot?
In multi-cycle the ALU is used in different cycles for different jobs, so it can be time-shared; single-cycle crams everything into one cycle, leaving no free moment. See Multi-cycle datapath.
WHY8. Why does pipelining beat single-cycle despite both having CPI ≈ 1?
Pipelining keeps CPI near 1 while slashing the clock period (each stage's short delay, not the whole instruction's), so overall time drops. See Pipelining.
WHY9. Why does a J-type jump need its own extra mux on the PC input?
Because the PC now has three possible next values — PC+4, branch target, and jump target — and the branch PCSrc mux only picks between two, so a second (jump) mux is added to override with the jump target.

Edge cases

EC1. What does the data memory do during an R-type instruction?
Nothing useful — MemRead and MemWrite are both 0, so any output is ignored; the block is physically present but electrically idle for this instruction.
EC2. What happens to the write-back path for sw?
It's dead — RegWrite = 0, so whatever appears on the write-back wires and destination mux is discarded; the register file is left untouched.
EC3. If a branch's ALU comparison gives Zero = 1 but the Branch signal is 0, is the branch taken?
No — PCSrc needs Branch AND Zero; with Branch = 0 (a non-branch instruction) the Zero output is irrelevant and PC advances by PC+4.
EC4. What is the destination register of a store instruction?
There is none — a store writes memory, not a register, so the entire destination-select logic is a don't-care.
EC5. If two instructions have equal maximum delay, which one sets the clock?
Either — the clock equals the shared maximum, so both are on the critical path and the period is that common value.
EC6. What happens if the immediate is zero for a lw?
It's a valid degenerate case — the sign-extended zero adds nothing, so the ALU computes the base register's address directly; the datapath behaves identically, just with offset 0.
EC7. Does a taken backward branch (negative offset) need special hardware?
No — sign-extension turns the negative 16-bit offset into a correct negative 32-bit value, and the same adder produces a smaller target address; the geometry of the path is unchanged.
EC8. Does a J-type jump ever read the register file or use the ALU result?
No — its next-PC comes purely from the instruction's own target bits plus PC[31:28]; register reads still happen physically but their outputs are ignored, and the ALU/Zero results play no role in the jump decision.