report_check_types -max_cap -net

This commit is contained in:
James Cherry 2021-03-07 10:21:53 -07:00
parent 9940576780
commit 6ebaf3ebdb
7 changed files with 111 additions and 142 deletions

View File

@ -649,14 +649,13 @@ public:
float &slack); float &slack);
void checkCapacitanceLimitPreamble(); void checkCapacitanceLimitPreamble();
// Return the pin with the min/max capacitance limit slack. // Return pins with the min/max slew limit slack.
// net=null check all nets
// corner=nullptr checks all corners. // corner=nullptr checks all corners.
Pin *pinMinCapacitanceLimitSlack(const Corner *corner, PinSeq *checkCapacitanceLimits(Net *net,
const MinMax *min_max); bool violators,
// Return all pins with min/max capacitance violations. const Corner *corner,
// corner=nullptr checks all corners. const MinMax *min_max);
PinSeq *pinCapacitanceLimitViolations(const Corner *corner,
const MinMax *min_max);
void reportCapacitanceLimitShortHeader(); void reportCapacitanceLimitShortHeader();
void reportCapacitanceLimitShort(Pin *pin, void reportCapacitanceLimitShort(Pin *pin,
const Corner *corner, const Corner *corner,

View File

@ -222,91 +222,84 @@ CheckCapacitanceLimits::checkCapacitance(const Pin *pin,
} }
PinSeq * PinSeq *
CheckCapacitanceLimits::pinCapacitanceLimitViolations(const Corner *corner, CheckCapacitanceLimits::checkCapacitanceLimits(Net *net,
const MinMax *min_max) bool violators,
const Corner *corner,
const MinMax *min_max)
{ {
const Network *network = sta_->network(); const Network *network = sta_->network();
PinSeq *violators = new PinSeq; PinSeq *cap_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);
pinCapacitanceLimitViolations(inst, corner, min_max, violators); while (pin_iter->hasNext()) {
Pin *pin = pin_iter->next();
checkCapLimits(pin, violators, corner, min_max, cap_pins, min_slack);
}
delete pin_iter;
} }
delete inst_iter; else {
// Check top level ports. LeafInstanceIterator *inst_iter = network->leafInstanceIterator();
pinCapacitanceLimitViolations(network->topInstance(), corner, min_max, violators); while (inst_iter->hasNext()) {
sort(violators, PinCapacitanceLimitSlackLess(corner, min_max, this, sta_)); Instance *inst = inst_iter->next();
return violators; checkCapLimits(inst, violators, corner, min_max, cap_pins, min_slack);
}
delete inst_iter;
// Check top level ports.
checkCapLimits(network->topInstance(), violators, corner, min_max,
cap_pins, min_slack);
}
sort(cap_pins, PinCapacitanceLimitSlackLess(corner, min_max, this, sta_));
// Keep the min slack pin unless all violators or net pins.
if (!cap_pins->empty() && !violators && net == nullptr)
cap_pins->resize(1);
return cap_pins;
} }
void void
CheckCapacitanceLimits::pinCapacitanceLimitViolations(Instance *inst, CheckCapacitanceLimits::checkCapLimits(Instance *inst,
const Corner *corner, bool violators,
const MinMax *min_max, const Corner *corner,
PinSeq *violators) const MinMax *min_max,
PinSeq *cap_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)) { checkCapLimits(pin, violators, corner, min_max, cap_pins, min_slack);
const Corner *corner1;
const RiseFall *rf;
float capacitance, limit, slack;
checkCapacitance(pin, corner, min_max, corner1, rf, capacitance, limit, slack );
if (rf && slack < 0.0 && !fuzzyInf(slack))
violators->push_back(pin);
}
} }
delete pin_iter; delete pin_iter;
} }
Pin *
CheckCapacitanceLimits::pinMinCapacitanceLimitSlack(const Corner *corner,
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();
pinMinCapacitanceLimitSlack(inst, corner, min_max, min_slack_pin, min_slack);
}
delete inst_iter;
// Check top level ports.
pinMinCapacitanceLimitSlack(network->topInstance(), corner, min_max,
min_slack_pin, min_slack);
return min_slack_pin;
}
void void
CheckCapacitanceLimits::pinMinCapacitanceLimitSlack(Instance *inst, CheckCapacitanceLimits::checkCapLimits(Pin *pin,
const Corner *corner, bool violators,
const MinMax *min_max, const Corner *corner,
// Return values. const MinMax *min_max,
Pin *&min_slack_pin, PinSeq *cap_pins,
float &min_slack) float &min_slack)
{ {
const Network *network = sta_->network(); if (checkPin(pin)) {
InstancePinIterator *pin_iter = network->pinIterator(inst); const Corner *corner1;
while (pin_iter->hasNext()) { const RiseFall *rf;
Pin *pin = pin_iter->next(); float capacitance, limit, slack;
if (checkPin(pin)) { checkCapacitance(pin, corner, min_max, corner1, rf, capacitance, limit, slack);
const Corner *corner1; if (!fuzzyInf(slack)) {
const RiseFall *rf; if (violators) {
float capacitance, limit, slack; if (slack < 0.0)
checkCapacitance(pin, corner, min_max, corner1, rf, capacitance, limit, slack); cap_pins->push_back(pin);
if (rf }
&& !fuzzyInf(slack) else {
&& (min_slack_pin == nullptr if (cap_pins->empty()
|| slack < min_slack)) { || slack < min_slack) {
min_slack_pin = pin; cap_pins->push_back(pin);
min_slack = slack; min_slack = slack;
}
} }
} }
} }
delete pin_iter;
} }
bool bool

