From 50a249d7ae377610124fbca57b457597285e68c1 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 19 Jul 2024 17:03:03 -0700 Subject: [PATCH] path enum for transparent low latch Signed-off-by: James Cherry --- liberty/Liberty.cc | 6 +++++- liberty/LibertyReader.cc | 4 ++-- search/PathEnum.cc | 22 +++++++++++++--------- search/Tag.cc | 4 +++- tcl/StaTcl.i | 5 ++--- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 8bad4c35..1e39e7ee 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1914,13 +1914,17 @@ LibertyCell::latchEnable(TimingArcSet *d_to_q_set, FuncExpr *&enable_func, const RiseFall *&enable_edge) const { - enable_port = nullptr; LatchEnable *latch_enable = latch_d_to_q_map_.findKey(d_to_q_set); if (latch_enable) { enable_port = latch_enable->enable(); enable_func = latch_enable->enableFunc(); enable_edge = latch_enable->enableEdge(); } + else { + enable_port = nullptr; + enable_func = nullptr; + enable_edge = nullptr; + } } const RiseFall * diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index fb23fe3e..ff63db88 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -3927,8 +3927,8 @@ LibertyReader::endTiming(LibertyGroup *group) { if (timing_) { // Set scale factor type in constraint tables. - for (auto tr : RiseFall::range()) { - TableModel *model = timing_->constraint(tr); + for (auto rf : RiseFall::range()) { + TableModel *model = timing_->constraint(rf); if (model) { ScaleFactorType type=timingTypeScaleFactorType(timing_->attrs()->timingType()); model->setScaleFactorType(type); diff --git a/search/PathEnum.cc b/search/PathEnum.cc index d9560f41..69e6df77 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.cc @@ -399,7 +399,7 @@ PathEnumFaninVisitor::reportDiversion(TimingArc *div_arc, report_->reportLine("path_enum: from %s -> %s", div_prev.name(this), before_div_.name(this)); - report_->reportLine("path_enum: to %s ->e", + report_->reportLine("path_enum: to %s", after_div->name(this)); } } @@ -502,9 +502,6 @@ PathEnum::makeDiversions(PathEnd *path_end, path.prevPath(this, prev_path, prev_arc); PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_, this); while (prev_arc - // Do not enumerate beyond latch D to Q edges. - // This breaks latch loop paths. - && prev_arc->role() != TimingRole::latchDtoQ() // Do not enumerate paths in the clk network. && !path.isClock(this)) { // Fanin visitor does all the work. @@ -512,6 +509,10 @@ PathEnum::makeDiversions(PathEnd *path_end, // previous path and arc as well as diversions. fanin_visitor.visitFaninPathsThru(path.vertex(this), prev_path.vertex(this), prev_arc); + // Do not enumerate beyond latch D to Q edges. + // This breaks latch loop paths. + if (prev_arc->role() == TimingRole::latchDtoQ()) + break; path.init(prev_path); path.prevPath(this, prev_path, prev_arc); } @@ -574,7 +575,7 @@ PathEnum::updatePathHeadDelays(PathEnumedSeq &paths, Path *after_div) { Tag *prev_tag = after_div->tag(this); - ClkInfo *clk_info = prev_tag->clkInfo(); + ClkInfo *prev_clk_info = prev_tag->clkInfo(); Arrival prev_arrival = search_->clkPathArrival(after_div); for (int i = paths.size() - 1; i >= 0; i--) { PathEnumed *path = paths[i]; @@ -585,19 +586,22 @@ PathEnum::updatePathHeadDelays(PathEnumedSeq &paths, ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_), arc, edge, false, path_ap); Arrival arrival = prev_arrival + arc_delay; - debugPrint(debug_, "path_enum", 3, "update arrival %s %s -> %s", - path->name(this), + debugPrint(debug_, "path_enum", 3, "update arrival %s %s %s -> %s", + path->vertex(this)->name(network_), + path->tag(this)->asString(this), delayAsString(path->arrival(this), this), delayAsString(arrival, this)); path->setArrival(arrival, this); prev_arrival = arrival; - if (sdc_->crprActive()) { + if (sdc_->crprActive() + // D->Q paths use the EN->Q clk info so no need to update. + && arc->role() != TimingRole::latchDtoQ()) { // When crpr is enabled the diverion may be from another crpr clk pin, // so update the tags to use the corresponding ClkInfo. Tag *tag = path->tag(this); Tag *updated_tag = search_->findTag(path->transition(this), path_ap, - clk_info, + prev_clk_info, tag->isClock(), tag->inputDelay(), tag->isSegmentStart(), diff --git a/search/Tag.cc b/search/Tag.cc index b50837f4..81942b88 100644 --- a/search/Tag.cc +++ b/search/Tag.cc @@ -97,11 +97,12 @@ Tag::asString(bool report_index, string result; if (report_index) - result += std::to_string(index_) + " "; + result += std::to_string(index_); if (report_rf_min_max) { const RiseFall *rf = transition(); PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_); + result += " "; result += rf->asString(); result += " "; result += path_ap->pathMinMax()->asString(); @@ -109,6 +110,7 @@ Tag::asString(bool report_index, result += std::to_string(path_ap_index_); } + result += " "; const ClockEdge *clk_edge = clkEdge(); if (clk_edge) result += clk_edge->name(); diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 8cdc27d7..a46d5385 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -4901,9 +4901,8 @@ latch_d_to_q_en() FuncExpr *enable_func; const RiseFall *enable_rf; lib_cell->latchEnable(d_q_set, enable_port, enable_func, enable_rf); - const char *en_name = enable_port->name(); - return stringPrintTmp("%s %s", en_name, enable_rf->asString()); - + if (enable_port) + return stringPrintTmp("%s %s", enable_port->name(), enable_rf->asString()); } return ""; }