sync
This commit is contained in:
parent
1af0963fd4
commit
0f2dba7eff
|
|
@ -657,7 +657,8 @@ GraphDelayCalc1::seedNoDrvrCellSlew(Vertex *drvr_vertex,
|
|||
drive_delay = cap * drive_res;
|
||||
slew = cap * drive_res;
|
||||
}
|
||||
if (!drvr_vertex->slewAnnotated(tr, ap_index))
|
||||
const MinMax *slew_min_max = dcalc_ap->slewMinMax();
|
||||
if (!drvr_vertex->slewAnnotated(tr, slew_min_max))
|
||||
graph_->setSlew(drvr_vertex, tr, ap_index, slew);
|
||||
arc_delay_calc->inputPortDelay(drvr_pin, delayAsFloat(slew), tr,
|
||||
parasitic, dcalc_ap);
|
||||
|
|
@ -674,6 +675,7 @@ GraphDelayCalc1::seedNoDrvrSlew(Vertex *drvr_vertex,
|
|||
DcalcAnalysisPt *dcalc_ap,
|
||||
ArcDelayCalc *arc_delay_calc)
|
||||
{
|
||||
const MinMax *slew_min_max = dcalc_ap->slewMinMax();
|
||||
DcalcAPIndex ap_index = dcalc_ap->index();
|
||||
Slew slew(default_slew);
|
||||
// Top level bidirect driver uses load slew unless
|
||||
|
|
@ -682,7 +684,7 @@ GraphDelayCalc1::seedNoDrvrSlew(Vertex *drvr_vertex,
|
|||
Vertex *load_vertex = graph_->pinLoadVertex(drvr_pin);
|
||||
slew = graph_->slew(load_vertex, tr, ap_index);
|
||||
}
|
||||
if (!drvr_vertex->slewAnnotated(tr, ap_index))
|
||||
if (!drvr_vertex->slewAnnotated(tr, slew_min_max))
|
||||
graph_->setSlew(drvr_vertex, tr, ap_index, slew);
|
||||
Parasitic *parasitic;
|
||||
bool delete_parasitic;
|
||||
|
|
@ -711,8 +713,7 @@ GraphDelayCalc1::seedLoadSlew(Vertex *vertex)
|
|||
while (ap_iter.hasNext()) {
|
||||
DcalcAnalysisPt *dcalc_ap = ap_iter.next();
|
||||
const MinMax *slew_min_max = dcalc_ap->slewMinMax();
|
||||
DcalcAPIndex ap_index = dcalc_ap->index();
|
||||
if (!vertex->slewAnnotated(tr, ap_index)) {
|
||||
if (!vertex->slewAnnotated(tr, slew_min_max)) {
|
||||
float slew = 0.0;
|
||||
if (clks) {
|
||||
slew = slew_min_max->initValue();
|
||||
|
|
@ -724,6 +725,7 @@ GraphDelayCalc1::seedLoadSlew(Vertex *vertex)
|
|||
slew = clk_slew;
|
||||
}
|
||||
}
|
||||
DcalcAPIndex ap_index = dcalc_ap->index();
|
||||
graph_->setSlew(vertex, tr, ap_index, slew);
|
||||
}
|
||||
}
|
||||
|
|
@ -988,11 +990,12 @@ GraphDelayCalc1::initRootSlews(Vertex *vertex)
|
|||
DcalcAnalysisPtIterator ap_iter(this);
|
||||
while (ap_iter.hasNext()) {
|
||||
DcalcAnalysisPt *dcalc_ap = ap_iter.next();
|
||||
const MinMax *slew_min_max = dcalc_ap->slewMinMax();
|
||||
DcalcAPIndex ap_index = dcalc_ap->index();
|
||||
TransRiseFallIterator tr_iter;
|
||||
while (tr_iter.hasNext()) {
|
||||
TransRiseFall *tr = tr_iter.next();
|
||||
if (!vertex->slewAnnotated(tr, ap_index))
|
||||
if (!vertex->slewAnnotated(tr, slew_min_max))
|
||||
graph_->setSlew(vertex, tr, ap_index, default_slew);
|
||||
}
|
||||
}
|
||||
|
|
@ -1181,9 +1184,10 @@ GraphDelayCalc1::initSlew(Vertex *vertex)
|
|||
while (ap_iter.hasNext()) {
|
||||
DcalcAnalysisPt *dcalc_ap = ap_iter.next();
|
||||
const MinMax *slew_min_max = dcalc_ap->slewMinMax();
|
||||
DcalcAPIndex ap_index = dcalc_ap->index();
|
||||
if (!vertex->slewAnnotated(tr, ap_index))
|
||||
if (!vertex->slewAnnotated(tr, slew_min_max)) {
|
||||
DcalcAPIndex ap_index = dcalc_ap->index();
|
||||
graph_->setSlew(vertex, tr, ap_index, slew_min_max->initValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1213,7 +1217,7 @@ GraphDelayCalc1::initWireDelays(Vertex *drvr_vertex,
|
|||
graph_->setWireArcDelay(wire_edge, tr, ap_index, delay_init_value);
|
||||
// Init load vertex slew.
|
||||
if (init_load_slews
|
||||
&& !load_vertex->slewAnnotated(tr, ap_index))
|
||||
&& !load_vertex->slewAnnotated(tr, slew_min_max))
|
||||
graph_->setSlew(load_vertex, tr, ap_index, slew_init_value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1278,8 +1282,9 @@ GraphDelayCalc1::findArcDelay(LibertyCell *drvr_cell,
|
|||
delayAsString(gate_slew, this));
|
||||
// Merge slews.
|
||||
const Slew &drvr_slew = graph_->slew(drvr_vertex, drvr_tr, ap_index);
|
||||
const MinMax *slew_min_max = dcalc_ap->slewMinMax();
|
||||
if (delayFuzzyGreater(gate_slew, drvr_slew, dcalc_ap->slewMinMax())
|
||||
&& !drvr_vertex->slewAnnotated(drvr_tr, ap_index))
|
||||
&& !drvr_vertex->slewAnnotated(drvr_tr, slew_min_max))
|
||||
graph_->setSlew(drvr_vertex, drvr_tr, ap_index, gate_slew);
|
||||
if (!graph_->arcDelayAnnotated(edge, arc, ap_index)) {
|
||||
const ArcDelay &prev_gate_delay = graph_->arcDelay(edge,arc,ap_index);
|
||||
|
|
@ -1479,8 +1484,8 @@ GraphDelayCalc1::annotateLoadDelays(Vertex *drvr_vertex,
|
|||
load_vertex->name(sdc_network_),
|
||||
delayAsString(wire_delay, this),
|
||||
delayAsString(load_slew, this));
|
||||
if (!load_vertex->slewAnnotated(drvr_tr, ap_index)) {
|
||||
if (drvr_vertex->slewAnnotated(drvr_tr, ap_index)) {
|
||||
if (!load_vertex->slewAnnotated(drvr_tr, slew_min_max)) {
|
||||
if (drvr_vertex->slewAnnotated(drvr_tr, slew_min_max)) {
|
||||
// Copy the driver slew to the load if it is annotated.
|
||||
const Slew &drvr_slew = graph_->slew(drvr_vertex,drvr_tr,ap_index);
|
||||
graph_->setSlew(load_vertex, drvr_tr, ap_index, drvr_slew);
|
||||
|
|
|
|||
|
|
@ -830,10 +830,14 @@ Graph::arcDelayAnnotated(Edge *edge,
|
|||
TimingArc *arc,
|
||||
DcalcAPIndex ap_index) const
|
||||
{
|
||||
unsigned index = (edge->arcDelays() + arc->index()) * ap_count_ + ap_index;
|
||||
if (index >= arc_delay_annotated_.size())
|
||||
internalError("arc_delay_annotated array bounds exceeded");
|
||||
return arc_delay_annotated_[index];
|
||||
if (arc_delay_annotated_.size()) {
|
||||
unsigned index = (edge->arcDelays() + arc->index()) * ap_count_ + ap_index;
|
||||
if (index >= arc_delay_annotated_.size())
|
||||
internalError("arc_delay_annotated array bounds exceeded");
|
||||
return arc_delay_annotated_[index];
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1162,6 +1166,8 @@ Vertex::init(Pin *pin,
|
|||
color_ = vertex_color_white;
|
||||
level_ = 0;
|
||||
bfs_in_queue_ = 0;
|
||||
crpr_path_pruning_disabled_ = false;
|
||||
requireds_pruned_ = false;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
@ -1191,13 +1197,9 @@ Vertex::setColor(VertexColor color)
|
|||
|
||||
bool
|
||||
Vertex::slewAnnotated(const TransRiseFall *tr,
|
||||
DcalcAPIndex ap_index) const
|
||||
const MinMax *min_max) const
|
||||
{
|
||||
// Track rise/fall/min/max annotations separately, but after that
|
||||
// only rise/fall.
|
||||
if (ap_index > 1)
|
||||
ap_index = 0;
|
||||
int index = ap_index * transitionCount() + tr->index();
|
||||
int index = min_max->index() * transitionCount() + tr->index();
|
||||
return ((1 << index) & slew_annotated_) != 0;
|
||||
}
|
||||
|
||||
|
|
@ -1229,6 +1231,18 @@ Vertex::removeSlewAnnotated()
|
|||
slew_annotated_ = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Vertex::setCrprPathPruningDisabled(bool disabled)
|
||||
{
|
||||
crpr_path_pruning_disabled_ = disabled;
|
||||
}
|
||||
|
||||
void
|
||||
Vertex::setRequiredsPruned(bool pruned)
|
||||
{
|
||||
requireds_pruned_ = pruned;
|
||||
}
|
||||
|
||||
TagGroupIndex
|
||||
Vertex::tagGroupIndex() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ public:
|
|||
void setTagGroupIndex(TagGroupIndex tag_index);
|
||||
// Slew is annotated by sdc set_annotated_transition cmd.
|
||||
bool slewAnnotated(const TransRiseFall *tr,
|
||||
DcalcAPIndex ap_index) const;
|
||||
const MinMax *min_max) const;
|
||||
// True if any rise/fall analysis pt slew is annotated.
|
||||
bool slewAnnotated() const;
|
||||
void setSlewAnnotated(bool annotated,
|
||||
|
|
@ -316,6 +316,11 @@ public:
|
|||
bool bfsInQueue(BfsIndex index) const;
|
||||
void setBfsInQueue(BfsIndex index, bool value);
|
||||
bool isRegClk() const { return is_reg_clk_; }
|
||||
bool crprPathPruningDisabled() const { return crpr_path_pruning_disabled_;}
|
||||
void setCrprPathPruningDisabled(bool disabled);
|
||||
bool requiredsPruned() const { return requireds_pruned_; }
|
||||
void setRequiredsPruned(bool pruned);
|
||||
|
||||
static int transitionCount() { return 2; } // rise/fall
|
||||
|
||||
protected:
|
||||
|
|
@ -328,14 +333,23 @@ protected:
|
|||
PathVertexRep *prev_paths_;
|
||||
EdgeIndex in_edges_; // Edges to this vertex.
|
||||
EdgeIndex out_edges_; // Edges from this vertex.
|
||||
unsigned int tag_group_index_:tag_group_index_bits;
|
||||
|
||||
// 4 bytes
|
||||
unsigned int tag_group_index_:tag_group_index_bits; // 24
|
||||
// Each bit corresponds to a different BFS queue.
|
||||
unsigned int bfs_in_queue_:bfs_index_bits; // 4
|
||||
unsigned int slew_annotated_:slew_annotated_bits;
|
||||
|
||||
// 4 bytes (32 bits)
|
||||
unsigned int level_:16;
|
||||
// Levelization search state.
|
||||
unsigned int color_:2;
|
||||
unsigned int sim_value_:3; // LogicValue
|
||||
bool has_requireds_:1;
|
||||
unsigned int slew_annotated_:4;
|
||||
// Bidirect pins have two vertices.
|
||||
// This flag distinguishes the driver and load vertices.
|
||||
bool is_bidirect_drvr_:1;
|
||||
bool is_reg_clk_:1;
|
||||
unsigned int sim_value_:3; // LogicValue
|
||||
bool is_disabled_constraint_:1;
|
||||
bool is_gated_clk_enable_:1;
|
||||
// Constrained by timing check edge.
|
||||
|
|
@ -344,11 +358,8 @@ protected:
|
|||
bool is_check_clk_:1;
|
||||
bool is_constrained_:1;
|
||||
bool has_downstream_clk_pin_:1;
|
||||
// Levelization search state.
|
||||
unsigned int color_:2;
|
||||
unsigned int level_:16;
|
||||
// Each bit corresponds to a different BFS queue.
|
||||
unsigned int bfs_in_queue_:bfs_index_bits;
|
||||
bool crpr_path_pruning_disabled_:1;
|
||||
bool requireds_pruned_:1;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Vertex);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#include "ObjectIndex.hh"
|
||||
#include "Set.hh"
|
||||
#include "Vector.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Transition.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -47,6 +49,7 @@ typedef Vector<GraphLoop*> GraphLoopSeq;
|
|||
// 16,777,215 tags
|
||||
static const int tag_group_index_bits = 24;
|
||||
static const TagGroupIndex tag_group_index_max = (1<<tag_group_index_bits)-1;
|
||||
static const int slew_annotated_bits = MinMax::index_count * TransRiseFall::index_count;
|
||||
|
||||
enum BfsIndex {
|
||||
bfs_dcalc,
|
||||
|
|
|
|||
|
|
@ -211,6 +211,12 @@ TimingArcSet::libertyCell() const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
TimingArcSetArcIterator *
|
||||
TimingArcSet::timingArcIterator()
|
||||
{
|
||||
return new TimingArcSetArcIterator(this);
|
||||
}
|
||||
|
||||
TimingArcIndex
|
||||
TimingArcSet::addTimingArc(TimingArc *arc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -164,6 +164,8 @@ public:
|
|||
TimingArc *&arc1,
|
||||
TimingArc *&arc2);
|
||||
const TimingArcSeq &arcs() const { return arcs_; }
|
||||
// Use the TimingArcSetArcIterator(arc_set) constructor instead.
|
||||
TimingArcSetArcIterator *timingArcIterator();
|
||||
TimingArcIndex addTimingArc(TimingArc *arc);
|
||||
void deleteTimingArc(TimingArc *arc);
|
||||
TimingArc *findTimingArc(unsigned arc_index);
|
||||
|
|
|
|||
|
|
@ -261,7 +261,6 @@ Search::init(StaState *sta)
|
|||
filter_ = NULL;
|
||||
filter_from_ = NULL;
|
||||
filter_to_ = NULL;
|
||||
have_paths_ = false;
|
||||
found_downstream_clk_pins_ = false;
|
||||
}
|
||||
|
||||
|
|
@ -294,8 +293,8 @@ void
|
|||
Search::clear()
|
||||
{
|
||||
crpr_path_pruning_enabled_ = true;
|
||||
unconstrained_paths_ = false;
|
||||
clk_arrivals_valid_ = false;
|
||||
arrivals_exist_ = false;
|
||||
arrivals_at_endpoints_exist_ = false;
|
||||
arrivals_seeded_ = false;
|
||||
requireds_exist_ = false;
|
||||
|
|
@ -381,13 +380,13 @@ void
|
|||
Search::deletePaths()
|
||||
{
|
||||
debugPrint0(debug_, "search", 1, "delete paths\n");
|
||||
if (have_paths_) {
|
||||
if (arrivals_exist_) {
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
deletePaths1(vertex);
|
||||
}
|
||||
have_paths_ = false;
|
||||
arrivals_exist_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -662,7 +661,6 @@ Search::arrivalsInvalid()
|
|||
deleteTags();
|
||||
genclks_->clear();
|
||||
deleteFilter();
|
||||
arrivals_exist_ = false;
|
||||
arrivals_at_endpoints_exist_ = false;
|
||||
arrivals_seeded_ = false;
|
||||
requireds_exist_ = false;
|
||||
|
|
@ -1096,8 +1094,11 @@ ArrivalVisitor::visit(Vertex *vertex)
|
|||
visitFaninPaths(vertex);
|
||||
if (crpr_active_
|
||||
&& search->crprPathPruningEnabled()
|
||||
&& !vertex->crprPathPruningDisabled()
|
||||
&& !has_fanin_one_)
|
||||
pruneCrprArrivals();
|
||||
vertex->setCrprPathPruningDisabled(false);
|
||||
|
||||
// Insert paths that originate here but
|
||||
if (!network->isTopLevelPort(pin)
|
||||
&& sdc->hasInputDelay(pin))
|
||||
|
|
@ -2769,7 +2770,6 @@ Search::setVertexArrivals(Vertex *vertex,
|
|||
vertex->setArrivals(arrivals);
|
||||
vertex->setPrevPaths(prev_paths);
|
||||
|
||||
have_paths_ = true;
|
||||
if (has_requireds) {
|
||||
requiredInvalid(vertex);
|
||||
vertex->setHasRequireds(false);
|
||||
|
|
@ -3472,6 +3472,7 @@ RequiredVisitor::visit(Vertex *vertex)
|
|||
debugPrint1(debug, "search", 2, "find required %s\n",
|
||||
vertex->name(sta_->network()));
|
||||
required_cmp_->requiredsInit(vertex, sta_);
|
||||
vertex->setRequiredsPruned(false);
|
||||
// Back propagate requireds from fanout.
|
||||
visitFanoutPaths(vertex);
|
||||
// Check for constraints at endpoints that set required times.
|
||||
|
|
@ -3488,7 +3489,7 @@ RequiredVisitor::visit(Vertex *vertex)
|
|||
|
||||
bool
|
||||
RequiredVisitor::visitFromToPath(const Pin *,
|
||||
Vertex *,
|
||||
Vertex *from_vertex,
|
||||
const TransRiseFall *from_tr,
|
||||
Tag *from_tag,
|
||||
PathVertex *from_path,
|
||||
|
|
@ -3500,7 +3501,7 @@ RequiredVisitor::visitFromToPath(const Pin *,
|
|||
Tag *to_tag,
|
||||
Arrival &,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap)
|
||||
const PathAnalysisPt *)
|
||||
{
|
||||
// Don't propagate required times through latch D->Q edges.
|
||||
if (edge->role() != TimingRole::latchDtoQ()) {
|
||||
|
|
@ -3533,31 +3534,11 @@ RequiredVisitor::visitFromToPath(const Pin *,
|
|||
delayAsString(required_cmp_->required(arrival_index), sta_));
|
||||
required_cmp_->requiredSet(arrival_index, from_required, req_min);
|
||||
}
|
||||
else {
|
||||
// Arrival that differ by crpr_pin may be pruned. Find an arrival
|
||||
// that matches everything but the crpr_pin.
|
||||
VertexPathIterator to_iter(to_vertex, to_tr, path_ap, sta_);
|
||||
while (to_iter.hasNext()) {
|
||||
PathVertex *to_path = to_iter.next();
|
||||
Tag *to_path_tag = to_path->tag(sta_);
|
||||
if (tagMatchNoCrpr(to_path_tag, to_tag)) {
|
||||
Required to_required = to_path->required(sta_);
|
||||
Required from_required = to_required - arc_delay;
|
||||
debugPrint2(debug, "search", 3, " to tag %2u: %s\n",
|
||||
to_path_tag->index(),
|
||||
to_path_tag->asString(sta_));
|
||||
debugPrint5(debug, "search", 3, " %s - %s = %s %s %s\n",
|
||||
delayAsString(to_required, sta_),
|
||||
delayAsString(arc_delay, sta_),
|
||||
delayAsString(from_required, sta_),
|
||||
min_max == MinMax::max() ? "<" : ">",
|
||||
delayAsString(required_cmp_->required(arrival_index),
|
||||
sta_));
|
||||
required_cmp_->requiredSet(arrival_index, from_required, req_min);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
from_vertex->setRequiredsPruned(true);
|
||||
// Propagate requireds pruned flag backwards.
|
||||
if (to_vertex->requiredsPruned())
|
||||
from_vertex->setRequiredsPruned(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -525,7 +525,6 @@ protected:
|
|||
|
||||
// findPathEnds arg.
|
||||
bool unconstrained_paths_;
|
||||
bool have_paths_;
|
||||
// Search predicates.
|
||||
SearchPred *search_adj_;
|
||||
SearchPred *search_clk_;
|
||||
|
|
|
|||
|
|
@ -2713,7 +2713,7 @@ Sta::vertexArrival(Vertex *vertex,
|
|||
search_->findArrivals(vertex->level());
|
||||
const MinMax *min_max = path_ap->pathMinMax();
|
||||
Arrival arrival = min_max->initValue();
|
||||
VertexPathIterator path_iter(vertex, tr, path_ap, search_);
|
||||
VertexPathIterator path_iter(vertex, tr, path_ap, this);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
const Arrival &path_arrival = path->arrival(this);
|
||||
|
|
@ -2744,7 +2744,7 @@ Sta::vertexRequired(Vertex *vertex,
|
|||
findRequired(vertex);
|
||||
const MinMax *min_max = path_ap->pathMinMax()->opposite();
|
||||
Required required = min_max->initValue();
|
||||
VertexPathIterator path_iter(vertex, tr, path_ap, search_);
|
||||
VertexPathIterator path_iter(vertex, tr, path_ap, this);
|
||||
while (path_iter.hasNext()) {
|
||||
const Path *path = path_iter.next();
|
||||
const Required path_required = path->required(this);
|
||||
|
|
@ -2794,7 +2794,7 @@ Sta::vertexSlack(Vertex *vertex,
|
|||
findRequired(vertex);
|
||||
MinMax *min = MinMax::min();
|
||||
Slack slack = min->initValue();
|
||||
VertexPathIterator path_iter(vertex, search_);
|
||||
VertexPathIterator path_iter(vertex, this);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
if (path->minMax(this) == min_max) {
|
||||
|
|
@ -2813,7 +2813,7 @@ Sta::vertexSlack(Vertex *vertex,
|
|||
{
|
||||
findRequired(vertex);
|
||||
Slack slack = MinMax::min()->initValue();
|
||||
VertexPathIterator path_iter(vertex, tr, min_max, search_);
|
||||
VertexPathIterator path_iter(vertex, tr, min_max, this);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
Slack path_slack = path->slack(this);
|
||||
|
|
@ -2850,7 +2850,7 @@ Sta::vertexSlack1(Vertex *vertex,
|
|||
{
|
||||
MinMax *min = MinMax::min();
|
||||
Slack slack = min->initValue();
|
||||
VertexPathIterator path_iter(vertex, tr, path_ap, search_);
|
||||
VertexPathIterator path_iter(vertex, tr, path_ap, this);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
Slack path_slack = path->slack(this);
|
||||
|
|
@ -2868,6 +2868,44 @@ Sta::findRequired(Vertex *vertex)
|
|||
searchPreamble();
|
||||
search_->findAllArrivals();
|
||||
search_->findRequireds(vertex->level());
|
||||
if (sdc_->crprEnabled()
|
||||
&& vertex->requiredsPruned()) {
|
||||
debugPrint1(debug_, "search", 2, "resurrect pruned required %s\n",
|
||||
vertex->name(sdc_network_));
|
||||
// printf("resurrect pruned required %s\n", vertex->name(sdc_network_));
|
||||
// Invalidate arrivals and requireds and disable
|
||||
// path pruning on fanout vertices.
|
||||
int fanout = 0;
|
||||
disableFanoutCrprPruning(vertex, fanout);
|
||||
// if (fanout > 100)
|
||||
// printf("fanout %s %d\n", vertex->name(network_), fanout);
|
||||
// Find fanout arrivals and requireds with pruning disabled.
|
||||
search_->findArrivals();
|
||||
search_->findRequireds(vertex->level());
|
||||
}
|
||||
}
|
||||
|
||||
// DFS to invalidate arrivals and requireds to
|
||||
// find arrivals with pruning disabled.
|
||||
void
|
||||
Sta::disableFanoutCrprPruning(Vertex *vertex,
|
||||
int &fanout)
|
||||
{
|
||||
if (!vertex->crprPathPruningDisabled()) {
|
||||
search_->arrivalInvalid(vertex);
|
||||
search_->requiredInvalid(vertex);
|
||||
vertex->setCrprPathPruningDisabled(true);
|
||||
fanout++;
|
||||
SearchPred *pred = search_->searchAdj();
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *to_vertex = edge->to(graph_);
|
||||
if (pred->searchThru(edge)
|
||||
&& pred->searchTo(to_vertex))
|
||||
disableFanoutCrprPruning(to_vertex, fanout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Slack
|
||||
|
|
|
|||
|
|
@ -1297,6 +1297,8 @@ protected:
|
|||
const MinMax *min_max);
|
||||
void parasiticsChangedAfter();
|
||||
void powerPreamble();
|
||||
void disableFanoutCrprPruning(Vertex *vertex,
|
||||
int &fanou);
|
||||
|
||||
CmdNamespace cmd_namespace_;
|
||||
Instance *current_instance_;
|
||||
|
|
|
|||
|
|
@ -1997,7 +1997,7 @@ private:
|
|||
%inline %{
|
||||
|
||||
float float_inf = INF;
|
||||
int group_count_max = PathGroup::group_count_max;
|
||||
int group_count_max = PathGroup::group_count_max;
|
||||
|
||||
const char *
|
||||
version()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <algorithm> // max
|
||||
#include <cmath> // abs
|
||||
#include "Machine.hh"
|
||||
#include "MinMax.hh" // INF
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -66,4 +67,11 @@ fuzzyGreaterEqual(float v1,
|
|||
return v1 > v2 || fuzzyEqual(v1, v2);
|
||||
}
|
||||
|
||||
bool
|
||||
fuzzyInf(float value)
|
||||
{
|
||||
return fuzzyEqual(value, INF)
|
||||
|| fuzzyEqual(value, -INF);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -35,5 +35,7 @@ fuzzyGreater(float v1,
|
|||
bool
|
||||
fuzzyGreaterEqual(float v1,
|
||||
float v2);
|
||||
bool
|
||||
fuzzyInf(float value);
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
Loading…
Reference in New Issue