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
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;
}
}

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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();

View File

@ -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_; }

View File

@ -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