View File

@ -42,12 +42,13 @@ public:
float &capacitance, float &capacitance,
float &limit, float &limit,
float &slack) const; float &slack) const;
// Return pins with the min/max cap limit slack.
// net=null check all nets
// corner=nullptr checks all corners. // corner=nullptr checks all corners.
PinSeq *pinCapacitanceLimitViolations(const Corner *corner, PinSeq *checkCapacitanceLimits(Net *net,
const MinMax *min_max); bool violators,
// corner=nullptr checks all corners. const Corner *corner,
Pin *pinMinCapacitanceLimitSlack(const Corner *corner, const MinMax *min_max);
const MinMax *min_max);
protected: protected:
void checkCapacitance(const Pin *pin, void checkCapacitance(const Pin *pin,
@ -75,16 +76,18 @@ protected:
// Return values. // Return values.
float &limit, float &limit,
bool &limit_exists) const; bool &limit_exists) const;
void pinCapacitanceLimitViolations(Instance *inst, void checkCapLimits(Instance *inst,
const Corner *corner, bool violators,
const MinMax *min_max, const Corner *corner,
PinSeq *violators); const MinMax *min_max,
void pinMinCapacitanceLimitSlack(Instance *inst, PinSeq *cap_pins,
const Corner *corner, float &min_slack);
const MinMax *min_max, void checkCapLimits(Pin *pin,
// Return values. bool violators,
Pin *&min_slack_pin, const Corner *corner,
float &min_slack); const MinMax *min_max,
PinSeq *cap_pins,
float &min_slack);
bool checkPin(Pin *pin); bool checkPin(Pin *pin);
const Sta *sta_; const Sta *sta_;

View File

@ -5021,20 +5021,15 @@ Sta::checkCapacitanceLimitPreamble()
ensureClkNetwork(); ensureClkNetwork();
} }
Pin *
Sta::pinMinCapacitanceLimitSlack(const Corner *corner,
const MinMax *min_max)
{
checkCapacitanceLimitPreamble();
return check_capacitance_limits_->pinMinCapacitanceLimitSlack(corner, min_max);
}
PinSeq * PinSeq *
Sta::pinCapacitanceLimitViolations(const Corner *corner, Sta::checkCapacitanceLimits(Net *net,
const MinMax *min_max) bool violators,
const Corner *corner,
const MinMax *min_max)
{ {
checkCapacitanceLimitPreamble(); checkCapacitanceLimitPreamble();
return check_capacitance_limits_->pinCapacitanceLimitViolations(corner, min_max); return check_capacitance_limits_->checkCapacitanceLimits(net, violators,
corner, min_max);
} }
void void

