report_check_types -max_fanout -net

This commit is contained in:
James Cherry 2021-03-07 20:43:51 -07:00
parent 6ebaf3ebdb
commit d2fe0e9497
9 changed files with 107 additions and 123 deletions

View File

@ -631,10 +631,12 @@ public:
float &slack); float &slack);
void checkFanoutLimitPreamble(); void checkFanoutLimitPreamble();
// Return the pin with the min/max fanout limit slack. // Return pins with the min/max fanout limit slack.
Pin *pinMinFanoutLimitSlack(const MinMax *min_max); // net=null check all nets
// Return all pins with min/max fanout violations. // corner=nullptr checks all corners.
PinSeq *pinFanoutLimitViolations(const MinMax *min_max); PinSeq *checkFanoutLimits(Net *net,
bool violators,
const MinMax *min_max);
void reportFanoutLimitShortHeader(); void reportFanoutLimitShortHeader();
void reportFanoutLimitShort(Pin *pin, void reportFanoutLimitShort(Pin *pin,
const MinMax *min_max); const MinMax *min_max);

View File

@ -221,6 +221,8 @@ CheckCapacitanceLimits::checkCapacitance(const Pin *pin,
} }
} }
////////////////////////////////////////////////////////////////
PinSeq * PinSeq *
CheckCapacitanceLimits::checkCapacitanceLimits(Net *net, CheckCapacitanceLimits::checkCapacitanceLimits(Net *net,
bool violators, bool violators,

View File

@ -202,86 +202,83 @@ CheckFanoutLimits::fanoutLoad(const Pin *pin) const
return fanout; return fanout;
} }
////////////////////////////////////////////////////////////////
PinSeq * PinSeq *
CheckFanoutLimits::pinFanoutLimitViolations(const MinMax *min_max) CheckFanoutLimits::checkFanoutLimits(Net *net,
bool violators,
const MinMax *min_max)
{ {
const Network *network = sta_->network(); const Network *network = sta_->network();
PinSeq *violators = new PinSeq; PinSeq *fanout_pins = new PinSeq;
LeafInstanceIterator *inst_iter = network->leafInstanceIterator(); Slack min_slack = MinMax::min()->initValue();
while (inst_iter->hasNext()) { if (net) {
Instance *inst = inst_iter->next(); NetPinIterator *pin_iter = network->pinIterator(net);
pinFanoutLimitViolations(inst, min_max, violators); while (pin_iter->hasNext()) {
Pin *pin = pin_iter->next();
checkFanoutLimits(pin, violators, min_max, fanout_pins, min_slack);
}
delete pin_iter;
} }
delete inst_iter; else {
LeafInstanceIterator *inst_iter = network->leafInstanceIterator();
// Check top level ports. while (inst_iter->hasNext()) {
pinFanoutLimitViolations(network->topInstance(), min_max, violators); Instance *inst = inst_iter->next();
sort(violators, PinFanoutLimitSlackLess(min_max, this, sta_)); checkFanoutLimits(inst, violators, min_max, fanout_pins, min_slack);
return violators; }
delete inst_iter;
// Check top level ports.
checkFanoutLimits(network->topInstance(), violators, min_max,
fanout_pins, min_slack);
}
sort(fanout_pins, PinFanoutLimitSlackLess(min_max, this, sta_));
// Keep the min slack pin unless all violators or net pins.
if (!fanout_pins->empty() && !violators && net == nullptr)
fanout_pins->resize(1);
return fanout_pins;
} }
void void
CheckFanoutLimits::pinFanoutLimitViolations(Instance *inst, CheckFanoutLimits::checkFanoutLimits(Instance *inst,
const MinMax *min_max, bool violators,
PinSeq *violators) const MinMax *min_max,
PinSeq *fanout_pins,
float &min_slack)
{ {
const Network *network = sta_->network(); const Network *network = sta_->network();
InstancePinIterator *pin_iter = network->pinIterator(inst); InstancePinIterator *pin_iter = network->pinIterator(inst);
while (pin_iter->hasNext()) { while (pin_iter->hasNext()) {
Pin *pin = pin_iter->next(); Pin *pin = pin_iter->next();
if (checkPin(pin)) { checkFanoutLimits(pin, violators, min_max, fanout_pins, min_slack);
float fanout;
float limit, slack;
checkFanout(pin, min_max, fanout, limit, slack );
if (slack < 0.0 && !fuzzyInf(slack))
violators->push_back(pin);
}
} }
delete pin_iter; delete pin_iter;
} }
Pin *
CheckFanoutLimits::pinMinFanoutLimitSlack(const MinMax *min_max)
{
const Network *network = sta_->network();
Pin *min_slack_pin = nullptr;
float min_slack = MinMax::min()->initValue();
LeafInstanceIterator *inst_iter = network->leafInstanceIterator();
while (inst_iter->hasNext()) {
Instance *inst = inst_iter->next();
pinMinFanoutLimitSlack(inst, min_max, min_slack_pin, min_slack);
}
delete inst_iter;
// Check top level ports.
pinMinFanoutLimitSlack(network->topInstance(), min_max,
min_slack_pin, min_slack);
return min_slack_pin;
}
void void
CheckFanoutLimits::pinMinFanoutLimitSlack(Instance *inst, CheckFanoutLimits::checkFanoutLimits(Pin *pin,
const MinMax *min_max, bool violators,
// Return values. const MinMax *min_max,
Pin *&min_slack_pin, PinSeq *fanout_pins,
float &min_slack) float &min_slack)
{ {
const Network *network = sta_->network(); if (checkPin(pin)) {
InstancePinIterator *pin_iter = network->pinIterator(inst); float fanout;
while (pin_iter->hasNext()) { float limit, slack;
Pin *pin = pin_iter->next(); checkFanout(pin, min_max, fanout, limit, slack);
if (checkPin(pin)) { if (!fuzzyInf(slack)) {
float fanout; if (violators) {
float limit, slack; if (slack < 0.0)
checkFanout(pin, min_max, fanout, limit, slack); fanout_pins->push_back(pin);
if (!fuzzyInf(slack) }
&& (min_slack_pin == nullptr else {
|| slack < min_slack)) { if (fanout_pins->empty()
min_slack_pin = pin; || slack < min_slack) {
min_slack = slack; fanout_pins->push_back(pin);
min_slack = slack;
}
} }
} }
} }
delete pin_iter;
} }
bool bool

