Skip to content

Commit 9c9b565

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents eb8ab08 + b65e8dd commit 9c9b565

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

include/sta/Search.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ public:
307307
Vertex *vertex,
308308
TagGroupBldr *tag_bldr);
309309
void enqueueLatchDataOutputs(Vertex *vertex);
310+
void enqueueLatchOutput(Vertex *vertex);
310311
virtual void seedRequired(Vertex *vertex);
311312
virtual void seedRequiredEnqueueFanin(Vertex *vertex);
312313
void seedInputDelayArrival(const Pin *pin,
@@ -417,6 +418,7 @@ public:
417418
void checkPrevPaths() const;
418419
void deletePaths(Vertex *vertex);
419420
void deleteTagGroup(TagGroup *group);
421+
bool postpone_latch_outputs_;
420422

421423
protected:
422424
void init(StaState *sta);

search/Search.cc

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ Search::init(StaState *sta)
254254
filter_to_ = nullptr;
255255
filtered_arrivals_ = new VertexSet(graph_);
256256
found_downstream_clk_pins_ = false;
257+
postpone_latch_outputs_ = false;
257258
}
258259

259260
// Init "options".
@@ -639,13 +640,15 @@ Search::findFilteredArrivals(bool thru_latches)
639640
// fanin startpoints to reach -thru/-to endpoints.
640641
arrival_visitor_->init(true);
641642
// Iterate until data arrivals at all latches stop changing.
643+
postpone_latch_outputs_ = true;
642644
for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs()) ; pass++) {
643645
if (thru_latches)
644646
enqueuePendingLatchOutputs();
645647
debugPrint(debug_, "search", 1, "find arrivals pass %d", pass);
646648
int arrival_count = arrival_iter_->visitParallel(max_level, arrival_visitor_);
647649
deleteTagsPrev();
648650
debugPrint(debug_, "search", 1, "found %d arrivals", arrival_count);
651+
postpone_latch_outputs_ = false;
649652
}
650653
arrivals_exist_ = true;
651654
}
@@ -1054,10 +1057,13 @@ Search::findAllArrivals(bool thru_latches)
10541057
{
10551058
arrival_visitor_->init(false);
10561059
// Iterate until data arrivals at all latches stop changing.
1060+
postpone_latch_outputs_ = true;
10571061
for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs()); pass++) {
10581062
enqueuePendingLatchOutputs();
10591063
debugPrint(debug_, "search", 1, "find arrivals pass %d", pass);
10601064
findArrivals1(levelize_->maxLevel());
1065+
if (pass > 2)
1066+
postpone_latch_outputs_ = false;
10611067
}
10621068
}
10631069

@@ -1076,8 +1082,11 @@ Search::clearPendingLatchOutputs()
10761082
void
10771083
Search::enqueuePendingLatchOutputs()
10781084
{
1079-
for (Vertex *latch_vertex : *pending_latch_outputs_)
1085+
for (Vertex *latch_vertex : *pending_latch_outputs_) {
1086+
debugPrint(debug_, "search", 2, "enqueue latch output %s",
1087+
latch_vertex->to_string(this).c_str());
10801088
arrival_iter_->enqueue(latch_vertex);
1089+
}
10811090
clearPendingLatchOutputs();
10821091
}
10831092

@@ -1475,6 +1484,13 @@ Search::enqueueLatchDataOutputs(Vertex *vertex)
14751484
}
14761485
}
14771486

1487+
void
1488+
Search::enqueueLatchOutput(Vertex *vertex)
1489+
{
1490+
LockGuard lock(pending_latch_outputs_lock_);
1491+
pending_latch_outputs_->insert(vertex);
1492+
}
1493+
14781494
void
14791495
Search::seedArrivals()
14801496
{
@@ -2287,11 +2303,34 @@ PathVisitor::visitFromPath(const Pin *from_pin,
22872303
else if (edge->role() == TimingRole::latchDtoQ()) {
22882304
if (min_max == MinMax::max()
22892305
&& clk) {
2290-
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
2291-
latches_->latchOutArrival(from_path, arc, edge, path_ap,
2292-
to_tag, arc_delay, to_arrival);
2293-
if (to_tag)
2294-
to_tag = search_->thruTag(to_tag, edge, to_rf, min_max, path_ap, tag_cache_);
2306+
bool postponed = false;
2307+
if (search_->postpone_latch_outputs_) {
2308+
const Path *from_clk_path = from_clk_info->crprClkPath(this);
2309+
if (from_clk_path) {
2310+
Vertex *d_clk_vertex = from_clk_path->vertex(this);
2311+
Level d_clk_level = d_clk_vertex->level();
2312+
Level q_level = to_vertex->level();
2313+
if (d_clk_level >= q_level) {
2314+
// Crpr clk path on latch data input is required to find Q
2315+
// arrival. If the data clk path level is >= Q level the
2316+
// crpr clk path prev_path pointers are not complete.
2317+
debugPrint(debug_, "search", 3, "postponed latch eval %d %s -> %s %d",
2318+
d_clk_level,
2319+
d_clk_vertex->to_string(this).c_str(),
2320+
edge->to_string(this).c_str(),
2321+
q_level);
2322+
postponed = true;
2323+
search_->enqueueLatchOutput(to_vertex);
2324+
}
2325+
}
2326+
}
2327+
if (!postponed) {
2328+
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
2329+
latches_->latchOutArrival(from_path, arc, edge, path_ap,
2330+
to_tag, arc_delay, to_arrival);
2331+
if (to_tag)
2332+
to_tag = search_->thruTag(to_tag, edge, to_rf, min_max, path_ap, tag_cache_);
2333+
}
22952334
}
22962335
}
22972336
else if (from_tag->isClock()) {

0 commit comments

Comments
 (0)