From 094ab8bbc71fd8831f15a66e129d5a4cbedea9f8 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 16 Apr 2021 11:09:43 -0700 Subject: [PATCH] CheckSlewLimits/CheckCapLimits::findLimits(corner) --- search/CheckCapacitanceLimits.cc | 104 ++++++++++++++++--------------- search/CheckCapacitanceLimits.hh | 29 ++++----- search/CheckSlewLimits.cc | 90 +++++++++++++------------- search/CheckSlewLimits.hh | 25 ++++---- search/ReportPath.cc | 9 ++- search/ReportPath.hh | 1 + search/Sta.cc | 38 +++++------ 7 files changed, 155 insertions(+), 141 deletions(-) diff --git a/search/CheckCapacitanceLimits.cc b/search/CheckCapacitanceLimits.cc index 1d883960..07f4457c 100644 --- a/search/CheckCapacitanceLimits.cc +++ b/search/CheckCapacitanceLimits.cc @@ -89,49 +89,49 @@ CheckCapacitanceLimits::CheckCapacitanceLimits(const Sta *sta) : void CheckCapacitanceLimits::checkCapacitance(const Pin *pin, - const Corner *corner1, + const Corner *corner, const MinMax *min_max, // Return values. - const Corner *&corner, - const RiseFall *&rf, - float &capacitance, - float &limit, - float &slack) const + const Corner *&corner1, + const RiseFall *&rf1, + float &capacitance1, + float &limit1, + float &slack1) const { - corner = nullptr; - rf = nullptr; - capacitance = 0.0; - limit = 0.0; - slack = MinMax::min()->initValue(); - if (corner1) - checkCapacitance1(pin, corner1, min_max, - corner, rf, capacitance, limit, slack); + corner1 = nullptr; + rf1 = nullptr; + capacitance1 = 0.0; + limit1 = 0.0; + slack1 = MinMax::min()->initValue(); + if (corner) + checkCapacitance1(pin, corner, min_max, + corner1, rf1, capacitance1, limit1, slack1); else { - for (auto corner1 : *sta_->corners()) { - checkCapacitance1(pin, corner1, min_max, - corner, rf, capacitance, limit, slack); + for (auto corner : *sta_->corners()) { + checkCapacitance1(pin, corner, min_max, + corner1, rf1, capacitance1, limit1, slack1); } } } void CheckCapacitanceLimits::checkCapacitance1(const Pin *pin, - const Corner *corner1, + const Corner *corner, const MinMax *min_max, // Return values. - const Corner *&corner, - const RiseFall *&rf, - float &capacitance, - float &limit, - float &slack) const + const Corner *&corner1, + const RiseFall *&rf1, + float &capacitance1, + float &limit1, + float &slack1) const { - float limit1; - bool limit1_exists; - findLimit(pin, min_max, limit1, limit1_exists); - if (limit1_exists) { - for (auto rf1 : RiseFall::range()) { - checkCapacitance(pin, corner1, min_max, rf1, limit1, - corner, rf, capacitance, slack, limit); + float limit; + bool limit_exists; + findLimit(pin, corner, min_max, limit, limit_exists); + if (limit_exists) { + for (auto rf : RiseFall::range()) { + checkCapacitance(pin, corner, min_max, rf, limit, + corner1, rf1, capacitance1, slack1, limit1); } } } @@ -139,6 +139,7 @@ CheckCapacitanceLimits::checkCapacitance1(const Pin *pin, // return the tightest limit. void CheckCapacitanceLimits::findLimit(const Pin *pin, + const Corner *corner, const MinMax *min_max, // Return values. float &limit, @@ -176,10 +177,11 @@ CheckCapacitanceLimits::findLimit(const Pin *pin, } LibertyPort *port = network->libertyPort(pin); if (port) { - port->capacitanceLimit(min_max, limit1, exists1); + LibertyPort *corner_port = port->cornerPort(corner->libertyIndex(min_max)); + corner_port->capacitanceLimit(min_max, limit1, exists1); if (!exists1 && port->direction()->isAnyOutput()) - port->libertyLibrary()->defaultMaxCapacitance(limit1, exists1); + corner_port->libertyLibrary()->defaultMaxCapacitance(limit1, exists1); if (exists1 && (!exists || min_max->compare(limit, limit1))) { @@ -192,32 +194,32 @@ CheckCapacitanceLimits::findLimit(const Pin *pin, void CheckCapacitanceLimits::checkCapacitance(const Pin *pin, - const Corner *corner1, + const Corner *corner, const MinMax *min_max, - const RiseFall *rf1, - float limit1, + const RiseFall *rf, + float limit, // Return values. - const Corner *&corner, - const RiseFall *&rf, - float &capacitance, - float &slack, - float &limit) const + const Corner *&corner1, + const RiseFall *&rf1, + float &capacitance1, + float &slack1, + float &limit1) const { - const DcalcAnalysisPt *dcalc_ap = corner1->findDcalcAnalysisPt(min_max); + const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max); GraphDelayCalc *dcalc = sta_->graphDelayCalc(); float cap = dcalc->loadCap(pin, dcalc_ap); - float slack1 = (min_max == MinMax::max()) - ? limit1 - cap : cap - limit1; - if (slack1 < slack + float slack = (min_max == MinMax::max()) + ? limit - cap : cap - limit; + if (slack < slack1 // Break ties for the sake of regression stability. - || (fuzzyEqual(slack1, slack) - && rf1->index() < rf->index())) { - corner = corner1; - rf = rf1; - capacitance = cap; - slack = slack1; - limit = limit1; + || (fuzzyEqual(slack, slack1) + && rf->index() < rf1->index())) { + corner1 = corner; + rf1 = rf; + capacitance1 = cap; + slack1 = slack; + limit1 = limit; } } diff --git a/search/CheckCapacitanceLimits.hh b/search/CheckCapacitanceLimits.hh index a47430e3..3a60d499 100644 --- a/search/CheckCapacitanceLimits.hh +++ b/search/CheckCapacitanceLimits.hh @@ -54,24 +54,25 @@ protected: void checkCapacitance(const Pin *pin, const Corner *corner, const MinMax *min_max, - const RiseFall *rf1, - float limit1, + const RiseFall *rf, + float limit, // Return values. const Corner *&corner1, - const RiseFall *&rf, - float &capacitance, - float &slack, - float &limit) const; + const RiseFall *&rf1, + float &capacitance1, + float &slack1, + float &limit1) const; void checkCapacitance1(const Pin *pin, - const Corner *corner1, - const MinMax *min_max, - // Return values. - const Corner *&corner, - const RiseFall *&rf, - float &capacitance, - float &limit, - float &slack) const; + const Corner *corner, + const MinMax *min_max, + // Return values. + const Corner *&corner1, + const RiseFall *&rf1, + float &capacitance1, + float &limit1, + float &slack1) const; void findLimit(const Pin *pin, + const Corner *corner, const MinMax *min_max, // Return values. float &limit, diff --git a/search/CheckSlewLimits.cc b/search/CheckSlewLimits.cc index d2df042d..21a5b9e8 100644 --- a/search/CheckSlewLimits.cc +++ b/search/CheckSlewLimits.cc @@ -121,45 +121,45 @@ CheckSlewLimits::checkSlews1(const Pin *pin, bool check_clks, // Return values. const Corner *&corner1, - const RiseFall *&rf, - Slew &slew, - float &limit, - float &slack) const + const RiseFall *&rf1, + Slew &slew1, + float &limit1, + float &slack1) const { Vertex *vertex, *bidirect_drvr_vertex; sta_->graph()->pinVertices(pin, vertex, bidirect_drvr_vertex); if (vertex) checkSlews1(vertex, corner, min_max, check_clks, - corner1, rf, slew, limit, slack); + corner1, rf1, slew1, limit1, slack1); if (bidirect_drvr_vertex) checkSlews1(bidirect_drvr_vertex, corner, min_max, check_clks, - corner1, rf, slew, limit, slack); + corner1, rf1, slew1, limit1, slack1); } void CheckSlewLimits::checkSlews1(Vertex *vertex, - const Corner *corner1, + const Corner *corner, const MinMax *min_max, bool check_clks, // Return values. - const Corner *&corner, - const RiseFall *&rf, - Slew &slew, - float &limit, - float &slack) const + const Corner *&corner1, + const RiseFall *&rf1, + Slew &slew1, + float &limit1, + float &slack1) const { const Pin *pin = vertex->pin(); if (!vertex->isDisabledConstraint() && !vertex->isConstant() && !sta_->clkNetwork()->isIdealClock(pin)) { - for (auto rf1 : RiseFall::range()) { - float limit1; - bool limit1_exists; - findLimit(pin, vertex, rf1, min_max, check_clks, - limit1, limit1_exists); - if (limit1_exists) { - checkSlew(vertex, corner1, rf1, min_max, limit1, - corner, rf, slew, slack, limit); + for (auto rf : RiseFall::range()) { + float limit; + bool limit_exists; + findLimit(pin, vertex, corner, rf, min_max, check_clks, + limit, limit_exists); + if (limit_exists) { + checkSlew(vertex, corner, rf, min_max, limit, + corner1, rf1, slew1, slack1, limit1); } } } @@ -169,6 +169,7 @@ CheckSlewLimits::checkSlews1(Vertex *vertex, void CheckSlewLimits::findLimit(const Pin *pin, const Vertex *vertex, + const Corner *corner, const RiseFall *rf, const MinMax *min_max, bool check_clks, @@ -218,11 +219,12 @@ CheckSlewLimits::findLimit(const Pin *pin, else { LibertyPort *port = network->libertyPort(pin); if (port) { - port->slewLimit(min_max, limit1, exists1); + LibertyPort *corner_port = port->cornerPort(corner->libertyIndex(min_max)); + corner_port->slewLimit(min_max, limit1, exists1); if (!exists1 && port->direction()->isAnyOutput() && min_max == MinMax::max()) - port->libertyLibrary()->defaultMaxSlew(limit1, exists1); + corner_port->libertyLibrary()->defaultMaxSlew(limit1, exists1); if (exists1 && (!exists || min_max->compare(limit, limit1))) { @@ -249,32 +251,32 @@ CheckSlewLimits::clockDomains(const Vertex *vertex, void CheckSlewLimits::checkSlew(Vertex *vertex, - const Corner *corner1, - const RiseFall *rf1, + const Corner *corner, + const RiseFall *rf, const MinMax *min_max, - float limit1, + float limit, // Return values. - const Corner *&corner, - const RiseFall *&rf, - Slew &slew, - float &slack, - float &limit) const + const Corner *&corner1, + const RiseFall *&rf1, + Slew &slew1, + float &slack1, + float &limit1) const { - const DcalcAnalysisPt *dcalc_ap = corner1->findDcalcAnalysisPt(min_max); - Slew slew1 = sta_->graph()->slew(vertex, rf1, dcalc_ap->index()); - float slew2 = delayAsFloat(slew1); - float slack1 = (min_max == MinMax::max()) - ? limit1 - slew2 : slew2 - limit1; - if (corner == nullptr - || (slack1 < slack + const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max); + Slew slew = sta_->graph()->slew(vertex, rf, dcalc_ap->index()); + float slew2 = delayAsFloat(slew); + float slack = (min_max == MinMax::max()) + ? limit - slew2 : slew2 - limit; + if (corner1 == nullptr + || (slack < slack1 // Break ties for the sake of regression stability. - || (fuzzyEqual(slack1, slack) - && rf1->index() < rf->index()))) { - corner = corner1; - rf = rf1; - slew = slew1; - slack = slack1; - limit = limit1; + || (fuzzyEqual(slack, slack1) + && rf->index() < rf1->index()))) { + corner1 = corner; + rf1 = rf; + slew1 = slew; + slack1 = slack; + limit1 = limit; } } diff --git a/search/CheckSlewLimits.hh b/search/CheckSlewLimits.hh index d254d87e..903848ac 100644 --- a/search/CheckSlewLimits.hh +++ b/search/CheckSlewLimits.hh @@ -60,20 +60,20 @@ protected: bool check_clks, // Return values. const Corner *&corner1, - const RiseFall *&rf, - Slew &slew, - float &limit, - float &slack) const; + const RiseFall *&rf1, + Slew &slew1, + float &limit1, + float &slack1) const; void checkSlews1(Vertex *vertex, - const Corner *corner1, + const Corner *corner, const MinMax *min_max, bool check_clks, // Return values. - const Corner *&corner, - const RiseFall *&rf, - Slew &slew, - float &limit, - float &slack) const; + const Corner *&corner1, + const RiseFall *&rf1, + Slew &slew1, + float &limit1, + float &slack1) const; void checkSlew(Vertex *vertex, const Corner *corner1, const RiseFall *rf1, @@ -87,12 +87,13 @@ protected: float &limit) const; void findLimit(const Pin *pin, const Vertex *vertex, + const Corner *corner, const RiseFall *rf, const MinMax *min_max, bool check_clks, // Return values. - float &limit1, - bool &limit1_exists) const; + float &limit, + bool &limit_exists) const; void checkSlewLimits(Instance *inst, bool violators, const Corner *corner, diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 818e2add..0d834aa3 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -1521,7 +1521,8 @@ ReportPath::reportLimitVerbose(const ReportField *field, float value, float limit, float slack, - const MinMax *min_max) + const Corner *corner, + const MinMax *min_max) { string line; line += "Pin "; @@ -1531,6 +1532,12 @@ ReportPath::reportLimitVerbose(const ReportField *field, line += rf->shortName(); else line += ' '; + // Don't report corner if the default corner is the only corner. + if (corner && corners_->count() > 1) { + line += " (corner "; + line += corner->name(); + line += ")"; + } report_->reportLineString(line); line = min_max->asString(); diff --git a/search/ReportPath.hh b/search/ReportPath.hh index 6274828d..b3687a53 100644 --- a/search/ReportPath.hh +++ b/search/ReportPath.hh @@ -126,6 +126,7 @@ public: float value, float limit, float slack, + const Corner *corner, const MinMax *min_max); ReportField *fieldSlew() const { return field_slew_; } ReportField *fieldFanout() const { return field_fanout_; } diff --git a/search/Sta.cc b/search/Sta.cc index c148ecd4..d850a9c3 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4965,13 +4965,13 @@ Sta::reportSlewLimitShort(Pin *pin, const MinMax *min_max) { const Corner *corner1; - const RiseFall *rf; - Slew slew; - float limit, slack; + const RiseFall *rf1; + Slew slew1; + float limit1, slack1; check_slew_limits_->checkSlew(pin, corner, min_max, true, - corner1, rf, slew, limit, slack); + corner1, rf1, slew1, limit1, slack1); report_path_->reportLimitShort(report_path_->fieldSlew(), pin, - delayAsFloat(slew), limit, slack); + delayAsFloat(slew1), limit1, slack1); } void @@ -4980,14 +4980,14 @@ Sta::reportSlewLimitVerbose(Pin *pin, const MinMax *min_max) { const Corner *corner1; - const RiseFall *rf; - Slew slew; - float limit, slack; + const RiseFall *rf1; + Slew slew1; + float limit1, slack1; check_slew_limits_->checkSlew(pin, corner, min_max, true, - corner1, rf, slew, limit, slack); - report_path_->reportLimitVerbose(report_path_->fieldSlew(), pin, rf, - delayAsFloat(slew), - limit, slack, min_max); + corner1, rf1, slew1, limit1, slack1); + report_path_->reportLimitVerbose(report_path_->fieldSlew(), pin, rf1, + delayAsFloat(slew1), + limit1, slack1, corner1, min_max); } void @@ -5051,7 +5051,7 @@ Sta::reportFanoutLimitVerbose(Pin *pin, fanout, limit, slack); report_path_->reportLimitVerbose(report_path_->fieldFanout(), pin, nullptr, fanout, - limit, slack, min_max); + limit, slack, nullptr, min_max); } void @@ -5114,14 +5114,14 @@ Sta::reportCapacitanceLimitVerbose(Pin *pin, const MinMax *min_max) { const Corner *corner1; - const RiseFall *rf; - float capacitance, limit, slack; + const RiseFall *rf1; + float capacitance1, limit1, slack1; check_capacitance_limits_->checkCapacitance(pin, corner, min_max, - corner1, rf, capacitance, - limit, slack); + corner1, rf1, capacitance1, + limit1, slack1); report_path_->reportLimitVerbose(report_path_->fieldCapacitance(), - pin, rf, capacitance, - limit, slack, min_max); + pin, rf1, capacitance1, + limit1, slack1, corner1, min_max); } void