View File

@ -438,38 +438,22 @@ proc report_fanout_limits { min_max all_violators verbose nosplit } {
} }
} }
proc report_capacitance_limits { corner min_max all_violators verbose nosplit } { proc report_capacitance_limits { net corner min_max violators verbose nosplit } {
if { $all_violators } { set pins [check_capacitance_limits $net $violators $corner $min_max]
set violators [pin_capacitance_limit_violations $corner $min_max] if { $pins != {} } {
if { $violators != {} } { report_line "${min_max} capacitance"
report_line "${min_max} capacitance" report_line ""
report_line "" if { $verbose } {
if { $verbose } { foreach pin $pins {
foreach pin $violators {
report_capacitance_limit_verbose $pin $corner $min_max
report_line ""
}
} else {
report_capacitance_limit_short_header
foreach pin $violators {
report_capacitance_limit_short $pin $corner $min_max
}
report_line ""
}
}
} else {
set pin [pin_min_capacitance_limit_slack $corner $min_max]
if { $pin != "NULL" } {
report_line "${min_max} capacitance"
report_line ""
if { $verbose } {
report_capacitance_limit_verbose $pin $corner $min_max report_capacitance_limit_verbose $pin $corner $min_max
report_line "" report_line ""
} else {
report_capacitance_limit_short_header
report_capacitance_limit_short $pin $corner $min_max
report_line ""
} }
} else {
report_capacitance_limit_short_header
foreach pin $pins {
report_capacitance_limit_short $pin $corner $min_max
}
report_line ""
} }
} }
} }

View File

@ -228,8 +228,9 @@ proc find_timing_paths_cmd { cmd args_var } {
set group_count $endpoint_count set group_count $endpoint_count
if [info exists keys(-group_count)] { if [info exists keys(-group_count)] {
set group_count $keys(-group_count) set group_count $keys(-group_count)
check_positive_integer "-group_count" $group_count
if { $group_count < 1 } { if { $group_count < 1 } {
sta_error 423 "-group_count must be a positive integer." sta_error 423 "-group_count must be >= 1."
} }
} }
@ -486,10 +487,10 @@ proc_redirect report_check_types {
report_fanout_limits "min" $violators $verbose $nosplit report_fanout_limits "min" $violators $verbose $nosplit
} }
if { $max_capacitance } { if { $max_capacitance } {
report_capacitance_limits $corner "max" $violators $verbose $nosplit report_capacitance_limits $net $corner "max" $violators $verbose $nosplit
} }
if { $min_capacitance } { if { $min_capacitance } {
report_capacitance_limits $corner "min" $violators $verbose $nosplit report_capacitance_limits $net $corner "min" $violators $verbose $nosplit
} }
if { $min_pulse_width } { if { $min_pulse_width } {
if { $violators } { if { $violators } {

View File

@ -4775,20 +4775,14 @@ report_fanout_limit_verbose(Pin *pin,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
Pin *
pin_min_capacitance_limit_slack(const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->pinMinCapacitanceLimitSlack(corner, min_max);
}
PinSeq * PinSeq *
pin_capacitance_limit_violations(const Corner *corner, check_capacitance_limits(Net *net,
const MinMax *min_max) bool violators,
const Corner *corner,
const MinMax *min_max)
{ {
cmdLinkedNetwork(); cmdLinkedNetwork();
return Sta::sta()->pinCapacitanceLimitViolations(corner, min_max); return Sta::sta()->checkCapacitanceLimits(net, violators, corner, min_max);
} }
void void