CheckSlewLimits/CheckCapLimits::findLimits(corner)

This commit is contained in:
James Cherry 2021-04-16 11:09:43 -07:00
parent b7ed8750b3
commit 094ab8bbc7
7 changed files with 155 additions and 141 deletions

View File

@ -89,49 +89,49 @@ CheckCapacitanceLimits::CheckCapacitanceLimits(const Sta *sta) :
void void
CheckCapacitanceLimits::checkCapacitance(const Pin *pin, CheckCapacitanceLimits::checkCapacitance(const Pin *pin,
const Corner *corner1, const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
// Return values. // Return values.
const Corner *&corner, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
float &capacitance, float &capacitance1,
float &limit, float &limit1,
float &slack) const float &slack1) const
{ {
corner = nullptr; corner1 = nullptr;
rf = nullptr; rf1 = nullptr;
capacitance = 0.0; capacitance1 = 0.0;
limit = 0.0; limit1 = 0.0;
slack = MinMax::min()->initValue(); slack1 = MinMax::min()->initValue();
if (corner1) if (corner)
checkCapacitance1(pin, corner1, min_max, checkCapacitance1(pin, corner, min_max,
corner, rf, capacitance, limit, slack); corner1, rf1, capacitance1, limit1, slack1);
else { else {
for (auto corner1 : *sta_->corners()) { for (auto corner : *sta_->corners()) {
checkCapacitance1(pin, corner1, min_max, checkCapacitance1(pin, corner, min_max,
corner, rf, capacitance, limit, slack); corner1, rf1, capacitance1, limit1, slack1);
} }
} }
} }
void void
CheckCapacitanceLimits::checkCapacitance1(const Pin *pin, CheckCapacitanceLimits::checkCapacitance1(const Pin *pin,
const Corner *corner1, const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
// Return values. // Return values.
const Corner *&corner, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
float &capacitance, float &capacitance1,
float &limit, float &limit1,
float &slack) const float &slack1) const
{ {
float limit1; float limit;
bool limit1_exists; bool limit_exists;
findLimit(pin, min_max, limit1, limit1_exists); findLimit(pin, corner, min_max, limit, limit_exists);
if (limit1_exists) { if (limit_exists) {
for (auto rf1 : RiseFall::range()) { for (auto rf : RiseFall::range()) {
checkCapacitance(pin, corner1, min_max, rf1, limit1, checkCapacitance(pin, corner, min_max, rf, limit,
corner, rf, capacitance, slack, limit); corner1, rf1, capacitance1, slack1, limit1);
} }
} }
} }
@ -139,6 +139,7 @@ CheckCapacitanceLimits::checkCapacitance1(const Pin *pin,
// return the tightest limit. // return the tightest limit.
void void
CheckCapacitanceLimits::findLimit(const Pin *pin, CheckCapacitanceLimits::findLimit(const Pin *pin,
const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
// Return values. // Return values.
float &limit, float &limit,
@ -176,10 +177,11 @@ CheckCapacitanceLimits::findLimit(const Pin *pin,
} }
LibertyPort *port = network->libertyPort(pin); LibertyPort *port = network->libertyPort(pin);
if (port) { 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 if (!exists1
&& port->direction()->isAnyOutput()) && port->direction()->isAnyOutput())
port->libertyLibrary()->defaultMaxCapacitance(limit1, exists1); corner_port->libertyLibrary()->defaultMaxCapacitance(limit1, exists1);
if (exists1 if (exists1
&& (!exists && (!exists
|| min_max->compare(limit, limit1))) { || min_max->compare(limit, limit1))) {
@ -192,32 +194,32 @@ CheckCapacitanceLimits::findLimit(const Pin *pin,
void void
CheckCapacitanceLimits::checkCapacitance(const Pin *pin, CheckCapacitanceLimits::checkCapacitance(const Pin *pin,
const Corner *corner1, const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
const RiseFall *rf1, const RiseFall *rf,
float limit1, float limit,
// Return values. // Return values.
const Corner *&corner, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
float &capacitance, float &capacitance1,
float &slack, float &slack1,
float &limit) const float &limit1) const
{ {
const DcalcAnalysisPt *dcalc_ap = corner1->findDcalcAnalysisPt(min_max); const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
GraphDelayCalc *dcalc = sta_->graphDelayCalc(); GraphDelayCalc *dcalc = sta_->graphDelayCalc();
float cap = dcalc->loadCap(pin, dcalc_ap); float cap = dcalc->loadCap(pin, dcalc_ap);
float slack1 = (min_max == MinMax::max()) float slack = (min_max == MinMax::max())
? limit1 - cap : cap - limit1; ? limit - cap : cap - limit;
if (slack1 < slack if (slack < slack1
// Break ties for the sake of regression stability. // Break ties for the sake of regression stability.
|| (fuzzyEqual(slack1, slack) || (fuzzyEqual(slack, slack1)
&& rf1->index() < rf->index())) { && rf->index() < rf1->index())) {
corner = corner1; corner1 = corner;
rf = rf1; rf1 = rf;
capacitance = cap; capacitance1 = cap;
slack = slack1; slack1 = slack;
limit = limit1; limit1 = limit;
} }
} }

View File

@ -54,24 +54,25 @@ protected:
void checkCapacitance(const Pin *pin, void checkCapacitance(const Pin *pin,
const Corner *corner, const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
const RiseFall *rf1, const RiseFall *rf,
float limit1, float limit,
// Return values. // Return values.
const Corner *&corner1, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
float &capacitance, float &capacitance1,
float &slack, float &slack1,
float &limit) const; float &limit1) const;
void checkCapacitance1(const Pin *pin, void checkCapacitance1(const Pin *pin,
const Corner *corner1, const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
// Return values. // Return values.
const Corner *&corner, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
float &capacitance, float &capacitance1,
float &limit, float &limit1,
float &slack) const; float &slack1) const;
void findLimit(const Pin *pin, void findLimit(const Pin *pin,
const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
// Return values. // Return values.
float &limit, float &limit,

View File

@ -121,45 +121,45 @@ CheckSlewLimits::checkSlews1(const Pin *pin,
bool check_clks, bool check_clks,
// Return values. // Return values.
const Corner *&corner1, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
Slew &slew, Slew &slew1,
float &limit, float &limit1,
float &slack) const float &slack1) const
{ {
Vertex *vertex, *bidirect_drvr_vertex; Vertex *vertex, *bidirect_drvr_vertex;
sta_->graph()->pinVertices(pin, vertex, bidirect_drvr_vertex); sta_->graph()->pinVertices(pin, vertex, bidirect_drvr_vertex);
if (vertex) if (vertex)
checkSlews1(vertex, corner, min_max, check_clks, checkSlews1(vertex, corner, min_max, check_clks,
corner1, rf, slew, limit, slack); corner1, rf1, slew1, limit1, slack1);
if (bidirect_drvr_vertex) if (bidirect_drvr_vertex)
checkSlews1(bidirect_drvr_vertex, corner, min_max, check_clks, checkSlews1(bidirect_drvr_vertex, corner, min_max, check_clks,
corner1, rf, slew, limit, slack); corner1, rf1, slew1, limit1, slack1);
} }
void void
CheckSlewLimits::checkSlews1(Vertex *vertex, CheckSlewLimits::checkSlews1(Vertex *vertex,
const Corner *corner1, const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
bool check_clks, bool check_clks,
// Return values. // Return values.
const Corner *&corner, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
Slew &slew, Slew &slew1,
float &limit, float &limit1,
float &slack) const float &slack1) const
{ {
const Pin *pin = vertex->pin(); const Pin *pin = vertex->pin();
if (!vertex->isDisabledConstraint() if (!vertex->isDisabledConstraint()
&& !vertex->isConstant() && !vertex->isConstant()
&& !sta_->clkNetwork()->isIdealClock(pin)) { && !sta_->clkNetwork()->isIdealClock(pin)) {
for (auto rf1 : RiseFall::range()) { for (auto rf : RiseFall::range()) {
float limit1; float limit;
bool limit1_exists; bool limit_exists;
findLimit(pin, vertex, rf1, min_max, check_clks, findLimit(pin, vertex, corner, rf, min_max, check_clks,
limit1, limit1_exists); limit, limit_exists);
if (limit1_exists) { if (limit_exists) {
checkSlew(vertex, corner1, rf1, min_max, limit1, checkSlew(vertex, corner, rf, min_max, limit,
corner, rf, slew, slack, limit); corner1, rf1, slew1, slack1, limit1);
} }
} }
} }
@ -169,6 +169,7 @@ CheckSlewLimits::checkSlews1(Vertex *vertex,
void void
CheckSlewLimits::findLimit(const Pin *pin, CheckSlewLimits::findLimit(const Pin *pin,
const Vertex *vertex, const Vertex *vertex,
const Corner *corner,
const RiseFall *rf, const RiseFall *rf,
const MinMax *min_max, const MinMax *min_max,
bool check_clks, bool check_clks,
@ -218,11 +219,12 @@ CheckSlewLimits::findLimit(const Pin *pin,
else { else {
LibertyPort *port = network->libertyPort(pin); LibertyPort *port = network->libertyPort(pin);
if (port) { 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 if (!exists1
&& port->direction()->isAnyOutput() && port->direction()->isAnyOutput()
&& min_max == MinMax::max()) && min_max == MinMax::max())
port->libertyLibrary()->defaultMaxSlew(limit1, exists1); corner_port->libertyLibrary()->defaultMaxSlew(limit1, exists1);
if (exists1 if (exists1
&& (!exists && (!exists
|| min_max->compare(limit, limit1))) { || min_max->compare(limit, limit1))) {
@ -249,32 +251,32 @@ CheckSlewLimits::clockDomains(const Vertex *vertex,
void void
CheckSlewLimits::checkSlew(Vertex *vertex, CheckSlewLimits::checkSlew(Vertex *vertex,
const Corner *corner1, const Corner *corner,
const RiseFall *rf1, const RiseFall *rf,
const MinMax *min_max, const MinMax *min_max,
float limit1, float limit,
// Return values. // Return values.
const Corner *&corner, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
Slew &slew, Slew &slew1,
float &slack, float &slack1,
float &limit) const float &limit1) const
{ {
const DcalcAnalysisPt *dcalc_ap = corner1->findDcalcAnalysisPt(min_max); const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
Slew slew1 = sta_->graph()->slew(vertex, rf1, dcalc_ap->index()); Slew slew = sta_->graph()->slew(vertex, rf, dcalc_ap->index());
float slew2 = delayAsFloat(slew1); float slew2 = delayAsFloat(slew);
float slack1 = (min_max == MinMax::max()) float slack = (min_max == MinMax::max())
? limit1 - slew2 : slew2 - limit1; ? limit - slew2 : slew2 - limit;
if (corner == nullptr if (corner1 == nullptr
|| (slack1 < slack || (slack < slack1
// Break ties for the sake of regression stability. // Break ties for the sake of regression stability.
|| (fuzzyEqual(slack1, slack) || (fuzzyEqual(slack, slack1)
&& rf1->index() < rf->index()))) { && rf->index() < rf1->index()))) {
corner = corner1; corner1 = corner;
rf = rf1; rf1 = rf;
slew = slew1; slew1 = slew;
slack = slack1; slack1 = slack;
limit = limit1; limit1 = limit;
} }
} }

View File

@ -60,20 +60,20 @@ protected:
bool check_clks, bool check_clks,
// Return values. // Return values.
const Corner *&corner1, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
Slew &slew, Slew &slew1,
float &limit, float &limit1,
float &slack) const; float &slack1) const;
void checkSlews1(Vertex *vertex, void checkSlews1(Vertex *vertex,
const Corner *corner1, const Corner *corner,
const MinMax *min_max, const MinMax *min_max,
bool check_clks, bool check_clks,
// Return values. // Return values.
const Corner *&corner, const Corner *&corner1,
const RiseFall *&rf, const RiseFall *&rf1,
Slew &slew, Slew &slew1,
float &limit, float &limit1,
float &slack) const; float &slack1) const;
void checkSlew(Vertex *vertex, void checkSlew(Vertex *vertex,
const Corner *corner1, const Corner *corner1,
const RiseFall *rf1, const RiseFall *rf1,
@ -87,12 +87,13 @@ protected:
float &limit) const; float &limit) const;
void findLimit(const Pin *pin, void findLimit(const Pin *pin,
const Vertex *vertex, const Vertex *vertex,
const Corner *corner,
const RiseFall *rf, const RiseFall *rf,
const MinMax *min_max, const MinMax *min_max,
bool check_clks, bool check_clks,
// Return values. // Return values.
float &limit1, float &limit,
bool &limit1_exists) const; bool &limit_exists) const;
void checkSlewLimits(Instance *inst, void checkSlewLimits(Instance *inst,
bool violators, bool violators,
const Corner *corner, const Corner *corner,

View File

@ -1521,7 +1521,8 @@ ReportPath::reportLimitVerbose(const ReportField *field,
float value, float value,
float limit, float limit,
float slack, float slack,
const MinMax *min_max) const Corner *corner,
const MinMax *min_max)
{ {
string line; string line;
line += "Pin "; line += "Pin ";
@ -1531,6 +1532,12 @@ ReportPath::reportLimitVerbose(const ReportField *field,
line += rf->shortName(); line += rf->shortName();
else else
line += ' '; 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); report_->reportLineString(line);
line = min_max->asString(); line = min_max->asString();

View File

@ -126,6 +126,7 @@ public:
float value, float value,
float limit, float limit,
float slack, float slack,
const Corner *corner,
const MinMax *min_max); const MinMax *min_max);
ReportField *fieldSlew() const { return field_slew_; } ReportField *fieldSlew() const { return field_slew_; }
ReportField *fieldFanout() const { return field_fanout_; } ReportField *fieldFanout() const { return field_fanout_; }

View File

@ -4965,13 +4965,13 @@ Sta::reportSlewLimitShort(Pin *pin,
const MinMax *min_max) const MinMax *min_max)
{ {
const Corner *corner1; const Corner *corner1;
const RiseFall *rf; const RiseFall *rf1;
Slew slew; Slew slew1;
float limit, slack; float limit1, slack1;
check_slew_limits_->checkSlew(pin, corner, min_max, true, 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, report_path_->reportLimitShort(report_path_->fieldSlew(), pin,
delayAsFloat(slew), limit, slack); delayAsFloat(slew1), limit1, slack1);
} }
void void
@ -4980,14 +4980,14 @@ Sta::reportSlewLimitVerbose(Pin *pin,
const MinMax *min_max) const MinMax *min_max)
{ {
const Corner *corner1; const Corner *corner1;
const RiseFall *rf; const RiseFall *rf1;
Slew slew; Slew slew1;
float limit, slack; float limit1, slack1;
check_slew_limits_->checkSlew(pin, corner, min_max, true, check_slew_limits_->checkSlew(pin, corner, min_max, true,
corner1, rf, slew, limit, slack); corner1, rf1, slew1, limit1, slack1);
report_path_->reportLimitVerbose(report_path_->fieldSlew(), pin, rf, report_path_->reportLimitVerbose(report_path_->fieldSlew(), pin, rf1,
delayAsFloat(slew), delayAsFloat(slew1),
limit, slack, min_max); limit1, slack1, corner1, min_max);
} }
void void
@ -5051,7 +5051,7 @@ Sta::reportFanoutLimitVerbose(Pin *pin,
fanout, limit, slack); fanout, limit, slack);
report_path_->reportLimitVerbose(report_path_->fieldFanout(), report_path_->reportLimitVerbose(report_path_->fieldFanout(),
pin, nullptr, fanout, pin, nullptr, fanout,
limit, slack, min_max); limit, slack, nullptr, min_max);
} }
void void
@ -5114,14 +5114,14 @@ Sta::reportCapacitanceLimitVerbose(Pin *pin,
const MinMax *min_max) const MinMax *min_max)
{ {
const Corner *corner1; const Corner *corner1;
const RiseFall *rf; const RiseFall *rf1;
float capacitance, limit, slack; float capacitance1, limit1, slack1;
check_capacitance_limits_->checkCapacitance(pin, corner, min_max, check_capacitance_limits_->checkCapacitance(pin, corner, min_max,
corner1, rf, capacitance, corner1, rf1, capacitance1,
limit, slack); limit1, slack1);
report_path_->reportLimitVerbose(report_path_->fieldCapacitance(), report_path_->reportLimitVerbose(report_path_->fieldCapacitance(),
pin, rf, capacitance, pin, rf1, capacitance1,
limit, slack, min_max); limit1, slack1, corner1, min_max);
} }
void void