From 180b2667ac015f27ce41c462768b1730acbcf117 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Thu, 19 Mar 2026 13:14:14 +0000 Subject: [PATCH 1/6] Fix clktree visualization crash from gui Signed-off-by: dsengupta0628 --- src/gui/src/clockWidget.cpp | 11 ++++++----- src/sta | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/gui/src/clockWidget.cpp b/src/gui/src/clockWidget.cpp index a5301542190..32ff53a4337 100644 --- a/src/gui/src/clockWidget.cpp +++ b/src/gui/src/clockWidget.cpp @@ -1336,11 +1336,12 @@ ClockNodeGraphicsViewItem* ClockTreeView::addLeafToScene( if (lib_port) { const float rise = lib_port->clkTreeDelay( 0.0, sta::RiseFall::rise(), sta::MinMax::max()); - const float fall = lib_port->clkTreeDelay( - 0.0, sta::RiseFall::fall(), sta::MinMax::max()); - - if (rise != 0 || fall != 0) { - ins_delay = (rise + fall) / 2.0; + // When the GUI builds its representation of the clock tree (via + // staGuiInterface::ClockTree::addPath), it explicitly filters the STA + // paths to only trace the rising edge of the clock because that's + // what it wants to visualize. So skip fall here + if (rise != 0) { + ins_delay = rise; } } } diff --git a/src/sta b/src/sta index d213f0fa711..69e11bbd0d4 160000 --- a/src/sta +++ b/src/sta @@ -1 +1 @@ -Subproject commit d213f0fa711cad444e8ef82ee395dc03b6e94510 +Subproject commit 69e11bbd0d4659730c0ef95d92c653a0c72b975f From 0f59482f4e57b464da2f8426dd0ad6805cf933ea Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Thu, 19 Mar 2026 16:55:28 +0000 Subject: [PATCH 2/6] nullcheck on arc in libertyport::clkTreeDelay and associated callers Signed-off-by: dsengupta0628 --- src/cts/src/LatencyBalancer.cpp | 7 +++++-- src/cts/src/TritonCTS.cpp | 4 +++- src/gui/src/clockWidget.cpp | 11 ++++------- src/sta | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/cts/src/LatencyBalancer.cpp b/src/cts/src/LatencyBalancer.cpp index 690672fafd2..47f299b799a 100644 --- a/src/cts/src/LatencyBalancer.cpp +++ b/src/cts/src/LatencyBalancer.cpp @@ -199,7 +199,9 @@ void LatencyBalancer::buildGraph(odb::dbNet* clkInputNet) 0.0, sta::RiseFall::fall(), sta::MinMax::max()); if (rise != 0 || fall != 0) { - insDelay = (rise + fall) / 2.0; + insDelay = (rise != 0 && fall != 0) + ? (rise + fall) / 2.0 + : (rise != 0 ? rise : fall); } } } @@ -341,7 +343,8 @@ void LatencyBalancer::computeSinkArrivalRecur(odb::dbNet* topClokcNet, 0.0, sta::RiseFall::fall(), sta::MinMax::max()); if (rise != 0 || fall != 0) { - insDelay = (rise + fall) / 2.0; + insDelay = (rise != 0 && fall != 0) ? (rise + fall) / 2.0 + : (rise != 0 ? rise : fall); } } } diff --git a/src/cts/src/TritonCTS.cpp b/src/cts/src/TritonCTS.cpp index bcaae1198bb..471de52703e 100644 --- a/src/cts/src/TritonCTS.cpp +++ b/src/cts/src/TritonCTS.cpp @@ -2203,7 +2203,9 @@ double TritonCTS::computeInsertionDelay(const std::string& name, if (rise != 0 || fall != 0) { // use average of max rise and max fall // TODO: do we need to look at min insertion delays? - double delayPerSec = (rise + fall) / 2.0; + double delayPerSec = (rise != 0 && fall != 0) + ? (rise + fall) / 2.0 + : (rise != 0 ? rise : fall); // convert delay to length because HTree uses lengths sta::Scene* corner = openSta_->cmdScene(); double capPerMicron diff --git a/src/gui/src/clockWidget.cpp b/src/gui/src/clockWidget.cpp index 32ff53a4337..724f30e0503 100644 --- a/src/gui/src/clockWidget.cpp +++ b/src/gui/src/clockWidget.cpp @@ -1336,13 +1336,10 @@ ClockNodeGraphicsViewItem* ClockTreeView::addLeafToScene( if (lib_port) { const float rise = lib_port->clkTreeDelay( 0.0, sta::RiseFall::rise(), sta::MinMax::max()); - // When the GUI builds its representation of the clock tree (via - // staGuiInterface::ClockTree::addPath), it explicitly filters the STA - // paths to only trace the rising edge of the clock because that's - // what it wants to visualize. So skip fall here - if (rise != 0) { - ins_delay = rise; - } + const float fall = lib_port->clkTreeDelay( + 0.0, sta::RiseFall::fall(), sta::MinMax::max()); + (rise != 0 && fall != 0) ? (rise + fall) / 2.0 + : (rise != 0 ? rise : fall); } } diff --git a/src/sta b/src/sta index 69e11bbd0d4..8e45eff4b9e 160000 --- a/src/sta +++ b/src/sta @@ -1 +1 @@ -Subproject commit 69e11bbd0d4659730c0ef95d92c653a0c72b975f +Subproject commit 8e45eff4b9e7740bf332b86103850adca447e0b7 From 3933aa12fadfb726400e2e94fbf08a37b349e0df Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Thu, 19 Mar 2026 17:48:20 +0000 Subject: [PATCH 3/6] update sta with fixed regression Signed-off-by: dsengupta0628 --- src/sta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sta b/src/sta index 8e45eff4b9e..2e0b35c4b20 160000 --- a/src/sta +++ b/src/sta @@ -1 +1 @@ -Subproject commit 8e45eff4b9e7740bf332b86103850adca447e0b7 +Subproject commit 2e0b35c4b20c488194f46a77e8b3c0430d97e3f4 From 7b80f59b006e36ff5dce5d43612b4a9c8a7f347c Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Thu, 19 Mar 2026 18:09:52 +0000 Subject: [PATCH 4/6] lhs ins_delay was missing- fixed now Signed-off-by: dsengupta0628 --- src/gui/src/clockWidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/src/clockWidget.cpp b/src/gui/src/clockWidget.cpp index 724f30e0503..defcbade3dd 100644 --- a/src/gui/src/clockWidget.cpp +++ b/src/gui/src/clockWidget.cpp @@ -1338,8 +1338,8 @@ ClockNodeGraphicsViewItem* ClockTreeView::addLeafToScene( 0.0, sta::RiseFall::rise(), sta::MinMax::max()); const float fall = lib_port->clkTreeDelay( 0.0, sta::RiseFall::fall(), sta::MinMax::max()); - (rise != 0 && fall != 0) ? (rise + fall) / 2.0 - : (rise != 0 ? rise : fall); + ins_delay = (rise != 0 && fall != 0) ? (rise + fall) / 2.0 + : (rise != 0 ? rise : fall); } } From 1d1d9636bdf5dba0ac8056b7bfca541fe5098d69 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Thu, 19 Mar 2026 18:37:28 +0000 Subject: [PATCH 5/6] ignore readability problem for ternary ops Signed-off-by: dsengupta0628 --- src/cts/src/LatencyBalancer.cpp | 17 ++++++++++++----- src/cts/src/TritonCTS.cpp | 9 ++++++--- src/gui/src/clockWidget.cpp | 8 ++++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/cts/src/LatencyBalancer.cpp b/src/cts/src/LatencyBalancer.cpp index 47f299b799a..5b04a8809c8 100644 --- a/src/cts/src/LatencyBalancer.cpp +++ b/src/cts/src/LatencyBalancer.cpp @@ -199,9 +199,12 @@ void LatencyBalancer::buildGraph(odb::dbNet* clkInputNet) 0.0, sta::RiseFall::fall(), sta::MinMax::max()); if (rise != 0 || fall != 0) { - insDelay = (rise != 0 && fall != 0) - ? (rise + fall) / 2.0 - : (rise != 0 ? rise : fall); + insDelay + = (rise != 0 && fall != 0) + ? (rise + fall) / 2.0 + : (rise != 0 + ? rise + : fall); // NOLINT(readability-avoid-nested-conditional-operator) } } } @@ -343,8 +346,12 @@ void LatencyBalancer::computeSinkArrivalRecur(odb::dbNet* topClokcNet, 0.0, sta::RiseFall::fall(), sta::MinMax::max()); if (rise != 0 || fall != 0) { - insDelay = (rise != 0 && fall != 0) ? (rise + fall) / 2.0 - : (rise != 0 ? rise : fall); + insDelay + = (rise != 0 && fall != 0) + ? (rise + fall) / 2.0 + : (rise != 0 + ? rise + : fall); // NOLINT(readability-avoid-nested-conditional-operator) } } } diff --git a/src/cts/src/TritonCTS.cpp b/src/cts/src/TritonCTS.cpp index 471de52703e..16c715dd6b8 100644 --- a/src/cts/src/TritonCTS.cpp +++ b/src/cts/src/TritonCTS.cpp @@ -2203,9 +2203,12 @@ double TritonCTS::computeInsertionDelay(const std::string& name, if (rise != 0 || fall != 0) { // use average of max rise and max fall // TODO: do we need to look at min insertion delays? - double delayPerSec = (rise != 0 && fall != 0) - ? (rise + fall) / 2.0 - : (rise != 0 ? rise : fall); + double delayPerSec + = (rise != 0 && fall != 0) + ? (rise + fall) / 2.0 + : (rise != 0 + ? rise + : fall); // NOLINT(readability-avoid-nested-conditional-operator) // convert delay to length because HTree uses lengths sta::Scene* corner = openSta_->cmdScene(); double capPerMicron diff --git a/src/gui/src/clockWidget.cpp b/src/gui/src/clockWidget.cpp index defcbade3dd..1a48605e951 100644 --- a/src/gui/src/clockWidget.cpp +++ b/src/gui/src/clockWidget.cpp @@ -1338,8 +1338,12 @@ ClockNodeGraphicsViewItem* ClockTreeView::addLeafToScene( 0.0, sta::RiseFall::rise(), sta::MinMax::max()); const float fall = lib_port->clkTreeDelay( 0.0, sta::RiseFall::fall(), sta::MinMax::max()); - ins_delay = (rise != 0 && fall != 0) ? (rise + fall) / 2.0 - : (rise != 0 ? rise : fall); + ins_delay + = (rise != 0 && fall != 0) + ? (rise + fall) / 2.0 + : (rise != 0 + ? rise + : fall); // NOLINT(readability-avoid-nested-conditional-operator) } } From d59d9b6c68e1834339e87712e5f2b9a09094d579 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Thu, 19 Mar 2026 19:21:00 +0000 Subject: [PATCH 6/6] reformatted Signed-off-by: dsengupta0628 --- src/cts/src/LatencyBalancer.cpp | 20 ++++++++------------ src/cts/src/TritonCTS.cpp | 10 ++++------ src/gui/src/clockWidget.cpp | 10 ++++------ 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/cts/src/LatencyBalancer.cpp b/src/cts/src/LatencyBalancer.cpp index 5b04a8809c8..a2464c13e37 100644 --- a/src/cts/src/LatencyBalancer.cpp +++ b/src/cts/src/LatencyBalancer.cpp @@ -199,12 +199,10 @@ void LatencyBalancer::buildGraph(odb::dbNet* clkInputNet) 0.0, sta::RiseFall::fall(), sta::MinMax::max()); if (rise != 0 || fall != 0) { - insDelay - = (rise != 0 && fall != 0) - ? (rise + fall) / 2.0 - : (rise != 0 - ? rise - : fall); // NOLINT(readability-avoid-nested-conditional-operator) + insDelay = (rise + fall); + if (rise != 0 && fall != 0) { + insDelay /= 2.0; + } } } } @@ -346,12 +344,10 @@ void LatencyBalancer::computeSinkArrivalRecur(odb::dbNet* topClokcNet, 0.0, sta::RiseFall::fall(), sta::MinMax::max()); if (rise != 0 || fall != 0) { - insDelay - = (rise != 0 && fall != 0) - ? (rise + fall) / 2.0 - : (rise != 0 - ? rise - : fall); // NOLINT(readability-avoid-nested-conditional-operator) + insDelay = (rise + fall); + if (rise != 0 && fall != 0) { + insDelay /= 2.0; + } } } } diff --git a/src/cts/src/TritonCTS.cpp b/src/cts/src/TritonCTS.cpp index 16c715dd6b8..a3135262012 100644 --- a/src/cts/src/TritonCTS.cpp +++ b/src/cts/src/TritonCTS.cpp @@ -2203,12 +2203,10 @@ double TritonCTS::computeInsertionDelay(const std::string& name, if (rise != 0 || fall != 0) { // use average of max rise and max fall // TODO: do we need to look at min insertion delays? - double delayPerSec - = (rise != 0 && fall != 0) - ? (rise + fall) / 2.0 - : (rise != 0 - ? rise - : fall); // NOLINT(readability-avoid-nested-conditional-operator) + double delayPerSec = (rise + fall); + if (rise != 0 && fall != 0) { + delayPerSec /= 2.0; + } // convert delay to length because HTree uses lengths sta::Scene* corner = openSta_->cmdScene(); double capPerMicron diff --git a/src/gui/src/clockWidget.cpp b/src/gui/src/clockWidget.cpp index 1a48605e951..3690843b70a 100644 --- a/src/gui/src/clockWidget.cpp +++ b/src/gui/src/clockWidget.cpp @@ -1338,12 +1338,10 @@ ClockNodeGraphicsViewItem* ClockTreeView::addLeafToScene( 0.0, sta::RiseFall::rise(), sta::MinMax::max()); const float fall = lib_port->clkTreeDelay( 0.0, sta::RiseFall::fall(), sta::MinMax::max()); - ins_delay - = (rise != 0 && fall != 0) - ? (rise + fall) / 2.0 - : (rise != 0 - ? rise - : fall); // NOLINT(readability-avoid-nested-conditional-operator) + ins_delay = (rise + fall); + if (rise != 0 && fall != 0) { + ins_delay /= 2.0; + } } }