View File

@ -35,8 +35,13 @@ public:
float &fanout, float &fanout,
float &limit, float &limit,
float &slack) const; float &slack) const;
PinSeq *pinFanoutLimitViolations(const MinMax *min_max); // Return pins with the min/max fanout limit slack.
Pin *pinMinFanoutLimitSlack(const MinMax *min_max); // net=null check all nets
// corner=nullptr checks all corners.
PinSeq *checkFanoutLimits(Net *net,
bool violators,
const MinMax *min_max);
protected: protected:
void checkFanout(const Pin *pin, void checkFanout(const Pin *pin,
@ -51,15 +56,17 @@ protected:
// Return values. // Return values.
float &limit, float &limit,
bool &limit_exists) const; bool &limit_exists) const;
void pinFanoutLimitViolations(Instance *inst,
const MinMax *min_max,
PinSeq *violators);
void pinMinFanoutLimitSlack(Instance *inst,
const MinMax *min_max,
// Return values.
Pin *&min_slack_pin,
float &min_slack);
float fanoutLoad(const Pin *pin) const; float fanoutLoad(const Pin *pin) const;
void checkFanoutLimits(Instance *inst,
bool violators,
const MinMax *min_max,
PinSeq *fanout_pins,
float &min_slack);
void checkFanoutLimits(Pin *pin,
bool violators,
const MinMax *min_max,
PinSeq *fanout_pins,
float &min_slack);
bool checkPin(Pin *pin); bool checkPin(Pin *pin);
const Sta *sta_; const Sta *sta_;

View File

