relevelize latch EN->Q

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2026-03-05 13:33:58 -08:00
parent 62cd210a8a
commit 8ed837d74b
5 changed files with 49 additions and 17 deletions

View File

@ -6,9 +6,11 @@ LABEL maintainer="James Cherry <cherry@parallaxsw.com>"
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y \
git \
wget \
cmake \
gcc \
gdb \
tcl-dev \
tcl-tclreadline \
libeigen3-dev \

View File

@ -78,6 +78,7 @@ public:
[[nodiscard]] bool isNonSeqTimingCheck() const { return is_non_seq_check_; }
[[nodiscard]] bool isDataCheck() const;
[[nodiscard]] bool isLatchDtoQ() const;
[[nodiscard]] bool isLatchEnToQ() const;
const TimingRole *genericRole() const;
const TimingRole *sdfRole() const;
// Timing check data path min/max.

View File

@ -163,6 +163,12 @@ TimingRole::isLatchDtoQ() const
return this == &latch_d_q_;
}
bool
TimingRole::isLatchEnToQ() const
{
return this == &latch_en_q_;
}
bool
TimingRole::isTimingCheckBetween() const
{

View File

@ -526,8 +526,16 @@ Levelize::ensureLatchLevels()
for (Edge *edge : latch_d_to_q_edges_) {
Vertex *from = edge->from(graph_);
Vertex *to = edge->to(graph_);
if (from->level() == to->level())
setLevel(from, from->level() + level_space_);
if (from->level() == to->level()) {
Level adjusted_level = from->level() + level_space_;
debugPrint(debug_, "levelize", 2, "latch %s %d (adjusted %d) -> %s %d",
from->to_string(this).c_str(),
from->level(),
adjusted_level,
to->to_string(this).c_str(),
to->level());
setLevel(from, adjusted_level);
}
}
latch_d_to_q_edges_.clear();
}
@ -536,7 +544,7 @@ void
Levelize::setLevel(Vertex *vertex,
Level level)
{
debugPrint(debug_, "levelize", 2, "set level %s %d",
debugPrint(debug_, "levelize", 3, "set level %s %d",
vertex->to_string(this).c_str(),
level);
vertex->setLevel(level);
@ -602,7 +610,7 @@ void
Levelize::relevelize()
{
for (Vertex *vertex : relevelize_from_) {
debugPrint(debug_, "levelize", 1, "relevelize from %s",
debugPrint(debug_, "levelize", 2, "relevelize from %s",
vertex->to_string(this).c_str());
if (isRoot(vertex))
roots_.insert(vertex);
@ -641,9 +649,20 @@ Levelize::visit(Vertex *vertex,
visit(to_vertex, edge, level+level_space, level_space,
path_vertices, path);
}
if (edge->role() == TimingRole::latchDtoQ())
const TimingRole *role = edge->role();
if (role->isLatchDtoQ())
latch_d_to_q_edges_.insert(edge);
if (role->isLatchEnToQ()) {
VertexInEdgeIterator edge_iter2(to_vertex, graph_);
while (edge_iter2.hasNext()) {
Edge *edge2 = edge_iter2.next();
if (edge2->role()->isLatchDtoQ())
latch_d_to_q_edges_.insert(edge2);
}
}
}
// Levelize bidirect driver as if it was a fanout of the bidirect load.
if (graph_delay_calc_->bidirectDrvrSlewFromLoad(from_pin)
&& !vertex->isBidirectDriver()) {

View File

@ -4671,12 +4671,14 @@ Sta::connectLoadPinAfter(Vertex *vertex)
VertexInEdgeIterator edge_iter(vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
Vertex *from_vertex = edge->from(graph_);
graph_delay_calc_->delayInvalid(from_vertex);
search_->requiredInvalid(from_vertex);
for (Mode *mode : modes_)
mode->sdc()->clkHpinDisablesChanged(from_vertex->pin());
levelize_->relevelizeFrom(from_vertex);
if (!edge->role()->isTimingCheck()) {
Vertex *from_vertex = edge->from(graph_);
graph_delay_calc_->delayInvalid(from_vertex);
search_->requiredInvalid(from_vertex);
levelize_->relevelizeFrom(from_vertex);
for (Mode *mode : modes_)
mode->sdc()->clkHpinDisablesChanged(from_vertex->pin());
}
}
Pin *pin = vertex->pin();
for (Mode *mode : modes_) {
@ -4754,12 +4756,14 @@ Sta::deleteEdge(Edge *edge)
edge->from(graph_)->name(sdc_network_),
edge->to(graph_)->name(sdc_network_));
Vertex *to = edge->to(graph_);
search_->deleteEdgeBefore(edge);
graph_delay_calc_->delayInvalid(to);
levelize_->relevelizeFrom(to);
levelize_->deleteEdgeBefore(edge);
for (Mode *mode : modes_)
mode->sdc()->clkHpinDisablesChanged(edge->from(graph_)->pin());
if (!edge->role()->isTimingCheck()) {
search_->deleteEdgeBefore(edge);
graph_delay_calc_->delayInvalid(to);
levelize_->relevelizeFrom(to);
levelize_->deleteEdgeBefore(edge);
for (Mode *mode : modes_)
mode->sdc()->clkHpinDisablesChanged(edge->from(graph_)->pin());
}
graph_->deleteEdge(edge);
}