VertexSet use vertex id for comparison
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
783db41dfd
commit
61c0f9d73c
|
|
@ -214,6 +214,8 @@ GraphDelayCalc1::GraphDelayCalc1(StaState *sta) :
|
|||
observer_(nullptr),
|
||||
delays_seeded_(false),
|
||||
incremental_(false),
|
||||
delays_exist_(false),
|
||||
invalid_delays_(new VertexSet(graph_)),
|
||||
search_pred_(new SearchPred1(sta)),
|
||||
search_non_latch_pred_(new SearchPredNonLatch2(sta)),
|
||||
clk_pred_(new ClkTreeSearchPred(sta)),
|
||||
|
|
@ -226,6 +228,7 @@ GraphDelayCalc1::GraphDelayCalc1(StaState *sta) :
|
|||
GraphDelayCalc1::~GraphDelayCalc1()
|
||||
{
|
||||
delete search_pred_;
|
||||
delete invalid_delays_;
|
||||
delete search_non_latch_pred_;
|
||||
delete clk_pred_;
|
||||
delete iter_;
|
||||
|
|
@ -293,7 +296,7 @@ GraphDelayCalc1::delaysInvalid()
|
|||
incremental_ = false;
|
||||
iter_->clear();
|
||||
// No need to keep track of incremental updates any more.
|
||||
invalid_delays_.clear();
|
||||
invalid_delays_->clear();
|
||||
invalid_check_edges_.clear();
|
||||
invalid_latch_edges_.clear();
|
||||
}
|
||||
|
|
@ -326,11 +329,11 @@ GraphDelayCalc1::delayInvalid(Vertex *vertex)
|
|||
debugPrint(debug_, "delay_calc", 2, "delay invalid %s",
|
||||
vertex->name(sdc_network_));
|
||||
if (graph_ && incremental_) {
|
||||
invalid_delays_.insert(vertex);
|
||||
invalid_delays_->insert(vertex);
|
||||
// Invalidate driver that triggers dcalc for multi-driver nets.
|
||||
MultiDrvrNet *multi_drvr = multiDrvrNet(vertex);
|
||||
if (multi_drvr)
|
||||
invalid_delays_.insert(multi_drvr->dcalcDrvr());
|
||||
invalid_delays_->insert(multi_drvr->dcalcDrvr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +342,7 @@ GraphDelayCalc1::deleteVertexBefore(Vertex *vertex)
|
|||
{
|
||||
iter_->deleteVertexBefore(vertex);
|
||||
if (incremental_)
|
||||
invalid_delays_.erase(vertex);
|
||||
invalid_delays_->erase(vertex);
|
||||
MultiDrvrNet *multi_drvr = multiDrvrNet(vertex);
|
||||
if (multi_drvr) {
|
||||
multi_drvr->drvrs()->erase(vertex);
|
||||
|
|
@ -432,9 +435,7 @@ GraphDelayCalc1::findDelays(Level level)
|
|||
void
|
||||
GraphDelayCalc1::seedInvalidDelays()
|
||||
{
|
||||
VertexSet::Iterator vertex_iter(invalid_delays_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
for (Vertex *vertex : *invalid_delays_) {
|
||||
if (vertex->isRoot())
|
||||
seedRootSlew(vertex, arc_delay_calc_);
|
||||
else {
|
||||
|
|
@ -442,7 +443,7 @@ GraphDelayCalc1::seedInvalidDelays()
|
|||
iter_->enqueue(vertex);
|
||||
}
|
||||
}
|
||||
invalid_delays_.clear();
|
||||
invalid_delays_->clear();
|
||||
}
|
||||
|
||||
class FindNetDrvrs : public PinVisitor
|
||||
|
|
@ -508,7 +509,7 @@ void
|
|||
GraphDelayCalc1::makeMultiDrvrNet(PinSet &drvr_pins)
|
||||
{
|
||||
debugPrint(debug_, "delay_calc", 3, "multi-driver net");
|
||||
VertexSet *drvr_vertices = new VertexSet;
|
||||
VertexSet *drvr_vertices = new VertexSet(graph_);
|
||||
MultiDrvrNet *multi_drvr = new MultiDrvrNet(drvr_vertices);
|
||||
Level max_drvr_level = 0;
|
||||
Vertex *max_drvr = nullptr;
|
||||
|
|
@ -549,11 +550,8 @@ GraphDelayCalc1::multiDrvrNet(const Vertex *drvr_vertex) const
|
|||
void
|
||||
GraphDelayCalc1::seedRootSlews()
|
||||
{
|
||||
VertexSet::Iterator root_iter(levelize_->roots());
|
||||
while (root_iter.hasNext()) {
|
||||
Vertex *vertex = root_iter.next();
|
||||
for (Vertex *vertex : *levelize_->roots())
|
||||
seedRootSlew(vertex, arc_delay_calc_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -919,9 +917,7 @@ GraphDelayCalc1::findDriverDelays(Vertex *drvr_vertex,
|
|||
Vertex *dcalc_drvr = multi_drvr->dcalcDrvr();
|
||||
if (drvr_vertex == dcalc_drvr) {
|
||||
bool init_load_slews = true;
|
||||
VertexSet::Iterator drvr_iter(multi_drvr->drvrs());
|
||||
while (drvr_iter.hasNext()) {
|
||||
Vertex *drvr_vertex = drvr_iter.next();
|
||||
for (Vertex *drvr_vertex : *multi_drvr->drvrs()) {
|
||||
// Only init load slews once so previous driver dcalc results
|
||||
// aren't clobbered.
|
||||
delay_changed |= findDriverDelays1(drvr_vertex, init_load_slews,
|
||||
|
|
@ -1381,9 +1377,7 @@ GraphDelayCalc1::findMultiDrvrGateDelay(MultiDrvrNet *multi_drvr,
|
|||
{
|
||||
ArcDelay delay_sum = 1.0;
|
||||
Slew slew_sum = 1.0;
|
||||
VertexSet::Iterator drvr_iter(multi_drvr->drvrs());
|
||||
while (drvr_iter.hasNext()) {
|
||||
Vertex *drvr_vertex1 = drvr_iter.next();
|
||||
for (Vertex *drvr_vertex1 : *multi_drvr->drvrs()) {
|
||||
Pin *drvr_pin1 = drvr_vertex1->pin();
|
||||
Instance *drvr_inst1 = network_->instance(drvr_pin1);
|
||||
LibertyCell *drvr_cell1 = network_->libertyCell(drvr_inst1);
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ protected:
|
|||
bool incremental_;
|
||||
bool delays_exist_;
|
||||
// Vertices with invalid -to delays.
|
||||
VertexSet invalid_delays_;
|
||||
VertexSet *invalid_delays_;
|
||||
// Timing check edges with invalid delays.
|
||||
EdgeSet invalid_check_edges_;
|
||||
// Latch D->Q edges with invalid delays.
|
||||
|
|
|
|||
|
|
@ -48,14 +48,18 @@ Graph::Graph(StaState *sta,
|
|||
have_arc_delays_(have_arc_delays),
|
||||
ap_count_(ap_count),
|
||||
width_check_annotations_(nullptr),
|
||||
period_check_annotations_(nullptr)
|
||||
period_check_annotations_(nullptr),
|
||||
reg_clk_vertices_(new VertexSet(graph_))
|
||||
{
|
||||
// For the benifit of reg_clk_vertices_ that references graph_.
|
||||
graph_ = this;
|
||||
}
|
||||
|
||||
Graph::~Graph()
|
||||
{
|
||||
delete vertices_;
|
||||
delete edges_;
|
||||
delete reg_clk_vertices_;
|
||||
deleteSlewTables();
|
||||
deleteArcDelayTables();
|
||||
removeWidthCheckAnnotations();
|
||||
|
|
@ -396,7 +400,7 @@ Graph::makeVertex(Pin *pin,
|
|||
vertex->init(pin, is_bidirect_drvr, is_reg_clk);
|
||||
makeVertexSlews(vertex);
|
||||
if (is_reg_clk)
|
||||
reg_clk_vertices_.insert(vertex);
|
||||
reg_clk_vertices_->insert(vertex);
|
||||
return vertex;
|
||||
}
|
||||
|
||||
|
|
@ -432,7 +436,7 @@ void
|
|||
Graph::deleteVertex(Vertex *vertex)
|
||||
{
|
||||
if (vertex->isRegClk())
|
||||
reg_clk_vertices_.erase(vertex);
|
||||
reg_clk_vertices_->erase(vertex);
|
||||
Pin *pin = vertex->pin_;
|
||||
if (vertex->isBidirectDriver())
|
||||
pin_bidirect_drvr_vertex_map_.erase(pin_bidirect_drvr_vertex_map_
|
||||
|
|
@ -1599,4 +1603,23 @@ EdgesThruHierPinIterator::EdgesThruHierPinIterator(const Pin *hpin,
|
|||
edge_iter_.init(edges_);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
VertexIdLess::VertexIdLess(Graph *&graph) :
|
||||
graph_(graph)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
VertexIdLess::operator()(const Vertex *vertex1,
|
||||
const Vertex *vertex2) const
|
||||
{
|
||||
return graph_->id(vertex1) < graph_->id(vertex2);
|
||||
}
|
||||
|
||||
VertexSet::VertexSet(Graph *&graph) :
|
||||
Set<Vertex*, VertexIdLess>(VertexIdLess(graph))
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ public:
|
|||
float period);
|
||||
// Remove all delay and slew annotations.
|
||||
void removeDelaySlewAnnotations();
|
||||
VertexSet *regClkVertices() { return ®_clk_vertices_; }
|
||||
VertexSet *regClkVertices() { return reg_clk_vertices_; }
|
||||
|
||||
static const int vertex_level_bits = 24;
|
||||
static const int vertex_level_max = (1<<vertex_level_bits)-1;
|
||||
|
|
@ -261,7 +261,7 @@ protected:
|
|||
// Sdf period check annotations.
|
||||
PeriodCheckAnnotations *period_check_annotations_;
|
||||
// Register/latch clock vertices to search from.
|
||||
VertexSet reg_clk_vertices_;
|
||||
VertexSet *reg_clk_vertices_;
|
||||
|
||||
friend class Vertex;
|
||||
friend class VertexIterator;
|
||||
|
|
@ -526,4 +526,22 @@ private:
|
|||
EdgeSet::Iterator edge_iter_;
|
||||
};
|
||||
|
||||
class VertexIdLess
|
||||
{
|
||||
public:
|
||||
VertexIdLess(Graph *&graph);
|
||||
bool operator()(const Vertex *vertex1,
|
||||
const Vertex *vertex2) const;
|
||||
|
||||
private:
|
||||
Graph *&graph_;
|
||||
};
|
||||
|
||||
class VertexSet : public Set<Vertex*, VertexIdLess>
|
||||
{
|
||||
public:
|
||||
VertexSet(Graph *&graph);
|
||||
VertexSet(const VertexSet &set);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@ class VertexIterator;
|
|||
class VertexInEdgeIterator;
|
||||
class VertexOutEdgeIterator;
|
||||
class GraphLoop;
|
||||
class VertexSet;
|
||||
|
||||
typedef ObjectId VertexId;
|
||||
typedef ObjectId EdgeId;
|
||||
typedef ObjectId ArcId;
|
||||
typedef Set<Vertex*> VertexSet;
|
||||
typedef Vector<Vertex*> VertexSeq;
|
||||
typedef Vector<Edge*> EdgeSeq;
|
||||
typedef Set<Edge*> EdgeSet;
|
||||
|
|
|
|||
|
|
@ -548,15 +548,15 @@ protected:
|
|||
// Requireds have been seeded by searching arrivals to all endpoints.
|
||||
bool requireds_seeded_;
|
||||
// Vertices with invalid arrival times to update and search from.
|
||||
VertexSet invalid_arrivals_;
|
||||
VertexSet *invalid_arrivals_;
|
||||
std::mutex invalid_arrivals_lock_;
|
||||
BfsFwdIterator *arrival_iter_;
|
||||
// Vertices with invalid required times to update and search from.
|
||||
VertexSet invalid_requireds_;
|
||||
VertexSet *invalid_requireds_;
|
||||
BfsBkwdIterator *required_iter_;
|
||||
bool tns_exists_;
|
||||
// Endpoint vertices with slacks that have changed since tns was found.
|
||||
VertexSet invalid_tns_;
|
||||
VertexSet *invalid_tns_;
|
||||
// Indexed by path_ap->index().
|
||||
SlackSeq tns_;
|
||||
// Indexed by path_ap->index().
|
||||
|
|
@ -585,7 +585,7 @@ protected:
|
|||
TagGroupIndex tag_group_capacity_;
|
||||
std::mutex tag_group_lock_;
|
||||
// Latches data outputs to queue on the next search pass.
|
||||
VertexSet pending_latch_outputs_;
|
||||
VertexSet *pending_latch_outputs_;
|
||||
std::mutex pending_latch_outputs_lock_;
|
||||
VertexSet *endpoints_;
|
||||
VertexSet *invalid_endpoints_;
|
||||
|
|
|
|||
|
|
@ -984,6 +984,8 @@ public:
|
|||
Arrival vertexArrival(Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
const PathAnalysisPt *path_ap);
|
||||
Arrival vertexArrival(Vertex *vertex,
|
||||
const MinMax *min_max);
|
||||
Required vertexRequired(Vertex *vertex,
|
||||
const MinMax *min_max);
|
||||
Required vertexRequired(Vertex *vertex,
|
||||
|
|
|
|||
|
|
@ -153,9 +153,7 @@ CheckTiming::checkRegClks(bool reg_multiple_clks,
|
|||
bool reg_no_clks)
|
||||
{
|
||||
PinSet no_clk_pins, multiple_clk_pins;
|
||||
VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices());
|
||||
while (reg_clk_iter.hasNext()) {
|
||||
Vertex *vertex = reg_clk_iter.next();
|
||||
for (Vertex *vertex : *graph_->regClkVertices()) {
|
||||
Pin *pin = vertex->pin();
|
||||
ClockSet clks;
|
||||
search_->clocks(vertex, clks);
|
||||
|
|
@ -318,7 +316,7 @@ CheckTiming::checkGeneratedClocks()
|
|||
if (clk->isGenerated()) {
|
||||
search_->genclks()->checkMaster(clk);
|
||||
bool found_clk = false;
|
||||
VertexSet src_vertices;
|
||||
VertexSet src_vertices(graph_);
|
||||
clk->srcPinVertices(src_vertices, network_, graph_);
|
||||
VertexSet::Iterator vertex_iter(src_vertices);
|
||||
while (vertex_iter.hasNext()) {
|
||||
|
|
|
|||
|
|
@ -190,9 +190,7 @@ ClkSkews::findClkSkew(ClockSet *clks,
|
|||
const SetupHold *setup_hold,
|
||||
ClkSkewMap &skews)
|
||||
{
|
||||
VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices());
|
||||
while (reg_clk_iter.hasNext()) {
|
||||
Vertex *src_vertex = reg_clk_iter.next();
|
||||
for (Vertex *src_vertex : *graph_->regClkVertices()) {
|
||||
if (hasClkPaths(src_vertex, clks)) {
|
||||
VertexOutEdgeIterator edge_iter(src_vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
|
|
@ -343,7 +341,7 @@ ClkSkews::findFanout(Vertex *from)
|
|||
{
|
||||
debugPrint(debug_, "fanout", 1, "%s",
|
||||
from->name(sdc_network_));
|
||||
VertexSet endpoints;
|
||||
VertexSet endpoints(graph_);
|
||||
FanOutSrchPred pred(this);
|
||||
BfsFwdIterator fanout_iter(BfsIndex::other, &pred, this);
|
||||
fanout_iter.enqueue(from);
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ FindRegVisitor::visitRegs(ClockSet *clks,
|
|||
while (clk_iter.hasNext()) {
|
||||
Clock *clk = clk_iter.next();
|
||||
FindRegClkPred clk_pred(clk, this);
|
||||
VertexSet visited_vertices;
|
||||
VertexSet visited_vertices(graph_);
|
||||
for (Pin *pin : clk->leafPins()) {
|
||||
Vertex *vertex, *bidirect_drvr_vertex;
|
||||
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
||||
|
|
@ -158,9 +158,7 @@ FindRegVisitor::visitRegs(ClockSet *clks,
|
|||
}
|
||||
}
|
||||
else {
|
||||
VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices());
|
||||
while (reg_clk_iter.hasNext()) {
|
||||
Vertex *vertex = reg_clk_iter.next();
|
||||
for (Vertex *vertex : *graph_->regClkVertices()) {
|
||||
visitRegs(vertex->pin(), TimingSense::positive_unate,
|
||||
RiseFallBoth::riseFall(),
|
||||
edge_triggered, latches);
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ void
|
|||
Genclks::seedSrcPins(Clock *clk,
|
||||
BfsBkwdIterator &iter)
|
||||
{
|
||||
VertexSet src_vertices;
|
||||
VertexSet src_vertices(graph_);
|
||||
clk->srcPinVertices(src_vertices, network_, graph_);
|
||||
VertexSet::Iterator vertex_iter(src_vertices);
|
||||
while (vertex_iter.hasNext()) {
|
||||
|
|
@ -583,7 +583,7 @@ Genclks::makeGenclkInfo(Clock *gclk)
|
|||
{
|
||||
FilterPath *src_filter = makeSrcFilter(gclk);
|
||||
Level gclk_level = clkPinMaxLevel(gclk);
|
||||
VertexSet *fanins = new VertexSet;
|
||||
VertexSet *fanins = new VertexSet(graph_);
|
||||
findFanin(gclk, fanins);
|
||||
GenclkInfo *genclk_info = new GenclkInfo(gclk, gclk_level, fanins,
|
||||
src_filter);
|
||||
|
|
@ -643,8 +643,8 @@ Genclks::findLatchFdbkEdges(const Clock *gclk,
|
|||
EdgeSet *fdbk_edges = nullptr;
|
||||
for (Pin *pin : gclk->masterClk()->leafPins()) {
|
||||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||
VertexSet path_vertices;
|
||||
VertexSet visited_vertices;
|
||||
VertexSet path_vertices(graph_);
|
||||
VertexSet visited_vertices(graph_);
|
||||
SearchPred1 srch_pred(this);
|
||||
findLatchFdbkEdges(vertex, gclk_level, srch_pred, path_vertices,
|
||||
visited_vertices, fdbk_edges);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ Levelize::Levelize(StaState *sta) :
|
|||
levels_valid_(false),
|
||||
max_level_(0),
|
||||
level_space_(10),
|
||||
roots_(new VertexSet(graph_)),
|
||||
relevelize_from_(new VertexSet(graph_)),
|
||||
loops_(nullptr),
|
||||
observer_(nullptr)
|
||||
{
|
||||
|
|
@ -47,6 +49,8 @@ Levelize::Levelize(StaState *sta) :
|
|||
|
||||
Levelize::~Levelize()
|
||||
{
|
||||
delete roots_;
|
||||
delete relevelize_from_;
|
||||
delete search_pred_;
|
||||
delete observer_;
|
||||
deleteLoops();
|
||||
|
|
@ -70,8 +74,8 @@ Levelize::clear()
|
|||
{
|
||||
levelized_ = false;
|
||||
levels_valid_ = false;
|
||||
roots_.clear();
|
||||
relevelize_from_.clear();
|
||||
roots_->clear();
|
||||
relevelize_from_->clear();
|
||||
clearLoopEdges();
|
||||
deleteLoops();
|
||||
}
|
||||
|
|
@ -146,7 +150,7 @@ Levelize::findRoots()
|
|||
setLevel(vertex, 0);
|
||||
if (isRoot(vertex)) {
|
||||
debugPrint(debug_, "levelize", 2, "root %s", vertex->name(sdc_network_));
|
||||
roots_.insert(vertex);
|
||||
roots_->insert(vertex);
|
||||
if (hasFanout(vertex, search_pred_, graph_))
|
||||
// Color roots with no fanout black so that they are
|
||||
// not treated as degenerate loops by levelizeCycles().
|
||||
|
|
@ -183,11 +187,8 @@ Levelize::sortRoots(VertexSeq &roots)
|
|||
{
|
||||
// roots_ is a set so insert/delete are fast for incremental changes.
|
||||
// Copy the set into a vector for sorting.
|
||||
VertexSet::Iterator root_iter(roots_);
|
||||
while (root_iter.hasNext()) {
|
||||
Vertex *root = root_iter.next();
|
||||
for (Vertex *root : *roots_)
|
||||
roots.push_back(root);
|
||||
}
|
||||
sort(roots, VertexNameLess(network_));
|
||||
}
|
||||
|
||||
|
|
@ -362,7 +363,7 @@ Levelize::levelizeCycles()
|
|||
// root".
|
||||
if (vertex->color() == LevelColor::white) {
|
||||
EdgeSeq path;
|
||||
roots_.insert(vertex);
|
||||
roots_->insert(vertex);
|
||||
visit(vertex, 0, level_space_, path);
|
||||
}
|
||||
}
|
||||
|
|
@ -384,17 +385,17 @@ Levelize::invalidFrom(Vertex *vertex)
|
|||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
relevelize_from_.insert(from_vertex);
|
||||
relevelize_from_->insert(from_vertex);
|
||||
}
|
||||
relevelize_from_.insert(vertex);
|
||||
relevelize_from_->insert(vertex);
|
||||
levels_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Levelize::deleteVertexBefore(Vertex *vertex)
|
||||
{
|
||||
roots_.erase(vertex);
|
||||
relevelize_from_.erase(vertex);
|
||||
roots_->erase(vertex);
|
||||
relevelize_from_->erase(vertex);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -402,7 +403,7 @@ Levelize::relevelizeFrom(Vertex *vertex)
|
|||
{
|
||||
debugPrint(debug_, "levelize", 1, "invalid relevelize from %s",
|
||||
vertex->name(sdc_network_));
|
||||
relevelize_from_.insert(vertex);
|
||||
relevelize_from_->insert(vertex);
|
||||
levels_valid_ = false;
|
||||
}
|
||||
|
||||
|
|
@ -429,15 +430,13 @@ Levelize::deleteEdgeBefore(Edge *edge)
|
|||
void
|
||||
Levelize::relevelize()
|
||||
{
|
||||
VertexSet::Iterator vertex_iter(relevelize_from_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
for (Vertex *vertex : *relevelize_from_) {
|
||||
debugPrint(debug_, "levelize", 1, "relevelize from %s",
|
||||
vertex->name(sdc_network_));
|
||||
if (search_pred_->searchFrom(vertex)) {
|
||||
if (isRoot(vertex)) {
|
||||
setLevel(vertex, 0);
|
||||
roots_.insert(vertex);
|
||||
roots_->insert(vertex);
|
||||
}
|
||||
EdgeSeq path;
|
||||
visit(vertex, vertex->level(), 1, path);
|
||||
|
|
@ -445,7 +444,7 @@ Levelize::relevelize()
|
|||
}
|
||||
ensureLatchLevels();
|
||||
levels_valid_ = true;
|
||||
relevelize_from_.clear();
|
||||
relevelize_from_->clear();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public:
|
|||
void deleteEdgeBefore(Edge *edge);
|
||||
int maxLevel() const { return max_level_; }
|
||||
// Vertices with no fanin edges.
|
||||
VertexSet &roots() { return roots_; }
|
||||
VertexSet *roots() { return roots_; }
|
||||
bool isRoot(Vertex *vertex);
|
||||
// Reset to virgin state.
|
||||
void clear();
|
||||
|
|
@ -77,8 +77,8 @@ protected:
|
|||
bool levels_valid_;
|
||||
Level max_level_;
|
||||
Level level_space_;
|
||||
VertexSet roots_;
|
||||
VertexSet relevelize_from_;
|
||||
VertexSet *roots_;
|
||||
VertexSet *relevelize_from_;
|
||||
GraphLoopSeq *loops_;
|
||||
EdgeSet loop_edges_;
|
||||
EdgeSet disabled_loop_edges_;
|
||||
|
|
|
|||
|
|
@ -808,7 +808,7 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to,
|
|||
makeGroupPathEnds(search->endpoints(), corner, min_max, visitor);
|
||||
else {
|
||||
// Only visit -to filter pins.
|
||||
VertexSet endpoints;
|
||||
VertexSet endpoints(graph_);
|
||||
PinSet pins;
|
||||
to->allPins(network, &pins);
|
||||
PinSet::Iterator pin_iter(pins);
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ Power::ensureActivities()
|
|||
void
|
||||
Power::seedActivities(BfsFwdIterator &bfs)
|
||||
{
|
||||
for (Vertex *vertex : levelize_->roots()) {
|
||||
for (Vertex *vertex : *levelize_->roots()) {
|
||||
const Pin *pin = vertex->pin();
|
||||
// Clock activities are baked in.
|
||||
if (!sdc_->isLeafPinClock(pin)
|
||||
|
|
|
|||
|
|
@ -225,6 +225,9 @@ Search::init(StaState *sta)
|
|||
arrivals_seeded_ = false;
|
||||
requireds_exist_ = false;
|
||||
requireds_seeded_ = false;
|
||||
invalid_arrivals_ = new VertexSet(graph_);
|
||||
invalid_requireds_ = new VertexSet(graph_);
|
||||
invalid_tns_ = new VertexSet(graph_);
|
||||
tns_exists_ = false;
|
||||
worst_slacks_ = nullptr;
|
||||
arrival_iter_ = new BfsFwdIterator(BfsIndex::arrival, nullptr, sta);
|
||||
|
|
@ -238,6 +241,7 @@ Search::init(StaState *sta)
|
|||
tag_groups_ = new TagGroup*[tag_group_capacity_];
|
||||
tag_group_next_ = 0;
|
||||
tag_group_set_ = new TagGroupSet(tag_group_capacity_);
|
||||
pending_latch_outputs_ = new VertexSet(graph_);
|
||||
visit_path_ends_ = new VisitPathEnds(this);
|
||||
gated_clk_ = new GatedClk(this);
|
||||
path_groups_ = nullptr;
|
||||
|
|
@ -273,7 +277,11 @@ Search::~Search()
|
|||
delete arrival_iter_;
|
||||
delete required_iter_;
|
||||
delete endpoints_;
|
||||
delete invalid_arrivals_;
|
||||
delete invalid_requireds_;
|
||||
delete invalid_tns_;
|
||||
delete invalid_endpoints_;
|
||||
delete pending_latch_outputs_;
|
||||
delete visit_path_ends_;
|
||||
delete gated_clk_;
|
||||
delete worst_slacks_;
|
||||
|
|
@ -295,10 +303,10 @@ Search::clear()
|
|||
requireds_seeded_ = false;
|
||||
tns_exists_ = false;
|
||||
clearWorstSlack();
|
||||
invalid_arrivals_.clear();
|
||||
invalid_arrivals_->clear();
|
||||
arrival_iter_->clear();
|
||||
invalid_requireds_.clear();
|
||||
invalid_tns_.clear();
|
||||
invalid_requireds_->clear();
|
||||
invalid_tns_->clear();
|
||||
required_iter_->clear();
|
||||
endpointsInvalid();
|
||||
deletePathGroups();
|
||||
|
|
@ -633,12 +641,12 @@ Search::deleteVertexBefore(Vertex *vertex)
|
|||
if (arrivals_exist_) {
|
||||
deletePaths(vertex);
|
||||
arrival_iter_->deleteVertexBefore(vertex);
|
||||
invalid_arrivals_.erase(vertex);
|
||||
invalid_arrivals_->erase(vertex);
|
||||
}
|
||||
if (requireds_exist_) {
|
||||
required_iter_->deleteVertexBefore(vertex);
|
||||
invalid_requireds_.erase(vertex);
|
||||
invalid_tns_.erase(vertex);
|
||||
invalid_requireds_->erase(vertex);
|
||||
invalid_tns_->erase(vertex);
|
||||
}
|
||||
if (endpoints_)
|
||||
endpoints_->erase(vertex);
|
||||
|
|
@ -650,7 +658,7 @@ bool
|
|||
Search::arrivalsValid()
|
||||
{
|
||||
return arrivals_exist_
|
||||
&& invalid_requireds_.empty();
|
||||
&& invalid_requireds_->empty();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -673,11 +681,11 @@ Search::arrivalsInvalid()
|
|||
arrival_iter_->clear();
|
||||
required_iter_->clear();
|
||||
// No need to keep track of incremental updates any more.
|
||||
invalid_arrivals_.clear();
|
||||
invalid_requireds_.clear();
|
||||
invalid_arrivals_->clear();
|
||||
invalid_requireds_->clear();
|
||||
tns_exists_ = false;
|
||||
clearWorstSlack();
|
||||
invalid_tns_.clear();
|
||||
invalid_tns_->clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -687,10 +695,10 @@ Search::requiredsInvalid()
|
|||
debugPrint(debug_, "search", 1, "requireds invalid");
|
||||
requireds_exist_ = false;
|
||||
requireds_seeded_ = false;
|
||||
invalid_requireds_.clear();
|
||||
invalid_requireds_->clear();
|
||||
tns_exists_ = false;
|
||||
clearWorstSlack();
|
||||
invalid_tns_.clear();
|
||||
invalid_tns_->clear();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -702,7 +710,7 @@ Search::arrivalInvalid(Vertex *vertex)
|
|||
if (!arrival_iter_->inQueue(vertex)) {
|
||||
// Lock for StaDelayCalcObserver called by delay calc threads.
|
||||
UniqueLock lock(invalid_arrivals_lock_);
|
||||
invalid_arrivals_.insert(vertex);
|
||||
invalid_arrivals_->insert(vertex);
|
||||
}
|
||||
tnsInvalid(vertex);
|
||||
}
|
||||
|
|
@ -772,7 +780,7 @@ Search::requiredInvalid(Vertex *vertex)
|
|||
if (!required_iter_->inQueue(vertex)) {
|
||||
// Lock for StaDelayCalcObserver called by delay calc threads.
|
||||
UniqueLock lock(invalid_arrivals_lock_);
|
||||
invalid_requireds_.insert(vertex);
|
||||
invalid_requireds_->insert(vertex);
|
||||
}
|
||||
tnsInvalid(vertex);
|
||||
}
|
||||
|
|
@ -926,19 +934,19 @@ Search::findAllArrivals(VertexVisitor *arrival_visitor)
|
|||
bool
|
||||
Search::havePendingLatchOutputs()
|
||||
{
|
||||
return pending_latch_outputs_.size() > 0;
|
||||
return !pending_latch_outputs_->empty();
|
||||
}
|
||||
|
||||
void
|
||||
Search::clearPendingLatchOutputs()
|
||||
{
|
||||
pending_latch_outputs_.clear();
|
||||
pending_latch_outputs_->clear();
|
||||
}
|
||||
|
||||
void
|
||||
Search::enqueuePendingLatchOutputs()
|
||||
{
|
||||
for (Vertex *latch_vertex : pending_latch_outputs_)
|
||||
for (Vertex *latch_vertex : *pending_latch_outputs_)
|
||||
arrival_iter_->enqueue(latch_vertex);
|
||||
clearPendingLatchOutputs();
|
||||
}
|
||||
|
|
@ -966,7 +974,7 @@ Search::findArrivals(Level level,
|
|||
int arrival_count = arrival_iter_->visitParallel(level, arrival_visitor);
|
||||
stats.report("Find arrivals");
|
||||
if (arrival_iter_->empty()
|
||||
&& invalid_arrivals_.empty()) {
|
||||
&& invalid_arrivals_->empty()) {
|
||||
clk_arrivals_valid_ = true;
|
||||
arrivals_at_endpoints_exist_ = true;
|
||||
}
|
||||
|
|
@ -1360,7 +1368,7 @@ Search::enqueueLatchDataOutputs(Vertex *vertex)
|
|||
if (latches_->isLatchDtoQ(out_edge)) {
|
||||
Vertex *out_vertex = out_edge->to(graph_);
|
||||
UniqueLock lock(pending_latch_outputs_lock_);
|
||||
pending_latch_outputs_.insert(out_vertex);
|
||||
pending_latch_outputs_->insert(out_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1368,7 +1376,7 @@ Search::enqueueLatchDataOutputs(Vertex *vertex)
|
|||
void
|
||||
Search::seedArrivals()
|
||||
{
|
||||
VertexSet vertices;
|
||||
VertexSet vertices(graph_);
|
||||
findClockVertices(vertices);
|
||||
findRootVertices(vertices);
|
||||
findInputDrvrVertices(vertices);
|
||||
|
|
@ -1394,9 +1402,9 @@ Search::findClockVertices(VertexSet &vertices)
|
|||
void
|
||||
Search::seedInvalidArrivals()
|
||||
{
|
||||
for (Vertex *vertex : invalid_arrivals_)
|
||||
for (Vertex *vertex : *invalid_arrivals_)
|
||||
seedArrival(vertex);
|
||||
invalid_arrivals_.clear();
|
||||
invalid_arrivals_->clear();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1605,7 +1613,7 @@ Search::makeUnclkedPaths(Vertex *vertex,
|
|||
void
|
||||
Search::findRootVertices(VertexSet &vertices)
|
||||
{
|
||||
for (Vertex *vertex : levelize_->roots()) {
|
||||
for (Vertex *vertex : *levelize_->roots()) {
|
||||
const Pin *pin = vertex->pin();
|
||||
if (!sdc_->isLeafPinClock(pin)
|
||||
&& !sdc_->hasInputDelay(pin)
|
||||
|
|
@ -3103,8 +3111,8 @@ VertexSet *
|
|||
Search::endpoints()
|
||||
{
|
||||
if (endpoints_ == nullptr) {
|
||||
endpoints_ = new VertexSet;
|
||||
invalid_endpoints_ = new VertexSet;
|
||||
endpoints_ = new VertexSet(graph_);
|
||||
invalid_endpoints_ = new VertexSet(graph_);
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
|
|
@ -3193,9 +3201,9 @@ Search::endpointsInvalid()
|
|||
void
|
||||
Search::seedInvalidRequireds()
|
||||
{
|
||||
for (Vertex *vertex : invalid_requireds_)
|
||||
for (Vertex *vertex : *invalid_requireds_)
|
||||
required_iter_->enqueue(vertex);
|
||||
invalid_requireds_.clear();
|
||||
invalid_requireds_->clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3687,7 +3695,7 @@ Search::tnsInvalid(Vertex *vertex)
|
|||
debugPrint(debug_, "tns", 2, "tns invalid %s",
|
||||
vertex->name(sdc_network_));
|
||||
UniqueLock lock(tns_lock_);
|
||||
invalid_tns_.insert(vertex);
|
||||
invalid_tns_->insert(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3695,7 +3703,7 @@ void
|
|||
Search::updateInvalidTns()
|
||||
{
|
||||
PathAPIndex path_ap_count = corners_->pathAnalysisPtCount();
|
||||
for (Vertex *vertex : invalid_tns_) {
|
||||
for (Vertex *vertex : *invalid_tns_) {
|
||||
// Network edits can change endpointedness since tnsInvalid was called.
|
||||
if (isEndpoint(vertex)) {
|
||||
debugPrint(debug_, "tns", 2, "update tns %s",
|
||||
|
|
@ -3709,7 +3717,7 @@ Search::updateInvalidTns()
|
|||
worst_slacks_->updateWorstSlacks(vertex, slacks);
|
||||
}
|
||||
}
|
||||
invalid_tns_.clear();
|
||||
invalid_tns_->clear();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3826,7 +3834,7 @@ Search::wnsTnsPreamble()
|
|||
findAllArrivals();
|
||||
// Required times are only needed at endpoints.
|
||||
if (requireds_seeded_) {
|
||||
for (Vertex *vertex : invalid_requireds_) {
|
||||
for (Vertex *vertex : *invalid_requireds_) {
|
||||
debugPrint(debug_, "search", 2, "tns update required %s",
|
||||
vertex->name(sdc_network_));
|
||||
if (isEndpoint(vertex)) {
|
||||
|
|
@ -3839,7 +3847,7 @@ Search::wnsTnsPreamble()
|
|||
required_iter_->enqueue(vertex);
|
||||
}
|
||||
}
|
||||
invalid_requireds_.clear();
|
||||
invalid_requireds_->clear();
|
||||
}
|
||||
else
|
||||
seedRequireds();
|
||||
|
|
|
|||
|
|
@ -2792,6 +2792,26 @@ Sta::vertexWorstSlackPath(Vertex *vertex,
|
|||
return vertexWorstSlackPath(vertex, nullptr, min_max);
|
||||
}
|
||||
|
||||
Arrival
|
||||
Sta::vertexArrival(Vertex *vertex,
|
||||
const MinMax *min_max)
|
||||
{
|
||||
searchPreamble();
|
||||
search_->findArrivals(vertex->level());
|
||||
Arrival arrival = min_max->initValue();
|
||||
VertexPathIterator path_iter(vertex, this);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
const Arrival &path_arrival = path->arrival(this);
|
||||
ClkInfo *clk_info = path->clkInfo(search_);
|
||||
if (path->minMax(this) == min_max
|
||||
&& !clk_info->isGenClkSrcPath()
|
||||
&& delayGreater(path->arrival(this), arrival, min_max, this))
|
||||
arrival = path_arrival;
|
||||
}
|
||||
return arrival;
|
||||
}
|
||||
|
||||
Arrival
|
||||
Sta::vertexArrival(Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
|
|
@ -4813,7 +4833,7 @@ Sta::findFaninPins(Vertex *vertex,
|
|||
PinSet *fanin,
|
||||
SearchPred &pred)
|
||||
{
|
||||
VertexSet visited;
|
||||
VertexSet visited(graph_);
|
||||
findFaninPins(vertex, flat, inst_levels,
|
||||
pin_levels, visited, &pred, 0, 0);
|
||||
VertexSet::Iterator visited_iter(visited);
|
||||
|
|
@ -4923,7 +4943,7 @@ Sta::findFanoutPins(Vertex *vertex,
|
|||
PinSet *fanout,
|
||||
SearchPred &pred)
|
||||
{
|
||||
VertexSet visited;
|
||||
VertexSet visited(graph_);
|
||||
findFanoutPins(vertex, flat, inst_levels,
|
||||
pin_levels, visited, &pred, 0, 0);
|
||||
VertexSet::Iterator visited_iter(visited);
|
||||
|
|
|
|||
|
|
@ -118,11 +118,8 @@ visitPathGroupVertices(PathGroup *path_group,
|
|||
VisitPathGroupEnds end_visitor(path_group, visitor, &matching_path_map,
|
||||
&bkwd_iter, sta);
|
||||
VisitPathEnds visit_path_ends(sta);
|
||||
VertexSet::Iterator end_iter(search->endpoints());
|
||||
while (end_iter.hasNext()) {
|
||||
Vertex *vertex = end_iter.next();
|
||||
for(Vertex *vertex : *search->endpoints())
|
||||
visit_path_ends.visitPathEnds(vertex, &end_visitor);
|
||||
}
|
||||
|
||||
// Search backward from the path ends thru vertices that have arrival tags
|
||||
// that match path_group end paths.
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ namespace sta {
|
|||
using std::min;
|
||||
|
||||
WorstSlacks::WorstSlacks(StaState *sta) :
|
||||
worst_slacks_(sta->corners()->pathAnalysisPtCount(), sta),
|
||||
sta_(sta)
|
||||
{
|
||||
worst_slacks_.resize(sta->corners()->pathAnalysisPtCount());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -46,7 +46,7 @@ WorstSlacks::worstSlack(const MinMax *min_max,
|
|||
PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index();
|
||||
Slack worst_slack1;
|
||||
Vertex *worst_vertex1;
|
||||
worst_slacks_[path_ap_index].worstSlack(path_ap_index, sta_,
|
||||
worst_slacks_[path_ap_index].worstSlack(path_ap_index,
|
||||
worst_slack1, worst_vertex1);
|
||||
if (delayLess(worst_slack1, worst_slack, sta_)) {
|
||||
worst_slack = worst_slack1;
|
||||
|
|
@ -63,7 +63,7 @@ WorstSlacks::worstSlack(const Corner *corner,
|
|||
Vertex *&worst_vertex)
|
||||
{
|
||||
PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index();
|
||||
worst_slacks_[path_ap_index].worstSlack(path_ap_index, sta_,
|
||||
worst_slacks_[path_ap_index].worstSlack(path_ap_index,
|
||||
worst_slack, worst_vertex);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ WorstSlacks::updateWorstSlacks(Vertex *vertex,
|
|||
{
|
||||
PathAPIndex path_ap_count = sta_->corners()->pathAnalysisPtCount();
|
||||
for (PathAPIndex i = 0; i < path_ap_count; i++)
|
||||
worst_slacks_[i].updateWorstSlack(vertex, slacks, i, sta_);
|
||||
worst_slacks_[i].updateWorstSlack(vertex, slacks, i);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -88,21 +88,30 @@ WorstSlacks::worstSlackNotifyBefore(Vertex *vertex)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
WorstSlack::WorstSlack() :
|
||||
WorstSlack::WorstSlack(StaState *sta) :
|
||||
StaState(sta),
|
||||
slack_init_(MinMax::min()->initValue()),
|
||||
worst_vertex_(nullptr),
|
||||
worst_slack_(slack_init_),
|
||||
slack_threshold_(slack_init_),
|
||||
queue_(new VertexSet(graph_)),
|
||||
min_queue_size_(10),
|
||||
max_queue_size_(20)
|
||||
{
|
||||
}
|
||||
|
||||
WorstSlack::WorstSlack(const WorstSlack &) :
|
||||
WorstSlack::~WorstSlack()
|
||||
{
|
||||
delete queue_;
|
||||
}
|
||||
|
||||
WorstSlack::WorstSlack(const WorstSlack &worst_slack) :
|
||||
StaState(worst_slack),
|
||||
slack_init_(MinMax::min()->initValue()),
|
||||
worst_vertex_(nullptr),
|
||||
worst_slack_(slack_init_),
|
||||
slack_threshold_(slack_init_),
|
||||
queue_(new VertexSet(graph_)),
|
||||
min_queue_size_(10),
|
||||
max_queue_size_(20)
|
||||
{
|
||||
|
|
@ -116,214 +125,181 @@ WorstSlack::deleteVertexBefore(Vertex *vertex)
|
|||
worst_vertex_ = nullptr;
|
||||
worst_slack_ = slack_init_;
|
||||
}
|
||||
queue_.erase(vertex);
|
||||
queue_->erase(vertex);
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::worstSlack(PathAPIndex path_ap_index,
|
||||
const StaState *sta,
|
||||
// Return values.
|
||||
Slack &worst_slack,
|
||||
Vertex *&worst_vertex)
|
||||
{
|
||||
findWorstSlack(path_ap_index, sta);
|
||||
findWorstSlack(path_ap_index);
|
||||
worst_slack = worst_slack_;
|
||||
worst_vertex = worst_vertex_;
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::findWorstSlack(PathAPIndex path_ap_index,
|
||||
const StaState *sta)
|
||||
WorstSlack::findWorstSlack(PathAPIndex path_ap_index)
|
||||
{
|
||||
if (worst_vertex_ == nullptr) {
|
||||
if (queue_.empty())
|
||||
initQueue(path_ap_index, sta);
|
||||
if (queue_->empty())
|
||||
initQueue(path_ap_index);
|
||||
else
|
||||
findWorstInQueue(path_ap_index, sta);
|
||||
findWorstInQueue(path_ap_index);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::initQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta)
|
||||
WorstSlack::initQueue(PathAPIndex path_ap_index)
|
||||
{
|
||||
Search *search = sta->search();
|
||||
const Debug *debug = sta->debug();
|
||||
debugPrint(debug, "wns", 3, "init queue");
|
||||
debugPrint(debug_, "wns", 3, "init queue");
|
||||
|
||||
queue_.clear();
|
||||
queue_->clear();
|
||||
worst_vertex_ = nullptr;
|
||||
worst_slack_ = slack_init_;
|
||||
slack_threshold_ = slack_init_;
|
||||
VertexSet::Iterator end_iter(search->endpoints());
|
||||
while (end_iter.hasNext()) {
|
||||
Vertex *vertex = end_iter.next();
|
||||
Slack slack = search->wnsSlack(vertex, path_ap_index);
|
||||
for(Vertex *vertex : *search_->endpoints()) {
|
||||
Slack slack = search_->wnsSlack(vertex, path_ap_index);
|
||||
if (!delayEqual(slack, slack_init_)) {
|
||||
if (delayLess(slack, worst_slack_, sta))
|
||||
setWorstSlack(vertex, slack, sta);
|
||||
if (delayLessEqual(slack, slack_threshold_, sta))
|
||||
queue_.insert(vertex);
|
||||
int queue_size = queue_.size();
|
||||
if (delayLess(slack, worst_slack_, this))
|
||||
setWorstSlack(vertex, slack);
|
||||
if (delayLessEqual(slack, slack_threshold_, this))
|
||||
queue_->insert(vertex);
|
||||
int queue_size = queue_->size();
|
||||
if (queue_size >= max_queue_size_)
|
||||
sortQueue(path_ap_index, sta);
|
||||
sortQueue(path_ap_index);
|
||||
}
|
||||
}
|
||||
debugPrint(debug, "wns", 3, "threshold %s",
|
||||
delayAsString(slack_threshold_, sta));
|
||||
debugPrint(debug_, "wns", 3, "threshold %s",
|
||||
delayAsString(slack_threshold_, this));
|
||||
// checkQueue();
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::sortQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta)
|
||||
WorstSlack::sortQueue(PathAPIndex path_ap_index)
|
||||
{
|
||||
if (queue_.size() > 0) {
|
||||
Search *search = sta->search();
|
||||
const Debug *debug = sta->debug();
|
||||
debugPrint(debug, "wns", 3, "sort queue");
|
||||
if (queue_->size() > 0) {
|
||||
debugPrint(debug_, "wns", 3, "sort queue");
|
||||
|
||||
VertexSeq vertices;
|
||||
vertices.reserve(queue_.size());
|
||||
VertexSet::Iterator queue_iter(queue_);
|
||||
while (queue_iter.hasNext()) {
|
||||
Vertex *vertex = queue_iter.next();
|
||||
vertices.reserve(queue_->size());
|
||||
for (Vertex *vertex : *queue_)
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
WnsSlackLess slack_less(path_ap_index, sta);
|
||||
WnsSlackLess slack_less(path_ap_index, this);
|
||||
sort(vertices, slack_less);
|
||||
|
||||
int vertex_count = vertices.size();
|
||||
int threshold_index = min(min_queue_size_, vertex_count - 1);
|
||||
Vertex *threshold_vertex = vertices[threshold_index];
|
||||
slack_threshold_ = search->wnsSlack(threshold_vertex, path_ap_index);
|
||||
debugPrint(debug, "wns", 3, "threshold %s",
|
||||
delayAsString(slack_threshold_, sta));
|
||||
slack_threshold_ = search_->wnsSlack(threshold_vertex, path_ap_index);
|
||||
debugPrint(debug_, "wns", 3, "threshold %s",
|
||||
delayAsString(slack_threshold_, this));
|
||||
|
||||
// Reinsert vertices with slack < threshold.
|
||||
queue_.clear();
|
||||
queue_->clear();
|
||||
VertexSeq::Iterator queue_iter2(vertices);
|
||||
while (queue_iter2.hasNext()) {
|
||||
Vertex *vertex = queue_iter2.next();
|
||||
Slack slack = search->wnsSlack(vertex, path_ap_index);
|
||||
if (delayGreater(slack, slack_threshold_, sta))
|
||||
Slack slack = search_->wnsSlack(vertex, path_ap_index);
|
||||
if (delayGreater(slack, slack_threshold_, this))
|
||||
break;
|
||||
queue_.insert(vertex);
|
||||
queue_->insert(vertex);
|
||||
}
|
||||
max_queue_size_ = queue_.size() * 2;
|
||||
max_queue_size_ = queue_->size() * 2;
|
||||
Vertex *worst_slack_vertex = vertices[0];
|
||||
Slack worst_slack_slack = search->wnsSlack(worst_slack_vertex, path_ap_index);
|
||||
setWorstSlack(worst_slack_vertex, worst_slack_slack, sta);
|
||||
Slack worst_slack_slack = search_->wnsSlack(worst_slack_vertex, path_ap_index);
|
||||
setWorstSlack(worst_slack_vertex, worst_slack_slack);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::findWorstInQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta)
|
||||
WorstSlack::findWorstInQueue(PathAPIndex path_ap_index)
|
||||
{
|
||||
Search *search = sta->search();
|
||||
const Debug *debug = sta->debug();
|
||||
debugPrint(debug, "wns", 3, "find worst in queue");
|
||||
debugPrint(debug_, "wns", 3, "find worst in queue");
|
||||
|
||||
worst_vertex_ = nullptr;
|
||||
worst_slack_ = slack_init_;
|
||||
VertexSet::Iterator queue_iter(queue_);
|
||||
while (queue_iter.hasNext()) {
|
||||
Vertex *vertex = queue_iter.next();
|
||||
Slack slack = search->wnsSlack(vertex, path_ap_index);
|
||||
if (delayLess(slack, worst_slack_, sta))
|
||||
setWorstSlack(vertex, slack, sta);
|
||||
for (Vertex *vertex : *queue_) {
|
||||
Slack slack = search_->wnsSlack(vertex, path_ap_index);
|
||||
if (delayLess(slack, worst_slack_, this))
|
||||
setWorstSlack(vertex, slack);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::checkQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta)
|
||||
WorstSlack::checkQueue(PathAPIndex path_ap_index)
|
||||
{
|
||||
Search *search = sta->search();
|
||||
Report *report = sta->report();
|
||||
const Network *network = sta->network();
|
||||
|
||||
VertexSeq ends;
|
||||
VertexSet::Iterator end_iter(search->endpoints());
|
||||
while (end_iter.hasNext()) {
|
||||
Vertex *end = end_iter.next();
|
||||
if (delayLessEqual(search->wnsSlack(end, path_ap_index),
|
||||
slack_threshold_, sta))
|
||||
for(Vertex *end : *search_->endpoints()) {
|
||||
if (delayLessEqual(search_->wnsSlack(end, path_ap_index),
|
||||
slack_threshold_, this))
|
||||
ends.push_back(end);
|
||||
}
|
||||
WnsSlackLess slack_less(path_ap_index, sta);
|
||||
WnsSlackLess slack_less(path_ap_index, this);
|
||||
sort(ends, slack_less);
|
||||
|
||||
VertexSet end_set;
|
||||
VertexSeq::Iterator end_iter2(ends);
|
||||
while (end_iter2.hasNext()) {
|
||||
Vertex *end = end_iter2.next();
|
||||
VertexSet end_set(graph_);
|
||||
for (Vertex *end : ends) {
|
||||
end_set.insert(end);
|
||||
if (!queue_.hasKey(end)
|
||||
&& delayLessEqual(search->wnsSlack(end, path_ap_index),
|
||||
slack_threshold_, sta))
|
||||
report->reportLine("WorstSlack queue missing %s %s < %s",
|
||||
end->name(network),
|
||||
delayAsString(search->wnsSlack(end, path_ap_index), sta),
|
||||
delayAsString(slack_threshold_, sta));
|
||||
if (!queue_->hasKey(end)
|
||||
&& delayLessEqual(search_->wnsSlack(end, path_ap_index),
|
||||
slack_threshold_, this))
|
||||
report_->reportLine("WorstSlack queue missing %s %s < %s",
|
||||
end->name(network_),
|
||||
delayAsString(search_->wnsSlack(end, path_ap_index), this),
|
||||
delayAsString(slack_threshold_, this));
|
||||
}
|
||||
|
||||
VertexSet::Iterator queue_iter(queue_);
|
||||
while (queue_iter.hasNext()) {
|
||||
Vertex *end = queue_iter.next();
|
||||
for (Vertex *end : *queue_) {
|
||||
if (!end_set.hasKey(end))
|
||||
report->reportLine("WorstSlack queue extra %s %s > %s",
|
||||
end->name(network),
|
||||
delayAsString(search->wnsSlack(end, path_ap_index), sta),
|
||||
delayAsString(slack_threshold_, sta));
|
||||
report_->reportLine("WorstSlack queue extra %s %s > %s",
|
||||
end->name(network_),
|
||||
delayAsString(search_->wnsSlack(end, path_ap_index), this),
|
||||
delayAsString(slack_threshold_, this));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::updateWorstSlack(Vertex *vertex,
|
||||
SlackSeq &slacks,
|
||||
PathAPIndex path_ap_index,
|
||||
const StaState *sta)
|
||||
PathAPIndex path_ap_index)
|
||||
{
|
||||
const Debug *debug = sta->debug();
|
||||
const Network *network = sta->network();
|
||||
Slack slack = slacks[path_ap_index];
|
||||
|
||||
// Locking is required because ArrivalVisitor is called by multiple
|
||||
// threads.
|
||||
UniqueLock lock(lock_);
|
||||
if (worst_vertex_
|
||||
&& delayLess(slack, worst_slack_, sta))
|
||||
setWorstSlack(vertex, slack, sta);
|
||||
&& delayLess(slack, worst_slack_, this))
|
||||
setWorstSlack(vertex, slack);
|
||||
else if (vertex == worst_vertex_)
|
||||
// Mark worst slack as unknown (updated by findWorstSlack().
|
||||
worst_vertex_ = nullptr;
|
||||
|
||||
if (!delayEqual(slack, slack_init_)
|
||||
&& delayLessEqual(slack, slack_threshold_, sta)) {
|
||||
debugPrint(debug, "wns", 3, "insert %s %s",
|
||||
vertex->name(network),
|
||||
delayAsString(slack, sta));
|
||||
queue_.insert(vertex);
|
||||
&& delayLessEqual(slack, slack_threshold_, this)) {
|
||||
debugPrint(debug_, "wns", 3, "insert %s %s",
|
||||
vertex->name(network_),
|
||||
delayAsString(slack, this));
|
||||
queue_->insert(vertex);
|
||||
}
|
||||
else {
|
||||
debugPrint(debug, "wns", 3, "delete %s %s",
|
||||
vertex->name(network),
|
||||
delayAsString(slack, sta));
|
||||
queue_.erase(vertex);
|
||||
debugPrint(debug_, "wns", 3, "delete %s %s",
|
||||
vertex->name(network_),
|
||||
delayAsString(slack, this));
|
||||
queue_->erase(vertex);
|
||||
}
|
||||
// checkQueue();
|
||||
}
|
||||
|
||||
void
|
||||
WorstSlack::setWorstSlack(Vertex *vertex,
|
||||
Slack slack,
|
||||
const StaState *sta)
|
||||
Slack slack)
|
||||
{
|
||||
debugPrint(sta->debug(), "wns", 3, "%s %s",
|
||||
vertex->name(sta->network()),
|
||||
delayAsString(slack, sta));
|
||||
debugPrint(debug_, "wns", 3, "%s %s",
|
||||
vertex->name(network_),
|
||||
delayAsString(slack, this));
|
||||
worst_vertex_ = vertex;
|
||||
worst_slack_ = slack;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "Vector.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "SearchClass.hh"
|
||||
#include "StaState.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -66,36 +67,29 @@ private:
|
|||
Search *search_;
|
||||
};
|
||||
|
||||
class WorstSlack
|
||||
class WorstSlack : public StaState
|
||||
{
|
||||
public:
|
||||
WorstSlack();
|
||||
WorstSlack(StaState *sta);
|
||||
~WorstSlack();
|
||||
WorstSlack(const WorstSlack &);
|
||||
void worstSlack(PathAPIndex path_ap_index,
|
||||
const StaState *sta,
|
||||
// Return values.
|
||||
Slack &worst_slack,
|
||||
Vertex *&worst_vertex);
|
||||
void updateWorstSlack(Vertex *vertex,
|
||||
SlackSeq &slacks,
|
||||
PathAPIndex path_ap_index,
|
||||
const StaState *sta);
|
||||
PathAPIndex path_ap_index);
|
||||
void deleteVertexBefore(Vertex *vertex);
|
||||
|
||||
protected:
|
||||
void findWorstSlack(PathAPIndex path_ap_index,
|
||||
const StaState *sta);
|
||||
void initQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta);
|
||||
void findWorstInQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta);
|
||||
void findWorstSlack(PathAPIndex path_ap_index);
|
||||
void initQueue(PathAPIndex path_ap_index);
|
||||
void findWorstInQueue(PathAPIndex path_ap_index);
|
||||
void setWorstSlack(Vertex *vertex,
|
||||
Slack slack,
|
||||
const StaState *sta);
|
||||
void sortQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta);
|
||||
void checkQueue(PathAPIndex path_ap_index,
|
||||
const StaState *sta);
|
||||
Slack slack);
|
||||
void sortQueue(PathAPIndex path_ap_index);
|
||||
void checkQueue(PathAPIndex path_ap_index);
|
||||
|
||||
Slack slack_init_;
|
||||
// Vertex with the worst slack.
|
||||
|
|
@ -104,7 +98,7 @@ protected:
|
|||
Slack worst_slack_;
|
||||
Slack slack_threshold_;
|
||||
// Vertices with slack < threshold_
|
||||
VertexSet queue_;
|
||||
VertexSet *queue_;
|
||||
// Queue is sorted and pruned to min_queue_size_ vertices when it
|
||||
// reaches max_queue_size_.
|
||||
int min_queue_size_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue