report_check_types -max_slew -net
This commit is contained in:
parent
66c13decad
commit
a0c9bd5fbc
|
|
@ -604,14 +604,13 @@ public:
|
|||
ClockSet &clks);
|
||||
|
||||
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.
|
||||
Pin *pinMinSlewLimitSlack(const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
// Return all pins with min/max slew violations.
|
||||
// corner=nullptr checks all corners.
|
||||
PinSeq *pinSlewLimitViolations(const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
PinSeq *checkSlewLimits(Net *net,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
void reportSlewLimitShortHeader();
|
||||
void reportSlewLimitShort(Pin *pin,
|
||||
const Corner *corner,
|
||||
|
|
|
|||
|
|
@ -279,88 +279,83 @@ CheckSlewLimits::checkSlew(Vertex *vertex,
|
|||
}
|
||||
|
||||
PinSeq *
|
||||
CheckSlewLimits::pinSlewLimitViolations(const Corner *corner,
|
||||
const MinMax *min_max)
|
||||
CheckSlewLimits::checkSlewLimits(Net *net,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
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();
|
||||
pinSlewLimitViolations(inst, corner, min_max, violators);
|
||||
PinSeq *slew_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();
|
||||
checkSlewLimits(pin, violators, corner, min_max, slew_pins, min_slack);
|
||||
}
|
||||
delete pin_iter;
|
||||
}
|
||||
delete inst_iter;
|
||||
// Check top level ports.
|
||||
pinSlewLimitViolations(network->topInstance(), corner, min_max, violators);
|
||||
sort(violators, PinSlewLimitSlackLess(corner, min_max, this, sta_));
|
||||
return violators;
|
||||
else {
|
||||
LeafInstanceIterator *inst_iter = network->leafInstanceIterator();
|
||||
while (inst_iter->hasNext()) {
|
||||
Instance *inst = inst_iter->next();
|
||||
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
|
||||
CheckSlewLimits::pinSlewLimitViolations(Instance *inst,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq *violators)
|
||||
CheckSlewLimits::checkSlewLimits(Instance *inst,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq *slew_pins,
|
||||
float &min_slack)
|
||||
{
|
||||
const Network *network = sta_->network();
|
||||
InstancePinIterator *pin_iter = network->pinIterator(inst);
|
||||
while (pin_iter->hasNext()) {
|
||||
Pin *pin = pin_iter->next();
|
||||
const Corner *corner1;
|
||||
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);
|
||||
checkSlewLimits(pin, violators, corner, min_max, slew_pins, min_slack);
|
||||
}
|
||||
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
|
||||
CheckSlewLimits::pinMinSlewLimitSlack(Instance *inst,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
// Return values.
|
||||
Pin *&min_slack_pin,
|
||||
float &min_slack)
|
||||
CheckSlewLimits::checkSlewLimits(Pin *pin,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq *slew_pins,
|
||||
float &min_slack)
|
||||
{
|
||||
const Network *network = sta_->network();
|
||||
InstancePinIterator *pin_iter = network->pinIterator(inst);
|
||||
while (pin_iter->hasNext()) {
|
||||
Pin *pin = pin_iter->next();
|
||||
const Corner *corner1;
|
||||
const RiseFall *rf;
|
||||
Slew slew;
|
||||
float limit, slack;
|
||||
checkSlew(pin, corner, min_max, true, corner1, rf, slew, limit, slack);
|
||||
if (rf
|
||||
&& (min_slack_pin == nullptr
|
||||
|| slack < min_slack)) {
|
||||
min_slack_pin = pin;
|
||||
min_slack = slack;
|
||||
const Corner *corner1;
|
||||
const RiseFall *rf;
|
||||
Slew slew;
|
||||
float limit, slack;
|
||||
checkSlew(pin, corner, min_max, true, corner1, rf, slew, limit, slack);
|
||||
if (!fuzzyInf(slack)) {
|
||||
if (violators) {
|
||||
if (slack < 0.0)
|
||||
slew_pins->push_back(pin);
|
||||
}
|
||||
else {
|
||||
if (slew_pins->empty()
|
||||
|| slack < min_slack) {
|
||||
slew_pins->push_back(pin);
|
||||
min_slack = slack;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete pin_iter;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -45,12 +45,13 @@ public:
|
|||
Slew &slew,
|
||||
float &limit,
|
||||
float &slack) const;
|
||||
// Return pins with the min/max slew limit slack.
|
||||
// net=null check all nets
|
||||
// corner=nullptr checks all corners.
|
||||
PinSeq *pinSlewLimitViolations(const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
// corner=nullptr checks all corners.
|
||||
Pin *pinMinSlewLimitSlack(const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
PinSeq *checkSlewLimits(Net *net,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
|
||||
protected:
|
||||
void checkSlews1(const Pin *pin,
|
||||
|
|
@ -92,16 +93,18 @@ protected:
|
|||
// Return values.
|
||||
float &limit1,
|
||||
bool &limit1_exists) const;
|
||||
void pinSlewLimitViolations(Instance *inst,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq *violators);
|
||||
void pinMinSlewLimitSlack(Instance *inst,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
// Return values.
|
||||
Pin *&min_slack_pin,
|
||||
float &min_slack);
|
||||
void checkSlewLimits(Instance *inst,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq *slew_pins,
|
||||
float &min_slack);
|
||||
void checkSlewLimits(Pin *pin,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq *slew_pins,
|
||||
float &min_slack);
|
||||
void clockDomains(const Vertex *vertex,
|
||||
// Return value.
|
||||
ClockSet &clks) const;
|
||||
|
|
|
|||
|
|
@ -4883,20 +4883,14 @@ Sta::checkSlewLimitPreamble()
|
|||
ensureClkNetwork();
|
||||
}
|
||||
|
||||
Pin *
|
||||
Sta::pinMinSlewLimitSlack(const Corner *corner,
|
||||
const MinMax *min_max)
|
||||
{
|
||||
checkSlewLimitPreamble();
|
||||
return check_slew_limits_->pinMinSlewLimitSlack(corner, min_max);
|
||||
}
|
||||
|
||||
PinSeq *
|
||||
Sta::pinSlewLimitViolations(const Corner *corner,
|
||||
const MinMax *min_max)
|
||||
Sta::checkSlewLimits(Net *net,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max)
|
||||
{
|
||||
checkSlewLimitPreamble();
|
||||
return check_slew_limits_->pinSlewLimitViolations(corner, min_max);
|
||||
return check_slew_limits_->checkSlewLimits(net, violators, corner, min_max);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -382,38 +382,22 @@ proc parse_path_group_arg { group_names } {
|
|||
return $names
|
||||
}
|
||||
|
||||
proc report_slew_limits { corner min_max all_violators verbose nosplit } {
|
||||
if { $all_violators } {
|
||||
set violators [pin_slew_limit_violations $corner $min_max]
|
||||
if { $violators != {} } {
|
||||
report_line "${min_max} slew"
|
||||
report_line ""
|
||||
if { $verbose } {
|
||||
foreach pin $violators {
|
||||
report_slew_limit_verbose $pin $corner $min_max
|
||||
report_line ""
|
||||
}
|
||||
} else {
|
||||
report_slew_limit_short_header
|
||||
foreach pin $violators {
|
||||
report_slew_limit_short $pin $corner $min_max
|
||||
}
|
||||
report_line ""
|
||||
proc report_slew_limits { net corner min_max violators verbose nosplit } {
|
||||
set pins [check_slew_limits $net $violators $corner $min_max]
|
||||
if { $pins != {} } {
|
||||
report_line "${min_max} slew"
|
||||
report_line ""
|
||||
if { $verbose } {
|
||||
foreach pin $pins {
|
||||
report_slew_limit_verbose $pin $corner $min_max
|
||||
report_line ""
|
||||
}
|
||||
}
|
||||
} else {
|
||||
set pin [pin_min_slew_limit_slack $corner $min_max]
|
||||
if { $pin != "NULL" } {
|
||||
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 ""
|
||||
} else {
|
||||
report_slew_limit_short_header
|
||||
foreach pin $pins {
|
||||
report_slew_limit_short $pin $corner $min_max
|
||||
}
|
||||
report_line ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
tcl/Sta.tcl
12
tcl/Sta.tcl
|
|
@ -322,13 +322,14 @@ define_sta_cmd_args "report_check_types" \
|
|||
[-max_fanout] [-min_fanout]\
|
||||
[-max_capacitance] [-min_capacitance]\
|
||||
[-min_pulse_width] [-min_period] [-max_skew]\
|
||||
[-net net]\
|
||||
[-digits digits] [-no_line_splits]\
|
||||
[> filename] [>> filename]}
|
||||
|
||||
proc_redirect report_check_types {
|
||||
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
|
||||
|
||||
set violators [info exists flags(-violators)]
|
||||
|
|
@ -354,6 +355,11 @@ proc_redirect report_check_types {
|
|||
|
||||
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 { $min_max == "max" || $min_max == "min_max" } {
|
||||
set setup 1
|
||||
|
|
@ -468,10 +474,10 @@ proc_redirect report_check_types {
|
|||
}
|
||||
|
||||
if { $max_slew } {
|
||||
report_slew_limits $corner "max" $violators $verbose $nosplit
|
||||
report_slew_limits $net $corner "max" $violators $verbose $nosplit
|
||||
}
|
||||
if { $min_slew } {
|
||||
report_slew_limits $corner "min" $violators $verbose $nosplit
|
||||
report_slew_limits $net $corner "min" $violators $verbose $nosplit
|
||||
}
|
||||
if { $max_fanout } {
|
||||
report_fanout_limits "max" $violators $verbose $nosplit
|
||||
|
|
|
|||
Loading…
Reference in New Issue