Retiming is one of several timing fixes. The critical path report shows the start point, end point and the logic in between.
Match the symptom to the fix.
Ask the questions top to bottom and stop at the first yes. Two rows of the table below sit beside this flow: a big enable mux at the endpoint and a high-fanout net are fixed in the RTL or by duplication, whichever branch you reach.
Symptom | Likely fix |
|---|---|
Long path between two registers, the next stage has plenty of slack | Retime (tool or by hand): move logic or registers across the boundary. |
Whole pipeline is balanced but still too slow | Add pipeline stages (higher latency) and rebalance. |
Path is inside a single-register feedback loop ( | Restructure: precompute, lookahead or split into parallel partial results. Moving registers alone cannot change the loop register count, though a loop with several registers can still be rebalanced. |
Path ends at a register with a big enable mux | For a free-running datapath whose consumers ignore invalid data, consider unconditional data writes plus valid tracking. Keep enables required for stalls or retained state; moving one requires preserving that contract. |
Path involves high-fanout net | Duplicate the driver register or buffer the net. |
Path crosses a clock domain | Not a retiming problem: fix the CDC design. |
Small imbalances suit the tool option. Critical interfaces suit a manual rewrite.
Automatic (tool) | Manual (RTL) | |
|---|---|---|
Effort | Flip an option | Rewrite stages and verify |
Debug | Internal signal names change | Names and waveforms stay familiar |
Control | Tool may refuse (resets, keep attributes, loops) | You decide exactly |
When | Early exploration; many small imbalances | Final design; critical interfaces; protocols |
An if(valid) data write still infers an enable. Removing an unnecessary enable means writing data every cycle and qualifying its consumption with valid, as in retiming-friendly coding. A blocked valid/ready offer must remain stable, so that retention enable cannot be discarded. Adding ranks changes latency; a subsequent legal retiming preserves the revised interface contract. Whether the tool can move the resulting cells depends on the flow and constraints.
cnt <= cnt + 1 fails timing. Can you retime it?No: it is a one-register feedback loop, so no register can move out of it without changing the function. Restructure it (for example, split into two smaller counters with a registered carry).
A parameterized multiplier plus a testbench that checks added ranks, not a performed tool retiming. There are EXTRA+1 register ranks. With acceptance at edge 0, y becomes available after edge EXTRA and a downstream pre-edge sampler consumes it at edge EXTRA+1. This checker samples after NBA (#1 ns with a 10 ns period), so it compares y to the input from EXTRA iterations earlier.
module scaled_mul #(parameter int EXTRA = 1) (
input logic clk,
input logic [7:0] a, b,
output logic [15:0] y
);
logic [15:0] chain [EXTRA + 1]; // chain[0] = product, then EXTRA extra pipeline registers
always_ff @(posedge clk) begin
chain[0] <= a * b;
for (int i = 1; i <= EXTRA; i++) chain[i] <= chain[i-1];
end
assign y = chain[EXTRA];
endmodule
The testbench checks added ranks, not a performed tool retiming. The delay is an RTL observation convention, not a physical settling measurement.