report_check_types -max_slew -net

This commit is contained in:
James Cherry 2021-03-06 06:44:12 -07:00
parent 66c13decad
commit a0c9bd5fbc
6 changed files with 110 additions and 129 deletions

View File

@ -604,14 +604,13 @@ public:
ClockSet &clks); ClockSet &clks);
void checkSlewLimitPreamble(); void checkSlewLimitPreamble();
// Return the pin with the min/max slew 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 *pinMinSlewLimitSlack(const Corner *corner, PinSeq *checkSlewLimits(Net *net,
const MinMax *min_max); bool violators,
// Return all pins with min/max slew violations. const Corner *corner,
// corner=nullptr checks all corners. const MinMax *min_max);
PinSeq *pinSlewLimitViolations(const Corner *corner,
const MinMax *min_max);
void reportSlewLimitShortHeader(); void reportSlewLimitShortHeader();
void reportSlewLimitShort(Pin *pin, void reportSlewLimitShort(Pin *pin,
const Corner *corner, const Corner *corner,

View File

@ -279,88 +279,83 @@ CheckSlewLimits::checkSlew(Vertex *vertex,
} }
PinSeq * PinSeq *
CheckSlewLimits::pinSlewLimitViolations(const Corner *corner, CheckSlewLimits::checkSlewLimits(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 *slew_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);
pinSlewLimitViolations(inst, corner, min_max, violators); while (pin_iter->hasNext()) {
Pin *pin = pin_iter->next();
checkSlewLimits(pin, violators, corner, min_max, slew_pins, min_slack);
}
delete pin_iter;
} }
delete inst_iter; else {
// Check top level ports. LeafInstanceIterator *inst_iter = network->leafInstanceIterator();
pinSlewLimitViolations(network->topInstance(), corner, min_max, violators); while (inst_iter->hasNext()) {
sort(violators, PinSlewLimitSlackLess(corner, min_max, this, sta_)); Instance *inst = inst_iter->next();
return violators; checkSlewLimits(inst, violators,corner, min_max, slew_pins, min_slack);
}
delete inst_iter;
// Check top level ports.
checkSlewLimits(network->topInstance(), violators, corner, min_max,
slew_pins, min_slack);
}
sort(slew_pins, PinSlewLimitSlackLess(corner, min_max, this, sta_));
// Keep the min slack pin unless all violators or net pins.
if (!slew_pins->empty() && !violators && net == nullptr)
slew_pins->resize(1);
return slew_pins;
} }
void void
CheckSlewLimits::pinSlewLimitViolations(Instance *inst, CheckSlewLimits::checkSlewLimits(Instance *inst,
const Corner *corner, bool violators,
const MinMax *min_max, const Corner *corner,
PinSeq *violators) const MinMax *min_max,
PinSeq *slew_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();
const Corner *corner1; checkSlewLimits(pin, violators, corner, min_max, slew_pins, min_slack);
const RiseFall *rf;
Slew slew;
float limit, slack;
checkSlew(pin, corner, min_max, true, corner1, rf, slew, limit, slack);
if (rf && slack < 0.0 && !fuzzyInf(slack))
violators->push_back(pin);
} }
delete pin_iter; delete pin_iter;
} }
Pin *
CheckSlewLimits::pinMinSlewLimitSlack(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();
pinMinSlewLimitSlack(inst, corner, min_max, min_slack_pin, min_slack);
}
delete inst_iter;
// Check top level ports.
pinMinSlewLimitSlack(network->topInstance(), corner, min_max,
min_slack_pin, min_slack);
return min_slack_pin;
}
void void
CheckSlewLimits::pinMinSlewLimitSlack(Instance *inst, CheckSlewLimits::checkSlewLimits(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 *slew_pins,
float &min_slack) float &min_slack)
{ {
const Network *network = sta_->network(); const Corner *corner1;
InstancePinIterator *pin_iter = network->pinIterator(inst); const RiseFall *rf;
while (pin_iter->hasNext()) { Slew slew;
Pin *pin = pin_iter->next(); float limit, slack;
const Corner *corner1; checkSlew(pin, corner, min_max, true, corner1, rf, slew, limit, slack);
const RiseFall *rf; if (!fuzzyInf(slack)) {
Slew slew; if (violators) {
float limit, slack; if (slack < 0.0)
checkSlew(pin, corner, min_max, true, corner1, rf, slew, limit, slack); slew_pins->push_back(pin);
if (rf }
&& (min_slack_pin == nullptr else {
|| slack < min_slack)) { if (slew_pins->empty()
min_slack_pin = pin; || slack < min_slack) {
min_slack = slack; slew_pins->push_back(pin);
min_slack = slack;
}
} }
} }
delete pin_iter;
} }
} // namespace } // namespace

View File

