graph dcalc use ClkNetwork

This commit is contained in:
James Cherry 2020-08-09 22:33:32 -07:00
parent 0db8d142d8
commit b36d2753d1
9 changed files with 27 additions and 185 deletions

View File

@ -116,12 +116,6 @@ GraphDelayCalc::ceff(Edge *,
return 0.0; return 0.0;
} }
bool
GraphDelayCalc::isIdealClk(const Vertex *vertex)
{
return false;
}
void void
GraphDelayCalc::minPulseWidth(const Pin *pin, GraphDelayCalc::minPulseWidth(const Pin *pin,
const RiseFall *hi_low, const RiseFall *hi_low,

View File

@ -230,7 +230,6 @@ GraphDelayCalc1::~GraphDelayCalc1()
delete clk_pred_; delete clk_pred_;
delete iter_; delete iter_;
deleteMultiDrvrNets(); deleteMultiDrvrNets();
clearIdealClkMap();
delete observer_; delete observer_;
} }
@ -293,7 +292,6 @@ GraphDelayCalc1::delaysInvalid()
delays_seeded_ = false; delays_seeded_ = false;
incremental_ = false; incremental_ = false;
iter_->clear(); iter_->clear();
clearIdealClkMap();
// No need to keep track of incremental updates any more. // No need to keep track of incremental updates any more.
invalid_delays_.clear(); invalid_delays_.clear();
invalid_checks_.clear(); invalid_checks_.clear();
@ -360,7 +358,6 @@ public:
virtual ~FindVertexDelays(); virtual ~FindVertexDelays();
virtual void visit(Vertex *vertex); virtual void visit(Vertex *vertex);
virtual VertexVisitor *copy(); virtual VertexVisitor *copy();
virtual void levelFinished();
protected: protected:
GraphDelayCalc1 *graph_delay_calc1_; GraphDelayCalc1 *graph_delay_calc1_;
@ -398,24 +395,6 @@ FindVertexDelays::visit(Vertex *vertex)
graph_delay_calc1_->findVertexDelay(vertex, arc_delay_calc_, true); 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 // The logical structure of incremental delay calculation closely
// resembles the incremental search arrival time algorithm // resembles the incremental search arrival time algorithm
// (Search::findArrivals). // (Search::findArrivals).
@ -437,7 +416,6 @@ GraphDelayCalc1::findDelays(Level level)
if (incremental_) if (incremental_)
seedInvalidDelays(); seedInvalidDelays();
mergeIdealClks();
FindVertexDelays visitor(this, arc_delay_calc_, false); FindVertexDelays visitor(this, arc_delay_calc_, false);
dcalc_count += iter_->visitParallel(level, &visitor); dcalc_count += iter_->visitParallel(level, &visitor);
@ -578,7 +556,6 @@ GraphDelayCalc1::seedRootSlews()
while (root_iter.hasNext()) { while (root_iter.hasNext()) {
Vertex *vertex = root_iter.next(); Vertex *vertex = root_iter.next();
seedRootSlew(vertex, arc_delay_calc_); seedRootSlew(vertex, arc_delay_calc_);
findIdealClks(vertex);
} }
} }
@ -857,7 +834,6 @@ GraphDelayCalc1::findVertexDelay(Vertex *vertex,
bool propagate) bool propagate)
{ {
const Pin *pin = vertex->pin(); const Pin *pin = vertex->pin();
bool ideal_clks_changed = findIdealClks(vertex);
// Don't clobber root slews. // Don't clobber root slews.
if (!vertex->isRoot()) { if (!vertex->isRoot()) {
debugPrint2(debug_, "delay_calc", 2, "find delays %s (%s)\n", debugPrint2(debug_, "delay_calc", 2, "find delays %s (%s)\n",
@ -871,7 +847,7 @@ GraphDelayCalc1::findVertexDelay(Vertex *vertex,
enqueueTimingChecksEdges(vertex); enqueueTimingChecksEdges(vertex);
// Enqueue adjacent vertices even if the delays did not // Enqueue adjacent vertices even if the delays did not
// change when non-incremental to stride past annotations. // change when non-incremental to stride past annotations.
if (delay_changed || ideal_clks_changed || !incremental_) if (delay_changed || !incremental_)
iter_->enqueueAdjacentVertices(vertex); 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 float
GraphDelayCalc1::ceff(Edge *edge, GraphDelayCalc1::ceff(Edge *edge,
TimingArc *arc, TimingArc *arc,

View File

@ -142,7 +142,6 @@ protected:
ArcDelayCalc *arc_delay_calc, ArcDelayCalc *arc_delay_calc,
bool propagate); bool propagate);
void enqueueTimingChecksEdges(Vertex *vertex); void enqueueTimingChecksEdges(Vertex *vertex);
bool findIdealClks(Vertex *vertex);
bool findArcDelay(LibertyCell *drvr_cell, bool findArcDelay(LibertyCell *drvr_cell,
const Pin *drvr_pin, const Pin *drvr_pin,
Vertex *drvr_vertex, Vertex *drvr_vertex,
@ -195,11 +194,6 @@ protected:
const RiseFall *from_rf, const RiseFall *from_rf,
const DcalcAnalysisPt *dcalc_ap); const DcalcAnalysisPt *dcalc_ap);
bool bidirectDrvrSlewFromLoad(const Vertex *vertex) const; 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, Slew idealClkSlew(const Vertex *vertex,
const RiseFall *rf, const RiseFall *rf,
const MinMax *min_max); const MinMax *min_max);
@ -214,7 +208,6 @@ protected:
Parasitic *drvr_parasitic, Parasitic *drvr_parasitic,
const RiseFall *rf, const RiseFall *rf,
const DcalcAnalysisPt *dcalc_ap) const; const DcalcAnalysisPt *dcalc_ap) const;
void mergeIdealClks();
// Observer for edge delay changes. // Observer for edge delay changes.
DelayCalcObserver *observer_; DelayCalcObserver *observer_;
@ -235,9 +228,6 @@ protected:
// Percentage (0.0:1.0) change in delay that causes downstream // Percentage (0.0:1.0) change in delay that causes downstream
// delays to be recomputed during incremental delay calculation. // delays to be recomputed during incremental delay calculation.
float incremental_delay_tolerance_; 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 FindVertexDelays;
friend class MultiDrvrNet; friend class MultiDrvrNet;

View File

@ -100,7 +100,6 @@ 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);
// Precedence: // Precedence:
// SDF annotation // SDF annotation
// Liberty library // Liberty library

View File

@ -93,6 +93,8 @@ public:
Search *search() const { return search_; } Search *search() const { return search_; }
Latches *latches() { return latches_; } Latches *latches() { return latches_; }
Latches *latches() const { return latches_; } Latches *latches() const { return latches_; }
ClkNetwork *clkNetwork() { return clk_network_; }
ClkNetwork *clkNetwork() const { return clk_network_; }
unsigned threadCount() const { return thread_count_; } unsigned threadCount() const { return thread_count_; }
bool pocvEnabled() const { return pocv_enabled_; } bool pocvEnabled() const { return pocv_enabled_; }
float sigmaFactor() const { return sigma_factor_; } float sigmaFactor() const { return sigma_factor_; }

View File

@ -28,6 +28,7 @@
#include "PathVertex.hh" #include "PathVertex.hh"
#include "PortDirection.hh" #include "PortDirection.hh"
#include "Search.hh" #include "Search.hh"
#include "ClkNetwork.hh"
namespace sta { namespace sta {
@ -147,13 +148,14 @@ CheckSlewLimits::checkSlews1(Vertex *vertex,
float &limit, float &limit,
float &slack) const float &slack) const
{ {
const Pin *pin = vertex->pin();
if (!vertex->isDisabledConstraint() if (!vertex->isDisabledConstraint()
&& !vertex->isConstant() && !vertex->isConstant()
&& !sta_->graphDelayCalc()->isIdealClk(vertex)) { && !sta_->clkNetwork()->isIdealClock(pin)) {
for (auto rf1 : RiseFall::range()) { for (auto rf1 : RiseFall::range()) {
float limit1; float limit1;
bool limit1_exists; bool limit1_exists;
findLimit(vertex->pin(), vertex, rf1, min_max, check_clks, findLimit(pin, vertex, rf1, min_max, check_clks,
limit1, limit1_exists); limit1, limit1_exists);
if (limit1_exists) { if (limit1_exists) {
checkSlew(vertex, corner1, rf1, min_max, limit1, checkSlew(vertex, corner1, rf1, min_max, limit1,
@ -186,7 +188,7 @@ CheckSlewLimits::findLimit(const Pin *pin,
bool exists1; bool exists1;
if (check_clks) { if (check_clks) {
// Look for clock slew limits. // Look for clock slew limits.
bool is_clk = sta_->search()->isClock(vertex); bool is_clk = sta_->clkNetwork()->isIdealClock(pin);
ClockSet clks; ClockSet clks;
clockDomains(vertex, clks); clockDomains(vertex, clks);
ClockSet::Iterator clk_iter(clks); ClockSet::Iterator clk_iter(clks);

View File

@ -143,23 +143,13 @@ ClkNetwork::findClkPins(bool ideal_only,
bool bool
ClkNetwork::isClock(const Pin *pin) const ClkNetwork::isClock(const Pin *pin) const
{ {
ClockSet clks; return pin_clks_map_.hasKey(pin);
bool exists;
pin_clks_map_.findKey(pin, clks, exists);
if (exists && clks.empty())
printf("luse empty clks\n");
return exists;
} }
bool bool
ClkNetwork::isIdealClock(const Pin *pin) const ClkNetwork::isIdealClock(const Pin *pin) const
{ {
ClockSet clks; return pin_ideal_clks_map_.hasKey(pin);
bool exists;
pin_ideal_clks_map_.findKey(pin, clks, exists);
if (exists && clks.empty())
printf("luse empty clks\n");
return exists;
} }
const ClockSet * const ClockSet *

View File

@ -4865,6 +4865,7 @@ Sta::checkSlewLimitPreamble()
findDelays(); findDelays();
if (check_slew_limits_ == nullptr) if (check_slew_limits_ == nullptr)
makeCheckSlewLimits(); makeCheckSlewLimits();
ensureClkNetwork();
} }
Pin * Pin *

View File

@ -3768,7 +3768,21 @@ update_generated_clks()
} }
bool 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(); Sta *sta = Sta::sta();
Graph *graph = sta->graph(); Graph *graph = sta->graph();
@ -3779,7 +3793,7 @@ pin_is_clock(const Pin *pin)
} }
bool bool
pin_is_genclk_src(const Pin *pin) is_genclk_src(const Pin *pin)
{ {
Sta *sta = Sta::sta(); Sta *sta = Sta::sta();
Graph *graph = sta->graph(); Graph *graph = sta->graph();