Skip to content

[rsz] Sub-optimal Leakage Power in VTSwapSpeedMove: Blindly swaps to lowest VT #4034

@Vi-shub

Description

@Vi-shub

Description

In the Resizer (src/rsz/src/VTSwapMove.cc), there is a significant sub-optimality in how the engine performs Threshold Voltage (VT) swapping to fix setup slack.
When a driver cell needs to be sped up, VTSwapSpeedMove::isSwappable evaluates the equivalent VT cells but blindly selects the fastest (and thus most leaky) cell available, rather than finding the optimal VT cell that just barely meets the slack requirement.
Code Reference: src/rsz/src/VTSwapMove.cc (lines ~147-148)

  sta::LibertyCellSeq equiv_cells = resizer_->getVTEquivCells(drvr_cell);
  best_cell = equiv_cells.empty() ? nullptr : equiv_cells.back();
  // ...
  // TODO: Avoid swapping to the lowest VT by considering slack

Because getVTEquivCells returns a sequence of cells ordered by speed/leakage, calling .back() unconditionally jumps to the lowest VT (fastest/highest leakage) cell in the library.

Impact: If a path has a minor setup violation of -5ps, and jumping to a medium-VT cell would improve it by +10ps (fixing the violation) while a low-VT cell improves it by +50ps, the current algorithm will aggressively choose the low-VT cell. @maliberty need your thought on this :)

Suggested Solution

Suggested Solution

Instead of blindly picking `equiv_cells.back()`, the algorithm should iterate through `equiv_cells` from slowest to fastest, calculate the delta delay/slack for each cell swap, and pick the *first* cell in the sorted sequence that satisfies the `drvr_slack` requirement safely.

```cpp
  // Conceptual fix for isSwappable / doMove:
  best_cell = nullptr;
  for (sta::LibertyCell* cand_cell : equiv_cells) {
    if (cand_cell == drvr_cell) continue;
    
    // Estimate slack improvement if cand_cell is used
    float delay_diff = estimateDelayDiff(drvr_cell, cand_cell); 
    
    if (drvr_slack + delay_diff >= setup_slack_margin) {
       best_cell = cand_cell;
       break; // Found the least-leaky cell that fixes the timing!
    }
  }
  
  // Fallback to the fastest cell if no intermediate cell completely fixes the slack
  if (!best_cell && !equiv_cells.empty()) {
      best_cell = equiv_cells.back(); 
  }

Additional Context

While exploring more deep into this repo. This issue was identified while reviewing TODO's in the Resizer source code. Fixing this algorithmic hole would provide a measurable improvement to leakage power metrics across standard macro benchmarks (like the ASAP7 or NanGate45 designs in OpenROAD-flow-scripts).

@luarss @maliberty can you please assign this to me :). I have started working on this.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions