refactor find clocks
This commit is contained in:
parent
07e1262186
commit
41f8a97271
|
|
@ -180,6 +180,7 @@ set(STA_SOURCE
|
||||||
search/ReportPath.cc
|
search/ReportPath.cc
|
||||||
search/Search.cc
|
search/Search.cc
|
||||||
search/SearchPred.cc
|
search/SearchPred.cc
|
||||||
|
search/FindClkPins.cc
|
||||||
search/Sim.cc
|
search/Sim.cc
|
||||||
search/Sta.cc
|
search/Sta.cc
|
||||||
search/StaState.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);
|
void setTclInterp(Tcl_Interp *interp);
|
||||||
Tcl_Interp *tclInterp();
|
Tcl_Interp *tclInterp();
|
||||||
void ensureLevelized();
|
void ensureLevelized();
|
||||||
|
|
@ -1367,6 +1374,11 @@ protected:
|
||||||
void replaceCell(Instance *inst,
|
void replaceCell(Instance *inst,
|
||||||
Cell *to_cell,
|
Cell *to_cell,
|
||||||
LibertyCell *to_lib_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_;
|
CmdNamespace cmd_namespace_;
|
||||||
Instance *current_instance_;
|
Instance *current_instance_;
|
||||||
|
|
@ -1385,6 +1397,10 @@ protected:
|
||||||
bool link_make_black_boxes_;
|
bool link_make_black_boxes_;
|
||||||
bool update_genclks_;
|
bool update_genclks_;
|
||||||
EquivCells *equiv_cells_;
|
EquivCells *equiv_cells_;
|
||||||
|
// findClkPins
|
||||||
|
PinSet clk_pins_;
|
||||||
|
PinSet ideal_clk_pins_;
|
||||||
|
bool clk_pins_valid_;
|
||||||
|
|
||||||
// Singleton sta used by tcl command interpreter.
|
// Singleton sta used by tcl command interpreter.
|
||||||
static Sta *sta_;
|
static Sta *sta_;
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ PinCapacitanceLimitSlackLess::operator()(Pin *pin1,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CheckCapacitanceLimits::CheckCapacitanceLimits(const StaState *sta) :
|
CheckCapacitanceLimits::CheckCapacitanceLimits(const Sta *sta) :
|
||||||
sta_(sta)
|
sta_(sta)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +205,8 @@ CheckCapacitanceLimits::checkCapacitance(const Pin *pin,
|
||||||
{
|
{
|
||||||
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
|
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
|
||||||
const OperatingConditions *op_cond = dcalc_ap->operatingConditions();
|
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())
|
float slack1 = (min_max == MinMax::max())
|
||||||
? limit1 - cap : cap - limit1;
|
? limit1 - cap : cap - limit1;
|
||||||
|
|
@ -313,18 +314,18 @@ CheckCapacitanceLimits::pinMinCapacitanceLimitSlack(Instance *inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CheckCapacitanceLimits::checkPin(const Pin *pin)
|
CheckCapacitanceLimits::checkPin(Pin *pin)
|
||||||
{
|
{
|
||||||
const Network *network = sta_->network();
|
const Network *network = sta_->network();
|
||||||
const Sim *sim = sta_->sim();
|
const Sim *sim = sta_->sim();
|
||||||
const Sdc *sdc = sta_->sdc();
|
const Sdc *sdc = sta_->sdc();
|
||||||
const Graph *graph = sta_->graph();
|
const Graph *graph = sta_->graph();
|
||||||
GraphDelayCalc *dcalc = sta_->graphDelayCalc();
|
Search *search = sta_->search();
|
||||||
Vertex *vertex = graph->pinLoadVertex(pin);
|
Vertex *vertex = graph->pinLoadVertex(pin);
|
||||||
return network->direction(pin)->isAnyOutput()
|
return network->direction(pin)->isAnyOutput()
|
||||||
&& !sim->logicZeroOne(pin)
|
&& !sim->logicZeroOne(pin)
|
||||||
&& !sdc->isDisabled(pin)
|
&& !sdc->isDisabled(pin)
|
||||||
&& !(vertex && sta_->graphDelayCalc()->isIdealClk(vertex));
|
&& !(vertex && sta_->isIdealClock(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Transition.hh"
|
#include "Transition.hh"
|
||||||
#include "NetworkClass.hh"
|
#include "NetworkClass.hh"
|
||||||
#include "SdcClass.hh"
|
#include "SdcClass.hh"
|
||||||
|
#include "Sta.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -29,7 +30,7 @@ class Corner;
|
||||||
class CheckCapacitanceLimits
|
class CheckCapacitanceLimits
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckCapacitanceLimits(const StaState *sta);
|
CheckCapacitanceLimits(const Sta *sta);
|
||||||
// corner=nullptr checks all corners.
|
// corner=nullptr checks all corners.
|
||||||
void checkCapacitance(const Pin *pin,
|
void checkCapacitance(const Pin *pin,
|
||||||
const Corner *corner1,
|
const Corner *corner1,
|
||||||
|
|
@ -84,9 +85,9 @@ protected:
|
||||||
// Return values.
|
// Return values.
|
||||||
Pin *&min_slack_pin,
|
Pin *&min_slack_pin,
|
||||||
float &min_slack);
|
float &min_slack);
|
||||||
bool checkPin(const Pin *pin);
|
bool checkPin(Pin *pin);
|
||||||
|
|
||||||
const StaState *sta_;
|
const Sta *sta_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include "Sim.hh"
|
#include "Sim.hh"
|
||||||
#include "PortDirection.hh"
|
#include "PortDirection.hh"
|
||||||
#include "Graph.hh"
|
#include "Graph.hh"
|
||||||
#include "GraphDelayCalc.hh"
|
#include "Search.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ PinFanoutLimitSlackLess::operator()(Pin *pin1,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CheckFanoutLimits::CheckFanoutLimits(const StaState *sta) :
|
CheckFanoutLimits::CheckFanoutLimits(const Sta *sta) :
|
||||||
sta_(sta)
|
sta_(sta)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -282,18 +282,17 @@ CheckFanoutLimits::pinMinFanoutLimitSlack(Instance *inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CheckFanoutLimits::checkPin(const Pin *pin)
|
CheckFanoutLimits::checkPin(Pin *pin)
|
||||||
{
|
{
|
||||||
const Network *network = sta_->network();
|
const Network *network = sta_->network();
|
||||||
const Sim *sim = sta_->sim();
|
const Sim *sim = sta_->sim();
|
||||||
const Sdc *sdc = sta_->sdc();
|
const Sdc *sdc = sta_->sdc();
|
||||||
const Graph *graph = sta_->graph();
|
const Graph *graph = sta_->graph();
|
||||||
GraphDelayCalc *dcalc = sta_->graphDelayCalc();
|
|
||||||
Vertex *vertex = graph->pinLoadVertex(pin);
|
Vertex *vertex = graph->pinLoadVertex(pin);
|
||||||
return network->direction(pin)->isAnyOutput()
|
return network->direction(pin)->isAnyOutput()
|
||||||
&& !sim->logicZeroOne(pin)
|
&& !sim->logicZeroOne(pin)
|
||||||
&& !sdc->isDisabled(pin)
|
&& !sdc->isDisabled(pin)
|
||||||
&& !(vertex && dcalc->isIdealClk(vertex));
|
&& !(vertex && sta_->isIdealClock(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "MinMax.hh"
|
#include "MinMax.hh"
|
||||||
#include "NetworkClass.hh"
|
#include "NetworkClass.hh"
|
||||||
#include "SdcClass.hh"
|
#include "SdcClass.hh"
|
||||||
|
#include "Sta.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ class StaState;
|
||||||
class CheckFanoutLimits
|
class CheckFanoutLimits
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckFanoutLimits(const StaState *sta);
|
CheckFanoutLimits(const Sta *sta);
|
||||||
void checkFanout(const Pin *pin,
|
void checkFanout(const Pin *pin,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
// Return values.
|
// Return values.
|
||||||
|
|
@ -59,9 +60,9 @@ protected:
|
||||||
Pin *&min_slack_pin,
|
Pin *&min_slack_pin,
|
||||||
float &min_slack);
|
float &min_slack);
|
||||||
float fanoutLoad(const Pin *pin) const;
|
float fanoutLoad(const Pin *pin) const;
|
||||||
bool checkPin(const Pin *pin);
|
bool checkPin(Pin *pin);
|
||||||
|
|
||||||
const StaState *sta_;
|
const Sta *sta_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // 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),
|
power_(nullptr),
|
||||||
link_make_black_boxes_(true),
|
link_make_black_boxes_(true),
|
||||||
update_genclks_(false),
|
update_genclks_(false),
|
||||||
equiv_cells_(nullptr)
|
equiv_cells_(nullptr),
|
||||||
|
clk_pins_valid_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -532,6 +533,7 @@ Sta::~Sta()
|
||||||
void
|
void
|
||||||
Sta::clear()
|
Sta::clear()
|
||||||
{
|
{
|
||||||
|
clkPinsInvalid();
|
||||||
// Constraints reference search filter, so clear search first.
|
// Constraints reference search filter, so clear search first.
|
||||||
search_->clear();
|
search_->clear();
|
||||||
sdc_->clear();
|
sdc_->clear();
|
||||||
|
|
@ -1136,6 +1138,7 @@ Sta::setPropagatedClock(Clock *clk)
|
||||||
sdc_->setPropagatedClock(clk);
|
sdc_->setPropagatedClock(clk);
|
||||||
graph_delay_calc_->delaysInvalid();
|
graph_delay_calc_->delaysInvalid();
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
|
clkPinsInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1144,6 +1147,7 @@ Sta::removePropagatedClock(Clock *clk)
|
||||||
sdc_->removePropagatedClock(clk);
|
sdc_->removePropagatedClock(clk);
|
||||||
graph_delay_calc_->delaysInvalid();
|
graph_delay_calc_->delaysInvalid();
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
|
clkPinsInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1152,6 +1156,7 @@ Sta::setPropagatedClock(Pin *pin)
|
||||||
sdc_->setPropagatedClock(pin);
|
sdc_->setPropagatedClock(pin);
|
||||||
graph_delay_calc_->delaysInvalid();
|
graph_delay_calc_->delaysInvalid();
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
|
clkPinsInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1160,6 +1165,7 @@ Sta::removePropagatedClock(Pin *pin)
|
||||||
sdc_->removePropagatedClock(pin);
|
sdc_->removePropagatedClock(pin);
|
||||||
graph_delay_calc_->delaysInvalid();
|
graph_delay_calc_->delaysInvalid();
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
|
clkPinsInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -4024,6 +4030,7 @@ Sta::connectDrvrPinAfter(Vertex *vertex)
|
||||||
graph_delay_calc_->delayInvalid(vertex);
|
graph_delay_calc_->delayInvalid(vertex);
|
||||||
search_->requiredInvalid(vertex);
|
search_->requiredInvalid(vertex);
|
||||||
search_->endpointInvalid(vertex);
|
search_->endpointInvalid(vertex);
|
||||||
|
clkPinsConnectPinAfter(vertex);
|
||||||
levelize_->invalidFrom(vertex);
|
levelize_->invalidFrom(vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4044,6 +4051,7 @@ Sta::connectLoadPinAfter(Vertex *vertex)
|
||||||
levelize_->invalidFrom(vertex);
|
levelize_->invalidFrom(vertex);
|
||||||
search_->arrivalInvalid(vertex);
|
search_->arrivalInvalid(vertex);
|
||||||
search_->endpointInvalid(vertex);
|
search_->endpointInvalid(vertex);
|
||||||
|
clkPinsConnectPinAfter(vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -4063,6 +4071,7 @@ Sta::disconnectPinBefore(Pin *pin)
|
||||||
if (edge->role()->isWire())
|
if (edge->role()->isWire())
|
||||||
deleteEdge(edge);
|
deleteEdge(edge);
|
||||||
}
|
}
|
||||||
|
clkPinsDisconnectPinBefore(vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (network_->isLoad(pin)) {
|
if (network_->isLoad(pin)) {
|
||||||
|
|
@ -4075,6 +4084,7 @@ Sta::disconnectPinBefore(Pin *pin)
|
||||||
if (edge->role()->isWire())
|
if (edge->role()->isWire())
|
||||||
deleteEdge(edge);
|
deleteEdge(edge);
|
||||||
}
|
}
|
||||||
|
clkPinsDisconnectPinBefore(vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (network_->isHierarchical(pin)) {
|
if (network_->isHierarchical(pin)) {
|
||||||
|
|
@ -4907,8 +4917,7 @@ Sta::checkFanoutLimitPreamble()
|
||||||
{
|
{
|
||||||
if (check_fanout_limits_ == nullptr)
|
if (check_fanout_limits_ == nullptr)
|
||||||
makeCheckFanoutLimits();
|
makeCheckFanoutLimits();
|
||||||
// For sim values and ideal clocks.
|
ensureClkPins();
|
||||||
findDelays();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pin *
|
Pin *
|
||||||
|
|
@ -4974,8 +4983,7 @@ Sta::checkCapacitanceLimitPreamble()
|
||||||
{
|
{
|
||||||
if (check_capacitance_limits_ == nullptr)
|
if (check_capacitance_limits_ == nullptr)
|
||||||
makeCheckCapacitanceLimits();
|
makeCheckCapacitanceLimits();
|
||||||
// For sim values and ideal clocks.
|
ensureClkPins();
|
||||||
findDelays();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pin *
|
Pin *
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue