Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/rsz/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ cc_library(
"src/SwapPinsMove.hh",
"src/UnbufferMove.cc",
"src/UnbufferMove.hh",
"src/VTSwapMove.hh",
"src/VTSwapMove.cc",
],
hdrs = [
"include/rsz/MakeResizer.hh",
Expand Down
4 changes: 4 additions & 0 deletions src/rsz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ repair_timing
[-skip_buffering]
[-skip_buffer_removal]
[-skip_last_gasp]
[-skip_vt_swap]
[-repair_tns tns_end_percent]
[-max_passes passes]
[-max_repairs_per_pass max_repairs_per_pass]
Expand All @@ -252,6 +253,7 @@ repair_timing
| `-skip_buffering` | Flag to skip rebuffering and load splitting. The default is to perform rebuffering and load splitting transforms during setup fixing. |
| `-skip_buffer_removal` | Flag to skip buffer removal. The default is to perform buffer removal transform during setup fixing. |
| `-skip_last_gasp` | Flag to skip final ("last gasp") optimizations. The default is to perform greedy sizing at the end of optimization. |
| `-skip_vt_swap` | Flag to skip threshold voltage (VT) swap optimizations. The default is to perform VT swap optimization to improve timing QoR. |
| `-repair_tns` | Percentage of violating endpoints to repair (0-100). When `tns_end_percent` is zero, only the worst endpoint is repaired. When `tns_end_percent` is 100 (default), all violating endpoints are repaired. |
| `-max_repairs_per_pass` | Maximum repairs per pass, default is 1. On the worst paths, the maximum number of repairs is attempted. It gradually decreases until the final violations which only get 1 repair per pass. |
| `-max_utilization` | Defines the percentage of core area used. |
Expand Down Expand Up @@ -449,6 +451,7 @@ The `report_equiv_cells` command finds all functionally equivalent library cells
report_equiv_cells
[-match_cell_footprint]
[-all]
[-vt]
lib_cell
```

Expand All @@ -458,6 +461,7 @@ report_equiv_cells
| ----- | ----- |
| `-match_cell_footprint` | Limit equivalent cell list to include only cells that match library cell_footprint attribute. |
| `-all` | List all equivalent cells, ignoring sizing restrictions and cell_footprint. Cells excluded due to these restrictions are marked with an asterisk. |
| `-vt` | List all threshold voltage (VT) equivalent cells such as HVT, RVT, LVT, SLVT. |

### Reporting Buffers

Expand Down
38 changes: 31 additions & 7 deletions src/rsz/include/rsz/Resizer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ class SizeDownMove;
class SizeUpMove;
class SwapPinsMove;
class UnbufferMove;
class VTSwapSpeedMove;
class SizeUpMatchMove;
class RegisterOdbCallbackGuard;

class NetHash
Expand All @@ -138,7 +140,9 @@ enum class MoveType
SIZEUP,
SIZEDOWN,
CLONE,
SPLIT
SPLIT,
VTSWAP_SPEED, // VT swap for timing (need VT swap for power also)
SIZEUP_MATCH // sizeup to match drive strength vs. prev stage
};

// Voltage Threshold (VT) category identifier
Expand All @@ -155,6 +159,11 @@ struct VTCategory
}
return vt_name < other.vt_name;
}
bool operator==(const VTCategory& other) const
{
return (vt_index == other.vt_index && vt_name == other.vt_name);
}
bool operator!=(const VTCategory& other) const { return !(*this == other); }
};

// Leakage statistics for cells in a single VT category
Expand Down Expand Up @@ -278,7 +287,8 @@ class Resizer : public dbStaState, public dbNetworkObserver
bool skip_size_down,
bool skip_buffering,
bool skip_buffer_removal,
bool skip_last_gasp);
bool skip_last_gasp,
bool skip_vt_swap);
// For testing.
void repairSetup(const Pin* end_pin);
// For testing.
Expand Down Expand Up @@ -407,7 +417,7 @@ class Resizer : public dbStaState, public dbNetworkObserver
double dbuToMeters(int dist) const;
int metersToDbu(double dist) const;
void makeEquivCells();
std::pair<int, std::string> cellVTType(dbMaster* master);
VTCategory cellVTType(dbMaster* master);

////////////////////////////////////////////////////////////////
void initBlock();
Expand All @@ -419,10 +429,10 @@ class Resizer : public dbStaState, public dbNetworkObserver
// For debugging - calls getSwappableCells
void reportEquivalentCells(LibertyCell* base_cell,
bool match_cell_footprint,
bool report_all_cells);
bool report_all_cells,
bool report_vt_equiv);
void reportBuffers(bool filtered);
void getBufferList(LibertyCellSeq& buffer_list,
LibraryAnalysisData& lib_data);
void getBufferList(LibertyCellSeq& buffer_list);
void setDebugGraphics(std::shared_ptr<ResizerObserver> graphics);

static MoveType parseMove(const std::string& s);
Expand All @@ -434,6 +444,9 @@ class Resizer : public dbStaState, public dbNetworkObserver
return estimate_parasitics_;
}

// Library analysis data
std::unique_ptr<LibraryAnalysisData> lib_data_;

protected:
void init();
double computeDesignArea();
Expand Down Expand Up @@ -495,6 +508,7 @@ class Resizer : public dbStaState, public dbNetworkObserver

void resizePreamble();
LibertyCellSeq getSwappableCells(LibertyCell* source_cell);
LibertyCellSeq getVTEquivCells(LibertyCell* source_cell);

bool getCin(const LibertyCell* cell, float& cin);
// Resize drvr_pin instance to target slew.
Expand Down Expand Up @@ -717,6 +731,12 @@ class Resizer : public dbStaState, public dbNetworkObserver

// Cache results of getSwappableCells() as this is expensive for large PDKs.
std::unordered_map<LibertyCell*, LibertyCellSeq> swappable_cells_cache_;
// Cache VT equivalent cells for each cell, equivalent cells are sorted in
// increasing order of leakage
// BUF_X1_RVT : { BUF_X1_RVT, BUF_X1_LVT, BUF_X1_SLVT }
// BUF_X1_LVT : { BUF_X1_RVT, BUF_X1_LVT, BUF_X1_SLVT }
// ...
std::unordered_map<LibertyCell*, LibertyCellSeq> vt_equiv_cells_cache_;

std::unique_ptr<CellTargetLoadMap> target_load_map_;
VertexSeq level_drvr_vertices_;
Expand Down Expand Up @@ -774,7 +794,7 @@ class Resizer : public dbStaState, public dbNetworkObserver
double buffer_sizing_cap_ratio_;

// VT layer hash
std::unordered_map<dbMaster*, std::pair<int, std::string>> vt_map_;
std::unordered_map<dbMaster*, VTCategory> vt_map_;
std::unordered_map<size_t, int>
vt_hash_map_; // maps hash value to unique int

Expand All @@ -789,6 +809,8 @@ class Resizer : public dbStaState, public dbNetworkObserver
std::unique_ptr<SizeUpMove> size_up_move_;
std::unique_ptr<SwapPinsMove> swap_pins_move_;
std::unique_ptr<UnbufferMove> unbuffer_move_;
std::unique_ptr<VTSwapSpeedMove> vt_swap_speed_move_;
std::unique_ptr<SizeUpMatchMove> size_up_match_move_;
int accepted_move_count_ = 0;
int rejected_move_count_ = 0;

Expand All @@ -807,6 +829,8 @@ class Resizer : public dbStaState, public dbNetworkObserver
friend class CloneMove;
friend class SwapPinsMove;
friend class UnbufferMove;
friend class SizeUpMatchMove;
friend class VTSwapSpeedMove;
friend class SwapArithModules;
friend class ConcreteSwapArithModules;
friend class Rebuffer;
Expand Down
1 change: 1 addition & 0 deletions src/rsz/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ add_library(rsz_lib
SplitLoadMove.cc
SwapPinsMove.cc
UnbufferMove.cc
VTSwapMove.cc
Resizer.cc
OdbCallBack.cc
ConcreteSwapArithModules.cc
Expand Down
13 changes: 6 additions & 7 deletions src/rsz/src/RepairHold.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,21 +212,20 @@ bool isDelayCell(const std::string& cell_name)
void RepairHold::filterHoldBuffers(LibertyCellSeq& hold_buffers)
{
LibertyCellSeq buffer_list;
LibraryAnalysisData lib_data;
resizer_->getBufferList(buffer_list, lib_data);
resizer_->getBufferList(buffer_list);

// Pick the least leaky VT for multiple VTs
int best_vt_index = -1;
int num_vt = lib_data.sorted_vt_categories.size();
int num_vt = resizer_->lib_data_->sorted_vt_categories.size();
if (num_vt > 0) {
best_vt_index = lib_data.sorted_vt_categories[0].first.vt_index;
best_vt_index = resizer_->lib_data_->sorted_vt_categories[0].first.vt_index;
}

// Pick the shortest cell site because this offers the most flexibility for
// hold fixing
int best_height = std::numeric_limits<int>::max();
odb::dbSite* best_site = nullptr;
for (const auto& site_data : lib_data.cells_by_site) {
for (const auto& site_data : resizer_->lib_data_->cells_by_site) {
int height = site_data.first->getHeight();
if (height < best_height) {
best_height = height;
Expand All @@ -236,7 +235,7 @@ void RepairHold::filterHoldBuffers(LibertyCellSeq& hold_buffers)

// Use DELAY cell footprint if available
bool lib_has_footprints = false;
for (const auto& [ft_str, count] : lib_data.cells_by_footprint) {
for (const auto& [ft_str, count] : resizer_->lib_data_->cells_by_footprint) {
if (isDelayCell(ft_str)) {
lib_has_footprints = true;
break;
Expand Down Expand Up @@ -313,7 +312,7 @@ bool RepairHold::addMatchingBuffers(const LibertyCellSeq& buffer_list,
bool vt_matches = true;
if (match_vt) {
auto vt_type = resizer_->cellVTType(master);
vt_matches = best_vt_index == -1 || vt_type.first == best_vt_index;
vt_matches = best_vt_index == -1 || vt_type.vt_index == best_vt_index;
}

bool footprint_matches = true;
Expand Down
52 changes: 36 additions & 16 deletions src/rsz/src/RepairSetup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
#include "CloneMove.hh"
#include "Rebuffer.hh"
#include "SizeDownMove.hh"
// This includes SizeUpMatchMove
#include "SizeUpMove.hh"
#include "SplitLoadMove.hh"
#include "SwapPinsMove.hh"
#include "UnbufferMove.hh"
#include "VTSwapMove.hh"
#include "rsz/Resizer.hh"
#include "sta/Corner.hh"
#include "sta/DcalcAnalysisPt.hh"
Expand Down Expand Up @@ -86,7 +88,8 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
const bool skip_size_down,
const bool skip_buffering,
const bool skip_buffer_removal,
const bool skip_last_gasp)
const bool skip_last_gasp,
const bool skip_vt_swap)
{
bool repaired = false;
init();
Expand Down Expand Up @@ -140,6 +143,15 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
move_sequence.push_back(resizer_->split_load_move_.get());
}
break;
case MoveType::VTSWAP_SPEED:
if (!skip_vt_swap
&& resizer_->lib_data_->sorted_vt_categories.size() > 1) {
move_sequence.push_back(resizer_->vt_swap_speed_move_.get());
}
break;
case MoveType::SIZEUP_MATCH:
move_sequence.push_back(resizer_->size_up_match_move_.get());
break;
}
}

Expand All @@ -148,6 +160,9 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
if (!skip_buffer_removal) {
move_sequence.push_back(resizer_->unbuffer_move_.get());
}
if (!skip_vt_swap && resizer_->lib_data_->sorted_vt_categories.size() > 1) {
move_sequence.push_back(resizer_->vt_swap_speed_move_.get());
}
// TODO: Add size_down_move to the sequence if we want to allow
// Always have sizing
move_sequence.push_back(resizer_->size_up_move_.get());
Expand Down Expand Up @@ -457,6 +472,8 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
int clone_moves_ = resizer_->clone_move_->numCommittedMoves();
int split_load_moves_ = resizer_->split_load_move_->numCommittedMoves();
int unbuffer_moves_ = resizer_->unbuffer_move_->numCommittedMoves();
int vt_swap_moves_ = resizer_->vt_swap_speed_move_->numCommittedMoves();
int size_up_match_moves_ = resizer_->size_up_match_move_->numCommittedMoves();

if (unbuffer_moves_ > 0) {
repaired = true;
Expand All @@ -476,14 +493,18 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
}
logger_->metric("design__instance__count__setup_buffer",
buffer_moves_ + split_load_moves_);
if (size_up_moves_ + size_down_moves_ > 0) {
if (size_up_moves_ + size_down_moves_ + size_up_match_moves_ + vt_swap_moves_
> 0) {
repaired = true;
logger_->info(RSZ,
51,
"Resized {} instances, {} sized up, {} sized down.",
size_up_moves_ + size_down_moves_,
"Resized {} instances: {} up, {} up match, {} down, {} VT",
size_up_moves_ + size_up_match_moves_ + size_down_moves_
+ vt_swap_moves_,
size_up_moves_,
size_down_moves_);
size_up_match_moves_,
size_down_moves_,
vt_swap_moves_);
}
if (swap_pins_moves_ > 0) {
repaired = true;
Expand Down Expand Up @@ -517,6 +538,7 @@ void RepairSetup::repairSetup(const Pin* end_pin)

move_sequence.clear();
move_sequence = {resizer_->unbuffer_move_.get(),
resizer_->vt_swap_speed_move_.get(),
resizer_->size_down_move_.get(),
resizer_->size_up_move_.get(),
resizer_->swap_pins_move_.get(),
Expand Down Expand Up @@ -755,7 +777,9 @@ void RepairSetup::printProgress(const int iteration,
itr_field,
resizer_->unbuffer_move_->numMoves(),
resizer_->size_up_move_->numMoves()
+ resizer_->size_down_move_->numMoves(),
+ resizer_->size_down_move_->numMoves()
+ resizer_->size_up_match_move_->numMoves()
+ resizer_->vt_swap_speed_move_->numMoves(),
resizer_->buffer_move_->numMoves()
+ resizer_->split_load_move_->numMoves(),
resizer_->clone_move_->numMoves(),
Expand Down Expand Up @@ -810,9 +834,14 @@ bool RepairSetup::terminateProgress(const int iteration,

// Perform some last fixing based on sizing only.
// This is a greedy opto that does not degrade WNS or TNS.
// TODO: add VT swap
void RepairSetup::repairSetupLastGasp(const OptoParams& params, int& num_viols)
{
move_sequence.clear();
move_sequence = {resizer_->vt_swap_speed_move_.get(),
resizer_->size_up_match_move_.get(),
resizer_->size_up_move_.get(),
resizer_->swap_pins_move_.get()};

// Sort remaining failing endpoints
const VertexSet* endpoints = sta_->endpoints();
vector<pair<Vertex*, Slack>> violating_ends;
Expand All @@ -838,15 +867,6 @@ void RepairSetup::repairSetupLastGasp(const OptoParams& params, int& num_viols)
return;
}

// Don't do anything unless there was some progress from previous fixing
if ((params.initial_tns - curr_tns) / params.initial_tns < 0.05) {
// clang-format off
debugPrint(logger_, RSZ, "repair_setup", 1, "last gasp is bailing out "
"because TNS was reduced by < 5% from previous fixing");
// clang-format on
return;
}

int end_index = 0;
int max_end_count = violating_ends.size();
if (max_end_count == 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/rsz/src/RepairSetup.hh
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ class RepairSetup : public sta::dbStaState
bool skip_size_down,
bool skip_buffering,
bool skip_buffer_removal,
bool skip_last_gasp);
bool skip_last_gasp,
bool skip_vt_swap);
// For testing.
void repairSetup(const Pin* end_pin);
// For testing.
Expand Down
Loading
Loading