Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsz: repairSetup: Restrict number of repairs per iteration #6244

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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/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`. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give the default (20)

| `-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
2 changes: 1 addition & 1 deletion src/rsz/test/repair_fanout6.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ report_check_types -max_fanout
# but there is no point in inserting extra buffers to fix non critical
# paths. What matters is repair_timning's ability to optimize the timing
# when it matters.
repair_timing -setup -repair_tns 0 -skip_gate_cloning
repair_timing -setup -repair_tns 0 -skip_gate_cloning -max_passes_per_iter 1000
report_worst_slack -max
Loading