Skip to content

Commit

Permalink
rsz: repairSetup: Restrict number of repairs per iteration to avoid f…
Browse files Browse the repository at this point in the history
…alling into local optimums

Signed-off-by: Eryk Szpotanski <[email protected]>
  • Loading branch information
eszpotanski committed Nov 26, 2024
1 parent c1904e2 commit 22d1195
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 21 deletions.
2 changes: 2 additions & 0 deletions src/rsz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ repair_timing
[-skip_last_gasp]
[-repair_tns tns_end_percent]
[-max_passes passes]
[-max_passes_per_iter passes]
[-max_utilization util]
[-max_buffer_percent buffer_percent]
[-match_cell_footprint]
Expand All @@ -311,6 +312,7 @@ repair_timing
| `-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. |
| `-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_passes_per_iter` | Max number of repairs per iteration for `rsz::repairSetup`. |
| `-max_utilization` | Defines the percentage of core area used. |
| `-max_buffer_percent` | Specify a maximum number of buffers to insert to repair hold violations as a percentage of the number of instances in the design. The default value is `20`, and the allowed values are integers `[0, 100]`. |
| `-match_cell_footprint` | Obey the Liberty cell footprint when swapping gates. |
Expand Down
45 changes: 30 additions & 15 deletions src/rsz/src/RepairSetup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace rsz {

using std::max;
using std::pair;
using std::set;
using std::string;
using std::vector;
using utl::RSZ;
Expand Down Expand Up @@ -87,9 +88,21 @@ void RepairSetup::init()
db_network_ = resizer_->db_network_;
}

struct SlackVertexPairComp
{
bool operator()(const pair<Vertex*, Slack>& end_slack1,
const pair<Vertex*, Slack>& end_slack2) const
{
return end_slack1.second < end_slack2.second
|| (end_slack1.second == end_slack2.second
&& end_slack1.first->objectIdx()
< end_slack2.first->objectIdx());
}
};

bool RepairSetup::repairSetup(const float setup_slack_margin,
const double repair_tns_end_percent,
const int max_passes,
const int max_passes_per_iter,
const bool verbose,
const bool skip_pin_swap,
const bool skip_gate_cloning,
Expand All @@ -110,7 +123,7 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,

// Sort failing endpoints by slack.
const VertexSet* endpoints = sta_->endpoints();
vector<pair<Vertex*, Slack>> violating_ends;
set<pair<Vertex*, Slack>, SlackVertexPairComp> violating_ends;
// logger_->setDebugLevel(RSZ, "repair_setup", 2);
// Should check here whether we can figure out the clock domain for each
// vertex. This may be the place where we can do some round robin fun to
Expand All @@ -119,14 +132,9 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
for (Vertex* end : *endpoints) {
const Slack end_slack = sta_->vertexSlack(end, max_);
if (end_slack < setup_slack_margin) {
violating_ends.emplace_back(end, end_slack);
violating_ends.emplace(end, end_slack);
}
}
std::stable_sort(violating_ends.begin(),
violating_ends.end(),
[](const auto& end_slack1, const auto& end_slack2) {
return end_slack1.second < end_slack2.second;
});
debugPrint(logger_,
RSZ,
"repair_setup",
Expand Down Expand Up @@ -174,8 +182,9 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
printProgress(opto_iteration, false, false, false, num_viols);
}
float fix_rate_threshold = inc_fix_rate_threshold_;
for (const auto& end_original_slack : violating_ends) {
Vertex* end = end_original_slack.first;
while (num_viols > 0 && !violating_ends.empty()) {
Vertex* end = violating_ends.begin()->first;
violating_ends.erase(violating_ends.begin());
Slack end_slack = sta_->vertexSlack(end, max_);
Slack worst_slack;
Vertex* worst_vertex;
Expand All @@ -202,14 +211,14 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
" max_end_count {}", end->name(network_), end_index,
max_end_count);
// clang-format on
break;
continue;
}
Slack prev_end_slack = end_slack;
Slack prev_worst_slack = worst_slack;
int pass = 1;
int decreasing_slack_passes = 0;
resizer_->journalBegin();
while (pass <= max_passes) {
while (pass <= max_passes_per_iter) {
opto_iteration++;
if (verbose) {
printProgress(opto_iteration, false, false, false, num_viols);
Expand Down Expand Up @@ -328,7 +337,8 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
// Allow slack to increase to get out of local minima.
// Do not update prev_end_slack so it saves the high water mark.
decreasing_slack_passes++;
if (decreasing_slack_passes > decreasing_slack_max_passes_) {
if (decreasing_slack_passes > decreasing_slack_max_passes_
|| pass == max_passes_per_iter) {
// Undo changes that reduced slack.
debugPrint(logger_,
RSZ,
Expand All @@ -350,9 +360,10 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
removed_buffer_count_);
// clang-format off
debugPrint(logger_, RSZ, "repair_setup", 1, "bailing out {} decreasing"
" passes {} > decreasig pass limit {}", end->name(network_),
decreasing_slack_passes, decreasing_slack_max_passes_);
" passes {} > decreasig pass limit {} or pass {} > max passes per iteration {}", end->name(network_),
decreasing_slack_passes, decreasing_slack_max_passes_, pass, max_passes_per_iter);
// clang-format on
++pass;
break;
}
}
Expand All @@ -370,6 +381,10 @@ bool RepairSetup::repairSetup(const float setup_slack_margin,
}
pass++;
} // while pass <= max_passes
if (pass == max_passes_per_iter + 1) {
// If violation was not fixed, placed it back to the queue
violating_ends.emplace(end, worst_slack);
}
if (verbose) {
printProgress(opto_iteration, true, false, false, num_viols);
}
Expand Down
2 changes: 1 addition & 1 deletion src/rsz/src/RepairSetup.hh
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class RepairSetup : public sta::dbStaState
// Percent of violating ends to repair to
// reduce tns (0.0-1.0).
double repair_tns_end_percent,
int max_passes,
int max_passes_per_iter,
bool verbose,
bool skip_pin_swap,
bool skip_gate_cloning,
Expand Down
4 changes: 2 additions & 2 deletions src/rsz/src/Resizer.i
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ repair_net_cmd(Net *net,
bool
repair_setup(double setup_margin,
double repair_tns_end_percent,
int max_passes,
int max_passes_per_iter,
bool match_cell_footprint, bool verbose,
bool skip_pin_swap, bool skip_gate_cloning,
bool skip_buffering, bool skip_buffer_removal,
Expand All @@ -604,7 +604,7 @@ repair_setup(double setup_margin,
ensureLinked();
Resizer *resizer = getResizer();
return resizer->repairSetup(setup_margin, repair_tns_end_percent,
max_passes, match_cell_footprint, verbose,
max_passes_per_iter, match_cell_footprint, verbose,
skip_pin_swap, skip_gate_cloning,
skip_buffering, skip_buffer_removal,
skip_last_gasp);
Expand Down
12 changes: 9 additions & 3 deletions src/rsz/src/Resizer.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ sta::define_cmd_args "repair_timing" {[-setup] [-hold]\
[-skip_last_gasp]\
[-repair_tns tns_end_percent]\
[-max_passes passes]\
[-max_passes_per_iter passes_per_iter]\
[-max_buffer_percent buffer_percent]\
[-max_utilization util] \
[-match_cell_footprint] \
Expand All @@ -546,7 +547,7 @@ proc repair_timing { args } {
sta::parse_key_args "repair_timing" args \
keys {-setup_margin -hold_margin -slack_margin \
-libraries -max_utilization -max_buffer_percent \
-recover_power -repair_tns -max_passes} \
-recover_power -repair_tns -max_passes -max_passes_per_iter} \
flags {-setup -hold -allow_setup_violations -skip_pin_swap -skip_gate_cloning \
-skip_buffering -skip_buffer_removal -skip_last_gasp -match_cell_footprint \
-verbose}
Expand Down Expand Up @@ -612,6 +613,11 @@ proc repair_timing { args } {
set max_passes $keys(-max_passes)
}

set max_passes_per_iter 20
if { [info exists keys(-max_passes_per_iter)] } {
set max_passes_per_iter $keys(-max_passes_per_iter)
}

set match_cell_footprint [info exists flags(-match_cell_footprint)]
if { [design_is_routed] } {
rsz::set_parasitics_src "detailed_routing"
Expand All @@ -627,8 +633,8 @@ proc repair_timing { args } {
set recovered_power [rsz::recover_power $recover_power_percent $match_cell_footprint]
} else {
if { $setup } {
set repaired_setup [rsz::repair_setup $setup_margin $repair_tns_end_percent $max_passes \
$match_cell_footprint $verbose \
set repaired_setup [rsz::repair_setup $setup_margin $repair_tns_end_percent \
$max_passes_per_iter $match_cell_footprint $verbose \
$skip_pin_swap $skip_gate_cloning $skip_buffering \
$skip_buffer_removal $skip_last_gasp]
}
Expand Down

0 comments on commit 22d1195

Please sign in to comment.