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;
}
bool
GraphDelayCalc::isIdealClk(const Vertex *vertex)
{
return false;
}
void
GraphDelayCalc::minPulseWidth(const Pin *pin,
const RiseFall *hi_low,

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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_; }

View File

@ -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);

View File

@ -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 *

View File

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

View File

@ -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();