RISC-V · Pipelining

The 5-stage pipeline, cycle by cycle

Pipelining does not make an instruction faster: each one still goes through five stages. What changes is that, in the best case, one instruction finishes every cycle. This page explains how to read a cycle diagram and when the pipeline has to wait.

The five stages

  • IF — fetches the instruction at the PC and advances the PC.
  • ID — decodes and reads the source registers. Hazards are detected here.
  • EX — the ALU computes the result, the memory address or the branch condition.
  • MEM — loads and stores access memory.
  • WB — the result is written to the destination register.

How to read the diagram

Each row is a stage and each column a clock cycle; the cell says which instruction occupies that stage in that cycle. With three independent instructions there are no waits: the first one finishes in cycle 5 and then one comes out per cycle.

Stage1234567
IFI0I1I2————
ID—I0I1I2———
EX——I0I1I2——
MEM———I0I1I2—
WB————I0I1I2
With forwarding: 7 cycles, 0 bubbles, 0 flushed instructions. I0 = addi t0, zero, 1 · I1 = addi t1, zero, 2 · I2 = addi t2, zero, 3

Without hazards, N instructions take N + 4 cycles: 4 to fill the pipeline and then one per cycle. Any cycle above that is a penalty, and the diagram shows where it happens: a bubble is an empty stage inserted while an instruction waits in ID, and FLUSH is an instruction discarded after a branch.

Pipeline simulator

Processor Configuration

Branches are resolved in EX and always treated as taken, so the next two instructions are discarded (2-cycle penalty). The simulator does not evaluate the condition or jump to the label: after the flush it continues with the instruction after the branch.

Exercises

Three typical exam situations: a load-use hazard, how to remove it by reordering and the cost of a branch.

Count the cycles of a load-use hazard

In the simulator’s 5-stage pipeline, how many cycles does this sequence take with and without forwarding? How many bubbles are there with forwarding?

lw   t0, 0(a0)
add  t1, t0, t0
sub  t2, t1, a1
Open in the tool

Reorder to remove the bubble

In the original order (lw, add, addi, sw) there is a load-use bubble and the sequence takes 9 cycles with forwarding. Here addi has been moved between lw and add. How many cycles does it take now with forwarding, and how many bubbles remain?

lw   t0, 0(a0)
addi t2, a1, 4
add  t1, t0, t0
sw   t1, 0(a2)
Open in the tool

The penalty of a branch

The simulator resolves branches in EX and treats them as taken. How many cycles does the sequence take with forwarding and how many instructions are discarded?

addi t0, t0, -1
bne  t0, zero, loop
addi a0, a0, 1
addi a1, a1, 1
Open in the tool

The simulator’s model

Textbooks describe several variants of this pipeline. The simulator implements one specific variant, and it is worth knowing it before comparing results with your notes:

  • With forwarding, results are passed from the EX/MEM and MEM/WB registers to the ALU input. The only wait is the load-use case: 1 bubble.
  • Without forwarding, the dependent instruction waits in ID until the producer leaves WB. The simulator does not model writing in the first half of the cycle and reading in the second, so a dependency between consecutive instructions costs 3 bubbles; in textbooks that do model it, it costs 2.
  • Conditional branches are resolved in EX and always treated as taken: the 2 instructions fetched behind are discarded. The simulator does not evaluate the condition or follow the label; after the flush it continues with the instruction after the branch, so the diagram shows the cost of the branch, not the real path of the program.
  • It knows the dependencies of arithmetic, logic, load, store, conditional branch, lui and auipc instructions. jal, jalr and others appear in the diagram but create no hazards (the tool warns about it). Up to 15 instructions are supported.
  • There are no structural hazards: separate instruction and data memories are assumed.

References