@@ -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()
10761082void
10771083Search::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+
14781494void
14791495Search::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