diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 19b160f1..dcfce10a 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -631,10 +631,12 @@ public: float &slack); void checkFanoutLimitPreamble(); - // Return the pin with the min/max fanout limit slack. - Pin *pinMinFanoutLimitSlack(const MinMax *min_max); - // Return all pins with min/max fanout violations. - PinSeq *pinFanoutLimitViolations(const MinMax *min_max); + // Return pins with the min/max fanout limit slack. + // net=null check all nets + // corner=nullptr checks all corners. + PinSeq *checkFanoutLimits(Net *net, + bool violators, + const MinMax *min_max); void reportFanoutLimitShortHeader(); void reportFanoutLimitShort(Pin *pin, const MinMax *min_max); diff --git a/search/CheckCapacitanceLimits.cc b/search/CheckCapacitanceLimits.cc index 6c0e0a57..1d883960 100644 --- a/search/CheckCapacitanceLimits.cc +++ b/search/CheckCapacitanceLimits.cc @@ -221,6 +221,8 @@ CheckCapacitanceLimits::checkCapacitance(const Pin *pin, } } +//////////////////////////////////////////////////////////////// + PinSeq * CheckCapacitanceLimits::checkCapacitanceLimits(Net *net, bool violators, diff --git a/search/CheckFanoutLimits.cc b/search/CheckFanoutLimits.cc index 9e169af5..9639f3b4 100644 --- a/search/CheckFanoutLimits.cc +++ b/search/CheckFanoutLimits.cc @@ -202,86 +202,83 @@ CheckFanoutLimits::fanoutLoad(const Pin *pin) const return fanout; } +//////////////////////////////////////////////////////////////// + PinSeq * -CheckFanoutLimits::pinFanoutLimitViolations(const MinMax *min_max) +CheckFanoutLimits::checkFanoutLimits(Net *net, + bool violators, + const MinMax *min_max) { const Network *network = sta_->network(); - PinSeq *violators = new PinSeq; - LeafInstanceIterator *inst_iter = network->leafInstanceIterator(); - while (inst_iter->hasNext()) { - Instance *inst = inst_iter->next(); - pinFanoutLimitViolations(inst, min_max, violators); + PinSeq *fanout_pins = new PinSeq; + Slack min_slack = MinMax::min()->initValue(); + if (net) { + NetPinIterator *pin_iter = network->pinIterator(net); + while (pin_iter->hasNext()) { + Pin *pin = pin_iter->next(); + checkFanoutLimits(pin, violators, min_max, fanout_pins, min_slack); + } + delete pin_iter; } - delete inst_iter; - - // Check top level ports. - pinFanoutLimitViolations(network->topInstance(), min_max, violators); - sort(violators, PinFanoutLimitSlackLess(min_max, this, sta_)); - return violators; + else { + LeafInstanceIterator *inst_iter = network->leafInstanceIterator(); + while (inst_iter->hasNext()) { + Instance *inst = inst_iter->next(); + checkFanoutLimits(inst, violators, min_max, fanout_pins, min_slack); + } + 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 -CheckFanoutLimits::pinFanoutLimitViolations(Instance *inst, - const MinMax *min_max, - PinSeq *violators) +CheckFanoutLimits::checkFanoutLimits(Instance *inst, + bool violators, + const MinMax *min_max, + PinSeq *fanout_pins, + float &min_slack) { const Network *network = sta_->network(); InstancePinIterator *pin_iter = network->pinIterator(inst); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); - if (checkPin(pin)) { - float fanout; - float limit, slack; - checkFanout(pin, min_max, fanout, limit, slack ); - if (slack < 0.0 && !fuzzyInf(slack)) - violators->push_back(pin); - } + checkFanoutLimits(pin, violators, min_max, fanout_pins, min_slack); } 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 -CheckFanoutLimits::pinMinFanoutLimitSlack(Instance *inst, - const MinMax *min_max, - // Return values. - Pin *&min_slack_pin, - float &min_slack) +CheckFanoutLimits::checkFanoutLimits(Pin *pin, + bool violators, + const MinMax *min_max, + PinSeq *fanout_pins, + float &min_slack) { - const Network *network = sta_->network(); - InstancePinIterator *pin_iter = network->pinIterator(inst); - while (pin_iter->hasNext()) { - Pin *pin = pin_iter->next(); - if (checkPin(pin)) { - float fanout; - float limit, slack; - checkFanout(pin, min_max, fanout, limit, slack); - if (!fuzzyInf(slack) - && (min_slack_pin == nullptr - || slack < min_slack)) { - min_slack_pin = pin; - min_slack = slack; + if (checkPin(pin)) { + float fanout; + float limit, slack; + checkFanout(pin, min_max, fanout, limit, slack); + if (!fuzzyInf(slack)) { + if (violators) { + if (slack < 0.0) + fanout_pins->push_back(pin); + } + else { + if (fanout_pins->empty() + || slack < min_slack) { + fanout_pins->push_back(pin); + min_slack = slack; + } } } } - delete pin_iter; } bool diff --git a/search/CheckFanoutLimits.hh b/search/CheckFanoutLimits.hh index 164455cc..8333970d 100644 --- a/search/CheckFanoutLimits.hh +++ b/search/CheckFanoutLimits.hh @@ -35,8 +35,13 @@ public: float &fanout, float &limit, float &slack) const; - PinSeq *pinFanoutLimitViolations(const MinMax *min_max); - Pin *pinMinFanoutLimitSlack(const MinMax *min_max); + // Return pins with the min/max fanout limit slack. + // net=null check all nets + // corner=nullptr checks all corners. + PinSeq *checkFanoutLimits(Net *net, + bool violators, + const MinMax *min_max); + protected: void checkFanout(const Pin *pin, @@ -51,15 +56,17 @@ protected: // Return values. float &limit, 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; + 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); const Sta *sta_; diff --git a/search/CheckSlewLimits.cc b/search/CheckSlewLimits.cc index f8fab364..d2df042d 100644 --- a/search/CheckSlewLimits.cc +++ b/search/CheckSlewLimits.cc @@ -278,6 +278,8 @@ CheckSlewLimits::checkSlew(Vertex *vertex, } } +//////////////////////////////////////////////////////////////// + PinSeq * CheckSlewLimits::checkSlewLimits(Net *net, bool violators, diff --git a/search/Sta.cc b/search/Sta.cc index 1019dc5c..18070cf9 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4956,18 +4956,13 @@ Sta::checkFanoutLimitPreamble() ensureClkNetwork(); } -Pin * -Sta::pinMinFanoutLimitSlack(const MinMax *min_max) -{ - checkFanoutLimitPreamble(); - return check_fanout_limits_->pinMinFanoutLimitSlack(min_max); -} - PinSeq * -Sta::pinFanoutLimitViolations(const MinMax *min_max) +Sta::checkFanoutLimits(Net *net, + bool violators, + const MinMax *min_max) { checkFanoutLimitPreamble(); - return check_fanout_limits_->pinFanoutLimitViolations(min_max); + return check_fanout_limits_->checkFanoutLimits(net, violators, min_max); } void diff --git a/tcl/Search.tcl b/tcl/Search.tcl index cddb5d35..a7dd5115 100644 --- a/tcl/Search.tcl +++ b/tcl/Search.tcl @@ -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 } { - if { $all_violators } { - set violators [pin_fanout_limit_violations $min_max] - if { $violators != {} } { - report_line "${min_max} fanout" - report_line "" - if { $verbose } { - foreach pin $violators { - report_fanout_limit_verbose $pin $min_max - report_line "" - } - } else { - report_fanout_limit_short_header - foreach pin $violators { - report_fanout_limit_short $pin $min_max - } - report_line "" +proc report_fanout_limits { net min_max violators verbose nosplit } { + set pins [check_fanout_limits $net $violators $min_max] + if { $pins != {} } { + report_line "${min_max} fanout" + report_line "" + if { $verbose } { + foreach pin $pins { + report_fanout_limit_verbose $pin $min_max + report_line "" } - } - } else { - set pin [pin_min_fanout_limit_slack $min_max] - if { $pin != "NULL" } { - 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 "" + } else { + report_fanout_limit_short_header + foreach pin $pins { + report_fanout_limit_short $pin $min_max } + report_line "" } } } diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl index 4d211ede..7b8487d7 100644 --- a/tcl/Sta.tcl +++ b/tcl/Sta.tcl @@ -481,10 +481,10 @@ proc_redirect report_check_types { report_slew_limits $net $corner "min" $violators $verbose $nosplit } if { $max_fanout } { - report_fanout_limits "max" $violators $verbose $nosplit + report_fanout_limits $net "max" $violators $verbose $nosplit } if { $min_fanout } { - report_fanout_limits "min" $violators $verbose $nosplit + report_fanout_limits $net "min" $violators $verbose $nosplit } if { $max_capacitance } { report_capacitance_limits $net $corner "max" $violators $verbose $nosplit diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 0c1dff31..d3293bc0 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -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 * -pin_fanout_limit_violations(const MinMax *min_max) +check_fanout_limits(Net *net, + bool violators, + const MinMax *min_max) { cmdLinkedNetwork(); - return Sta::sta()->pinFanoutLimitViolations(min_max); + return Sta::sta()->checkFanoutLimits(net, violators, min_max); } void