ClkNetwork
This commit is contained in:
parent
ff7557bb1f
commit
0db8d142d8
|
|
@ -158,6 +158,7 @@ set(STA_SOURCE
|
|||
search/CheckSlewLimits.cc
|
||||
search/CheckTiming.cc
|
||||
search/ClkInfo.cc
|
||||
search/ClkNetwork.cc
|
||||
search/ClkSkew.cc
|
||||
search/Corner.cc
|
||||
search/Crpr.cc
|
||||
|
|
@ -181,7 +182,6 @@ set(STA_SOURCE
|
|||
search/ReportPath.cc
|
||||
search/Search.cc
|
||||
search/SearchPred.cc
|
||||
search/FindClkPins.cc
|
||||
search/Sim.cc
|
||||
search/Sta.cc
|
||||
search/StaState.cc
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
// 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 "GraphDelayCalc1.hh"
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "Stats.hh"
|
||||
#include "MinMax.hh"
|
||||
|
|
@ -34,7 +36,7 @@
|
|||
#include "ArcDelayCalc.hh"
|
||||
#include "DcalcAnalysisPt.hh"
|
||||
#include "NetCaps.hh"
|
||||
#include "GraphDelayCalc1.hh"
|
||||
#include "ClkNetwork.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -1387,7 +1389,7 @@ GraphDelayCalc1::edgeFromSlew(const Vertex *from_vertex,
|
|||
{
|
||||
const TimingRole *role = edge->role();
|
||||
if (role->genericRole() == TimingRole::regClkToQ()
|
||||
&& isIdealClk(from_vertex))
|
||||
&& clk_network_->isIdealClock(from_vertex->pin()))
|
||||
return idealClkSlew(from_vertex, from_rf, dcalc_ap->slewMinMax());
|
||||
else
|
||||
return graph_->slew(from_vertex, from_rf, dcalc_ap->index());
|
||||
|
|
@ -1399,7 +1401,7 @@ GraphDelayCalc1::idealClkSlew(const Vertex *vertex,
|
|||
const MinMax *min_max)
|
||||
{
|
||||
float slew = min_max->initValue();
|
||||
const ClockSet *clks = idealClks(vertex);
|
||||
const ClockSet *clks = clk_network_->idealClocks(vertex->pin());
|
||||
ClockSet::ConstIterator clk_iter(clks);
|
||||
while (clk_iter.hasNext()) {
|
||||
Clock *clk = clk_iter.next();
|
||||
|
|
@ -1585,7 +1587,7 @@ GraphDelayCalc1::checkEdgeClkSlew(const Vertex *from_vertex,
|
|||
const RiseFall *from_rf,
|
||||
const DcalcAnalysisPt *dcalc_ap)
|
||||
{
|
||||
if (isIdealClk(from_vertex))
|
||||
if (clk_network_->isIdealClock(from_vertex->pin()))
|
||||
return idealClkSlew(from_vertex, from_rf, dcalc_ap->checkClkSlewMinMax());
|
||||
else
|
||||
return graph_->slew(from_vertex, from_rf, dcalc_ap->checkClkSlewIndex());
|
||||
|
|
@ -1674,15 +1676,49 @@ GraphDelayCalc1::setIdealClks(const Vertex *vertex,
|
|||
ClockSet *
|
||||
GraphDelayCalc1::idealClks(const Vertex *vertex)
|
||||
{
|
||||
return ideal_clks_map_.findKey(vertex);
|
||||
ClockSet *ideal_clks = ideal_clks_map_.findKey(vertex);
|
||||
const ClockSet *ideal_clks2 = clk_network_->idealClocks(vertex->pin());
|
||||
if (ideal_clks) {
|
||||
for (Clock *clk : *ideal_clks) {
|
||||
if (ideal_clks2) {
|
||||
if (!ideal_clks2->findKey(clk))
|
||||
printf("pin %s clk_net missing1 %s\n",
|
||||
vertex->name(network_),
|
||||
clk->name());
|
||||
}
|
||||
else
|
||||
printf("pin %s clk_net missing2 %s\n",
|
||||
vertex->name(network_),
|
||||
clk->name());
|
||||
}
|
||||
if (ideal_clks2) {
|
||||
for (Clock *clk : *ideal_clks2) {
|
||||
if (ideal_clks) {
|
||||
if (!ideal_clks->findKey(clk)) {
|
||||
printf("pin %s dcalc missing3 %s\n",
|
||||
vertex->name(network_),
|
||||
clk->name());
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("pin %s dcalc missing4 %s\n",
|
||||
vertex->name(network_),
|
||||
clk->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ideal_clks;
|
||||
}
|
||||
|
||||
bool
|
||||
GraphDelayCalc1::isIdealClk(const Vertex *vertex)
|
||||
{
|
||||
const ClockSet *clks = idealClks(vertex);
|
||||
return clks != 0
|
||||
bool ideal = clks != 0
|
||||
&& clks->size() > 0;
|
||||
if (ideal != clk_network_->isIdealClock(vertex->pin()))
|
||||
printf("ideal missmatch\n");
|
||||
return ideal;
|
||||
}
|
||||
|
||||
float
|
||||
|
|
@ -1765,7 +1801,7 @@ GraphDelayCalc1::reportDelayCalc(Edge *edge,
|
|||
const Slew &from_slew = checkEdgeClkSlew(from_vertex, from_rf, dcalc_ap);
|
||||
int slew_index = dcalc_ap->checkDataSlewIndex();
|
||||
const Slew &to_slew = graph_->slew(to_vertex, to_rf, slew_index);
|
||||
bool from_ideal_clk = isIdealClk(from_vertex);
|
||||
bool from_ideal_clk = clk_network_->isIdealClock(from_vertex->pin());
|
||||
const char *from_slew_annotation = from_ideal_clk ? " (ideal clock)" : nullptr;
|
||||
arc_delay_calc_->reportCheckDelay(cell, arc, from_slew, from_slew_annotation,
|
||||
to_slew, related_out_cap, pvt, dcalc_ap,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <mutex>
|
||||
|
||||
#include "Delay.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
// 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/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Map.hh"
|
||||
#include "Set.hh"
|
||||
#include "StaState.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
typedef Map<const Pin*, ClockSet> PinClksMap;
|
||||
typedef Map<const Clock *, PinSet> ClkPinsMap;
|
||||
|
||||
class Sta;
|
||||
|
||||
// Find clock network pins.
|
||||
// This is not as reliable as Search::isClock but is much cheaper.
|
||||
class ClkNetwork : public StaState
|
||||
{
|
||||
public:
|
||||
ClkNetwork(StaState *sta);
|
||||
void ensureClkNetwork();
|
||||
void clear();
|
||||
bool isClock(const Pin *pin) const;
|
||||
bool isIdealClock(const Pin *pin) const;
|
||||
const ClockSet *clocks(const Pin *pin);
|
||||
const ClockSet *idealClocks(const Pin *pin);
|
||||
void clkPinsInvalid();
|
||||
|
||||
protected:
|
||||
void deletePinBefore(const Pin *pin);
|
||||
void connectPinAfter(const Pin *pin);
|
||||
void disconnectPinBefore(const Pin *pin);
|
||||
friend class Sta;
|
||||
|
||||
private:
|
||||
void findClkPins();
|
||||
void findClkPins(bool ideal_only,
|
||||
PinClksMap &clk_pin_map);
|
||||
|
||||
bool clk_pins_valid_;
|
||||
// pin -> clks
|
||||
PinClksMap pin_clks_map_;
|
||||
// pin -> ideal clks
|
||||
PinClksMap pin_ideal_clks_map_;
|
||||
// clock -> pins
|
||||
ClkPinsMap clk_pins_map_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1145,12 +1145,14 @@ public:
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void ensureClkPins();
|
||||
bool isIdealClock(Pin *pin) const;
|
||||
void ensureClkNetwork();
|
||||
// Assumes ensureClkNetwork() has been called.
|
||||
bool isClock(Pin *pin) const;
|
||||
// Assumes ensureClkNetwork() has been called.
|
||||
bool isIdealClock(Pin *pin) const;
|
||||
void clkPinsInvalid();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void setTclInterp(Tcl_Interp *interp);
|
||||
Tcl_Interp *tclInterp();
|
||||
|
|
@ -1235,7 +1237,8 @@ protected:
|
|||
virtual void makeGraphDelayCalc();
|
||||
virtual void makeSim();
|
||||
virtual void makeSearch();
|
||||
virtual void makeLatches();
|
||||
virtual void makeLatches();
|
||||
virtual void makeClkNetwork();
|
||||
virtual void makeCheckTiming();
|
||||
virtual void makeCheckSlewLimits();
|
||||
virtual void makeCheckFanoutLimits();
|
||||
|
|
@ -1330,11 +1333,6 @@ 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);
|
||||
void sdcChangedGraph();
|
||||
void ensureGraphSdcAnnotated();
|
||||
|
||||
|
|
@ -1356,10 +1354,6 @@ protected:
|
|||
bool update_genclks_;
|
||||
EquivCells *equiv_cells_;
|
||||
bool graph_sdc_annotated_;
|
||||
// findClkPins
|
||||
PinSet clk_pins_;
|
||||
PinSet ideal_clk_pins_;
|
||||
bool clk_pins_valid_;
|
||||
|
||||
// Singleton sta used by tcl command interpreter.
|
||||
static Sta *sta_;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class Parasitics;
|
|||
class ArcDelayCalc;
|
||||
class GraphDelayCalc;
|
||||
class Latches;
|
||||
class ClkNetwork;
|
||||
class DispatchQueue;
|
||||
|
||||
// Most STA components use functionality in other components.
|
||||
|
|
@ -114,6 +115,7 @@ protected:
|
|||
Sim *sim_;
|
||||
Search *search_;
|
||||
Latches *latches_;
|
||||
ClkNetwork *clk_network_;
|
||||
int thread_count_;
|
||||
DispatchQueue *dispatch_queue_;
|
||||
bool pocv_enabled_;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
// 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 "ClkNetwork.hh"
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Bfs.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "SearchPred.hh"
|
||||
#include "Search.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
ClkNetwork::ClkNetwork(StaState *sta) :
|
||||
StaState(sta),
|
||||
clk_pins_valid_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::ensureClkNetwork()
|
||||
{
|
||||
if (!clk_pins_valid_)
|
||||
findClkPins();
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::clear()
|
||||
{
|
||||
clk_pins_valid_ = false;
|
||||
pin_clks_map_.clear();
|
||||
clk_pins_map_.clear();
|
||||
pin_ideal_clks_map_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::clkPinsInvalid()
|
||||
{
|
||||
debugPrint0(debug_, "clk_network", 1, "clk network invalid\n");
|
||||
clk_pins_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::deletePinBefore(const Pin *pin)
|
||||
{
|
||||
if (isClock(pin))
|
||||
clkPinsInvalid();
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::disconnectPinBefore(const Pin *pin)
|
||||
{
|
||||
if (isClock(pin))
|
||||
clkPinsInvalid();
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::connectPinAfter(const Pin *pin)
|
||||
{
|
||||
if (isClock(pin))
|
||||
clkPinsInvalid();
|
||||
}
|
||||
|
||||
class ClkSearchPred : public ClkTreeSearchPred
|
||||
{
|
||||
public:
|
||||
ClkSearchPred(const StaState *sta);
|
||||
virtual bool searchTo(const Vertex *to);
|
||||
};
|
||||
|
||||
ClkSearchPred::ClkSearchPred(const StaState *sta) :
|
||||
ClkTreeSearchPred(sta)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ClkSearchPred::searchTo(const Vertex *to)
|
||||
{
|
||||
const Sdc *sdc = sta_->sdc();
|
||||
return !sdc->isLeafPinClock(to->pin());
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::findClkPins()
|
||||
{
|
||||
debugPrint0(debug_, "clk_network", 1, "find clk network\n");
|
||||
clear();
|
||||
findClkPins(false, pin_clks_map_);
|
||||
findClkPins(true, pin_ideal_clks_map_);
|
||||
clk_pins_valid_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
ClkNetwork::findClkPins(bool ideal_only,
|
||||
PinClksMap &pin_clks_map)
|
||||
{
|
||||
ClkSearchPred srch_pred(this);
|
||||
BfsFwdIterator bfs(BfsIndex::other, &srch_pred, this);
|
||||
for (Clock *clk : sdc_->clks()) {
|
||||
if (!ideal_only
|
||||
|| !clk->isPropagated()) {
|
||||
PinSet &clk_pins = clk_pins_map_[clk];
|
||||
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 (!ideal_only
|
||||
|| !sdc_->isPropagatedClock(pin)) {
|
||||
clk_pins.insert(pin);
|
||||
ClockSet &pin_clks = pin_clks_map[pin];
|
||||
pin_clks.insert(clk);
|
||||
bfs.enqueueAdjacentVertices(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ClkNetwork::isClock(const Pin *pin) const
|
||||
{
|
||||
ClockSet clks;
|
||||
bool exists;
|
||||
pin_clks_map_.findKey(pin, clks, exists);
|
||||
if (exists && clks.empty())
|
||||
printf("luse empty clks\n");
|
||||
return exists;
|
||||
}
|
||||
|
||||
bool
|
||||
ClkNetwork::isIdealClock(const Pin *pin) const
|
||||
{
|
||||
ClockSet clks;
|
||||
bool exists;
|
||||
pin_ideal_clks_map_.findKey(pin, clks, exists);
|
||||
if (exists && clks.empty())
|
||||
printf("luse empty clks\n");
|
||||
return exists;
|
||||
}
|
||||
|
||||
const ClockSet *
|
||||
ClkNetwork::clocks(const Pin *pin)
|
||||
{
|
||||
if (pin_clks_map_.hasKey(pin))
|
||||
return &pin_clks_map_[pin];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ClockSet *
|
||||
ClkNetwork::idealClocks(const Pin *pin)
|
||||
{
|
||||
if (pin_ideal_clks_map_.hasKey(pin))
|
||||
return &pin_ideal_clks_map_[pin];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
// 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
|
||||
|
|
@ -64,6 +64,7 @@
|
|||
#include "ReportPath.hh"
|
||||
#include "VisitPathGroupVertices.hh"
|
||||
#include "Genclks.hh"
|
||||
#include "ClkNetwork.hh"
|
||||
#include "Power.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -268,8 +269,7 @@ Sta::Sta() :
|
|||
link_make_black_boxes_(true),
|
||||
update_genclks_(false),
|
||||
equiv_cells_(nullptr),
|
||||
graph_sdc_annotated_(false),
|
||||
clk_pins_valid_(false)
|
||||
graph_sdc_annotated_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -289,6 +289,7 @@ Sta::makeComponents()
|
|||
makeSim();
|
||||
makeSearch();
|
||||
makeLatches();
|
||||
makeClkNetwork();
|
||||
makeSdcNetwork();
|
||||
makeReportPath();
|
||||
makePower();
|
||||
|
|
@ -348,6 +349,7 @@ Sta::updateComponentsState()
|
|||
report_path_->copyState(this);
|
||||
if (check_timing_)
|
||||
check_timing_->copyState(this);
|
||||
clk_network_->copyState(this);
|
||||
if (power_)
|
||||
power_->copyState(this);
|
||||
}
|
||||
|
|
@ -478,6 +480,12 @@ Sta::makeReportPath()
|
|||
report_path_ = new ReportPath(this);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::makeClkNetwork()
|
||||
{
|
||||
clk_network_ = new ClkNetwork(this);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::makePower()
|
||||
{
|
||||
|
|
@ -525,6 +533,7 @@ Sta::~Sta()
|
|||
delete debug_;
|
||||
delete units_;
|
||||
delete report_;
|
||||
delete clk_network_;
|
||||
delete power_;
|
||||
delete equiv_cells_;
|
||||
delete dispatch_queue_;
|
||||
|
|
@ -2090,6 +2099,7 @@ Sta::removeConstraints()
|
|||
if (graph_)
|
||||
sdc_->removeGraphAnnotations();
|
||||
sdc_->clear();
|
||||
clk_network_->clear();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3107,7 +3117,7 @@ Sta::findDelays(Level level)
|
|||
void
|
||||
Sta::delayCalcPreamble()
|
||||
{
|
||||
ensureLevelized();
|
||||
ensureClkNetwork();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3986,8 +3996,10 @@ Sta::connectPinAfter(Pin *pin)
|
|||
EdgesThruHierPinIterator edge_iter(pin, network_, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
if (edge->role()->isWire())
|
||||
if (edge->role()->isWire()) {
|
||||
connectDrvrPinAfter(edge->from(graph_));
|
||||
connectLoadPinAfter(edge->to(graph_));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -4034,12 +4046,13 @@ Sta::connectDrvrPinAfter(Vertex *vertex)
|
|||
search_->endpointInvalid(to_vertex);
|
||||
sdc_->clkHpinDisablesChanged(to_vertex->pin());
|
||||
}
|
||||
sdc_->clkHpinDisablesChanged(vertex->pin());
|
||||
Pin *pin = vertex->pin();
|
||||
sdc_->clkHpinDisablesChanged(pin);
|
||||
graph_delay_calc_->delayInvalid(vertex);
|
||||
search_->requiredInvalid(vertex);
|
||||
search_->endpointInvalid(vertex);
|
||||
clkPinsConnectPinAfter(vertex);
|
||||
levelize_->invalidFrom(vertex);
|
||||
clk_network_->connectPinAfter(pin);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4054,12 +4067,13 @@ Sta::connectLoadPinAfter(Vertex *vertex)
|
|||
search_->requiredInvalid(from_vertex);
|
||||
sdc_->clkHpinDisablesChanged(from_vertex->pin());
|
||||
}
|
||||
sdc_->clkHpinDisablesChanged(vertex->pin());
|
||||
Pin *pin = vertex->pin();
|
||||
sdc_->clkHpinDisablesChanged(pin);
|
||||
graph_delay_calc_->delayInvalid(vertex);
|
||||
levelize_->invalidFrom(vertex);
|
||||
search_->arrivalInvalid(vertex);
|
||||
search_->endpointInvalid(vertex);
|
||||
clkPinsConnectPinAfter(vertex);
|
||||
clk_network_->connectPinAfter(pin);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4079,7 +4093,7 @@ Sta::disconnectPinBefore(Pin *pin)
|
|||
if (edge->role()->isWire())
|
||||
deleteEdge(edge);
|
||||
}
|
||||
clkPinsDisconnectPinBefore(vertex);
|
||||
clk_network_->disconnectPinBefore(pin);
|
||||
}
|
||||
}
|
||||
if (network_->isLoad(pin)) {
|
||||
|
|
@ -4092,7 +4106,7 @@ Sta::disconnectPinBefore(Pin *pin)
|
|||
if (edge->role()->isWire())
|
||||
deleteEdge(edge);
|
||||
}
|
||||
clkPinsDisconnectPinBefore(vertex);
|
||||
clk_network_->disconnectPinBefore(pin);
|
||||
}
|
||||
}
|
||||
if (network_->isHierarchical(pin)) {
|
||||
|
|
@ -4100,8 +4114,10 @@ Sta::disconnectPinBefore(Pin *pin)
|
|||
EdgesThruHierPinIterator edge_iter(pin, network_, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
if (edge->role()->isWire())
|
||||
if (edge->role()->isWire()) {
|
||||
deleteEdge(edge);
|
||||
clk_network_->disconnectPinBefore(edge->from(graph_)->pin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4229,6 +4245,7 @@ Sta::deletePinBefore(Pin *pin)
|
|||
}
|
||||
}
|
||||
sim_->deletePinBefore(pin);
|
||||
clk_network_->deletePinBefore(pin);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4926,7 +4943,7 @@ Sta::checkFanoutLimitPreamble()
|
|||
{
|
||||
if (check_fanout_limits_ == nullptr)
|
||||
makeCheckFanoutLimits();
|
||||
ensureClkPins();
|
||||
ensureClkNetwork();
|
||||
}
|
||||
|
||||
Pin *
|
||||
|
|
@ -4991,7 +5008,7 @@ Sta::checkCapacitanceLimitPreamble()
|
|||
{
|
||||
if (check_capacitance_limits_ == nullptr)
|
||||
makeCheckCapacitanceLimits();
|
||||
ensureClkPins();
|
||||
ensureClkNetwork();
|
||||
}
|
||||
|
||||
Pin *
|
||||
|
|
@ -5244,4 +5261,31 @@ Sta::power(const Instance *inst,
|
|||
power_->power(inst, corner, result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Sta::ensureClkNetwork()
|
||||
{
|
||||
ensureLevelized();
|
||||
clk_network_->ensureClkNetwork();
|
||||
}
|
||||
|
||||
bool
|
||||
Sta::isClock(Pin *pin) const
|
||||
{
|
||||
return clk_network_->isClock(pin);
|
||||
}
|
||||
|
||||
bool
|
||||
Sta::isIdealClock(Pin *pin) const
|
||||
{
|
||||
return clk_network_->isIdealClock(pin);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::clkPinsInvalid()
|
||||
{
|
||||
clk_network_->clkPinsInvalid();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ StaState::StaState() :
|
|||
sim_(nullptr),
|
||||
search_(nullptr),
|
||||
latches_(nullptr),
|
||||
clk_network_(nullptr),
|
||||
thread_count_(1),
|
||||
dispatch_queue_(nullptr),
|
||||
pocv_enabled_(false),
|
||||
|
|
@ -63,6 +64,7 @@ StaState::StaState(const StaState *sta) :
|
|||
sim_(sta->sim_),
|
||||
search_(sta->search_),
|
||||
latches_(sta->latches_),
|
||||
clk_network_(sta->clk_network_),
|
||||
thread_count_(sta->thread_count_),
|
||||
dispatch_queue_(sta->dispatch_queue_),
|
||||
pocv_enabled_(sta->pocv_enabled_),
|
||||
|
|
@ -89,6 +91,7 @@ StaState::copyState(const StaState *sta)
|
|||
sim_ = sta->sim_;
|
||||
search_ = sta->search_;
|
||||
latches_ = sta->latches_;
|
||||
clk_network_ = sta->clk_network_;
|
||||
thread_count_ = sta->thread_count_;
|
||||
dispatch_queue_ = sta->dispatch_queue_;
|
||||
pocv_enabled_ = sta->pocv_enabled_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue