Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations57
  • Combinational Design58
  • Sequential Design61
    • Flip-Flops and Registers
    • Counters and Timers
    • Shift Registers and LFSRs
    • Pipelining
    • Stalls, Bubbles and Hazards
    • Retiming
      • Retiming Mechanism
      • Retiming Decision Guide
      • Handshake-Aware Retiming
      • Practice
      • Sample Q&A
      • Checklist
      • Worked Examples and Waveforms
      • Corner Cases and Stress Tests
      • Integration and Sign-off Notes
  • FSM & Control66
  • Timing & Clocking64
  • Reset & CDC58
  • Memory & Buses94
  • Advanced RTL60
  • Senior & Interview175
  • Glossary and Notation
Loading lesson

‹Retiming
  1. Topics
  2. RTL Design
  3. Sequential Design
  4. Retiming
  5. Retiming Decision Guide

Part 3 · Sequential · Intermediate

Retiming Decision Guide

When to retime by hand, when to let the tool do it, and when to restructure instead.

On this page

    Why this matters

    Retiming is only one timing fix, and a tool may legally rearrange registers on a verified protocol interface. Start from the critical path report, then pick the cheapest fix that keeps the contract.

    After this lesson you can: match a timing symptom to a fix, and choose between automatic and manual retiming for a block.

    Start from the timing report

    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.

    Decision flowchart. From the critical path, if it crosses a clock domain, fix the CDC design. Otherwise, if it is inside a one-register loop, restructure. Otherwise, if the next stage has slack, retime; if not, add a stage and rebalance.
    Three questions in order: clock domain, feedback loop, neighbour slack. Only the last one leads to retiming.

    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 (x <= f(x))

    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.

    Automatic or manual

    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

    Tip

    Make the manual version parametric: put the number of output pipeline registers in a parameter. Then adding or removing a stage is a one-line change and the testbench checks the latency parameter.

    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.

    Common mistakes

    Warning

    Never retime a block that is part of a verified protocol interface without re-running that protocol's testbench. A tool can legally rearrange registers so that an output that was driven directly by a flop is now driven through combinational logic after the registers. That changes clock-to-output timing and allows glitches. Most flows let you forbid retiming at ports.

    Check yourself A counter 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).

    Testbench

    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.

    scaled_mul.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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
    

    Remember

    • Small imbalances suit the tool option; critical interfaces suit a manual rewrite.

    • Put the number of output ranks in a parameter, so adding a stage is a one-line change.

    • Re-run a protocol's testbench after retiming any block inside it.

    How this was checked

    The testbench checks added ranks, not a performed tool retiming. The delay is an RTL observation convention, not a physical settling measurement.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • Timing analysis

    Previous

    169 / 694

    Next: Handshake-Aware Retiming

    Up next

    Up nextHandshake-Aware Retiming

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Practice
    • Sample Q&A
    • Checklist