@ -278,6 +278,8 @@ CheckSlewLimits::checkSlew(Vertex *vertex,
} }
} }
////////////////////////////////////////////////////////////////
PinSeq * PinSeq *
CheckSlewLimits::checkSlewLimits(Net *net, CheckSlewLimits::checkSlewLimits(Net *net,
bool violators, bool violators,

View File

@ -4956,18 +4956,13 @@ Sta::checkFanoutLimitPreamble()
ensureClkNetwork(); ensureClkNetwork();
} }
Pin *
Sta::pinMinFanoutLimitSlack(const MinMax *min_max)
{
checkFanoutLimitPreamble();
return check_fanout_limits_->pinMinFanoutLimitSlack(min_max);
}
PinSeq * PinSeq *
Sta::pinFanoutLimitViolations(const MinMax *min_max) Sta::checkFanoutLimits(Net *net,
bool violators,
const MinMax *min_max)
{ {
checkFanoutLimitPreamble(); checkFanoutLimitPreamble();
return check_fanout_limits_->pinFanoutLimitViolations(min_max); return check_fanout_limits_->checkFanoutLimits(net, violators, min_max);
} }
void void

View File

@ -402,38 +402,22 @@ proc report_slew_limits { net corner min_max violators verbose nosplit } {
} }
} }
proc report_fanout_limits { min_max all_violators verbose nosplit } { proc report_fanout_limits { net min_max violators verbose nosplit } {
if { $all_violators } { set pins [check_fanout_limits $net $violators $min_max]
set violators [pin_fanout_limit_violations $min_max] if { $pins != {} } {
if { $violators != {} } { report_line "${min_max} fanout"
report_line "${min_max} fanout" report_line ""
report_line "" if { $verbose } {
if { $verbose } { foreach pin $pins {
foreach pin $violators { report_fanout_limit_verbose $pin $min_max
report_fanout_limit_verbose $pin $min_max report_line ""
report_line ""
}
} else {
report_fanout_limit_short_header
foreach pin $violators {
report_fanout_limit_short $pin $min_max
}
report_line ""
} }
} } else {
} else { report_fanout_limit_short_header
set pin [pin_min_fanout_limit_slack $min_max] foreach pin $pins {
if { $pin != "NULL" } { report_fanout_limit_short $pin $min_max
report_line "${min_max} fanout"
report_line ""
if { $verbose } {
report_fanout_limit_verbose $pin $min_max
report_line ""
} else {
report_fanout_limit_short_header
report_fanout_limit_short $pin $min_max
report_line ""
} }
report_line ""
} }
} }
} }

View File

@ -481,10 +481,10 @@ proc_redirect report_check_types {
report_slew_limits $net $corner "min" $violators $verbose $nosplit report_slew_limits $net $corner "min" $violators $verbose $nosplit
} }
if { $max_fanout } { if { $max_fanout } {
report_fanout_limits "max" $violators $verbose $nosplit report_fanout_limits $net "max" $violators $verbose $nosplit
} }
if { $min_fanout } { if { $min_fanout } {
report_fanout_limits "min" $violators $verbose $nosplit report_fanout_limits $net "min" $violators $verbose $nosplit
} }
if { $max_capacitance } { if { $max_capacitance } {
report_capacitance_limits $net $corner "max" $violators $verbose $nosplit report_capacitance_limits $net $corner "max" $violators $verbose $nosplit

View File

@ -4739,18 +4739,13 @@ report_slew_limit_verbose(Pin *pin,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
Pin *
pin_min_fanout_limit_slack(const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->pinMinFanoutLimitSlack(min_max);
}
PinSeq * PinSeq *
pin_fanout_limit_violations(const MinMax *min_max) check_fanout_limits(Net *net,
bool violators,
const MinMax *min_max)
{ {
cmdLinkedNetwork(); cmdLinkedNetwork();
return Sta::sta()->pinFanoutLimitViolations(min_max); return Sta::sta()->checkFanoutLimits(net, violators, min_max);
} }
void void