From b136ba309a66ca015d438e04329b8c326a16d92a Mon Sep 17 00:00:00 2001 From: James Cherry Date: Thu, 9 Apr 2026 15:13:40 -0700 Subject: [PATCH 01/10] PrimaDelayCalc::reportGateDelay resolves #418 Signed-off-by: James Cherry --- dcalc/PrimaDelayCalc.cc | 146 +++++++++++++++++++++++++++++----------- dcalc/PrimaDelayCalc.hh | 7 ++ 2 files changed, 113 insertions(+), 40 deletions(-) diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index 561b7953..93388a10 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -216,43 +216,8 @@ PrimaDelayCalc::gateDelays(ArcDcalcArgSeq &dcalc_args, parasitics_ = scene->parasitics(min_max); node_index_map_ = NodeIndexMap(ParasiticNodeLess(parasitics_, network_)); - bool failed = false; - output_waveforms_.resize(drvr_count_); - for (size_t drvr_idx = 0; drvr_idx < drvr_count_; drvr_idx++) { - ArcDcalcArg &dcalc_arg = dcalc_args[drvr_idx]; - GateTableModel *table_model = dcalc_arg.arc()->gateTableModel(scene, min_max); - if (table_model && dcalc_arg.parasitic()) { - OutputWaveforms *output_waveforms = table_model->outputWaveforms(); - float in_slew = dcalc_arg.inSlewFlt(); - if (output_waveforms - // Bounds check because extrapolating waveforms does not work for shit. - && output_waveforms->slewAxis()->inBounds(in_slew) - && output_waveforms->capAxis()->inBounds(dcalc_arg.loadCap())) { - output_waveforms_[drvr_idx] = output_waveforms; - debugPrint(debug_, "ccs_dcalc", 1, "{} {}", dcalc_arg.drvrCell()->name(), - drvr_rf_->shortName()); - LibertyCell *drvr_cell = dcalc_arg.drvrCell(); - const LibertyLibrary *drvr_library = drvr_cell->libertyLibrary(); - bool vdd_exists; - drvr_library->supplyVoltage("VDD", vdd_, vdd_exists); - if (!vdd_exists) - report_->error(1720, "VDD not defined in library {}", - drvr_library->name()); - drvr_cell->ensureVoltageWaveforms(scenes_); - if (drvr_idx == 0) { - vth_ = drvr_library->outputThreshold(drvr_rf_) * vdd_; - vl_ = drvr_library->slewLowerThreshold(drvr_rf_) * vdd_; - vh_ = drvr_library->slewUpperThreshold(drvr_rf_) * vdd_; - } - } - else - failed = true; - } - else - failed = true; - } - - if (failed) + bool arg_fail = checkArgs(dcalc_args, scene, min_max); + if (arg_fail) return tableDcalcResults(); else { simulate(); @@ -260,6 +225,100 @@ PrimaDelayCalc::gateDelays(ArcDcalcArgSeq &dcalc_args, } } +// Return true on failure. +// Use falureReason() to get failure string. +bool +PrimaDelayCalc::checkArgs(ArcDcalcArgSeq &dcalc_args, + const Scene *scene, + const MinMax *min_max) +{ + drvr_count_ = dcalc_args.size(); + output_waveforms_.resize(drvr_count_); + failure_reason_ = nullptr; + failure_arg_ = nullptr; + for (size_t drvr_idx = 0; drvr_idx < drvr_count_; drvr_idx++) { + ArcDcalcArg &dcalc_arg = dcalc_args[drvr_idx]; + GateTableModel *table_model = dcalc_arg.arc()->gateTableModel(scene, min_max); + if (table_model) { + if (dcalc_arg.parasitic()) { + OutputWaveforms *output_waveforms = table_model->outputWaveforms(); + float in_slew = dcalc_arg.inSlewFlt(); + if (output_waveforms) { + const LibertyLibrary *drvr_library = dcalc_arg.drvrLibrary(); + float vdd; + bool vdd_exists; + drvr_library->supplyVoltage("VDD", vdd, vdd_exists); + if (vdd_exists) { + if (drvr_idx == 0) { + // Assume drivers are in the same library. + const RiseFall *drvr_rf = dcalc_arg.drvrEdge(); + vdd_ = vdd; + vth_ = drvr_library->outputThreshold(drvr_rf) * vdd_; + vl_ = drvr_library->slewLowerThreshold(drvr_rf) * vdd_; + vh_ = drvr_library->slewUpperThreshold(drvr_rf) * vdd_; + } + } + else { + failure_reason_ = "vdd not defined"; + failure_arg_ = &dcalc_arg; + } + + // Bounds check because extrapolating waveforms does not work for shit. + if (output_waveforms->slewAxis()->inBounds(in_slew)) { + if (output_waveforms->capAxis()->inBounds(dcalc_arg.loadCap())) { + output_waveforms_[drvr_idx] = output_waveforms; + debugPrint(debug_, "prima", 1, "{} {}", + dcalc_arg.drvrCell()->name(), + dcalc_arg.drvrEdge()->to_string().c_str()); + LibertyCell *drvr_cell = dcalc_arg.drvrCell(); + drvr_cell->ensureVoltageWaveforms(scenes_); + } + else { + failure_reason_ = "load cap out of bounds"; + failure_arg_ = &dcalc_arg; + } + } + else { + failure_reason_ = "input slew out of bounds"; + failure_arg_ = &dcalc_arg; + } + } + else { + failure_reason_ = "no output waveforms"; + failure_arg_ = &dcalc_arg; + } + } + else { + failure_reason_ = "no parasitic"; + failure_arg_ = &dcalc_arg; + } + } + else { + failure_reason_ = "no table model"; + failure_arg_ = &dcalc_arg; + } + } + if (failure_reason_) { + std::string reason = failureReason(); + debugPrint(debug_,"prima", 1, "arg check failed {}.", reason.c_str()); + } + return failure_reason_ != nullptr; +} + +std::string +PrimaDelayCalc::failureReason() +{ + const Pin *drvr_pin = failure_arg_->drvrPin(); + const Instance *inst = network_->instance(drvr_pin); + LibertyPort *from = failure_arg_->arc()->from(); + LibertyPort *to = failure_arg_->arc()->to(); + return sta::format("{} {} -> {} {}", + sdc_network_->pathName(inst), + from->name(), + to->name(), + failure_reason_); +} + ArcDcalcResultSeq PrimaDelayCalc::tableDcalcResults() { @@ -938,8 +997,16 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, const MinMax *min_max, int digits) { - GateTimingModel *model = arc->gateModel(scene, min_max); - if (model) { + ArcDcalcArgSeq dcalc_args; + dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew, + load_cap, parasitic); + bool arg_fail = checkArgs(dcalc_args, scene, min_max); + if (arg_fail) + return table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap, + parasitic, load_pin_index_map, scene, + min_max, digits); + else { + GateTimingModel *model = arc->gateModel(scene, min_max); // Delay calc to find ceff. gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic, load_pin_index_map, scene, min_max); @@ -949,7 +1016,6 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, in_slew1, ceff, min_max, PocvMode::scalar, digits); } - return ""; } //////////////////////////////////////////////////////////////// diff --git a/dcalc/PrimaDelayCalc.hh b/dcalc/PrimaDelayCalc.hh index c0b39ba7..086e29ce 100644 --- a/dcalc/PrimaDelayCalc.hh +++ b/dcalc/PrimaDelayCalc.hh @@ -100,6 +100,10 @@ public: const Scene *scene, const MinMax *min_max, int digits) override; + bool checkArgs(ArcDcalcArgSeq &dcalc_args, + const Scene *scene, + const MinMax *min_max); + std::string failureReason(); // Record waveform for drvr/load pin. void watchPin(const Pin *pin) override; @@ -253,6 +257,9 @@ protected: // Delay calculator to use when ccs waveforms are missing from liberty. ArcDelayCalc *table_dcalc_; + const char *failure_reason_; + ArcDcalcArg *failure_arg_; + using ArcDelayCalc::reduceParasitic; }; From d6268da88f93f695ee8b427959bd49422276c11f Mon Sep 17 00:00:00 2001 From: Mike Inouye Date: Fri, 10 Apr 2026 10:28:01 -0700 Subject: [PATCH 02/10] Consider multi-bit flops as having sequentials. (#419) --- liberty/Liberty.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 31e17cbe..ae375e21 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1489,7 +1489,7 @@ LibertyCell::outputPortSequential(LibertyPort *port) bool LibertyCell::hasSequentials() const { - return !sequentials_.empty(); + return !sequentials_.empty() || statetable_ != nullptr; } void From 53f53e464a4d24109b246854bddd439846e9e03d Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 10 Apr 2026 10:22:17 -0700 Subject: [PATCH 03/10] CmakeLists Signed-off-by: James Cherry --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f3495ba..57d080be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -595,13 +595,13 @@ set(CXX_FLAGS -Wall -Wextra -pedantic -Wcast-qual -Wredundant-decls if(ENABLE_TSAN) message(STATUS "Thread sanitizer: ${ENABLE_TSAN}") set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=thread") - set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=thread") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=thread") endif() if(ENABLE_ASAN) message(STATUS "Address sanitizer: ${ENABLE_ASAN}") set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=address") - set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=address") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=address") endif() target_compile_options(OpenSTA @@ -627,6 +627,7 @@ message(STATUS "STA library: ${CMAKE_BINARY_DIR}/libOpenSTA.a") add_executable(sta app/Main.cc) target_link_libraries(sta + PRIVATE sta_swig OpenSTA ) From 6ef92c5fc09356b4691e6f29c09162534d5ac489 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 10 Apr 2026 10:35:36 -0700 Subject: [PATCH 04/10] LibertyPort::less Signed-off-by: James Cherry --- liberty/Liberty.cc | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index ae375e21..1817a7a2 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -2477,18 +2477,10 @@ bool LibertyPort::less(const LibertyPort *port1, const LibertyPort *port2) { - if (port1 == nullptr && port2 != nullptr) - return true; - if (port1 != nullptr && port2 == nullptr) - return false; - const std::string &name1 = port1->name(); - const std::string &name2 = port2->name(); - if (name1 == name2) { - PortDirection *dir1 = port1->direction(); - PortDirection *dir2 = port2->direction(); - return dir1->index() < dir2->index(); - } - return name1 < name2; + if (port1 && port2) + return port1->pinIndex() < port2->pinIndex(); + else + return port1 == nullptr && port2 != nullptr; } void From 094aa1adc4e7db14f89f6372ca05a0775df3f120 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 10 Apr 2026 10:53:55 -0700 Subject: [PATCH 05/10] VerilogNamespace use string_view Signed-off-by: James Cherry --- include/sta/VerilogNamespace.hh | 17 ++++---- network/VerilogNamespace.cc | 76 ++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 37 deletions(-) diff --git a/include/sta/VerilogNamespace.hh b/include/sta/VerilogNamespace.hh index bcdddb52..5b874189 100644 --- a/include/sta/VerilogNamespace.hh +++ b/include/sta/VerilogNamespace.hh @@ -25,25 +25,26 @@ #pragma once #include +#include namespace sta { std::string -cellVerilogName(std::string sta_name); +cellVerilogName(std::string_view sta_name); std::string -instanceVerilogName(std::string sta_name); +instanceVerilogName(std::string_view sta_name); std::string -netVerilogName(std::string sta_name); +netVerilogName(std::string_view sta_name); std::string -portVerilogName(std::string sta_name); +portVerilogName(std::string_view sta_name); std::string -moduleVerilogToSta(std::string sta_name); +moduleVerilogToSta(std::string_view sta_name); std::string -instanceVerilogToSta(std::string sta_name); +instanceVerilogToSta(std::string_view sta_name); std::string -netVerilogToSta(std::string sta_name); +netVerilogToSta(std::string_view sta_name); std::string -portVerilogToSta(std::string sta_name); +portVerilogToSta(std::string_view sta_name); } // namespace diff --git a/network/VerilogNamespace.cc b/network/VerilogNamespace.cc index b12d9c3a..28f07dc0 100644 --- a/network/VerilogNamespace.cc +++ b/network/VerilogNamespace.cc @@ -34,26 +34,26 @@ namespace sta { constexpr char verilog_escape = '\\'; static std::string -staToVerilog(std::string sta_name); +staToVerilog(std::string_view sta_name); static std::string -staToVerilog2(std::string sta_name); +staToVerilog2(std::string_view sta_name); static std::string -verilogToSta(const std::string verilog_name); +verilogToSta(const std::string_view verilog_name); std::string -cellVerilogName(std::string sta_name) +cellVerilogName(std::string_view sta_name) { return staToVerilog(sta_name); } std::string -instanceVerilogName(std::string sta_name) +instanceVerilogName(std::string_view sta_name) { return staToVerilog(sta_name); } std::string -netVerilogName(std::string sta_name) +netVerilogName(std::string_view sta_name) { bool is_bus; std::string bus_name; @@ -69,13 +69,20 @@ netVerilogName(std::string sta_name) } std::string -portVerilogName(std::string sta_name) +portVerilogName(std::string_view sta_name) { return staToVerilog2(sta_name); } +// functions expect a value representable as unsigned char or EOF. +static bool +isAlnumUnderscore(char ch) +{ + return std::isalnum(static_cast(ch)) != 0 || ch == '_'; +} + static std::string -staToVerilog(std::string sta_name) +staToVerilog(std::string_view sta_name) { // Leave room for leading escape and trailing space if the name // needs to be escaped. @@ -87,14 +94,18 @@ staToVerilog(std::string sta_name) char ch = sta_name[i]; if (ch == verilog_escape) { escaped = true; - char next_ch = sta_name[i + 1]; - if (next_ch == verilog_escape) { - escaped_name += next_ch; - i++; + if (i + 1 < sta_length) { + char next_ch = sta_name[i + 1]; + if (next_ch == verilog_escape) { + escaped_name += next_ch; + i++; + } } + else + escaped_name += ch; } else { - if ((!(isalnum(ch) || ch == '_'))) + if (!isAlnumUnderscore(ch)) escaped = true; escaped_name += ch; } @@ -105,11 +116,11 @@ staToVerilog(std::string sta_name) return escaped_name; } else - return sta_name; + return std::string(sta_name); } static std::string -staToVerilog2(std::string sta_name) +staToVerilog2(std::string_view sta_name) { constexpr char bus_brkt_left = '['; constexpr char bus_brkt_right = ']'; @@ -123,16 +134,19 @@ staToVerilog2(std::string sta_name) char ch = sta_name[i]; if (ch == verilog_escape) { escaped = true; - char next_ch = sta_name[i + 1]; - if (next_ch == verilog_escape) { - escaped_name += next_ch; - i++; + if (i + 1 < sta_length) { + char next_ch = sta_name[i + 1]; + if (next_ch == verilog_escape) { + escaped_name += next_ch; + i++; + } } + else + escaped_name += ch; } else { bool is_brkt = (ch == bus_brkt_left || ch == bus_brkt_right); - if ((!(isalnum(ch) || ch == '_') && !is_brkt) - || is_brkt) + if ((!isAlnumUnderscore(ch) && !is_brkt) || is_brkt) escaped = true; escaped_name += ch; } @@ -143,45 +157,49 @@ staToVerilog2(std::string sta_name) return escaped_name; } else - return sta_name; + return std::string(sta_name); } //////////////////////////////////////////////////////////////// std::string -moduleVerilogToSta(std::string module_name) +moduleVerilogToSta(std::string_view module_name) { return verilogToSta(module_name); } std::string -instanceVerilogToSta(std::string inst_name) +instanceVerilogToSta(std::string_view inst_name) { return verilogToSta(inst_name); } std::string -netVerilogToSta(std::string net_name) +netVerilogToSta(std::string_view net_name) { return verilogToSta(net_name); } std::string -portVerilogToSta(std::string port_name) +portVerilogToSta(std::string_view port_name) { return verilogToSta(port_name); } static std::string -verilogToSta(std::string verilog_name) +verilogToSta(std::string_view verilog_name) { + if (verilog_name.empty()) + return std::string(verilog_name); + if (verilog_name.front() == '\\') { constexpr char divider = '/'; constexpr char bus_brkt_left = '['; constexpr char bus_brkt_right = ']'; size_t verilog_name_length = verilog_name.size(); - if (isspace(verilog_name.back())) + if (verilog_name_length > 1 + && std::isspace(static_cast(verilog_name.back())) != 0) verilog_name_length--; std::string sta_name; // Ignore leading '\'. @@ -198,7 +216,7 @@ verilogToSta(std::string verilog_name) return sta_name; } else - return verilog_name; + return std::string(verilog_name); } } // namespace From 0a8a86d606f7db262b7611823ad1cb757498d5dc Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 10 Apr 2026 14:49:25 -0700 Subject: [PATCH 06/10] FilterObjects use string_view Signed-off-by: James Cherry --- CMakeLists.txt | 3 + include/sta/FilterObjects.hh | 1 + sdc/FilterObjects.cc | 111 +++++++++++++++++++---------------- 3 files changed, 66 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57d080be..b9308293 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,9 @@ option(ENABLE_ASAN "Compile with address santizer enabled" OFF) # Turn on to debug compiler args. set(CMAKE_VERBOSE_MAKEFILE OFF) +# Write compile_commands.json to the build directory for clang-tidy. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(STA_HOME ${PROJECT_SOURCE_DIR}) message(STATUS "STA version: ${PROJECT_VERSION}") diff --git a/include/sta/FilterObjects.hh b/include/sta/FilterObjects.hh index 7420b450..dbeec3c5 100644 --- a/include/sta/FilterObjects.hh +++ b/include/sta/FilterObjects.hh @@ -28,6 +28,7 @@ #include #include +#include "NetworkClass.hh" #include "SdcClass.hh" #include "SearchClass.hh" #include "StringUtil.hh" diff --git a/sdc/FilterObjects.cc b/sdc/FilterObjects.cc index 6e263037..45e59997 100644 --- a/sdc/FilterObjects.cc +++ b/sdc/FilterObjects.cc @@ -24,11 +24,17 @@ #include "FilterObjects.hh" -#include -#include #include #include +#include +#include +#include +#include +#include +#include "NetworkClass.hh" +#include "Network.hh" +#include "StringUtil.hh" #include "Property.hh" #include "PatternMatch.hh" #include "Sta.hh" @@ -52,22 +58,27 @@ public: undefined }; - Token(std::string text, + Token(std::string_view text, Kind kind); - - std::string text; - Kind kind; + const std::string &text() const { return text_; } + Kind kind() const { return kind_; } + + std::string text_; + Kind kind_; }; struct PredicateToken : public Token { - PredicateToken(std::string property, - std::string op, - std::string arg); + PredicateToken(std::string_view property, + std::string_view op, + std::string_view arg); + const std::string &property() const { return property_; } + const std::string &op() const { return op_; } + const std::string &arg() const { return arg_; } - std::string property; - std::string op; - std::string arg; + std::string property_; + std::string op_; + std::string arg_; }; FilterExpr(std::string_view expression, @@ -82,19 +93,21 @@ private: Report *report_; }; -FilterExpr::Token::Token(std::string text, +FilterExpr::Token::Token(std::string_view text, Token::Kind kind) : - text (text), - kind(kind) + text_(text), + kind_(kind) { } -FilterExpr::PredicateToken::PredicateToken(std::string property, - std::string op, - std::string arg) : - Token(property + " " + op + " " + arg, +FilterExpr::PredicateToken::PredicateToken(std::string_view property, + std::string_view op, + std::string_view arg) : + Token(sta::format("{} {} {}", property, op, arg), Token::Kind::predicate), - property(property), op(op), arg(arg) + property_(property), + op_(op), + arg_(arg) { } @@ -140,7 +153,7 @@ FilterExpr::lex() std::string property = token_match[1].str(); // The default operation on a predicate if an op and arg are - // omitted is 'prop == 1 || true'. + // omitted is 'prop == 1'. std::string op = "=="; std::string arg = "1"; @@ -175,7 +188,7 @@ FilterExpr::shuntingYard(std::vector> &infix) std::stack> operator_stack; for (auto &token : infix) { - switch (token->kind) { + switch (token->kind()) { case Token::Kind::predicate: output.push_back(std::move(token)); break; @@ -185,7 +198,7 @@ FilterExpr::shuntingYard(std::vector> &infix) // The operators' enum values are ascending by precedence: // inv > and > or while (operator_stack.size() - && operator_stack.top()->kind > token->kind) { + && operator_stack.top()->kind() > token->kind()) { output.push_back(std::move(operator_stack.top())); operator_stack.pop(); } @@ -208,7 +221,7 @@ FilterExpr::shuntingYard(std::vector> &infix) if (operator_stack.empty()) report_->error(2601, "-filter extraneous )."); while (operator_stack.size() - && operator_stack.top()->kind != Token::Kind::op_lparen) { + && operator_stack.top()->kind() != Token::Kind::op_lparen) { output.push_back(std::move(operator_stack.top())); operator_stack.pop(); if (operator_stack.empty()) @@ -224,7 +237,7 @@ FilterExpr::shuntingYard(std::vector> &infix) } while (operator_stack.size()) { - if (operator_stack.top()->kind == Token::Kind::op_lparen) + if (operator_stack.top()->kind() == Token::Kind::op_lparen) report_->error(2603, "-filter unmatched (."); output.push_back(std::move(operator_stack.top())); operator_stack.pop(); @@ -235,20 +248,20 @@ FilterExpr::shuntingYard(std::vector> &infix) //////////////////////////////////////////////////////////////// -template std::set -filterObjects(const char *property, - const char *op, - const char *pattern, +template static std::set +filterObjects(std::string_view property, + std::string_view op, + std::string_view pattern, std::set &all, Sta *sta) { Properties &properties = sta->properties(); Network *network = sta->network(); auto filtered_objects = std::set(); - bool exact_match = stringEq(op, "=="); - bool pattern_match = stringEq(op, "=~"); - bool not_match = stringEq(op, "!="); - bool not_pattern_match = stringEq(op, "!~"); + bool exact_match = (op == "=="); + bool pattern_match = (op == "=~"); + bool not_match = (op == "!="); + bool not_pattern_match = (op == "!~"); for (T *object : all) { PropertyValue value = properties.getProperty(object, property); std::string prop = value.to_string(network); @@ -259,8 +272,8 @@ filterObjects(const char *property, else if (stringEqual(pattern, "false")) pattern = "0"; } - if ((exact_match && stringEq(prop.c_str(), pattern)) - || (not_match && !stringEq(prop.c_str(), pattern)) + if ((exact_match && prop == pattern) + || (not_match && prop != pattern) || (pattern_match && patternMatch(pattern, prop)) || (not_pattern_match && !patternMatch(pattern, prop))) filtered_objects.insert(object); @@ -268,9 +281,9 @@ filterObjects(const char *property, return filtered_objects; } -template std::vector +template static std::vector filterObjects(std::string_view filter_expression, - std::vector *objects, + const std::vector *objects, Sta *sta) { Report *report = sta->report(); @@ -286,7 +299,7 @@ filterObjects(std::string_view filter_expression, auto postfix = filter.postfix(); std::stack> eval_stack; for (auto &token : postfix) { - if (token->kind == FilterExpr::Token::Kind::op_or) { + if (token->kind() == FilterExpr::Token::Kind::op_or) { if (eval_stack.size() < 2) report->error(2604, "-filter logical OR requires at least two operands."); auto arg0 = eval_stack.top(); @@ -298,7 +311,7 @@ filterObjects(std::string_view filter_expression, std::inserter(union_result, union_result.begin())); eval_stack.push(union_result); } - else if (token->kind == FilterExpr::Token::Kind::op_and) { + else if (token->kind() == FilterExpr::Token::Kind::op_and) { if (eval_stack.size() < 2) { report->error(2605, "-filter logical AND requires two operands."); } @@ -313,7 +326,7 @@ filterObjects(std::string_view filter_expression, intersection_result.begin())); eval_stack.push(intersection_result); } - else if (token->kind == FilterExpr::Token::Kind::op_inv) { + else if (token->kind() == FilterExpr::Token::Kind::op_inv) { if (eval_stack.size() < 1) { report->error(2606, "-filter NOT missing operand."); } @@ -327,13 +340,13 @@ filterObjects(std::string_view filter_expression, difference_result.begin())); eval_stack.push(difference_result); } - else if (token->kind == FilterExpr::Token::Kind::defined - || token->kind == FilterExpr::Token::Kind::undefined) { + else if (token->kind() == FilterExpr::Token::Kind::defined + || token->kind() == FilterExpr::Token::Kind::undefined) { bool should_be_defined = - (token->kind == FilterExpr::Token::Kind::defined); + (token->kind() == FilterExpr::Token::Kind::defined); auto result = std::set(); for (auto object : all) { - PropertyValue value = properties.getProperty(object, token->text); + PropertyValue value = properties.getProperty(object, token->text()); bool is_defined = false; switch (value.type()) { case PropertyValue::Type::float_: @@ -377,12 +390,12 @@ filterObjects(std::string_view filter_expression, } eval_stack.push(result); } - else if (token->kind == FilterExpr::Token::Kind::predicate) { + else if (token->kind() == FilterExpr::Token::Kind::predicate) { auto *predicate_token = static_cast(token.get()); - auto result = filterObjects(predicate_token->property.c_str(), - predicate_token->op.c_str(), - predicate_token->arg.c_str(), + auto result = filterObjects(predicate_token->property(), + predicate_token->op(), + predicate_token->arg(), all, sta); eval_stack.push(result); } @@ -495,7 +508,7 @@ filterExprToPostfix(std::string_view expr, auto postfix = filter.postfix(); StringSeq result; for (auto &token : postfix) - result.push_back(token->text); + result.push_back(token->text()); return result; } From 7da56adeddd5a3afe5a3cda8c0f14c7e2b0630ee Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Mon, 13 Apr 2026 21:18:34 +0000 Subject: [PATCH 07/10] undo my changes to avoid prima dcalc crash to pick implementation from upstream Signed-off-by: dsengupta0628 --- dcalc/PrimaDelayCalc.cc | 2 +- search/Sta.cc | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index 1169327a..561b7953 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -944,7 +944,7 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic, load_pin_index_map, scene, min_max); float in_slew1 = delayAsFloat(in_slew); - float ceff = ceff_vth_.empty() ? load_cap : ceff_vth_[0]; + float ceff = ceff_vth_[0]; return model->reportGateDelay(pinPvt(drvr_pin, scene, min_max), in_slew1, ceff, min_max, PocvMode::scalar, digits); diff --git a/search/Sta.cc b/search/Sta.cc index 2bff54b2..d8bc2b4d 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4169,12 +4169,6 @@ Sta::readSpef(std::string_view name, parasitics = findParasitics(std::string(name)); if (parasitics == nullptr) parasitics = makeConcreteParasitics(std::string(name), std::string(filename)); - if (scene) - scene->setParasitics(parasitics, min_max); - else { - for (Scene *scn : scenes_) - scn->setParasitics(parasitics, min_max); - } } bool success = readSpefFile(filename, instance, pin_cap_included, From 5f698bf5966b63e04f61dff5296c64987f119981 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Mon, 13 Apr 2026 22:03:24 +0000 Subject: [PATCH 08/10] fix the path of checkArgs fail and no-ccs in liberty that causes garbage RC vals in report_dcalc Signed-off-by: dsengupta0628 --- dcalc/PrimaDelayCalc.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index 93388a10..f3c7ec5d 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -1001,10 +1001,14 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew, load_cap, parasitic); bool arg_fail = checkArgs(dcalc_args, scene, min_max); - if (arg_fail) + if (arg_fail) { + const RiseFall *rf = arc->toEdge()->asRiseFall(); + const Parasitic *reduced = + table_dcalc_->findParasitic(drvr_pin, rf, scene, min_max); return table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap, - parasitic, load_pin_index_map, scene, + reduced, load_pin_index_map, scene, min_max, digits); + } else { GateTimingModel *model = arc->gateModel(scene, min_max); // Delay calc to find ceff. From 92f23e1b6d707a92d1b74ea21fcd8a762002d842 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Mon, 13 Apr 2026 22:28:04 +0000 Subject: [PATCH 09/10] regoldened regressions as now it correctly fallsback tableCalc and not PrimaDcalc Signed-off-by: dsengupta0628 --- dcalc/test/dcalc_prima_report.ok | 52 +++---- dcalc/test/dcalc_prima_report.tcl | 18 +++ parasitics/test/parasitics_reduce.ok | 156 +++++++++++---------- parasitics/test/parasitics_reduce_dcalc.ok | 156 +++++++++++---------- 4 files changed, 214 insertions(+), 168 deletions(-) diff --git a/dcalc/test/dcalc_prima_report.ok b/dcalc/test/dcalc_prima_report.ok index 028acd17..b694d7fe 100644 --- a/dcalc/test/dcalc_prima_report.ok +++ b/dcalc/test/dcalc_prima_report.ok @@ -42,50 +42,54 @@ Cell: BUFx2_ASAP7_75t_R Arc sense: positive_unate Arc type: combinational A ^ -> Y ^ +Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.50 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 50.73 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.50 +| 5.76 11.52 v -------------------- -40.00 | 35.12 50.39 -80.00 | 40.08 55.44 -Table value = 39.70 +40.00 | 27.29 35.12 +80.00 | 32.30 40.08 +Table value = 35.06 PVT scale factor = 1.00 -Delay = 39.70 +Delay = 35.06 ------- input_net_transition = 50.73 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.50 +| 5.76 11.52 v -------------------- -40.00 | 37.28 71.28 -80.00 | 38.13 71.69 -Table value = 44.70 +40.00 | 20.70 37.28 +80.00 | 21.40 38.13 +Table value = 34.55 PVT scale factor = 1.00 -Slew = 44.70 +Slew = 34.55 +Driver waveform slew = 47.36 ............................................. A v -> Y v +Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.09 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 48.72 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.09 +| 5.76 11.52 v -------------------- -40.00 | 36.17 49.65 -80.00 | 43.28 56.72 -Table value = 40.58 +40.00 | 29.18 36.17 +80.00 | 36.09 43.28 +Table value = 35.97 PVT scale factor = 1.00 -Delay = 40.58 +Delay = 35.97 ------- input_net_transition = 48.72 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.09 +| 5.76 11.52 v -------------------- -40.00 | 31.72 59.66 -80.00 | 32.63 60.23 -Table value = 37.84 +40.00 | 18.15 31.72 +80.00 | 19.36 32.63 +Table value = 28.57 PVT scale factor = 1.00 -Slew = 37.84 +Slew = 28.57 +Driver waveform slew = 40.66 ............................................. diff --git a/dcalc/test/dcalc_prima_report.tcl b/dcalc/test/dcalc_prima_report.tcl index c9d719aa..f2a801a9 100644 --- a/dcalc/test/dcalc_prima_report.tcl +++ b/dcalc/test/dcalc_prima_report.tcl @@ -12,5 +12,23 @@ create_clock -name clk -period 500 -waveform {0 250} {clk1 clk2 clk3} set_delay_calculator prima read_spef -name spef ../../test/reg1_asap7.spef + +# read_spef -name only parks the parasitics under in the +# parasitics_name_map_; it does NOT bind them to any Scene (this is the +# deferred-binding flow for MCMM -- see examples/mcmm3.tcl and Sta::readSpef +# in search/Sta.cc). Without an explicit Scene binding, report_dcalc / +# report_checks would see only pin capacitance (~0.57 fF here) and produce +# incorrect table lookups, instead of the wire-cap-annotated ~13.97 fF we +# expect for this design. define_scene with -spef spef creates a Scene +# bound to the -name'd Parasitics via Scene::setParasitics and makes it the +# current Scene, so Prima receives the full RC network. +define_scene scene1 \ + -liberty {asap7sc7p5t_SEQ_RVT_FF_nldm_220123 \ + asap7sc7p5t_INVBUF_RVT_FF_nldm_211120 \ + asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120 \ + asap7sc7p5t_OA_RVT_FF_nldm_211120 \ + asap7sc7p5t_AO_RVT_FF_nldm_211120} \ + -spef spef + report_checks report_dcalc -from u1/A -to u1/Y diff --git a/parasitics/test/parasitics_reduce.ok b/parasitics/test/parasitics_reduce.ok index 9f53401c..02e58279 100644 --- a/parasitics/test/parasitics_reduce.ok +++ b/parasitics/test/parasitics_reduce.ok @@ -459,50 +459,54 @@ Cell: BUFx2_ASAP7_75t_R Arc sense: positive_unate Arc type: combinational A ^ -> Y ^ +Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.50 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 50.73 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.50 +| 5.76 11.52 v -------------------- -40.00 | 35.12 50.39 -80.00 | 40.08 55.44 -Table value = 39.70 +40.00 | 27.29 35.12 +80.00 | 32.30 40.08 +Table value = 35.06 PVT scale factor = 1.00 -Delay = 39.70 +Delay = 35.06 ------- input_net_transition = 50.73 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.50 +| 5.76 11.52 v -------------------- -40.00 | 37.28 71.28 -80.00 | 38.13 71.69 -Table value = 44.70 +40.00 | 20.70 37.28 +80.00 | 21.40 38.13 +Table value = 34.55 PVT scale factor = 1.00 -Slew = 44.70 +Slew = 34.55 +Driver waveform slew = 47.36 ............................................. A v -> Y v +Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.09 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 48.75 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.09 +| 5.76 11.52 v -------------------- -40.00 | 36.17 49.65 -80.00 | 43.28 56.72 -Table value = 40.59 +40.00 | 29.18 36.17 +80.00 | 36.09 43.28 +Table value = 35.98 PVT scale factor = 1.00 -Delay = 40.59 +Delay = 35.98 ------- input_net_transition = 48.75 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.09 +| 5.76 11.52 v -------------------- -40.00 | 31.72 59.66 -80.00 | 32.63 60.23 -Table value = 37.84 +40.00 | 18.15 31.72 +80.00 | 19.36 32.63 +Table value = 28.57 PVT scale factor = 1.00 -Slew = 37.84 +Slew = 28.57 +Driver waveform slew = 40.66 ............................................. @@ -512,50 +516,54 @@ Cell: AND2x2_ASAP7_75t_R Arc sense: positive_unate Arc type: combinational A ^ -> Y ^ +Pi model C2=6.70 Rpi=2.42 C1=7.32, Ceff=10.90 P = 1.00 V = 0.70 T = 25.00 ------- input_net_transition = 50.41 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.90 +| 5.76 11.52 v -------------------- -40.00 | 40.48 58.12 -80.00 | 45.47 63.31 -Table value = 45.62 +40.00 | 31.28 40.48 +80.00 | 36.30 45.47 +Table value = 40.79 PVT scale factor = 1.00 -Delay = 45.62 +Delay = 40.79 ------- input_net_transition = 50.41 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.90 +| 5.76 11.52 v -------------------- -40.00 | 43.68 82.62 -80.00 | 44.42 82.97 -Table value = 52.30 +40.00 | 24.52 43.68 +80.00 | 25.29 44.42 +Table value = 41.80 PVT scale factor = 1.00 -Slew = 52.30 +Slew = 41.80 +Driver waveform slew = 55.90 ............................................. A v -> Y v +Pi model C2=6.70 Rpi=2.42 C1=7.32, Ceff=10.35 P = 1.00 V = 0.70 T = 25.00 ------- input_net_transition = 48.36 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.35 +| 5.76 11.52 v -------------------- -40.00 | 43.09 58.01 -80.00 | 52.65 67.66 -Table value = 48.33 +40.00 | 35.35 43.09 +80.00 | 44.73 52.65 +Table value = 43.51 PVT scale factor = 1.00 -Delay = 48.33 +Delay = 43.51 ------- input_net_transition = 48.36 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.35 +| 5.76 11.52 v -------------------- -40.00 | 35.08 65.82 -80.00 | 36.06 66.39 -Table value = 41.94 +40.00 | 20.09 35.08 +80.00 | 21.45 36.06 +Table value = 32.26 PVT scale factor = 1.00 -Slew = 41.94 +Slew = 32.26 +Driver waveform slew = 45.57 ............................................. @@ -565,50 +573,54 @@ Cell: DFFHQx4_ASAP7_75t_R Arc sense: non_unate Arc type: Reg Clk to Q CLK ^ -> Q ^ +Pi model C2=6.70 Rpi=2.42 C1=7.22, Ceff=9.22 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.92 -| 11.52 23.04 +| total_output_net_capacitance = 9.22 +| 5.76 11.52 v -------------------- -40.00 | 64.09 71.91 -80.00 | 69.26 77.08 -Table value = 66.81 +40.00 | 59.92 64.09 +80.00 | 65.10 69.26 +Table value = 63.51 PVT scale factor = 1.00 -Delay = 66.81 +Delay = 63.51 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.92 -| 11.52 23.04 +| total_output_net_capacitance = 9.22 +| 5.76 11.52 v -------------------- -40.00 | 21.04 37.91 -80.00 | 21.05 37.92 -Table value = 24.56 +40.00 | 13.01 21.04 +80.00 | 13.01 21.05 +Table value = 17.83 PVT scale factor = 1.00 -Slew = 24.56 +Slew = 17.83 +Driver waveform slew = 22.83 ............................................. CLK ^ -> Q v +Pi model C2=6.70 Rpi=2.42 C1=7.21, Ceff=8.89 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.91 -| 11.52 23.04 +| total_output_net_capacitance = 8.89 +| 5.76 11.52 v -------------------- -40.00 | 61.63 68.60 -80.00 | 66.47 73.44 -Table value = 64.09 +40.00 | 57.80 61.63 +80.00 | 62.64 66.47 +Table value = 60.90 PVT scale factor = 1.00 -Delay = 64.09 +Delay = 60.90 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.91 -| 11.52 23.04 +| total_output_net_capacitance = 8.89 +| 5.76 11.52 v -------------------- -40.00 | 17.99 31.89 -80.00 | 17.98 31.88 -Table value = 20.87 +40.00 | 11.30 17.99 +80.00 | 11.31 17.98 +Table value = 14.94 PVT scale factor = 1.00 -Slew = 20.87 +Slew = 14.94 +Driver waveform slew = 19.18 ............................................. diff --git a/parasitics/test/parasitics_reduce_dcalc.ok b/parasitics/test/parasitics_reduce_dcalc.ok index 68cca2f9..aa12f18f 100644 --- a/parasitics/test/parasitics_reduce_dcalc.ok +++ b/parasitics/test/parasitics_reduce_dcalc.ok @@ -1362,50 +1362,54 @@ Cell: BUFx2_ASAP7_75t_R Arc sense: positive_unate Arc type: combinational A ^ -> Y ^ +Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.50 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 50.73 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.50 +| 5.76 11.52 v -------------------- -40.00 | 35.12 50.39 -80.00 | 40.08 55.44 -Table value = 39.70 +40.00 | 27.29 35.12 +80.00 | 32.30 40.08 +Table value = 35.06 PVT scale factor = 1.00 -Delay = 39.70 +Delay = 35.06 ------- input_net_transition = 50.73 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.50 +| 5.76 11.52 v -------------------- -40.00 | 37.28 71.28 -80.00 | 38.13 71.69 -Table value = 44.70 +40.00 | 20.70 37.28 +80.00 | 21.40 38.13 +Table value = 34.55 PVT scale factor = 1.00 -Slew = 44.70 +Slew = 34.55 +Driver waveform slew = 47.36 ............................................. A v -> Y v +Pi model C2=6.70 Rpi=2.42 C1=7.27, Ceff=10.09 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 48.75 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.09 +| 5.76 11.52 v -------------------- -40.00 | 36.17 49.65 -80.00 | 43.28 56.72 -Table value = 40.59 +40.00 | 29.18 36.17 +80.00 | 36.09 43.28 +Table value = 35.98 PVT scale factor = 1.00 -Delay = 40.59 +Delay = 35.98 ------- input_net_transition = 48.75 -| total_output_net_capacitance = 13.97 -| 11.52 23.04 +| total_output_net_capacitance = 10.09 +| 5.76 11.52 v -------------------- -40.00 | 31.72 59.66 -80.00 | 32.63 60.23 -Table value = 37.84 +40.00 | 18.15 31.72 +80.00 | 19.36 32.63 +Table value = 28.57 PVT scale factor = 1.00 -Slew = 37.84 +Slew = 28.57 +Driver waveform slew = 40.66 ............................................. @@ -1415,50 +1419,54 @@ Cell: AND2x2_ASAP7_75t_R Arc sense: positive_unate Arc type: combinational A ^ -> Y ^ +Pi model C2=6.70 Rpi=2.42 C1=7.32, Ceff=10.90 P = 1.00 V = 0.70 T = 25.00 ------- input_net_transition = 50.41 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.90 +| 5.76 11.52 v -------------------- -40.00 | 40.48 58.12 -80.00 | 45.47 63.31 -Table value = 45.62 +40.00 | 31.28 40.48 +80.00 | 36.30 45.47 +Table value = 40.79 PVT scale factor = 1.00 -Delay = 45.62 +Delay = 40.79 ------- input_net_transition = 50.41 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.90 +| 5.76 11.52 v -------------------- -40.00 | 43.68 82.62 -80.00 | 44.42 82.97 -Table value = 52.30 +40.00 | 24.52 43.68 +80.00 | 25.29 44.42 +Table value = 41.80 PVT scale factor = 1.00 -Slew = 52.30 +Slew = 41.80 +Driver waveform slew = 55.90 ............................................. A v -> Y v +Pi model C2=6.70 Rpi=2.42 C1=7.32, Ceff=10.35 P = 1.00 V = 0.70 T = 25.00 ------- input_net_transition = 48.36 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.35 +| 5.76 11.52 v -------------------- -40.00 | 43.09 58.01 -80.00 | 52.65 67.66 -Table value = 48.33 +40.00 | 35.35 43.09 +80.00 | 44.73 52.65 +Table value = 43.51 PVT scale factor = 1.00 -Delay = 48.33 +Delay = 43.51 ------- input_net_transition = 48.36 -| total_output_net_capacitance = 14.02 -| 11.52 23.04 +| total_output_net_capacitance = 10.35 +| 5.76 11.52 v -------------------- -40.00 | 35.08 65.82 -80.00 | 36.06 66.39 -Table value = 41.94 +40.00 | 20.09 35.08 +80.00 | 21.45 36.06 +Table value = 32.26 PVT scale factor = 1.00 -Slew = 41.94 +Slew = 32.26 +Driver waveform slew = 45.57 ............................................. @@ -1468,50 +1476,54 @@ Cell: DFFHQx4_ASAP7_75t_R Arc sense: non_unate Arc type: Reg Clk to Q CLK ^ -> Q ^ +Pi model C2=6.70 Rpi=2.42 C1=7.22, Ceff=9.22 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.92 -| 11.52 23.04 +| total_output_net_capacitance = 9.22 +| 5.76 11.52 v -------------------- -40.00 | 64.09 71.91 -80.00 | 69.26 77.08 -Table value = 66.81 +40.00 | 59.92 64.09 +80.00 | 65.10 69.26 +Table value = 63.51 PVT scale factor = 1.00 -Delay = 66.81 +Delay = 63.51 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.92 -| 11.52 23.04 +| total_output_net_capacitance = 9.22 +| 5.76 11.52 v -------------------- -40.00 | 21.04 37.91 -80.00 | 21.05 37.92 -Table value = 24.56 +40.00 | 13.01 21.04 +80.00 | 13.01 21.05 +Table value = 17.83 PVT scale factor = 1.00 -Slew = 24.56 +Slew = 17.83 +Driver waveform slew = 22.83 ............................................. CLK ^ -> Q v +Pi model C2=6.70 Rpi=2.42 C1=7.21, Ceff=8.89 P = 1.00 V = 0.77 T = 0.00 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.91 -| 11.52 23.04 +| total_output_net_capacitance = 8.89 +| 5.76 11.52 v -------------------- -40.00 | 61.63 68.60 -80.00 | 66.47 73.44 -Table value = 64.09 +40.00 | 57.80 61.63 +80.00 | 62.64 66.47 +Table value = 60.90 PVT scale factor = 1.00 -Delay = 64.09 +Delay = 60.90 ------- input_net_transition = 48.38 -| total_output_net_capacitance = 13.91 -| 11.52 23.04 +| total_output_net_capacitance = 8.89 +| 5.76 11.52 v -------------------- -40.00 | 17.99 31.89 -80.00 | 17.98 31.88 -Table value = 20.87 +40.00 | 11.30 17.99 +80.00 | 11.31 17.98 +Table value = 14.94 PVT scale factor = 1.00 -Slew = 20.87 +Slew = 14.94 +Driver waveform slew = 19.18 ............................................. From bba8a697f64acb11dfa0252a482d5066b11a8d44 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Wed, 15 Apr 2026 21:40:39 +0000 Subject: [PATCH 10/10] Renamed the two output files in sdc_exception_thru_override.tcl so they don't collide with op from sdc_exception_override_priority.tcl Signed-off-by: dsengupta0628 --- sdc/test/sdc_exception_thru_override.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdc/test/sdc_exception_thru_override.tcl b/sdc/test/sdc_exception_thru_override.tcl index 6e99442f..717da908 100644 --- a/sdc/test/sdc_exception_thru_override.tcl +++ b/sdc/test/sdc_exception_thru_override.tcl @@ -144,8 +144,8 @@ set_false_path -from [get_ports in2] -fall_to [get_ports out2] set_multicycle_path 2 -setup -from [get_clocks clk1] -to [get_clocks clk2] set_max_delay 7.0 -from [get_ports in3] -rise_through [get_pins or1/ZN] -to [get_ports out2] -set sdc1 [make_result_file sdc_exc_override1.sdc] +set sdc1 [make_result_file sdc_exc_thru_override1.sdc] write_sdc -no_timestamp $sdc1 -set sdc2 [make_result_file sdc_exc_override2.sdc] +set sdc2 [make_result_file sdc_exc_thru_override2.sdc] write_sdc -no_timestamp -compatible $sdc2