CheckSlewLimits/CheckCapLimits::findLimits(corner)
This commit is contained in:
parent
b7ed8750b3
commit
094ab8bbc7
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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_; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue