Draft preview. Lessons are being written and reviewed.

Digital Design / Module 8: Arithmetic and datapaths

47. Pipelining

Increase throughput with registers.

Lecture coming soon

See it move

The idea

If a calculation takes too long for one clock cycle, split it into stages with registers between them. Each stage does part of the work, so the clock can run faster. Think of a car assembly line: a car still takes the same total labour, yet a finished car leaves every few minutes.

What changes

  • Throughput improves: one result per cycle, at a higher clock rate.
  • Latency gets worse: each result takes more cycles, and usually slightly more time overall.

For total logic delay T and flop overhead t ( plus setup), k stages give a clock period of about T/k + t.

Diminishing returns

With T = 12 ns and t = 0.5 ns:

StagesPeriodRelative speed
112.5 ns1.0 x
34.5 ns2.8 x
62.5 ns5.0 x
121.5 ns8.3 x

More stages never quite pay off in proportion, since the flop overhead stays constant, and logic can't always be cut evenly. Flops also cost area and clock power.

Keeping things aligned

Any signal that belongs with the data must be delayed by the same number of stages.

always_ff @(posedge clk) begin
  s1 <= a + b;     v1 <= in_valid;
  s2 <= s1 * c;    v2 <= v1;
end

If the valid bit takes a different path, it will pair with the wrong data. This is a very common pipelining bug.

Hazards

In a CPU, a later instruction might need a result still in the pipeline. That is a hazard, and it requires forwarding or stalling. A pure streaming pipeline with no feedback avoids this.

Common mistake

Pipelining a path that has feedback, such as a counter or an accumulator, without considering the consequences. Registers inside a feedback loop change the function: each result arrives too late for the next calculation.

Key ideas

  • Cut long combinational paths into stages.
  • Latency increases; clock rate may rise.
  • Keep valid signals and data aligned.

Your exercise

Pipeline a slow adder chain and compare fmax.

Find the bug

This code has one deliberate bug. Read the symptom, then click the line you think is wrong.

What goes wrong: The result is right, but valid rises one cycle too early, so the next block captures the wrong value.

Interview questions

coreLatency or throughput: which does pipelining improve?

basicA calculation has 12 ns of logic, and each flop adds 0.5 ns of overhead. What are the clock period, frequency and latency with 4 equal stages?

basicWhen you pipeline a datapath, why must the valid bit also pass through the same number of registers?

coreThis two-stage pipeline computes (a + b) x c. With inputs (3, 4, 5), then (1, 1, 9), then (2, 6, 3), the outputs are 63, 6 and 0 instead of 35, 18 and 24. Why?

always @(posedge clk) begin
  s1 <= a + b;
  s2 <= s1 * c;
end

core12 ns of logic is cut into three stages of 5, 3 and 4 ns, and each flop adds 0.5 ns. What clock period do you get, and what would perfect balance give?

coreA 3-stage pipeline runs at 4.5 ns. How long does it take to process 1000 independent items, and how does that compare with an unpipelined 12.5 ns design?

coreAn accumulator is 'pipelined' by adding a register inside its feedback loop. With inputs 1 to 8, what does the output become?

always @(posedge clk) begin
  r    <= accp + x;  // adder output registered
  accp <= r;         // fed back one cycle later
end

advancedWith 12 ns of logic and 0.5 ns of flop overhead, what speedup do 100 stages give, and what is the limit?

advancedIn a classic five-stage CPU pipeline, why can't forwarding alone remove the stall after a load whose result is used by the very next instruction?

Practise these 9 questions with animations