refactor find clocks
This commit is contained in:
parent
07e1262186
commit
41f8a97271
|
|
@ -180,6 +180,7 @@ set(STA_SOURCE
|
|||
search/ReportPath.cc
|
||||
search/Search.cc
|
||||
search/SearchPred.cc
|
||||
search/FindClkPins.cc
|
||||
search/Sim.cc
|
||||
search/Sta.cc
|
||||
search/StaState.cc
|
||||
|
|
|
|||
|
|
@ -1189,6 +1189,13 @@ public:
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void ensureClkPins();
|
||||
bool isIdealClock(Pin *pin) const;
|
||||
bool isClock(Pin *pin) const;
|
||||
void clkPinsInvalid();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void setTclInterp(Tcl_Interp *interp);
|
||||
Tcl_Interp *tclInterp();
|
||||
void ensureLevelized();
|
||||
|
|
@ -1367,6 +1374,11 @@ protected:
|
|||
void replaceCell(Instance *inst,
|
||||
Cell *to_cell,
|
||||
LibertyCell *to_lib_cell);
|
||||
void clkPinsConnectPinAfter(Vertex *vertex);
|
||||
void clkPinsDisconnectPinBefore(Vertex *vertex);
|
||||
void findClkPins();
|
||||
void findClkPins(bool ideal_only,
|
||||
PinSet &clk_pins);
|
||||
|
||||
CmdNamespace cmd_namespace_;
|
||||
Instance *current_instance_;
|
||||
|
|
@ -1385,6 +1397,10 @@ protected:
|
|||
bool link_make_black_boxes_;
|
||||
bool update_genclks_;
|
||||
EquivCells *equiv_cells_;
|
||||
// findClkPins
|
||||
PinSet clk_pins_;
|
||||
PinSet ideal_clk_pins_;
|
||||
bool clk_pins_valid_;
|
||||
|
||||
// Singleton sta used by tcl command interpreter.
|
||||
static Sta *sta_;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ PinCapacitanceLimitSlackLess::operator()(Pin *pin1,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
CheckCapacitanceLimits::CheckCapacitanceLimits(const StaState *sta) :
|
||||
CheckCapacitanceLimits::CheckCapacitanceLimits(const Sta *sta) :
|
||||
sta_(sta)
|
||||
{
|
||||
}
|
||||
|
|
@ -205,7 +205,8 @@ CheckCapacitanceLimits::checkCapacitance(const Pin *pin,
|
|||
{
|
||||
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
|
||||
const OperatingConditions *op_cond = dcalc_ap->operatingConditions();
|
||||
float cap = sta_->graphDelayCalc()->loadCap(pin, dcalc_ap);
|
||||
GraphDelayCalc *dcalc = sta_->graphDelayCalc();
|
||||
float cap = dcalc->loadCap(pin, dcalc_ap);
|
||||
|
||||
float slack1 = (min_max == MinMax::max())
|
||||
? limit1 - cap : cap - limit1;
|
||||
|
|
@ -313,18 +314,18 @@ CheckCapacitanceLimits::pinMinCapacitanceLimitSlack(Instance *inst,
|
|||
}
|
||||
|
||||
bool
|
||||
CheckCapacitanceLimits::checkPin(const Pin *pin)
|
||||
CheckCapacitanceLimits::checkPin(Pin *pin)
|
||||
{
|
||||
const Network *network = sta_->network();
|
||||
const Sim *sim = sta_->sim();
|
||||
const Sdc *sdc = sta_->sdc();
|
||||
const Graph *graph = sta_->graph();
|
||||
GraphDelayCalc *dcalc = sta_->graphDelayCalc();
|
||||
Search *search = sta_->search();
|
||||
Vertex *vertex = graph->pinLoadVertex(pin);
|
||||
return network->direction(pin)->isAnyOutput()
|
||||
&& !sim->logicZeroOne(pin)
|
||||
&& !sdc->isDisabled(pin)
|
||||
&& !(vertex && sta_->graphDelayCalc()->isIdealClk(vertex));
|
||||
&& !(vertex && sta_->isIdealClock(pin));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "Transition.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "Sta.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ class Corner;
|
|||
class CheckCapacitanceLimits
|
||||
{
|
||||
public:
|
||||
CheckCapacitanceLimits(const StaState *sta);
|
||||
CheckCapacitanceLimits(const Sta *sta);
|
||||
// corner=nullptr checks all corners.
|
||||
void checkCapacitance(const Pin *pin,
|
||||
const Corner *corner1,
|
||||
|
|
@ -84,9 +85,9 @@ protected:
|
|||
// Return values.
|
||||
Pin *&min_slack_pin,
|
||||
float &min_slack);
|
||||
bool checkPin(const Pin *pin);
|
||||
bool checkPin(Pin *pin);
|
||||
|
||||
const StaState *sta_;
|
||||
const Sta *sta_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include "Sim.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Graph.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Search.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ PinFanoutLimitSlackLess::operator()(Pin *pin1,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
CheckFanoutLimits::CheckFanoutLimits(const StaState *sta) :
|
||||
CheckFanoutLimits::CheckFanoutLimits(const Sta *sta) :
|
||||
sta_(sta)
|
||||
{
|
||||
}
|
||||
|
|
@ -282,18 +282,17 @@ CheckFanoutLimits::pinMinFanoutLimitSlack(Instance *inst,
|
|||
}
|
||||
|
||||
bool
|
||||
CheckFanoutLimits::checkPin(const Pin *pin)
|
||||
CheckFanoutLimits::checkPin(Pin *pin)
|
||||
{
|
||||
const Network *network = sta_->network();
|
||||
const Sim *sim = sta_->sim();
|
||||
const Sdc *sdc = sta_->sdc();
|
||||
const Graph *graph = sta_->graph();
|
||||
GraphDelayCalc *dcalc = sta_->graphDelayCalc();
|
||||
Vertex *vertex = graph->pinLoadVertex(pin);
|
||||
return network->direction(pin)->isAnyOutput()
|
||||
&& !sim->logicZeroOne(pin)
|
||||
&& !sdc->isDisabled(pin)
|
||||
&& !(vertex && dcalc->isIdealClk(vertex));
|
||||
&& !(vertex && sta_->isIdealClock(pin));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "MinMax.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "Sta.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ class StaState;
|
|||
class CheckFanoutLimits
|
||||
{
|
||||
public:
|
||||
CheckFanoutLimits(const StaState *sta);
|
||||
CheckFanoutLimits(const Sta *sta);
|
||||
void checkFanout(const Pin *pin,
|
||||
const MinMax *min_max,
|
||||
// Return values.
|
||||
|
|
@ -59,9 +60,9 @@ protected:
|
|||
Pin *&min_slack_pin,
|
||||
float &min_slack);
|
||||
float fanoutLoad(const Pin *pin) const;
|
||||
bool checkPin(const Pin *pin);
|
||||
bool checkPin(Pin *pin);
|
||||
|
||||
const StaState *sta_;
|
||||
const Sta *sta_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2020, Parallax Software, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Sta.hh"
|
||||
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Bfs.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "SearchPred.hh"
|
||||
#include "Search.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
void
|
||||
Sta::ensureClkPins()
|
||||
{
|
||||
if (!clk_pins_valid_) {
|
||||
ensureLevelized();
|
||||
findClkPins();
|
||||
clk_pins_valid_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Sta::clkPinsInvalid()
|
||||
{
|
||||
clk_pins_valid_ = false;
|
||||
clk_pins_.clear();
|
||||
ideal_clk_pins_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Sta::clkPinsDisconnectPinBefore(Vertex *vertex)
|
||||
{
|
||||
// If the pin is in the clock network but not a clock endpoint
|
||||
// everything downstream is invalid.
|
||||
if (clk_pins_.hasKey(vertex->pin())
|
||||
&& !isClkEnd(vertex, graph_))
|
||||
clk_pins_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Sta::clkPinsConnectPinAfter(Vertex *vertex)
|
||||
{
|
||||
// If the pin fanin is part of the clock network
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from = edge->from(graph_);
|
||||
if (clk_pins_.hasKey(from->pin())) {
|
||||
clk_pins_valid_ = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find clock network pins.
|
||||
// This is not as reliable as Search::isClock but is much cheaper.
|
||||
void
|
||||
Sta::findClkPins()
|
||||
{
|
||||
// Use two passes to find ideal and propagated clock network pins.
|
||||
findClkPins(false, clk_pins_);
|
||||
findClkPins(true, ideal_clk_pins_);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::findClkPins(bool ideal_only,
|
||||
PinSet &clk_pins)
|
||||
{
|
||||
ClkArrivalSearchPred srch_pred(this);
|
||||
BfsFwdIterator bfs(BfsIndex::other, &srch_pred, this);
|
||||
for (Clock *clk : sdc_->clks()) {
|
||||
if (!ideal_only
|
||||
|| !clk->isPropagated()) {
|
||||
for (Pin *pin : clk->leafPins()) {
|
||||
if (!ideal_only
|
||||
|| !sdc_->isPropagatedClock(pin)) {
|
||||
Vertex *vertex, *bidirect_drvr_vertex;
|
||||
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
||||
bfs.enqueue(vertex);
|
||||
if (bidirect_drvr_vertex)
|
||||
bfs.enqueue(bidirect_drvr_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (bfs.hasNext()) {
|
||||
Vertex *vertex = bfs.next();
|
||||
Pin *pin = vertex->pin();
|
||||
if (!sdc_->isPropagatedClock(pin)) {
|
||||
clk_pins.insert(pin);
|
||||
bfs.enqueueAdjacentVertices(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Sta::isClock(Pin *pin) const
|
||||
{
|
||||
return clk_pins_.hasKey(pin);
|
||||
}
|
||||
|
||||
bool
|
||||
Sta::isIdealClock(Pin *pin) const
|
||||
{
|
||||
return ideal_clk_pins_.hasKey(pin);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -268,7 +268,8 @@ Sta::Sta() :
|
|||
power_(nullptr),
|
||||
link_make_black_boxes_(true),
|
||||
update_genclks_(false),
|
||||
equiv_cells_(nullptr)
|
||||
equiv_cells_(nullptr),
|
||||
clk_pins_valid_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -532,6 +533,7 @@ Sta::~Sta()
|
|||
void
|
||||
Sta::clear()
|
||||
{
|
||||
clkPinsInvalid();
|
||||
// Constraints reference search filter, so clear search first.
|
||||
search_->clear();
|
||||
sdc_->clear();
|
||||
|
|
@ -1136,6 +1138,7 @@ Sta::setPropagatedClock(Clock *clk)
|
|||
sdc_->setPropagatedClock(clk);
|
||||
graph_delay_calc_->delaysInvalid();
|
||||
search_->arrivalsInvalid();
|
||||
clkPinsInvalid();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1144,6 +1147,7 @@ Sta::removePropagatedClock(Clock *clk)
|
|||
sdc_->removePropagatedClock(clk);
|
||||
graph_delay_calc_->delaysInvalid();
|
||||
search_->arrivalsInvalid();
|
||||
clkPinsInvalid();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1152,6 +1156,7 @@ Sta::setPropagatedClock(Pin *pin)
|
|||
sdc_->setPropagatedClock(pin);
|
||||
graph_delay_calc_->delaysInvalid();
|
||||
search_->arrivalsInvalid();
|
||||
clkPinsInvalid();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1160,6 +1165,7 @@ Sta::removePropagatedClock(Pin *pin)
|
|||
sdc_->removePropagatedClock(pin);
|
||||
graph_delay_calc_->delaysInvalid();
|
||||
search_->arrivalsInvalid();
|
||||
clkPinsInvalid();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4024,6 +4030,7 @@ Sta::connectDrvrPinAfter(Vertex *vertex)
|
|||
graph_delay_calc_->delayInvalid(vertex);
|
||||
search_->requiredInvalid(vertex);
|
||||
search_->endpointInvalid(vertex);
|
||||
clkPinsConnectPinAfter(vertex);
|
||||
levelize_->invalidFrom(vertex);
|
||||
}
|
||||
|
||||
|
|
@ -4044,6 +4051,7 @@ Sta::connectLoadPinAfter(Vertex *vertex)
|
|||
levelize_->invalidFrom(vertex);
|
||||
search_->arrivalInvalid(vertex);
|
||||
search_->endpointInvalid(vertex);
|
||||
clkPinsConnectPinAfter(vertex);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4063,6 +4071,7 @@ Sta::disconnectPinBefore(Pin *pin)
|
|||
if (edge->role()->isWire())
|
||||
deleteEdge(edge);
|
||||
}
|
||||
clkPinsDisconnectPinBefore(vertex);
|
||||
}
|
||||
}
|
||||
if (network_->isLoad(pin)) {
|
||||
|
|
@ -4075,6 +4084,7 @@ Sta::disconnectPinBefore(Pin *pin)
|
|||
if (edge->role()->isWire())
|
||||
deleteEdge(edge);
|
||||
}
|
||||
clkPinsDisconnectPinBefore(vertex);
|
||||
}
|
||||
}
|
||||
if (network_->isHierarchical(pin)) {
|
||||
|
|
@ -4907,8 +4917,7 @@ Sta::checkFanoutLimitPreamble()
|
|||
{
|
||||
if (check_fanout_limits_ == nullptr)
|
||||
makeCheckFanoutLimits();
|
||||
// For sim values and ideal clocks.
|
||||
findDelays();
|
||||
ensureClkPins();
|
||||
}
|
||||
|
||||
Pin *
|
||||
|
|
@ -4974,8 +4983,7 @@ Sta::checkCapacitanceLimitPreamble()
|
|||
{
|
||||
if (check_capacitance_limits_ == nullptr)
|
||||
makeCheckCapacitanceLimits();
|
||||
// For sim values and ideal clocks.
|
||||
findDelays();
|
||||
ensureClkPins();
|
||||
}
|
||||
|
||||
Pin *
|
||||
|
|
|
|||
Loading…
Reference in New Issue