path enum for transparent low latch

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2024-07-19 17:03:03 -07:00
parent 9359bec909
commit 50a249d7ae
5 changed files with 25 additions and 16 deletions

View File

@ -1914,13 +1914,17 @@ LibertyCell::latchEnable(TimingArcSet *d_to_q_set,
FuncExpr *&enable_func, FuncExpr *&enable_func,
const RiseFall *&enable_edge) const const RiseFall *&enable_edge) const
{ {
enable_port = nullptr;
LatchEnable *latch_enable = latch_d_to_q_map_.findKey(d_to_q_set); LatchEnable *latch_enable = latch_d_to_q_map_.findKey(d_to_q_set);
if (latch_enable) { if (latch_enable) {
enable_port = latch_enable->enable(); enable_port = latch_enable->enable();
enable_func = latch_enable->enableFunc(); enable_func = latch_enable->enableFunc();
enable_edge = latch_enable->enableEdge(); enable_edge = latch_enable->enableEdge();
} }
else {
enable_port = nullptr;
enable_func = nullptr;
enable_edge = nullptr;
}
} }
const RiseFall * const RiseFall *

View File

@ -3927,8 +3927,8 @@ LibertyReader::endTiming(LibertyGroup *group)
{ {
if (timing_) { if (timing_) {
// Set scale factor type in constraint tables. // Set scale factor type in constraint tables.
for (auto tr : RiseFall::range()) { for (auto rf : RiseFall::range()) {
TableModel *model = timing_->constraint(tr); TableModel *model = timing_->constraint(rf);
if (model) { if (model) {
ScaleFactorType type=timingTypeScaleFactorType(timing_->attrs()->timingType()); ScaleFactorType type=timingTypeScaleFactorType(timing_->attrs()->timingType());
model->setScaleFactorType(type); model->setScaleFactorType(type);

View File

@ -399,7 +399,7 @@ PathEnumFaninVisitor::reportDiversion(TimingArc *div_arc,
report_->reportLine("path_enum: from %s -> %s", report_->reportLine("path_enum: from %s -> %s",
div_prev.name(this), div_prev.name(this),
before_div_.name(this)); before_div_.name(this));
report_->reportLine("path_enum: to %s ->e", report_->reportLine("path_enum: to %s",
after_div->name(this)); after_div->name(this));
} }
} }
@ -502,9 +502,6 @@ PathEnum::makeDiversions(PathEnd *path_end,
path.prevPath(this, prev_path, prev_arc); path.prevPath(this, prev_path, prev_arc);
PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_, this); PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_, this);
while (prev_arc 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. // Do not enumerate paths in the clk network.
&& !path.isClock(this)) { && !path.isClock(this)) {
// Fanin visitor does all the work. // Fanin visitor does all the work.
@ -512,6 +509,10 @@ PathEnum::makeDiversions(PathEnd *path_end,
// previous path and arc as well as diversions. // previous path and arc as well as diversions.
fanin_visitor.visitFaninPathsThru(path.vertex(this), fanin_visitor.visitFaninPathsThru(path.vertex(this),
prev_path.vertex(this), prev_arc); 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.init(prev_path);
path.prevPath(this, prev_path, prev_arc); path.prevPath(this, prev_path, prev_arc);
} }
@ -574,7 +575,7 @@ PathEnum::updatePathHeadDelays(PathEnumedSeq &paths,
Path *after_div) Path *after_div)
{ {
Tag *prev_tag = after_div->tag(this); 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); Arrival prev_arrival = search_->clkPathArrival(after_div);
for (int i = paths.size() - 1; i >= 0; i--) { for (int i = paths.size() - 1; i >= 0; i--) {
PathEnumed *path = paths[i]; PathEnumed *path = paths[i];
@ -585,19 +586,22 @@ PathEnum::updatePathHeadDelays(PathEnumedSeq &paths,
ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_), ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_),
arc, edge, false, path_ap); arc, edge, false, path_ap);
Arrival arrival = prev_arrival + arc_delay; Arrival arrival = prev_arrival + arc_delay;
debugPrint(debug_, "path_enum", 3, "update arrival %s %s -> %s", debugPrint(debug_, "path_enum", 3, "update arrival %s %s %s -> %s",
path->name(this), path->vertex(this)->name(network_),
path->tag(this)->asString(this),
delayAsString(path->arrival(this), this), delayAsString(path->arrival(this), this),
delayAsString(arrival, this)); delayAsString(arrival, this));
path->setArrival(arrival, this); path->setArrival(arrival, this);
prev_arrival = arrival; 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, // When crpr is enabled the diverion may be from another crpr clk pin,
// so update the tags to use the corresponding ClkInfo. // so update the tags to use the corresponding ClkInfo.
Tag *tag = path->tag(this); Tag *tag = path->tag(this);
Tag *updated_tag = search_->findTag(path->transition(this), Tag *updated_tag = search_->findTag(path->transition(this),
path_ap, path_ap,
clk_info, prev_clk_info,
tag->isClock(), tag->isClock(),
tag->inputDelay(), tag->inputDelay(),
tag->isSegmentStart(), tag->isSegmentStart(),

View File

@ -97,11 +97,12 @@ Tag::asString(bool report_index,
string result; string result;
if (report_index) if (report_index)
result += std::to_string(index_) + " "; result += std::to_string(index_);
if (report_rf_min_max) { if (report_rf_min_max) {
const RiseFall *rf = transition(); const RiseFall *rf = transition();
PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_); PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_);
result += " ";
result += rf->asString(); result += rf->asString();
result += " "; result += " ";
result += path_ap->pathMinMax()->asString(); result += path_ap->pathMinMax()->asString();
@ -109,6 +110,7 @@ Tag::asString(bool report_index,
result += std::to_string(path_ap_index_); result += std::to_string(path_ap_index_);
} }
result += " ";
const ClockEdge *clk_edge = clkEdge(); const ClockEdge *clk_edge = clkEdge();
if (clk_edge) if (clk_edge)
result += clk_edge->name(); result += clk_edge->name();

View File

@ -4901,9 +4901,8 @@ latch_d_to_q_en()
FuncExpr *enable_func; FuncExpr *enable_func;
const RiseFall *enable_rf; const RiseFall *enable_rf;
lib_cell->latchEnable(d_q_set, enable_port, enable_func, enable_rf); lib_cell->latchEnable(d_q_set, enable_port, enable_func, enable_rf);
const char *en_name = enable_port->name(); if (enable_port)
return stringPrintTmp("%s %s", en_name, enable_rf->asString()); return stringPrintTmp("%s %s", enable_port->name(), enable_rf->asString());
} }
return ""; return "";
} }