This commit is contained in:
James Cherry 2019-03-17 15:45:59 -07:00
parent e5c9bc43fd
commit 5162905e11
4 changed files with 67 additions and 13 deletions

View File

@ -16,7 +16,7 @@
cmake_minimum_required (VERSION 3.9)
project(STA VERSION 2.0.10)
project(STA VERSION 2.0.11)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 11)

View File

@ -227,8 +227,8 @@ Search::Search(StaState *sta) :
void
Search::init(StaState *sta)
{
crpr_path_pruning_enabled_ = true;
unconstrained_paths_ = false;
initVars();
search_adj_ = new SearchThru(nullptr, sta);
eval_pred_ = new EvalPred(sta);
check_crpr_ = new CheckCrpr(sta);
@ -264,6 +264,15 @@ Search::init(StaState *sta)
found_downstream_clk_pins_ = false;
}
// Init "options".
void
Search::initVars()
{
unconstrained_paths_ = false;
crpr_path_pruning_enabled_ = true;
crpr_approx_missing_requireds_ = true;
}
Search::~Search()
{
deletePaths();
@ -292,8 +301,8 @@ Search::~Search()
void
Search::clear()
{
crpr_path_pruning_enabled_ = true;
unconstrained_paths_ = false;
initVars();
clk_arrivals_valid_ = false;
arrivals_at_endpoints_exist_ = false;
arrivals_seeded_ = false;
@ -328,6 +337,18 @@ Search::setCrprpathPruningEnabled(bool enabled)
crpr_path_pruning_enabled_ = enabled;
}
bool
Search::crprApproxMissingRequireds() const
{
return crpr_approx_missing_requireds_;
}
void
Search::setCrprApproxMissingRequireds(bool enabled)
{
crpr_approx_missing_requireds_ = enabled;
}
void
Search::deleteTags()
{
@ -3436,7 +3457,7 @@ RequiredVisitor::visitFromToPath(const Pin *,
Tag *to_tag,
Arrival &,
const MinMax *min_max,
const PathAnalysisPt *)
const PathAnalysisPt *path_ap)
{
// Don't propagate required times through latch D->Q edges.
if (edge->role() != TimingRole::latchDtoQ()) {
@ -3469,8 +3490,35 @@ RequiredVisitor::visitFromToPath(const Pin *,
delayAsString(required_cmp_->required(arrival_index), sta_));
required_cmp_->requiredSet(arrival_index, from_required, req_min);
}
else
else {
if (sta_->search()->crprApproxMissingRequireds()) {
// Arrival on to_vertex that differs by crpr_pin was pruned.
// Find an arrival that matches everything but the crpr_pin
// as an appromate required.
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;
}
}
}
from_vertex->setRequiredsPruned(true);
}
// Propagate requireds pruned flag backwards.
if (to_vertex->requiredsPruned())
from_vertex->setRequiredsPruned(true);

View File

@ -70,10 +70,15 @@ public:
// Reset to virgin state.
void clear();
// When enabled, non-critical path arrivals are pruned to improve
// run time and reduce memory. The side-effect is that slacks for
// non-critical paths on intermediate pins may be incorrect.
// run time and reduce memory.
bool crprPathPruningEnabled() const;
void setCrprpathPruningEnabled(bool enabled);
// When path pruning is enabled required times for non-critical paths
// that have been pruned require additional search. This option
// disables additional search to returns approximate required times.
bool crprApproxMissingRequireds() const;
void setCrprApproxMissingRequireds(bool enabled);
bool unconstrainedPaths() const { return unconstrained_paths_; }
// from/thrus/to are owned and deleted by Search.
// Use corner nullptr to report timing for all corners.
@ -344,6 +349,7 @@ public:
protected:
void init(StaState *sta);
void initVars();
void makeAnalysisPts(AnalysisType analysis_type);
void makeAnalysisPts(bool swap_clk_min_max,
bool report_min,
@ -524,6 +530,8 @@ protected:
// findPathEnds arg.
bool unconstrained_paths_;
bool crpr_path_pruning_enabled_;
bool crpr_approx_missing_requireds_;
// Search predicates.
SearchPred *search_adj_;
SearchPred *search_clk_;
@ -591,7 +599,6 @@ protected:
VisitPathEnds *visit_path_ends_;
GatedClk *gated_clk_;
CheckCrpr *check_crpr_;
bool crpr_path_pruning_enabled_;
Genclks *genclks_;
};

View File

@ -2880,13 +2880,14 @@ Sta::findRequired(Vertex *vertex)
search_->findRequireds(vertex->level());
if (sdc_->crprEnabled()
&& search_->crprPathPruningEnabled()
&& !search_->crprApproxMissingRequireds()
// Clocks invariably have requireds that are pruned but isn't
// worth finding arrivals and requireds all over again for
// the entire fanout of the clock.
&& !search_->isClock(vertex)
&& vertex->requiredsPruned()) {
// Invalidate arrivals and requireds and disable
// path pruning on fanout vertices.
// path pruning on fanout vertices with DFS.
int fanout = 0;
disableFanoutCrprPruning(vertex, fanout);
debugPrint2(debug_, "search", 1, "resurrect pruned required %s fanout %d\n",
@ -2898,8 +2899,6 @@ Sta::findRequired(Vertex *vertex)
}
}
// DFS to invalidate fanout arrivals and requireds to
// find arrivals with pruning disabled.
void
Sta::disableFanoutCrprPruning(Vertex *vertex,
int &fanout)