path enum rm duplicate paths
commit 0e13dae22d52d61b0d8d91b1a499d9dea9d23a9b
Author: James Cherry <cherry@parallaxsw.com>
Date: Wed Apr 23 11:18:50 2025 -0700
path enum
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 8871e3653178e84aec4142819c9bac0556f52e29
Author: James Cherry <cherry@parallaxsw.com>
Date: Tue Apr 22 16:30:35 2025 -0700
path enum w/crpr rm duplicate paths
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 4da0d520762cb8bcc858398bceea62169ac9ad8a
Author: James Cherry <cherry@parallaxsw.com>
Date: Tue Apr 22 16:26:52 2025 -0700
TimingArc::to_string
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit d2e6f218f58bf67dfd6f8d2c48a24f92ed32b849
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Apr 18 18:44:31 2025 -0700
comment
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 7c673dfdfc6e18c154a1a9011b59a6406f2439f4
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Apr 18 16:52:36 2025 -0700
path enum debug
Signed-off-by: James Cherry <cherry@parallaxsw.com>
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
400c473fe3
commit
cba0cf5cc4
|
|
@ -236,6 +236,7 @@ public:
|
|||
const Transition *to_rf,
|
||||
TimingModel *model);
|
||||
~TimingArc();
|
||||
std::string to_string() const;
|
||||
LibertyPort *from() const { return set_->from(); }
|
||||
LibertyPort *to() const { return set_->to(); }
|
||||
const Transition *fromEdge() const { return from_rf_; }
|
||||
|
|
|
|||
|
|
@ -33,9 +33,10 @@ class Variables
|
|||
{
|
||||
public:
|
||||
Variables();
|
||||
// TCL variable sta_propagate_gated_clock_enable.
|
||||
// TCL variable sta_crpr_enabled.
|
||||
bool crprEnabled() const { return crpr_enabled_; }
|
||||
void setCrprEnabled(bool enabled);
|
||||
// TCL variable sta_crpr_mode.
|
||||
CrprMode crprMode() const { return crpr_mode_; }
|
||||
void setCrprMode(CrprMode mode);
|
||||
// Propagate gated clock enable arrivals.
|
||||
|
|
|
|||
|
|
@ -555,6 +555,19 @@ TimingArc::~TimingArc()
|
|||
delete scaled_models_;
|
||||
}
|
||||
|
||||
string
|
||||
TimingArc::to_string() const
|
||||
{
|
||||
string str = set_->from()->name();
|
||||
str += " ";
|
||||
str += from_rf_->to_string();
|
||||
str += " -> ";
|
||||
str += set_->to()->name();
|
||||
str += " ";
|
||||
str += to_rf_->to_string();
|
||||
return str;
|
||||
}
|
||||
|
||||
GateTimingModel *
|
||||
TimingArc::gateModel(const DcalcAnalysisPt *dcalc_ap) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// A diversion is an alternate path formed by changing the previous
|
||||
// path/arc of before_div to after_div/div_arc in path.
|
||||
//
|
||||
|
|
@ -178,16 +176,17 @@ PathEnum::findNext()
|
|||
div_queue_.pop();
|
||||
PathEnd *path_end = div->pathEnd();
|
||||
Vertex *vertex = path_end->vertex(this);
|
||||
path_counts_[vertex]++;
|
||||
if (debug_->check("path_enum", 2)) {
|
||||
Path *path = path_end->path();
|
||||
report_->reportLine("path_enum: next path %s delay %s slack %s",
|
||||
report_->reportLine("path_enum: next path %zu %s delay %s slack %s",
|
||||
path_counts_[vertex],
|
||||
path->to_string(this).c_str(),
|
||||
delayAsString(path_end->dataArrivalTime(this), this),
|
||||
delayAsString(path_end->slack(this), this));
|
||||
reportDiversionPath(div);
|
||||
}
|
||||
|
||||
path_counts_[vertex]++;
|
||||
if (path_counts_[vertex] <= endpoint_path_count_) {
|
||||
// Add diversions for all arcs converging on the path up to the
|
||||
// diversion.
|
||||
|
|
@ -213,14 +212,14 @@ PathEnum::reportDiversionPath(Diversion *div)
|
|||
{
|
||||
PathEnd *path_end = div->pathEnd();
|
||||
Path *path = path_end->path();
|
||||
Path *p = path->prevPath();
|
||||
Path *p = path_end->path();
|
||||
Path *after_div = div->divPath();
|
||||
while (p) {
|
||||
report_->reportLine("path_enum: %s %s%s",
|
||||
p->to_string(this).c_str(),
|
||||
delayAsString(p->arrival(), this),
|
||||
Path::equal(p, after_div, this) ? " <-diversion" : "");
|
||||
if (network_->isLatchData(p->pin(this)))
|
||||
Path::equal(p, after_div, this) ? " <-after diversion" : "");
|
||||
if (p != path && network_->isLatchData(p->pin(this)))
|
||||
break;
|
||||
p = p->prevPath();
|
||||
}
|
||||
|
|
@ -228,6 +227,8 @@ PathEnum::reportDiversionPath(Diversion *div)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef std::set<std::pair<const Vertex*, const TimingArc*>> VisitedFanins;
|
||||
|
||||
class PathEnumFaninVisitor : public PathVisitor
|
||||
{
|
||||
public:
|
||||
|
|
@ -271,14 +272,13 @@ private:
|
|||
Slack path_end_slack_;
|
||||
Path *before_div_;
|
||||
bool unique_pins_;
|
||||
int before_div_rf_index_;
|
||||
Tag *before_div_tag_;
|
||||
PathAPIndex before_div_ap_index_;
|
||||
Arrival before_div_arrival_;
|
||||
TimingArc *prev_arc_;
|
||||
Vertex *prev_vertex_;
|
||||
PathEnum *path_enum_;
|
||||
bool crpr_active_;
|
||||
VisitedFanins visited_fanins_;
|
||||
};
|
||||
|
||||
PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end,
|
||||
|
|
@ -290,9 +290,7 @@ PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end,
|
|||
path_end_slack_(path_end->slack(this)),
|
||||
before_div_(before_div),
|
||||
unique_pins_(unique_pins),
|
||||
before_div_rf_index_(before_div_->rfIndex(this)),
|
||||
before_div_tag_(before_div_->tag(this)),
|
||||
before_div_ap_index_(before_div_->pathAnalysisPtIndex(this)),
|
||||
before_div_arrival_(before_div_->arrival()),
|
||||
path_enum_(path_enum),
|
||||
crpr_active_(crprActive())
|
||||
|
|
@ -305,12 +303,11 @@ PathEnumFaninVisitor::visitFaninPathsThru(Path *before_div,
|
|||
TimingArc *prev_arc)
|
||||
{
|
||||
before_div_ = before_div;
|
||||
before_div_rf_index_ = before_div_->rfIndex(this);
|
||||
before_div_tag_ = before_div_->tag(this);
|
||||
before_div_ap_index_ = before_div_->pathAnalysisPtIndex(this);
|
||||
before_div_arrival_ = before_div_->arrival();
|
||||
prev_arc_ = prev_arc;
|
||||
prev_vertex_ = prev_vertex;
|
||||
visited_fanins_.clear();
|
||||
visitFaninPaths(before_div_->vertex(this));
|
||||
}
|
||||
|
||||
|
|
@ -338,33 +335,39 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
|||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap)
|
||||
{
|
||||
// These paths fanin to before_div_ so we know to_vertex matches.
|
||||
if ((!unique_pins_ || from_vertex != prev_vertex_)
|
||||
&& arc != prev_arc_
|
||||
&& tagMatchNoCrpr(to_tag, before_div_tag_)) {
|
||||
debugPrint(debug_, "path_enum", 3, "visit fanin %s -> %s %s %s",
|
||||
from_path->to_string(this).c_str(),
|
||||
to_vertex->to_string(this).c_str(),
|
||||
to_rf->to_string().c_str(),
|
||||
delayAsString(search_->deratedDelay(from_vertex, arc, edge,
|
||||
false,path_ap), this));
|
||||
// These paths fanin to before_div_ so we know to_vertex matches.
|
||||
if (to_rf->index() == before_div_rf_index_
|
||||
&& path_ap->index() == before_div_ap_index_
|
||||
&& arc != prev_arc_
|
||||
&& (!unique_pins_ || from_vertex != prev_vertex_)
|
||||
&& tagMatchNoCrpr(to_tag, before_div_tag_)) {
|
||||
if (crpr_active_) {
|
||||
// Ingore paths that only differ by crpr from same vertex/edge.
|
||||
if (visited_fanins_.find({from_vertex, arc}) == visited_fanins_.end()) {
|
||||
PathEnd *div_end;
|
||||
Path *after_div_copy;
|
||||
// Make the diverted path end to check slack with from_path crpr.
|
||||
makeDivertedPathEnd(from_path, edge, arc, div_end, after_div_copy);
|
||||
if (div_end) {
|
||||
// Only enumerate paths with greater slack.
|
||||
if (delayGreaterEqual(div_end->slack(this), path_end_slack_, this)) {
|
||||
if (div_end->slack(this) >= (path_end_slack_ * (1.0-.001))) {
|
||||
reportDiversion(edge, arc, from_path);
|
||||
path_enum_->makeDiversion(div_end, after_div_copy);
|
||||
visited_fanins_.emplace(from_vertex, arc);
|
||||
}
|
||||
else
|
||||
delete div_end;
|
||||
}
|
||||
}
|
||||
else
|
||||
debugPrint(debug_, "path_enum", 3, " pruned %s %s",
|
||||
edge->to_string(this).c_str(),
|
||||
arc->to_string().c_str());
|
||||
}
|
||||
// Only enumerate slower/faster paths.
|
||||
else if (delayLessEqual(to_arrival, before_div_arrival_, min_max, this)) {
|
||||
PathEnd *div_end;
|
||||
|
|
@ -468,11 +471,8 @@ PathEnum::pruneDiversionQueue()
|
|||
}
|
||||
|
||||
// Add the top diversions back.
|
||||
DiversionSeq::Iterator div_iter(divs);
|
||||
while (div_iter.hasNext()) {
|
||||
Diversion *div = div_iter.next();
|
||||
for (Diversion *div : divs)
|
||||
div_queue_.push(div);
|
||||
}
|
||||
}
|
||||
|
||||
Arrival
|
||||
|
|
|
|||
|
|
@ -733,7 +733,7 @@ MakePathEndsAll::vertexEnd(Vertex *)
|
|||
// Only save the worst path end for each crpr tag.
|
||||
// PathEnum will peel the others.
|
||||
if (!unique_ends.hasKey(path_end)) {
|
||||
debugPrint(debug, "path_enum", 5, "insert %s %s %s %d",
|
||||
debugPrint(debug, "path_group", 2, "insert %s %s %s %d",
|
||||
path_end->vertex(sta_)->to_string(sta_).c_str(),
|
||||
path_end->typeName(),
|
||||
path_end->transition(sta_)->to_string().c_str(),
|
||||
|
|
@ -748,7 +748,7 @@ MakePathEndsAll::vertexEnd(Vertex *)
|
|||
}
|
||||
}
|
||||
else
|
||||
debugPrint(debug, "path_enum", 5, "prune %s %s %s %d",
|
||||
debugPrint(debug, "path_group", 3, "prune %s %s %s %d",
|
||||
path_end->vertex(sta_)->to_string(sta_).c_str(),
|
||||
path_end->typeName(),
|
||||
path_end->transition(sta_)->to_string().c_str(),
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "Search.hh"
|
||||
#include "search/Levelize.hh"
|
||||
#include "search/ReportPath.hh"
|
||||
#include "PathExpanded.hh"
|
||||
#include "Sta.hh"
|
||||
|
||||
using namespace sta;
|
||||
|
|
@ -1248,6 +1249,7 @@ bool is_data_check() { return self->isDataCheck(); }
|
|||
bool is_output_delay() { return self->isOutputDelay(); }
|
||||
bool is_path_delay() { return self->isPathDelay(); }
|
||||
bool is_gated_clock() { return self->isGatedClock(); }
|
||||
Pin *pin() { return self->vertex(Sta::sta())->pin(); }
|
||||
Vertex *vertex() { return self->vertex(Sta::sta()); }
|
||||
Path *path() { return self->path(); }
|
||||
RiseFall *end_transition()
|
||||
|
|
@ -1313,6 +1315,12 @@ pin()
|
|||
return self->pin(sta);
|
||||
}
|
||||
|
||||
const RiseFall *
|
||||
edge()
|
||||
{
|
||||
return self->transition(Sta::sta());
|
||||
}
|
||||
|
||||
string
|
||||
tag()
|
||||
{
|
||||
|
|
@ -1334,6 +1342,13 @@ pins()
|
|||
return pins;
|
||||
}
|
||||
|
||||
const Path *
|
||||
start_path()
|
||||
{
|
||||
PathExpanded expanded(self, Sta::sta());
|
||||
return expanded.startPath();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
%extend VertexPathIterator {
|
||||
|
|
|
|||
Loading…
Reference in New Issue