Digital Design / Module 8: Arithmetic and datapaths
48. Retiming and area-speed trade-offs
Decide between parallel and shared hardware.
See it move
Retiming
Retiming moves registers through combinational logic without changing what the circuit computes. It evens out path delays. If one stage takes 5.5 ns and the next 1.5 ns, moving some logic across the register can give a more balanced result. Move the register in the animation above and watch the worst stage change.
The value of each output stays the same, cycle by cycle. The clock simply runs faster, since the longest path is now shorter. Synthesis tools can do this automatically, provided the design doesn't need specific register positions.
Parallel or shared hardware
Given a task, you can trade area against time:
- Parallel: two multipliers process two streams, for double the and double the area.
- Shared: one multiplier alternates between streams, for half the area and half the throughput, plus muxes and control logic.
// One multiplier shared between two streams on alternate cycles
always_ff @(posedge clk) sel <= ~sel;
assign x = sel ? a2 : a1;
assign y = sel ? b2 : b1;
always_ff @(posedge clk) begin
p <= x * y;
if (sel) p1 <= p; else p2 <= p; // p holds last cycle's stream
endHow to choose
First ask what is required: throughput, , area, power. Then work out:
- Required rate: results per second.
- Clock: what the process allows.
- Copies: the required rate divided by the clock rate, rounded up.
If a block must deliver 2 billion results per second on a 1 GHz clock, you need two copies, and if it must deliver just 100 million, then ten streams can share one copy.
The power angle
Two slower copies can use less energy than one fast copy, because lower frequency allows lower voltage, and power falls with voltage squared. This is one reason chips have moved to many cores and wide accelerators.
Common mistake
Sharing hardware because it looks elegant, then finding that the muxes and control logic have used up the savings. Sharing small blocks, such as an adder, rarely helps. Share large ones, such as multipliers and memories.
Key ideas
- Retiming moves registers without changing behaviour.
- Parallel hardware boosts throughput; sharing saves area.
- Check latency requirements first.
Your exercise
Interview questions
coreWhat is resource sharing's cost?
Throughput, plus muxes and control.
basicWhat does retiming change, and what does it keep the same?
Retiming moves existing registers through combinational logic to balance path delays. It keeps the circuit's behaviour at its outputs the same, cycle by cycle, including the latency. What changes are the internal register positions and the worst path, so the clock can run faster. Pipelining is different, since it adds registers and increases latency.
basicA block must deliver 750 million results per second, and each copy produces one result per cycle at 400 MHz. How many copies do you need?
750 / 400 = 1.875, which rounds up to 2 copies. One copy gives only 400 million results per second. Two copies give 800 million, which leaves some headroom. Always round up, since a fraction of a copy can't be built.
coreA chain of logic blocks has delays of 1.5, 4, 2, 3.5 and 1 ns, with one register to place between blocks (flop overhead ignored). Where should it go?
The running totals are 1.5, 5.5, 7.5, 11 and 12 ns. After the 1.5 ns block, the stages are 1.5 and 10.5, so the worst is 10.5. After the 4 ns block, they are 5.5 and 6.5, worst 6.5. After the 2 ns block, they are 7.5 and 4.5, worst 7.5, so the best position is after the 4 ns block, giving 6.5 ns. A perfect split, 6 and 6, isn't possible because blocks can't be divided.
coreOne multiplier is shared between two streams on alternate cycles. A designer 'cleans up' the output demux so that sel = 1 means stream 2, and now the streams' results are swapped. Why?
always @(posedge clk) sel <= rst ? 1'b0 : ~sel; assign x = sel ? a2 : a1; assign y = sel ? b2 : b1; always @(posedge clk) begin p <= x * y; if (sel) q2 <= p; else q1 <= p; // 'cleaned up' end
p is registered, so it holds the product chosen by the previous cycle's sel. When sel is 1 now, it was 0 last cycle, so p holds stream 1's product. The original code, if (sel) p1 <= p, was correct for that reason. In simulation with 3 x 4 on stream 1 and 7 x 8 on stream 2, the cleaned-up version put 56 into stream 1's output and 12 into stream 2's.
coreWhen does sharing one hardware block between two streams fail to save area?
When the block is small compared with the muxes, registers and control needed to share it. Sharing an adder, for example, costs input muxes about as large as the adder, plus a select signal and output registers. Sharing pays off for large blocks such as multipliers, dividers and memories. Sharing also halves each stream's throughput, so it only works if that is enough.
coreWhen a tool moves a register backward through logic during retiming, what can go wrong with its reset value?
The new register must reset to a value that, passed through the logic, gives the original register's reset value. Through an inverter that means the opposite value, which is easy. Through some logic, though, no input value may produce the required output, and then the move is not equivalent from reset. Moving a register forward is always possible, since the new reset value is just the logic applied to the old ones. This is why tools may restrict retiming of registers with resets.
advancedOne multiplier runs at 1 GHz and 1.0 V. Alternatively, two copies run at 500 MHz, which allows 0.8 V. Compare the dynamic power, assuming each copy has the same switched capacitance.
Dynamic power scales with C x V^2 x f. One copy gives C x 1.0^2 x 1.0 = 1.0 (relative units). Two copies give 2 x C x 0.8^2 x 0.5 = 0.64. That is 36% less dynamic power for the same throughput, paid for with twice the area and more leakage, which this calculation ignores. That trade is one reason chips moved to many slower cores and wide accelerators.
advancedCan retiming speed up a feedback loop, such as an accumulator, whose loop delay exceeds one clock period?
No. Retiming preserves the number of registers around any loop. A loop with one register must complete its whole delay in one cycle, wherever that register sits. Retiming can only balance the logic around the loop, and logic outside it. To go faster, you must change the algorithm, for example with carry-save accumulation, or by interleaving several independent streams so that extra registers in the loop are acceptable.