liberty default_fanout_load, fanout_load for report -max_fanout

This commit is contained in:
James Cherry 2020-06-08 20:11:15 -07:00
parent 6b4f2cc130
commit 32adfad72e
10 changed files with 151 additions and 60 deletions

View File

@ -202,7 +202,9 @@ public:
void defaultMaxFanout(float &fanout,
bool &exists) const;
void setDefaultMaxFanout(float fanout);
float defaultFanoutLoad() const { return default_fanout_load_; }
void defaultFanoutLoad(// Return values.
float &fanout,
bool &exists) const;
void setDefaultFanoutLoad(float load);
// Logic thresholds.
@ -307,6 +309,7 @@ protected:
RiseFallValues default_inout_pin_res_;
RiseFallValues default_output_pin_res_;
float default_fanout_load_;
bool default_fanout_load_exists_;
float default_max_cap_;
bool default_max_cap_exists_;
float default_max_fanout_;
@ -623,6 +626,10 @@ public:
LibertyLibrary *libertyLibrary() const { return liberty_cell_->libertyLibrary(); }
LibertyPort *findLibertyMember(int index) const;
LibertyPort *findLibertyBusBit(int index) const;
void fanoutLoad(// Return values.
float &fanout_load,
bool &exists) const;
void setFanoutLoad(float fanout_load);
float capacitance(const RiseFall *rf,
const MinMax *min_max) const;
void capacitance(const RiseFall *rf,
@ -748,6 +755,8 @@ protected:
RiseFallMinMax capacitance_;
MinMaxFloatValues slew_limit_; // inputs and outputs
MinMaxFloatValues cap_limit_; // outputs
float fanout_load_; // inputs
bool fanout_load_exists_;
MinMaxFloatValues fanout_limit_; // outputs
float min_period_;
float min_pulse_width_[RiseFall::index_count];

View File

@ -647,12 +647,12 @@ public:
const MinMax *min_max);
void reportFanoutLimitVerbose(Pin *pin,
const MinMax *min_max);
void checkFanouts(const Pin *pin,
const MinMax *min_max,
// Return values.
float &fanout,
float &limit,
float &slack);
void checkFanout(const Pin *pin,
const MinMax *min_max,
// Return values.
float &fanout,
float &limit,
float &slack);
void checkCapacitanceLimitPreamble();
// Return the pin with the min/max capacitance limit slack.

View File

@ -71,6 +71,7 @@ LibertyLibrary::LibertyLibrary(const char *name,
default_output_pin_cap_(0.0),
default_bidirect_pin_cap_(0.0),
default_fanout_load_(0.0),
default_fanout_load_exists_(false),
default_max_cap_(0.0),
default_max_cap_exists_(false),
default_max_fanout_(0.0),
@ -425,10 +426,20 @@ LibertyLibrary::setDefaultMaxCapacitance(float cap)
default_max_cap_exists_ = true;
}
void
LibertyLibrary::defaultFanoutLoad(// Return values.
float &fanout,
bool &exists) const
{
fanout = default_fanout_load_;
exists = default_fanout_load_exists_;
}
void
LibertyLibrary::setDefaultFanoutLoad(float load)
{
default_fanout_load_ = load;
default_fanout_load_exists_ = true;
}
void
@ -1811,8 +1822,8 @@ LibertyPort::LibertyPort(LibertyCell *cell,
function_(nullptr),
tristate_enable_(nullptr),
scaled_ports_(nullptr),
// capacitance_ intentionally not initialized so
// liberty reader can apply default capacitance.
fanout_load_(0.0),
fanout_load_exists_(false),
min_period_(0.0),
pulse_clk_trigger_(nullptr),
pulse_clk_sense_(nullptr),
@ -2040,6 +2051,22 @@ LibertyPort::setCapacitanceLimit(float cap,
cap_limit_.setValue(min_max, cap);
}
void
LibertyPort::fanoutLoad(// Return values.
float &fanout_load,
bool &exists) const
{
fanout_load = fanout_load_;
exists = fanout_load_exists_;
}
void
LibertyPort::setFanoutLoad(float fanout_load)
{
fanout_load_ = fanout_load;
fanout_load_exists_ = true;
}
void
LibertyPort::fanoutLimit(const MinMax *min_max,
// Return values.

View File

@ -307,6 +307,7 @@ LibertyReader::defineVisitors()
&LibertyReader::visitRiseCapRange);
defineAttrVisitor("fall_capacitance_range",
&LibertyReader::visitFallCapRange);
defineAttrVisitor("fanout_load", &LibertyReader::visitFanoutLoad);
defineAttrVisitor("max_fanout", &LibertyReader::visitMaxFanout);
defineAttrVisitor("min_fanout", &LibertyReader::visitMinFanout);
defineAttrVisitor("max_transition", &LibertyReader::visitMaxTransition);
@ -2967,6 +2968,21 @@ LibertyReader::defaultCap(LibertyPort *port)
return cap;
}
void
LibertyReader::visitFanoutLoad(LibertyAttr *attr)
{
if (ports_) {
float fanout;
bool exists;
getAttrFloat(attr, fanout, exists);
if (exists) {
visitPorts([&] (LibertyPort *port) {
port->setFanoutLoad(fanout);
});
}
}
}
void
LibertyReader::visitMaxFanout(LibertyAttr *attr)
{

View File

@ -206,6 +206,7 @@ public:
virtual void visitFallCap(LibertyAttr *attr);
virtual void visitRiseCapRange(LibertyAttr *attr);
virtual void visitFallCapRange(LibertyAttr *attr);
virtual void visitFanoutLoad(LibertyAttr *attr);
virtual void visitMaxFanout(LibertyAttr *attr);
virtual void visitMinFanout(LibertyAttr *attr);
virtual void visitFanout(LibertyAttr *attr,

View File

@ -145,6 +145,7 @@ CheckCapacitanceLimits::checkCapacitance1(const Pin *pin,
}
}
// return the tightest limit.
void
CheckCapacitanceLimits::findLimit(const Pin *pin,
const MinMax *min_max,
@ -152,28 +153,45 @@ CheckCapacitanceLimits::findLimit(const Pin *pin,
float &limit,
bool &exists) const
{
exists = false;
// Default to top ("design") limit.
limit = top_limit_;
exists = top_limit_exists_;
const Network *network = sta_->network();
Sdc *sdc = sta_->sdc();
float limit1;
bool exists1;
if (network->isTopLevelPort(pin)) {
Port *port = network->port(pin);
sdc->capacitanceLimit(port, min_max, limit, exists);
if (!exists) {
limit = top_limit_;
exists = top_limit_exists_;
sdc->capacitanceLimit(port, min_max, limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
}
else {
Cell *cell = network->cell(network->instance(pin));
sdc->capacitanceLimit(cell, min_max,
limit, exists);
if (!exists) {
LibertyPort *port = network->libertyPort(pin);
if (port) {
port->capacitanceLimit(min_max, limit, exists);
if (!exists
&& port->direction()->isAnyOutput())
port->libertyLibrary()->defaultMaxCapacitance(limit, exists);
limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
LibertyPort *port = network->libertyPort(pin);
if (port) {
port->capacitanceLimit(min_max, limit1, exists1);
if (!exists1
&& port->direction()->isAnyOutput())
port->libertyLibrary()->defaultMaxCapacitance(limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
}
}

View File

@ -105,6 +105,7 @@ CheckFanoutLimits::checkFanout(const Pin *pin,
fanout, slack, limit);
}
// return the tightest limit.
void
CheckFanoutLimits::findLimit(const Pin *pin,
const MinMax *min_max,
@ -112,29 +113,46 @@ CheckFanoutLimits::findLimit(const Pin *pin,
float &limit,
bool &exists) const
{
exists = false;
// Default to top ("design") limit.
limit = top_limit_;
exists = top_limit_exists_;
const Network *network = sta_->network();
Sdc *sdc = sta_->sdc();
float limit1;
bool exists1;
if (network->isTopLevelPort(pin)) {
Port *port = network->port(pin);
sdc->fanoutLimit(port, min_max, limit, exists);
if (!exists) {
limit = top_limit_;
exists = top_limit_exists_;
sdc->fanoutLimit(port, min_max, limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
}
else {
Cell *cell = network->cell(network->instance(pin));
sdc->fanoutLimit(cell, min_max,
limit, exists);
if (!exists) {
LibertyPort *port = network->libertyPort(pin);
if (port) {
port->fanoutLimit(min_max, limit, exists);
if (!exists
&& min_max == MinMax::max()
&& port->direction()->isAnyOutput())
port->libertyLibrary()->defaultMaxFanout(limit, exists);
limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
LibertyPort *port = network->libertyPort(pin);
if (port) {
port->fanoutLimit(min_max, limit1, exists1);
if (!exists1
&& min_max == MinMax::max()
&& port->direction()->isAnyOutput())
port->libertyLibrary()->defaultMaxFanout(limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
}
}
@ -149,7 +167,7 @@ CheckFanoutLimits::checkFanout(const Pin *pin,
float &slack,
float &limit) const
{
float fanout1 = this->fanout(pin);
float fanout1 = fanoutLoad(pin);
float slack1 = (min_max == MinMax::max())
? limit1 - fanout1
: fanout1 - limit1;
@ -161,7 +179,7 @@ CheckFanoutLimits::checkFanout(const Pin *pin,
}
float
CheckFanoutLimits::fanout(const Pin *pin) const
CheckFanoutLimits::fanoutLoad(const Pin *pin) const
{
float fanout = 0;
const Network *network = sta_->network();
@ -170,8 +188,18 @@ CheckFanoutLimits::fanout(const Pin *pin) const
NetPinIterator *pin_iter = network->pinIterator(net);
while (pin_iter->hasNext()) {
Pin *pin = pin_iter->next();
if (network->isLoad(pin))
fanout++;
if (network->isLoad(pin)) {
LibertyPort *port = network->libertyPort(pin);
float fanout_load;
bool exists;
port->fanoutLoad(fanout_load, exists);
if (!exists) {
LibertyLibrary *lib = port->libertyLibrary();
lib->defaultFanoutLoad(fanout_load, exists);
}
if (exists)
fanout += fanout_load;
}
}
delete pin_iter;
}

View File

@ -60,7 +60,7 @@ protected:
// Return values.
Pin *&min_slack_pin,
float &min_slack);
float fanout(const Pin *pin) const;
float fanoutLoad(const Pin *pin) const;
float top_limit_;
bool top_limit_exists_;

View File

@ -170,6 +170,7 @@ CheckSlewLimits::checkSlews1(Vertex *vertex,
}
}
// return the tightest limit.
void
CheckSlewLimits::findLimit(const Pin *pin,
const Vertex *vertex,
@ -202,7 +203,6 @@ CheckSlewLimits::findLimit(const Pin *pin,
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
// Use the tightest clock limit.
limit = limit1;
exists = true;
}
@ -210,7 +210,6 @@ CheckSlewLimits::findLimit(const Pin *pin,
if (network->isTopLevelPort(pin)) {
Port *port = network->port(pin);
sdc->slewLimit(port, min_max, limit1, exists1);
// Use the tightest limit.
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
@ -222,23 +221,16 @@ CheckSlewLimits::findLimit(const Pin *pin,
LibertyPort *port = network->libertyPort(pin);
if (port) {
port->slewLimit(min_max, limit1, exists1);
// Use the tightest limit.
if (!exists1
&& port->direction()->isAnyOutput()
&& min_max == MinMax::max())
port->libertyLibrary()->defaultMaxSlew(limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
if (port->direction()->isAnyOutput()
&& min_max == MinMax::max()) {
port->libertyLibrary()->defaultMaxSlew(limit1, exists1);
if (exists1
&& (!exists
|| min_max->compare(limit, limit1))) {
limit = limit1;
exists = true;
}
}
}
}
}

View File

@ -4954,12 +4954,12 @@ Sta::reportFanoutLimitVerbose(Pin *pin,
}
void
Sta::checkFanouts(const Pin *pin,
const MinMax *min_max,
// Return values.
float &fanout,
float &limit,
float &slack)
Sta::checkFanout(const Pin *pin,
const MinMax *min_max,
// Return values.
float &fanout,
float &limit,
float &slack)
{
checkFanoutLimitPreamble();
check_fanout_limits_->init(min_max);