diff --git a/Dockerfile.ubuntu22.04 b/Dockerfile.ubuntu22.04 index 9a803c8f..e636fc21 100644 --- a/Dockerfile.ubuntu22.04 +++ b/Dockerfile.ubuntu22.04 @@ -6,9 +6,11 @@ LABEL maintainer="James Cherry " ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ + git \ wget \ cmake \ gcc \ + gdb \ tcl-dev \ tcl-tclreadline \ libeigen3-dev \ diff --git a/include/sta/TimingRole.hh b/include/sta/TimingRole.hh index 3621f63c..d77a8454 100644 --- a/include/sta/TimingRole.hh +++ b/include/sta/TimingRole.hh @@ -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. diff --git a/liberty/TimingRole.cc b/liberty/TimingRole.cc index 1839e52f..e772d1bc 100644 --- a/liberty/TimingRole.cc +++ b/liberty/TimingRole.cc @@ -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 { diff --git a/search/Levelize.cc b/search/Levelize.cc index 5a0127b0..a53f8f7e 100644 --- a/search/Levelize.cc +++ b/search/Levelize.cc @@ -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()) { diff --git a/search/Sta.cc b/search/Sta.cc index 7899a110..527e8ee1 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -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); }