Draft preview. Lessons are being written and reviewed.

Digital Design / Module 12: Projects and interview preparation

66. Major project: small RISC-style CPU

Design a working processor of your own.

Lecture coming soon

See it move

The goal

Design a small processor of your own. It touches almost every topic in this course: register files, an ALU, FSMs or , memories, and hazards. Few things will impress an interviewer more than explaining a CPU you built yourself.

Start with an instruction set

Keep it small and original, and write it down first: instruction formats, registers, and behaviour. The animation above shows a tiny teaching machine: four registers and five instructions, enough to run a real loop.

The classic stages

  • Fetch: read the instruction at the program counter.
  • Decode: work out the operation, and read registers.
  • Execute: use the ALU, or decide a branch.
  • Memory: load or store data.
  • Write back: put the result in a register.

Step 1: single cycle

All five stages happen in one long clock cycle. It's simple, and easy to get right. It's slow, as the clock must fit the longest instruction. Get all your instructions working here first.

Step 2: pipeline

Put registers between stages, to run a higher clock. One instruction finishes per cycle, in the ideal case. Then come the hazards:

HazardExampleFix
DataNext instruction reads a result not written yetForward from a later stage
Load-useInstruction reads a value still coming from memoryStall one cycle
ControlBranch changes the next instructionFlush, or predict

Verifying it

  • Write test programs with known final register values, and check them automatically.
  • Build a simple instruction-set simulator in Python, and compare both, instruction by instruction.
  • Test hazards directly: back-to-back dependent instructions, branches after loads, and so on.

Common mistake

Starting with the pipeline. Debugging a pipeline when instructions aren't correct yet is painful. Build the single-cycle version and a good test suite first. Those same tests will then catch your pipeline bugs immediately.

Key ideas

  • Fetch, decode, execute, memory, write back.
  • Begin single-cycle; then pipeline it.
  • Handle hazards by forwarding and stalling.

Your exercise

Implement a small original instruction set and run your own test program.

Interview questions

coreData hazard solutions?

basicName the five classic stages of a simple pipelined CPU and what each one does.

basicEach of five stages takes 3 ns of logic, and each register adds 0.3 ns. What clock period does a single-cycle design need, and what does a five-stage pipeline need? What is the ideal speed-up?

coreA five-stage pipeline runs 30 instructions. There are 2 load-use stalls and 5 taken branches, each flushing 2 instructions. How many cycles does it take?

coreIn this forwarding mux, why is the EX/MEM result checked before the MEM/WB result?

always @(*) begin
  if (exmem_we && exmem_rd == idex_rs1)
    alu_a = exmem_result;          // one stage ahead
  else if (memwb_we && memwb_rd == idex_rs1)
    alu_a = memwb_result;          // two stages ahead
  else
    alu_a = idex_rs1_val;          // register file
end

coreWhy can forwarding not remove the stall after a load whose result is used by the next instruction?

coreYour pipelined CPU gives a wrong final register value on a test program. How do you find the faulty instruction quickly?

advancedBranches are decided in execute and cost 2 cycles when taken. How could you reduce that, and what does it cost?

advancedIn a five-stage pipeline, an instruction in decode reads a register in the same cycle that write back writes it. What must the register file do, and what happens if it does not?

Practise these 9 questions with animations