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