do not check slew limits on ideal clk nets

This commit is contained in:
James Cherry 2020-03-01 13:10:00 -08:00
parent 9cacb0cfd9
commit 1dbae09fb7
3 changed files with 58 additions and 55 deletions

View File

@ -101,6 +101,7 @@ public:
virtual float ceff(Edge *edge, virtual float ceff(Edge *edge,
TimingArc *arc, TimingArc *arc,
const DcalcAnalysisPt *dcalc_ap); const DcalcAnalysisPt *dcalc_ap);
virtual bool isIdealClk(const Vertex *vertex) = 0;
// Precedence: // Precedence:
// SDF annotation // SDF annotation
// Liberty library // Liberty library

View File

@ -197,7 +197,7 @@ protected:
bool setIdealClks(const Vertex *vertex, bool setIdealClks(const Vertex *vertex,
ClockSet *clks); ClockSet *clks);
ClockSet *idealClks(const Vertex *vertex); ClockSet *idealClks(const Vertex *vertex);
bool isIdealClk(const Vertex *vertex); virtual bool isIdealClk(const Vertex *vertex);
Slew idealClkSlew(const Vertex *vertex, Slew idealClkSlew(const Vertex *vertex,
const RiseFall *rf, const RiseFall *rf,
const MinMax *min_max); const MinMax *min_max);

View File

@ -23,6 +23,7 @@
#include "StaState.hh" #include "StaState.hh"
#include "DcalcAnalysisPt.hh" #include "DcalcAnalysisPt.hh"
#include "Corner.hh" #include "Corner.hh"
#include "GraphDelayCalc.hh"
#include "PathVertex.hh" #include "PathVertex.hh"
#include "Search.hh" #include "Search.hh"
#include "CheckSlewLimits.hh" #include "CheckSlewLimits.hh"
@ -173,66 +174,40 @@ CheckSlewLimits::findLimit(const Pin *pin,
// Return values. // Return values.
float &limit, float &limit,
bool &exists) const bool &exists) const
{ {
exists = false; exists = false;
const Network *network = sta_->network(); if (!sta_->graphDelayCalc()->isIdealClk(vertex)) {
Sdc *sdc = sta_->sdc(); const Network *network = sta_->network();
bool is_clk = sta_->search()->isClock(vertex); Sdc *sdc = sta_->sdc();
// Look for clock slew limits. bool is_clk = sta_->search()->isClock(vertex);
ClockSet clks; // Look for clock slew limits.
clockDomains(vertex, clks); ClockSet clks;
ClockSet::Iterator clk_iter(clks); clockDomains(vertex, clks);
while (clk_iter.hasNext()) { ClockSet::Iterator clk_iter(clks);
Clock *clk = clk_iter.next(); while (clk_iter.hasNext()) {
PathClkOrData clk_data = is_clk ? PathClkOrData::clk : PathClkOrData::data; Clock *clk = clk_iter.next();
float clk_limit; PathClkOrData clk_data = is_clk ? PathClkOrData::clk : PathClkOrData::data;
bool clk_limit_exists; float clk_limit;
sdc->slewLimit(clk, rf, clk_data, min_max, bool clk_limit_exists;
clk_limit, clk_limit_exists); sdc->slewLimit(clk, rf, clk_data, min_max,
if (clk_limit_exists clk_limit, clk_limit_exists);
&& (!exists if (clk_limit_exists
|| min_max->compare(limit, clk_limit))) {
// Use the tightest clock limit.
limit = clk_limit;
exists = true;
}
}
if (!exists) {
// Default to top ("design") limit.
exists = top_limit_exists_;
limit = top_limit_;
if (network->isTopLevelPort(pin)) {
Port *port = network->port(pin);
float port_limit;
bool port_limit_exists;
sdc->slewLimit(port, min_max, port_limit, port_limit_exists);
// Use the tightest limit.
if (port_limit_exists
&& (!exists && (!exists
|| min_max->compare(limit, port_limit))) { || min_max->compare(limit, clk_limit))) {
limit = port_limit; // Use the tightest clock limit.
limit = clk_limit;
exists = true; exists = true;
} }
} }
else { if (!exists) {
float pin_limit; // Default to top ("design") limit.
bool pin_limit_exists; exists = top_limit_exists_;
sdc->slewLimit(pin, min_max, limit = top_limit_;
pin_limit, pin_limit_exists); if (network->isTopLevelPort(pin)) {
// Use the tightest limit. Port *port = network->port(pin);
if (pin_limit_exists float port_limit;
&& (!exists bool port_limit_exists;
|| min_max->compare(limit, pin_limit))) { sdc->slewLimit(port, min_max, port_limit, port_limit_exists);
limit = pin_limit;
exists = true;
}
float port_limit;
bool port_limit_exists;
LibertyPort *port = network->libertyPort(pin);
if (port) {
port->slewLimit(min_max, port_limit, port_limit_exists);
// Use the tightest limit. // Use the tightest limit.
if (port_limit_exists if (port_limit_exists
&& (!exists && (!exists
@ -241,6 +216,33 @@ CheckSlewLimits::findLimit(const Pin *pin,
exists = true; exists = true;
} }
} }
else {
float pin_limit;
bool pin_limit_exists;
sdc->slewLimit(pin, min_max,
pin_limit, pin_limit_exists);
// Use the tightest limit.
if (pin_limit_exists
&& (!exists
|| min_max->compare(limit, pin_limit))) {
limit = pin_limit;
exists = true;
}
float port_limit;
bool port_limit_exists;
LibertyPort *port = network->libertyPort(pin);
if (port) {
port->slewLimit(min_max, port_limit, port_limit_exists);
// Use the tightest limit.
if (port_limit_exists
&& (!exists
|| min_max->compare(limit, port_limit))) {
limit = port_limit;
exists = true;
}
}
}
} }
} }
} }