@ -45,12 +45,13 @@ public:
Slew &slew, Slew &slew,
float &limit, float &limit,
float &slack) const; float &slack) const;
// Return pins with the min/max slew limit slack.
// net=null check all nets
// corner=nullptr checks all corners. // corner=nullptr checks all corners.
PinSeq *pinSlewLimitViolations(const Corner *corner, PinSeq *checkSlewLimits(Net *net,
const MinMax *min_max); bool violators,
// corner=nullptr checks all corners. const Corner *corner,
Pin *pinMinSlewLimitSlack(const Corner *corner, const MinMax *min_max);
const MinMax *min_max);
protected: protected:
void checkSlews1(const Pin *pin, void checkSlews1(const Pin *pin,
@ -92,16 +93,18 @@ protected:
// Return values. // Return values.
float &limit1, float &limit1,
bool &limit1_exists) const; bool &limit1_exists) const;
void pinSlewLimitViolations(Instance *inst, void checkSlewLimits(Instance *inst,
const Corner *corner, bool violators,
const MinMax *min_max, const Corner *corner,
PinSeq *violators); const MinMax *min_max,
void pinMinSlewLimitSlack(Instance *inst, PinSeq *slew_pins,
const Corner *corner, float &min_slack);
const MinMax *min_max, void checkSlewLimits(Pin *pin,
// Return values. bool violators,
Pin *&min_slack_pin, const Corner *corner,
float &min_slack); const MinMax *min_max,
PinSeq *slew_pins,
float &min_slack);
void clockDomains(const Vertex *vertex, void clockDomains(const Vertex *vertex,
// Return value. // Return value.
ClockSet &clks) const; ClockSet &clks) const;

View File

@ -4883,20 +4883,14 @@ Sta::checkSlewLimitPreamble()
ensureClkNetwork(); ensureClkNetwork();
} }
Pin *
Sta::pinMinSlewLimitSlack(const Corner *corner,
const MinMax *min_max)
{
checkSlewLimitPreamble();
return check_slew_limits_->pinMinSlewLimitSlack(corner, min_max);
}
PinSeq * PinSeq *
Sta::pinSlewLimitViolations(const Corner *corner, Sta::checkSlewLimits(Net *net,
const MinMax *min_max) bool violators,
const Corner *corner,
const MinMax *min_max)
{ {
checkSlewLimitPreamble(); checkSlewLimitPreamble();
return check_slew_limits_->pinSlewLimitViolations(corner, min_max); return check_slew_limits_->checkSlewLimits(net, violators, corner, min_max);
} }
void void

View File

@ -382,38 +382,22 @@ proc parse_path_group_arg { group_names } {
return $names return $names
} }
proc report_slew_limits { corner min_max all_violators verbose nosplit } { proc report_slew_limits { net corner min_max violators verbose nosplit } {
if { $all_violators } { set pins [check_slew_limits $net $violators $corner $min_max]
set violators [pin_slew_limit_violations $corner $min_max] if { $pins != {} } {
if { $violators != {} } { report_line "${min_max} slew"
report_line "${min_max} slew" report_line ""
report_line "" if { $verbose } {
if { $verbose } { foreach pin $pins {
foreach pin $violators { report_slew_limit_verbose $pin $corner $min_max
report_slew_limit_verbose $pin $corner $min_max report_line ""
report_line ""
}
} else {
report_slew_limit_short_header
foreach pin $violators {
report_slew_limit_short $pin $corner $min_max
}
report_line ""
} }
} } else {
} else { report_slew_limit_short_header
set pin [pin_min_slew_limit_slack $corner $min_max] foreach pin $pins {
if { $pin != "NULL" } { report_slew_limit_short $pin $corner $min_max
report_line "${min_max} slew"
report_line ""
if { $verbose } {
report_slew_limit_verbose $pin $corner $min_max
report_line ""
} else {
report_slew_limit_short_header
report_slew_limit_short $pin $corner $min_max
report_line ""
} }
report_line ""
} }
} }
} }

View File

@ -322,13 +322,14 @@ define_sta_cmd_args "report_check_types" \
[-max_fanout] [-min_fanout]\ [-max_fanout] [-min_fanout]\
[-max_capacitance] [-min_capacitance]\ [-max_capacitance] [-min_capacitance]\
[-min_pulse_width] [-min_period] [-max_skew]\ [-min_pulse_width] [-min_period] [-max_skew]\
[-net net]\
[-digits digits] [-no_line_splits]\ [-digits digits] [-no_line_splits]\
[> filename] [>> filename]} [> filename] [>> filename]}
proc_redirect report_check_types { proc_redirect report_check_types {
variable path_options variable path_options
parse_key_args "report_check_types" args keys {-corner}\ parse_key_args "report_check_types" args keys {-net -corner}\
flags {-violators -all_violators -verbose -no_line_splits} 0 flags {-violators -all_violators -verbose -no_line_splits} 0
set violators [info exists flags(-violators)] set violators [info exists flags(-violators)]
@ -354,6 +355,11 @@ proc_redirect report_check_types {
set corner [parse_corner_or_all keys] set corner [parse_corner_or_all keys]
set net "NULL"
if { [info exists keys(-net)] } {
set net [get_net_warn "-net" $keys(-net)]
}
if { $args == {} } { if { $args == {} } {
if { $min_max == "max" || $min_max == "min_max" } { if { $min_max == "max" || $min_max == "min_max" } {
set setup 1 set setup 1
@ -468,10 +474,10 @@ proc_redirect report_check_types {
} }
if { $max_slew } { if { $max_slew } {
report_slew_limits $corner "max" $violators $verbose $nosplit report_slew_limits $net $corner "max" $violators $verbose $nosplit
} }
if { $min_slew } { if { $min_slew } {
report_slew_limits $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 "max" $violators $verbose $nosplit