graph dcalc use ClkNetwork
This commit is contained in:
parent
0db8d142d8
commit
b36d2753d1
|
|
@ -116,12 +116,6 @@ GraphDelayCalc::ceff(Edge *,
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
bool
|
||||
GraphDelayCalc::isIdealClk(const Vertex *vertex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
GraphDelayCalc::minPulseWidth(const Pin *pin,
|
||||
const RiseFall *hi_low,
|
||||
|
|
|
|||
|
|
@ -230,7 +230,6 @@ GraphDelayCalc1::~GraphDelayCalc1()
|
|||
delete clk_pred_;
|
||||
delete iter_;
|
||||
deleteMultiDrvrNets();
|
||||
clearIdealClkMap();
|
||||
delete observer_;
|
||||
}
|
||||
|
||||
|
|
@ -293,7 +292,6 @@ GraphDelayCalc1::delaysInvalid()
|
|||
delays_seeded_ = false;
|
||||
incremental_ = false;
|
||||
iter_->clear();
|
||||
clearIdealClkMap();
|
||||
// No need to keep track of incremental updates any more.
|
||||
invalid_delays_.clear();
|
||||
invalid_checks_.clear();
|
||||
|
|
@ -360,7 +358,6 @@ public:
|
|||
virtual ~FindVertexDelays();
|
||||
virtual void visit(Vertex *vertex);
|
||||
virtual VertexVisitor *copy();
|
||||
virtual void levelFinished();
|
||||
|
||||
protected:
|
||||
GraphDelayCalc1 *graph_delay_calc1_;
|
||||
|
|
@ -398,24 +395,6 @@ FindVertexDelays::visit(Vertex *vertex)
|
|||
graph_delay_calc1_->findVertexDelay(vertex, arc_delay_calc_, true);
|
||||
}
|
||||
|
||||
void
|
||||
FindVertexDelays::levelFinished()
|
||||
{
|
||||
graph_delay_calc1_->mergeIdealClks();
|
||||
}
|
||||
|
||||
void
|
||||
GraphDelayCalc1::mergeIdealClks()
|
||||
{
|
||||
for (auto vertex_clks : ideal_clks_map_next_) {
|
||||
const Vertex *vertex = vertex_clks.first;
|
||||
ClockSet *prev_clks = ideal_clks_map_.findKey(vertex);
|
||||
delete prev_clks;
|
||||
ideal_clks_map_[vertex] = vertex_clks.second;
|
||||
}
|
||||
ideal_clks_map_next_.clear();
|
||||
}
|
||||
|
||||
// The logical structure of incremental delay calculation closely
|
||||
// resembles the incremental search arrival time algorithm
|
||||
// (Search::findArrivals).
|
||||
|
|
@ -437,7 +416,6 @@ GraphDelayCalc1::findDelays(Level level)
|
|||
if (incremental_)
|
||||
seedInvalidDelays();
|
||||
|
||||
mergeIdealClks();
|
||||
FindVertexDelays visitor(this, arc_delay_calc_, false);
|
||||
dcalc_count += iter_->visitParallel(level, &visitor);
|
||||
|
||||
|
|
@ -578,7 +556,6 @@ GraphDelayCalc1::seedRootSlews()
|
|||
while (root_iter.hasNext()) {
|
||||
Vertex *vertex = root_iter.next();
|
||||
seedRootSlew(vertex, arc_delay_calc_);
|
||||
findIdealClks(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -857,7 +834,6 @@ GraphDelayCalc1::findVertexDelay(Vertex *vertex,
|
|||
bool propagate)
|
||||
{
|
||||
const Pin *pin = vertex->pin();
|
||||
bool ideal_clks_changed = findIdealClks(vertex);
|
||||
// Don't clobber root slews.
|
||||
if (!vertex->isRoot()) {
|
||||
debugPrint2(debug_, "delay_calc", 2, "find delays %s (%s)\n",
|
||||
|
|
@ -871,7 +847,7 @@ GraphDelayCalc1::findVertexDelay(Vertex *vertex,
|
|||
enqueueTimingChecksEdges(vertex);
|
||||
// Enqueue adjacent vertices even if the delays did not
|
||||
// change when non-incremental to stride past annotations.
|
||||
if (delay_changed || ideal_clks_changed || !incremental_)
|
||||
if (delay_changed || !incremental_)
|
||||
iter_->enqueueAdjacentVertices(vertex);
|
||||
}
|
||||
}
|
||||
|
|
@ -1595,132 +1571,6 @@ GraphDelayCalc1::checkEdgeClkSlew(const Vertex *from_vertex,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
GraphDelayCalc1::findIdealClks(Vertex *vertex)
|
||||
{
|
||||
const Pin *pin = vertex->pin();
|
||||
ClockSet *ideal_clks = nullptr;
|
||||
if (sdc_->isLeafPinClock(pin)) {
|
||||
// Seed ideal clocks pins.
|
||||
if (!sdc_->isPropagatedClock(pin)) {
|
||||
ClockSet *clks = sdc_->findLeafPinClocks(pin);
|
||||
ClockSet::ConstIterator clk_iter(clks);
|
||||
while (clk_iter.hasNext()) {
|
||||
Clock *clk = clk_iter.next();
|
||||
if (!clk->isPropagated()) {
|
||||
if (ideal_clks == nullptr) {
|
||||
ideal_clks = new ClockSet;
|
||||
debugPrint1(debug_, "ideal_clks", 1, " %s\n",
|
||||
vertex->name(sdc_network_));
|
||||
}
|
||||
ideal_clks->insert(clk);
|
||||
debugPrint1(debug_, "ideal_clks", 1, " %s\n", clk->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!sdc_->isPropagatedClock(pin)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
if (clk_pred_->searchThru(edge)) {
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
ClockSet *from_clks = idealClks(from_vertex);
|
||||
if (from_clks) {
|
||||
ClockSet::ConstIterator from_clk_iter(from_clks);
|
||||
while (from_clk_iter.hasNext()) {
|
||||
Clock *from_clk = from_clk_iter.next();
|
||||
if (ideal_clks == nullptr) {
|
||||
ideal_clks = new ClockSet;
|
||||
debugPrint1(debug_, "ideal_clks", 1, " %s\n",
|
||||
vertex->name(sdc_network_));
|
||||
}
|
||||
ideal_clks->insert(from_clk);
|
||||
debugPrint1(debug_, "ideal_clks", 1, " %s\n", from_clk->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return setIdealClks(vertex, ideal_clks);
|
||||
}
|
||||
|
||||
void
|
||||
GraphDelayCalc1::clearIdealClkMap()
|
||||
{
|
||||
ideal_clks_map_.deleteContentsClear();
|
||||
ideal_clks_map_next_.deleteContentsClear();
|
||||
}
|
||||
|
||||
bool
|
||||
GraphDelayCalc1::setIdealClks(const Vertex *vertex,
|
||||
ClockSet *clks)
|
||||
{
|
||||
bool changed = false;
|
||||
ClockSet *clks1 = ideal_clks_map_.findKey(vertex);
|
||||
if (!ClockSet::equal(clks, clks1)) {
|
||||
// Only lock for updates to vertex ideal clks.
|
||||
// Finding ideal clks by level means only changes at the current
|
||||
// delay calc level are changed.
|
||||
UniqueLock lock(ideal_clks_map_next_lock_);
|
||||
ideal_clks_map_next_[vertex] = clks;
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
delete clks;
|
||||
return changed;
|
||||
}
|
||||
|
||||
ClockSet *
|
||||
GraphDelayCalc1::idealClks(const Vertex *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);
|
||||
bool ideal = clks != 0
|
||||
&& clks->size() > 0;
|
||||
if (ideal != clk_network_->isIdealClock(vertex->pin()))
|
||||
printf("ideal missmatch\n");
|
||||
return ideal;
|
||||
}
|
||||
|
||||
float
|
||||
GraphDelayCalc1::ceff(Edge *edge,
|
||||
TimingArc *arc,
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ protected:
|
|||
ArcDelayCalc *arc_delay_calc,
|
||||
bool propagate);
|
||||
void enqueueTimingChecksEdges(Vertex *vertex);
|
||||
bool findIdealClks(Vertex *vertex);
|
||||
bool findArcDelay(LibertyCell *drvr_cell,
|
||||
const Pin *drvr_pin,
|
||||
Vertex *drvr_vertex,
|
||||
|
|
@ -195,11 +194,6 @@ protected:
|
|||
const RiseFall *from_rf,
|
||||
const DcalcAnalysisPt *dcalc_ap);
|
||||
bool bidirectDrvrSlewFromLoad(const Vertex *vertex) const;
|
||||
void clearIdealClkMap();
|
||||
bool setIdealClks(const Vertex *vertex,
|
||||
ClockSet *clks);
|
||||
ClockSet *idealClks(const Vertex *vertex);
|
||||
virtual bool isIdealClk(const Vertex *vertex);
|
||||
Slew idealClkSlew(const Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
|
|
@ -214,7 +208,6 @@ protected:
|
|||
Parasitic *drvr_parasitic,
|
||||
const RiseFall *rf,
|
||||
const DcalcAnalysisPt *dcalc_ap) const;
|
||||
void mergeIdealClks();
|
||||
|
||||
// Observer for edge delay changes.
|
||||
DelayCalcObserver *observer_;
|
||||
|
|
@ -235,9 +228,6 @@ protected:
|
|||
// Percentage (0.0:1.0) change in delay that causes downstream
|
||||
// delays to be recomputed during incremental delay calculation.
|
||||
float incremental_delay_tolerance_;
|
||||
VertexIdealClksMap ideal_clks_map_;
|
||||
VertexIdealClksMap ideal_clks_map_next_;
|
||||
std::mutex ideal_clks_map_next_lock_;
|
||||
|
||||
friend class FindVertexDelays;
|
||||
friend class MultiDrvrNet;
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ public:
|
|||
virtual float ceff(Edge *edge,
|
||||
TimingArc *arc,
|
||||
const DcalcAnalysisPt *dcalc_ap);
|
||||
virtual bool isIdealClk(const Vertex *vertex);
|
||||
// Precedence:
|
||||
// SDF annotation
|
||||
// Liberty library
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ public:
|
|||
Search *search() const { return search_; }
|
||||
Latches *latches() { return latches_; }
|
||||
Latches *latches() const { return latches_; }
|
||||
ClkNetwork *clkNetwork() { return clk_network_; }
|
||||
ClkNetwork *clkNetwork() const { return clk_network_; }
|
||||
unsigned threadCount() const { return thread_count_; }
|
||||
bool pocvEnabled() const { return pocv_enabled_; }
|
||||
float sigmaFactor() const { return sigma_factor_; }
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "PathVertex.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Search.hh"
|
||||
#include "ClkNetwork.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -147,13 +148,14 @@ CheckSlewLimits::checkSlews1(Vertex *vertex,
|
|||
float &limit,
|
||||
float &slack) const
|
||||
{
|
||||
const Pin *pin = vertex->pin();
|
||||
if (!vertex->isDisabledConstraint()
|
||||
&& !vertex->isConstant()
|
||||
&& !sta_->graphDelayCalc()->isIdealClk(vertex)) {
|
||||
&& !sta_->clkNetwork()->isIdealClock(pin)) {
|
||||
for (auto rf1 : RiseFall::range()) {
|
||||
float limit1;
|
||||
bool limit1_exists;
|
||||
findLimit(vertex->pin(), vertex, rf1, min_max, check_clks,
|
||||
findLimit(pin, vertex, rf1, min_max, check_clks,
|
||||
limit1, limit1_exists);
|
||||
if (limit1_exists) {
|
||||
checkSlew(vertex, corner1, rf1, min_max, limit1,
|
||||
|
|
@ -186,7 +188,7 @@ CheckSlewLimits::findLimit(const Pin *pin,
|
|||
bool exists1;
|
||||
if (check_clks) {
|
||||
// Look for clock slew limits.
|
||||
bool is_clk = sta_->search()->isClock(vertex);
|
||||
bool is_clk = sta_->clkNetwork()->isIdealClock(pin);
|
||||
ClockSet clks;
|
||||
clockDomains(vertex, clks);
|
||||
ClockSet::Iterator clk_iter(clks);
|
||||
|
|
|
|||
|
|
@ -143,23 +143,13 @@ ClkNetwork::findClkPins(bool ideal_only,
|
|||
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;
|
||||
return pin_clks_map_.hasKey(pin);
|
||||
}
|
||||
|
||||
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;
|
||||
return pin_ideal_clks_map_.hasKey(pin);
|
||||
}
|
||||
|
||||
const ClockSet *
|
||||
|
|
|
|||
|
|
@ -4865,6 +4865,7 @@ Sta::checkSlewLimitPreamble()
|
|||
findDelays();
|
||||
if (check_slew_limits_ == nullptr)
|
||||
makeCheckSlewLimits();
|
||||
ensureClkNetwork();
|
||||
}
|
||||
|
||||
Pin *
|
||||
|
|
|
|||
18
tcl/StaTcl.i
18
tcl/StaTcl.i
|
|
@ -3768,7 +3768,21 @@ update_generated_clks()
|
|||
}
|
||||
|
||||
bool
|
||||
pin_is_clock(const Pin *pin)
|
||||
is_clock(Pin *pin)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
return sta->isClock(pin);
|
||||
}
|
||||
|
||||
bool
|
||||
is_ideal_clock(Pin *pin)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
return sta->isIdealClock(pin);
|
||||
}
|
||||
|
||||
bool
|
||||
is_clock_search(const Pin *pin)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
Graph *graph = sta->graph();
|
||||
|
|
@ -3779,7 +3793,7 @@ pin_is_clock(const Pin *pin)
|
|||
}
|
||||
|
||||
bool
|
||||
pin_is_genclk_src(const Pin *pin)
|
||||
is_genclk_src(const Pin *pin)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
Graph *graph = sta->graph();
|
||||
|
|
|
|||
Loading…
Reference in New Issue