eval latches out of bfs
Signed-off-by: James Cherry <cherry@CerezoBook.local>
This commit is contained in:
parent
9e39e42703
commit
1c6ab172e2
|
|
@ -75,6 +75,8 @@ using ExceptionPathSeq = std::vector<ExceptionPath*>;
|
|||
class Search : public StaState
|
||||
{
|
||||
public:
|
||||
bool postpone_latch_outputs_{false};
|
||||
|
||||
Search(StaState *sta);
|
||||
~Search() override;
|
||||
void copyState(const StaState *sta) override;
|
||||
|
|
@ -530,9 +532,6 @@ protected:
|
|||
const MinMax *min_max) const;
|
||||
void seedRequireds();
|
||||
void seedInvalidRequireds();
|
||||
[[nodiscard]] bool havePendingLatchOutputs();
|
||||
void clearPendingLatchOutputs();
|
||||
void enqueuePendingLatchOutputs();
|
||||
void findFilteredArrivals(bool thru_latches);
|
||||
void findArrivalsSeed();
|
||||
void seedFilterStarts();
|
||||
|
|
@ -669,7 +668,6 @@ protected:
|
|||
std::mutex filtered_arrivals_lock_;
|
||||
|
||||
bool found_downstream_clk_pins_{false};
|
||||
bool postpone_latch_outputs_{false};
|
||||
std::vector<Path*> enum_paths_;
|
||||
|
||||
VisitPathEnds *visit_path_ends_;
|
||||
|
|
|
|||
|
|
@ -356,7 +356,9 @@ PathEnumFaninVisitor::visitFaninPathsThru(Path *before_div,
|
|||
prev_vertex_ = prev_vertex;
|
||||
visited_fanins_.clear();
|
||||
unique_edge_divs_.clear();
|
||||
search_->postpone_latch_outputs_ = false;
|
||||
visitFaninPaths(before_div_->vertex(this));
|
||||
search_->postpone_latch_outputs_ = true;
|
||||
|
||||
if (unique_edges_) {
|
||||
for (auto [vertex_edge, div] : unique_edge_divs_)
|
||||
|
|
@ -422,6 +424,14 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
|||
Arrival & /* to_arrival */,
|
||||
const MinMax *)
|
||||
{
|
||||
debugPrint(debug_, "path_enum", 3, "visit fanin {} -> {} {} {}",
|
||||
from_path->to_string(this),
|
||||
to_vertex->to_string(this), to_rf->shortName(),
|
||||
delayAsString(
|
||||
search_->deratedDelay(
|
||||
from_vertex, arc, edge, false, from_path->minMax(this),
|
||||
from_path->dcalcAnalysisPtIndex(this), from_path->sdc(this)),
|
||||
this));
|
||||
// These paths fanin to before_div_ so we know to_vertex matches.
|
||||
if ((!unique_pins_ || from_vertex != prev_vertex_)
|
||||
&& (!unique_edges_ || from_vertex != prev_vertex_
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ Search::clear()
|
|||
deletePathGroups();
|
||||
deletePaths();
|
||||
deleteTags();
|
||||
clearPendingLatchOutputs();
|
||||
pending_latch_outputs_.clear();
|
||||
pending_clk_endpoints_.clear();
|
||||
deleteFilter();
|
||||
found_downstream_clk_pins_ = false;
|
||||
|
|
@ -644,18 +644,26 @@ Search::findFilteredArrivals(bool thru_latches)
|
|||
// Search always_to_endpoint to search from exisiting arrivals at
|
||||
// fanin startpoints to reach -thru/-to endpoints.
|
||||
arrival_visitor_->init(true, false, eval_pred_);
|
||||
// Iterate until data arrivals at all latches stop changing.
|
||||
postpone_latch_outputs_ = true;
|
||||
enqueuePendingClkFanouts();
|
||||
for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs());
|
||||
postpone_latch_outputs_ = true;
|
||||
bool have_pending_latch_outputs = false;
|
||||
// Iterate until data arrivals at all latches stop changing.
|
||||
for (int pass = 1;
|
||||
pass == 1 || (thru_latches && have_pending_latch_outputs);
|
||||
pass++) {
|
||||
if (thru_latches)
|
||||
enqueuePendingLatchOutputs();
|
||||
debugPrint(debug_, "search", 1, "find arrivals pass {}", pass);
|
||||
|
||||
int arrival_count = arrival_iter_->visitParallel(max_level, arrival_visitor_);
|
||||
deleteTagsPrev();
|
||||
debugPrint(debug_, "search", 1, "found {} arrivals", arrival_count);
|
||||
|
||||
have_pending_latch_outputs = !pending_latch_outputs_.empty();
|
||||
postpone_latch_outputs_ = false;
|
||||
for (Vertex *latch_vertex : pending_latch_outputs_)
|
||||
arrival_visitor_->visit(latch_vertex);
|
||||
pending_latch_outputs_.clear();
|
||||
postpone_latch_outputs_ = true;
|
||||
|
||||
deleteTagsPrev();
|
||||
}
|
||||
arrivals_exist_ = true;
|
||||
}
|
||||
|
|
@ -983,41 +991,23 @@ Search::findAllArrivals(bool thru_latches,
|
|||
if (!clks_only)
|
||||
enqueuePendingClkFanouts();
|
||||
arrival_visitor_->init(false, clks_only, eval_pred_);
|
||||
// Iterate until data arrivals at all latches stop changing.
|
||||
postpone_latch_outputs_ = true;
|
||||
for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs());
|
||||
bool have_pending_latch_outputs = false;
|
||||
// Iterate until data arrivals at all latches stop changing.
|
||||
for (int pass = 1; pass == 1 || (thru_latches && have_pending_latch_outputs);
|
||||
pass++) {
|
||||
enqueuePendingLatchOutputs();
|
||||
debugPrint(debug_, "search", 1, "find arrivals pass {}", pass);
|
||||
findArrivals1(levelize_->maxLevel());
|
||||
if (pass > 2)
|
||||
postpone_latch_outputs_ = false;
|
||||
|
||||
have_pending_latch_outputs = !pending_latch_outputs_.empty();
|
||||
postpone_latch_outputs_ = false;
|
||||
for (Vertex *latch_vertex : pending_latch_outputs_)
|
||||
arrival_visitor_->visit(latch_vertex);
|
||||
pending_latch_outputs_.clear();
|
||||
postpone_latch_outputs_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Search::havePendingLatchOutputs()
|
||||
{
|
||||
return !pending_latch_outputs_.empty();
|
||||
}
|
||||
|
||||
void
|
||||
Search::clearPendingLatchOutputs()
|
||||
{
|
||||
pending_latch_outputs_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Search::enqueuePendingLatchOutputs()
|
||||
{
|
||||
for (Vertex *latch_vertex : pending_latch_outputs_) {
|
||||
debugPrint(debug_, "search", 2, "enqueue latch output {}",
|
||||
latch_vertex->to_string(this));
|
||||
arrival_iter_->enqueue(latch_vertex);
|
||||
}
|
||||
clearPendingLatchOutputs();
|
||||
}
|
||||
|
||||
void
|
||||
Search::enqueuePendingClkFanouts()
|
||||
{
|
||||
|
|
@ -1148,6 +1138,17 @@ ArrivalVisitor::visit(Vertex *vertex)
|
|||
{
|
||||
debugPrint(debug_, "search", 2, "find arrivals {}",
|
||||
vertex->to_string(this));
|
||||
|
||||
if (search_->postponeLatchOutputs()) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
if (edge->role()->isLatchDtoQ()) {
|
||||
search_->enqueueLatchOutput(edge->to(graph_));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Pin *pin = vertex->pin();
|
||||
tag_bldr_->init(vertex);
|
||||
has_fanin_one_ = graph_->hasFaninOne(vertex);
|
||||
|
|
@ -2139,26 +2140,7 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
}
|
||||
else if (edge->role() == TimingRole::latchDtoQ()) {
|
||||
if (min_max == MinMax::max() && clk) {
|
||||
bool postponed = false;
|
||||
if (search_->postponeLatchOutputs()) {
|
||||
const Path *from_clk_path = from_clk_info->crprClkPath(this);
|
||||
if (from_clk_path) {
|
||||
Vertex *d_clk_vertex = from_clk_path->vertex(this);
|
||||
Level d_clk_level = d_clk_vertex->level();
|
||||
Level q_level = to_vertex->level();
|
||||
if (d_clk_level >= q_level) {
|
||||
// Crpr clk path on latch data input is required to find Q
|
||||
// arrival. If the data clk path level is >= Q level the
|
||||
// crpr clk path prev_path pointers are not complete.
|
||||
debugPrint(debug_, "search", 3, "postponed latch eval {} {} -> {} {}",
|
||||
d_clk_level, d_clk_vertex->to_string(this),
|
||||
edge->to_string(this), q_level);
|
||||
postponed = true;
|
||||
search_->enqueueLatchOutput(to_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!postponed) {
|
||||
if (!search_->postponeLatchOutputs()) {
|
||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, min_max,
|
||||
dcalc_ap, sdc);
|
||||
latches_->latchOutArrival(from_path, arc, edge, to_tag, arc_delay,
|
||||
|
|
|
|||
Loading…
Reference in New Issue