diff --git a/CMakeLists.txt b/CMakeLists.txt
index 055927fd..3c6ab462 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -403,6 +403,17 @@ find_package(Threads)
find_package(Eigen3 REQUIRED)
+# fmt library: fallback when std::format is not available (e.g. GCC 11 on Ubuntu 22.04)
+find_package(fmt QUIET)
+if(NOT fmt_FOUND)
+ include(FetchContent)
+ FetchContent_Declare(fmt
+ GIT_REPOSITORY https://github.com/fmtlib/fmt.git
+ GIT_TAG 10.2.1
+ )
+ FetchContent_MakeAvailable(fmt)
+endif()
+
include(cmake/FindCUDD.cmake)
# configure a header file to pass some of the CMake settings
@@ -518,6 +529,7 @@ target_sources(OpenSTA
target_link_libraries(OpenSTA
Eigen3::Eigen
+ fmt::fmt
${TCL_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${CUDD_LIB}
diff --git a/app/StaMain.cc b/app/StaMain.cc
index a7147ab0..079112e1 100644
--- a/app/StaMain.cc
+++ b/app/StaMain.cc
@@ -96,11 +96,10 @@ sourceTclFile(const char *filename,
bool verbose,
Tcl_Interp *interp)
{
- std::string cmd;
- stringPrint(cmd, "sta::include_file %s %s %s",
- filename,
- echo ? "1" : "0",
- verbose ? "1" : "0");
+ std::string cmd = sta::format("sta::include_file {} {} {}",
+ filename,
+ echo ? "1" : "0",
+ verbose ? "1" : "0");
int code = Tcl_Eval(interp, cmd.c_str());
const char *result = Tcl_GetStringResult(interp);
if (result[0] != '\0')
diff --git a/dcalc/ArcDcalcWaveforms.cc b/dcalc/ArcDcalcWaveforms.cc
index 6c1e7560..00f1e3bb 100644
--- a/dcalc/ArcDcalcWaveforms.cc
+++ b/dcalc/ArcDcalcWaveforms.cc
@@ -60,7 +60,7 @@ ArcDcalcWaveforms::inputWaveform(ArcDcalcArg &dcalc_arg,
bool vdd_exists;
library->supplyVoltage("VDD", vdd, vdd_exists);
if (!vdd_exists)
- report->error(1751, "VDD not defined in library %s", library->name());
+ report->error(1751, "VDD not defined in library {}", library->name());
float slew1 = delayAsFloat(in_slew, min_max, sta);
Waveform in_waveform = driver_waveform->waveform(slew1);
// Delay time axis.
diff --git a/dcalc/ArcDelayCalc.cc b/dcalc/ArcDelayCalc.cc
index 54143b28..86759411 100644
--- a/dcalc/ArcDelayCalc.cc
+++ b/dcalc/ArcDelayCalc.cc
@@ -94,24 +94,24 @@ makeArcDcalcArg(const char *inst_name,
else {
const Network *network = sta->network();
const Instance *inst = network->instance(in_pin);
- report->warn(2100, "no timing arc for %s input/driver pins.",
+ report->warn(2100, "no timing arc for {} input/driver pins.",
network->pathName(inst));
}
}
else
- report->warn(2101, "%s not a valid rise/fall.", drvr_rf_name);
+ report->warn(2101, "{} not a valid rise/fall.", drvr_rf_name);
}
else
- report->warn(2102, "Pin %s/%s not found.", inst_name, drvr_port_name);
+ report->warn(2102, "Pin {}/{} not found.", inst_name, drvr_port_name);
}
else
- report->warn(2103, "%s not a valid rise/fall.", in_rf_name);
+ report->warn(2103, "{} not a valid rise/fall.", in_rf_name);
}
else
- report->warn(2104, "Pin %s/%s not found.", inst_name, in_port_name);
+ report->warn(2104, "Pin {}/{} not found.", inst_name, in_port_name);
}
else
- report->warn(2105, "Instance %s not found.", inst_name);
+ report->warn(2105, "Instance {} not found.", inst_name);
return ArcDcalcArg();
}
diff --git a/dcalc/ArnoldiDelayCalc.cc b/dcalc/ArnoldiDelayCalc.cc
index 2b44188e..c85d1998 100644
--- a/dcalc/ArnoldiDelayCalc.cc
+++ b/dcalc/ArnoldiDelayCalc.cc
@@ -1156,7 +1156,7 @@ ra_hinv(double y,
ex = exp(-x);
f = x+ex-1.0-y;
if (f<-1e-8 || f>1e-8)
- debugPrint(debug, "arnoldi", 1, "y f %g %g", y, f);
+ debugPrint(debug, "arnoldi", 1, "y f {:g} {:g}", y, f);
return x;
}
@@ -1290,7 +1290,7 @@ ArnoldiDelayCalc::ra_solve_for_s(delay_work *D,
s = s - f/df;
if (std::abs(f)>.5e-12) // .5ps
- debugPrint(debug_, "arnoldi", 1, "ra_solve_for_s p %g tlohi %s err %s",
+ debugPrint(debug_, "arnoldi", 1, "ra_solve_for_s p {:g} tlohi {} err {}",
p,
units_->timeUnit()->asString(tlohi),
units_->timeUnit()->asString(f));
@@ -1399,7 +1399,7 @@ ArnoldiDelayCalc::ar1_ceff_delay(delay_work *D,
double ceff,tlohi,t50_sy,r,s,t50_sr,rdelay;
float df, sf;
- debugPrint(debug_, "arnoldi", 1, "ctot=%s",
+ debugPrint(debug_, "arnoldi", 1, "ctot={}",
units_->capacitanceUnit()->asString(ctot));
rdelay = ra_rdelay_1(tab,ctot);
@@ -1421,18 +1421,18 @@ ArnoldiDelayCalc::ar1_ceff_delay(delay_work *D,
if (debug_->check("arnoldi", 1)) {
double p = 1.0/(r*ctot);
double thix,tlox;
- debugPrint(debug_, "arnoldi", 1, "at r=%s s=%s",
+ debugPrint(debug_, "arnoldi", 1, "at r={} s={}",
units_->resistanceUnit()->asString(r),
units_->timeUnit()->asString(s));
thix = ra_solve_for_t(p,s,vhi);
tlox = ra_solve_for_t(p,s,vlo);
tab->table->gateDelay(tab->pvt,tab->in_slew, ctot, df, sf);
- debugPrint(debug_, "arnoldi", 1, "table slew (in_slew %s ctot %s) = %s",
+ debugPrint(debug_, "arnoldi", 1, "table slew (in_slew {} ctot {}) = {}",
units_->timeUnit()->asString(tab->in_slew),
units_->capacitanceUnit()->asString(ctot),
delayAsString(sf, this));
tlohi = slew_derate*delayAsFloat(sf);
- debugPrint(debug_, "arnoldi", 1, "tlohi %s %s",
+ debugPrint(debug_, "arnoldi", 1, "tlohi {} {}",
units_->timeUnit()->asString(tlohi),
units_->timeUnit()->asString(tlox-thix));
}
@@ -1468,11 +1468,11 @@ ArnoldiDelayCalc::ar1_ceff_delay(delay_work *D,
// new mvs at ceff
s = ra_get_s(D,tab,r,ceff);
- debugPrint(debug_, "arnoldi", 1, "new mvs s = %s",
+ debugPrint(debug_, "arnoldi", 1, "new mvs s = {}",
units_->timeUnit()->asString(s));
}
}
- debugPrint(debug_, "arnoldi", 1, "r %s s %s ceff_time %s ceff %s",
+ debugPrint(debug_, "arnoldi", 1, "r {} s {} ceff_time {} ceff {}",
units_->resistanceUnit()->asString(r),
units_->timeUnit()->asString(s),
units_->timeUnit()->asString(ceff_time),
diff --git a/dcalc/ArnoldiReduce.cc b/dcalc/ArnoldiReduce.cc
index 5fee6823..046e8e8d 100644
--- a/dcalc/ArnoldiReduce.cc
+++ b/dcalc/ArnoldiReduce.cc
@@ -1,25 +1,25 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
-//
+//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-//
+//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
-//
+//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
-//
+//
// This notice may not be removed or altered from any source distribution.
// (c) 2018 Nefelus, Inc.
@@ -34,6 +34,7 @@
#include "Network.hh"
#include "Units.hh"
#include "Arnoldi.hh"
+#include "Format.hh"
#include "parasitics/ConcreteParasiticsPvt.hh"
namespace sta {
@@ -43,10 +44,7 @@ rcmodel::rcmodel() :
{
}
-rcmodel::~rcmodel()
-{
- free(pinV);
-}
+rcmodel::~rcmodel() { free(pinV); }
float
rcmodel::capacitance() const
@@ -67,7 +65,7 @@ struct ts_point
ParasiticNode *node_;
int eN;
bool is_term;
- int tindex; // index into termV of corresponding term
+ int tindex; // index into termV of corresponding term
ts_edge **eV;
bool visited;
ts_edge *in_edge;
@@ -85,7 +83,6 @@ struct ts_edge
////////////////////////////////////////////////////////////////
-
const int ArnoldiReduce::ts_point_count_incr_ = 1024;
const int ArnoldiReduce::ts_edge_count_incr_ = 1024;
@@ -96,31 +93,32 @@ ArnoldiReduce::ArnoldiReduce(StaState *sta) :
termNmax(256),
dNmax(8)
{
- ts_pointV = (ts_point*)malloc(ts_pointNmax*sizeof(ts_point));
- ts_ordV = (int*)malloc(ts_pointNmax*sizeof(int));
- ts_pordV = (ts_point**)malloc(ts_pointNmax*sizeof(ts_point*));
- _u0 = (double*)malloc(ts_pointNmax*sizeof(double));
- _u1 = (double*)malloc(ts_pointNmax*sizeof(double));
- y = (double*)malloc(ts_pointNmax*sizeof(double));
- iv = (double*)malloc(ts_pointNmax*sizeof(double));
- r = (double*)malloc(ts_pointNmax*sizeof(double));
- c = (double*)malloc(ts_pointNmax*sizeof(double));
- par = (int*)malloc(ts_pointNmax*sizeof(int));
+ ts_pointV = (ts_point *)malloc(ts_pointNmax * sizeof(ts_point));
+ ts_ordV = (int *)malloc(ts_pointNmax * sizeof(int));
+ ts_pordV = (ts_point **)malloc(ts_pointNmax * sizeof(ts_point *));
+ _u0 = (double *)malloc(ts_pointNmax * sizeof(double));
+ _u1 = (double *)malloc(ts_pointNmax * sizeof(double));
+ y = (double *)malloc(ts_pointNmax * sizeof(double));
+ iv = (double *)malloc(ts_pointNmax * sizeof(double));
+ r = (double *)malloc(ts_pointNmax * sizeof(double));
+ c = (double *)malloc(ts_pointNmax * sizeof(double));
+ par = (int *)malloc(ts_pointNmax * sizeof(int));
- ts_edgeV = (ts_edge*)malloc(ts_edgeNmax*sizeof(ts_edge));
- ts_stackV = (ts_edge**)malloc(ts_edgeNmax*sizeof(ts_edge*));
- ts_eV = (ts_edge**)malloc(2*ts_edgeNmax*sizeof(ts_edge*));
+ ts_edgeV = (ts_edge *)malloc(ts_edgeNmax * sizeof(ts_edge));
+ ts_stackV = (ts_edge **)malloc(ts_edgeNmax * sizeof(ts_edge *));
+ ts_eV = (ts_edge **)malloc(2 * ts_edgeNmax * sizeof(ts_edge *));
- pinV = (const Pin**)malloc(termNmax*sizeof(const Pin*));
- termV = (int*)malloc(termNmax*sizeof(int));
- outV = (int*)malloc(termNmax*sizeof(int));
+ pinV = (const Pin **)malloc(termNmax * sizeof(const Pin *));
+ termV = (int *)malloc(termNmax * sizeof(int));
+ outV = (int *)malloc(termNmax * sizeof(int));
- d = (double*)malloc(dNmax*sizeof(double));
- e = (double*)malloc(dNmax*sizeof(double));
- U = (double**)malloc(dNmax*sizeof(double*));
- U0 = (double*)malloc(dNmax*termNmax*sizeof(double));
+ d = (double *)malloc(dNmax * sizeof(double));
+ e = (double *)malloc(dNmax * sizeof(double));
+ U = (double **)malloc(dNmax * sizeof(double *));
+ U0 = (double *)malloc(dNmax * termNmax * sizeof(double));
int h;
- for (h=0;hparasitics(min_max);
- parasitic_network_ = reinterpret_cast(parasitic);
+ parasitic_network_ = reinterpret_cast(parasitic);
loadWork();
return makeRcmodelDrv();
@@ -200,7 +198,7 @@ ArnoldiReduce::loadWork()
ts_edge *e;
int tindex;
- for (p = p0; p!=pend; p++) {
+ for (p = p0; p != pend; p++) {
p->node_ = nullptr;
p->eN = 0;
p->is_term = false;
@@ -246,14 +244,14 @@ ArnoldiReduce::loadWork()
e++;
}
- for (p=p0;p!=pend;p++) {
+ for (p = p0; p != pend; p++) {
if (p->node_) {
p->eV = eV;
eV += p->eN;
p->eN = 0;
}
}
- for (e=e0;e!=eend;e++) {
+ for (e = e0; e != eend; e++) {
e->from->eV[e->from->eN++] = e;
if (e->to != e->from)
e->to->eV[e->to->eN++] = e;
@@ -267,30 +265,33 @@ ArnoldiReduce::allocPoints()
free(par);
free(c);
free(r);
- free(iv); free(y); free(_u1); free(_u0);
+ free(iv);
+ free(y);
+ free(_u1);
+ free(_u0);
free(ts_pordV);
free(ts_ordV);
free(ts_pointV);
ts_pointNmax = ts_pointN + ts_point_count_incr_;
- ts_pointV = (ts_point*)malloc(ts_pointNmax*sizeof(ts_point));
- ts_ordV = (int*)malloc(ts_pointNmax*sizeof(int));
- ts_pordV = (ts_point**)malloc(ts_pointNmax*sizeof(ts_point*));
- _u0 = (double*)malloc(ts_pointNmax*sizeof(double));
- _u1 = (double*)malloc(ts_pointNmax*sizeof(double));
- y = (double*)malloc(ts_pointNmax*sizeof(double));
- iv = (double*)malloc(ts_pointNmax*sizeof(double));
- r = (double*)malloc(ts_pointNmax*sizeof(double));
- c = (double*)malloc(ts_pointNmax*sizeof(double));
- par = (int*)malloc(ts_pointNmax*sizeof(int));
+ ts_pointV = (ts_point *)malloc(ts_pointNmax * sizeof(ts_point));
+ ts_ordV = (int *)malloc(ts_pointNmax * sizeof(int));
+ ts_pordV = (ts_point **)malloc(ts_pointNmax * sizeof(ts_point *));
+ _u0 = (double *)malloc(ts_pointNmax * sizeof(double));
+ _u1 = (double *)malloc(ts_pointNmax * sizeof(double));
+ y = (double *)malloc(ts_pointNmax * sizeof(double));
+ iv = (double *)malloc(ts_pointNmax * sizeof(double));
+ r = (double *)malloc(ts_pointNmax * sizeof(double));
+ c = (double *)malloc(ts_pointNmax * sizeof(double));
+ par = (int *)malloc(ts_pointNmax * sizeof(int));
}
if (ts_edgeN > ts_edgeNmax) {
free(ts_edgeV);
free(ts_eV);
free(ts_stackV);
ts_edgeNmax = ts_edgeN + ts_edge_count_incr_;
- ts_edgeV = (ts_edge*)malloc(ts_edgeNmax*sizeof(ts_edge));
- ts_stackV = (ts_edge**)malloc(ts_edgeNmax*sizeof(ts_edge*));
- ts_eV = (ts_edge**)malloc(2*ts_edgeNmax*sizeof(ts_edge*));
+ ts_edgeV = (ts_edge *)malloc(ts_edgeNmax * sizeof(ts_edge));
+ ts_stackV = (ts_edge **)malloc(ts_edgeNmax * sizeof(ts_edge *));
+ ts_eV = (ts_edge **)malloc(2 * ts_edgeNmax * sizeof(ts_edge *));
}
}
@@ -302,65 +303,69 @@ ArnoldiReduce::allocTerms(int nterms)
free(outV);
free(termV);
free(pinV);
- termNmax = nterms+256;
- pinV = (const Pin**)malloc(termNmax*sizeof(const Pin*));
- termV = (int*)malloc(termNmax*sizeof(int));
- outV = (int*)malloc(termNmax*sizeof(int));
+ termNmax = nterms + 256;
+ pinV = (const Pin **)malloc(termNmax * sizeof(const Pin *));
+ termV = (int *)malloc(termNmax * sizeof(int));
+ outV = (int *)malloc(termNmax * sizeof(int));
- U0 = (double*)malloc(dNmax*termNmax*sizeof(double));
+ U0 = (double *)malloc(dNmax * termNmax * sizeof(double));
int h;
- for (h=0;h(node)]];
+ return &ts_pointV[pt_map_[reinterpret_cast(node)]];
}
rcmodel *
ArnoldiReduce::makeRcmodelDrv()
{
ParasiticNode *drv_node =
- parasitics_->findParasiticNode(parasitic_network_, drvr_pin_);
+ parasitics_->findParasiticNode(parasitic_network_, drvr_pin_);
ts_point *pdrv = findPt(drv_node);
makeRcmodelDfs(pdrv);
getRC();
- if (ctot_ < 1e-22) // 1e-10ps
+ if (ctot_ < 1e-22) // 1e-10ps
return nullptr;
setTerms(pdrv);
makeRcmodelFromTs();
return makeRcmodelFromW();
}
-#define ts_orient( pp, ee) \
- if (ee->from!=pp) { ee->to = ee->from; ee->from = pp; }
+#define ts_orient(pp, ee) \
+ if (ee->from != pp) { \
+ ee->to = ee->from; \
+ ee->from = pp; \
+ }
void
ArnoldiReduce::makeRcmodelDfs(ts_point *pdrv)
{
bool loop = false;
int k;
- ts_point *p,*q;
+ ts_point *p, *q;
ts_point *p0 = ts_pointV;
ts_point *pend = p0 + ts_pointN;
- for (p=p0;p!=pend;p++)
+ for (p = p0; p != pend; p++)
p->visited = 0;
ts_edge *e;
ts_edge **stackV = ts_stackV;
int stackN = 1;
stackV[0] = e = pdrv->eV[0];
- ts_orient(pdrv,e);
+ ts_orient(pdrv, e);
pdrv->visited = 1;
pdrv->in_edge = nullptr;
pdrv->ts = 0;
- ts_ordV[0] = pdrv-p0;
+ ts_ordV[0] = pdrv - p0;
ts_pordV[0] = pdrv;
ts_ordN = 1;
- while (stackN>0) {
- e = stackV[stackN-1];
+ while (stackN > 0) {
+ e = stackV[stackN - 1];
q = e->to;
if (q->visited) {
@@ -368,47 +373,53 @@ ArnoldiReduce::makeRcmodelDfs(ts_point *pdrv)
// ignore, and do not even set *loop
if (e->to != e->from)
loop = true;
- } else {
+ }
+ else {
// try to descend
q->visited = 1;
q->ts = ts_ordN++;
ts_pordV[q->ts] = q;
- ts_ordV[q->ts] = q-p0;
+ ts_ordV[q->ts] = q - p0;
q->in_edge = e;
- if (q->eN>1) {
- for (k=0;keN;k++) if (q->eV[k] != e) break;
+ if (q->eN > 1) {
+ for (k = 0; k < q->eN; k++)
+ if (q->eV[k] != e)
+ break;
e = q->eV[k];
- ts_orient(q,e);
+ ts_orient(q, e);
stackV[stackN++] = e;
- continue; // descent
+ continue; // descent
}
}
// try to ascend
- while (--stackN>=0) {
+ while (--stackN >= 0) {
e = stackV[stackN];
p = e->from;
// find e in p->eV
- for (k=0;keN;k++) if (p->eV[k]==e) break;
+ for (k = 0; k < p->eN; k++)
+ if (p->eV[k] == e)
+ break;
// if (k==p->eN) notice(0,"ERROR, e not found!\n");
++k;
- if (k>=p->eN) continue;
+ if (k >= p->eN)
+ continue;
e = p->eV[k];
// check that next sibling is not the incoming edge
- if (stackN>0 && e==stackV[stackN-1]) {
- ++k;
- if (k>=p->eN) continue;
- e = p->eV[k];
+ if (stackN > 0 && e == stackV[stackN - 1]) {
+ ++k;
+ if (k >= p->eN)
+ continue;
+ e = p->eV[k];
}
- ts_orient(p,e);
+ ts_orient(p, e);
stackV[stackN++] = e;
break;
}
- } // while (stackN)
+ } // while (stackN)
if (loop)
- debugPrint(debug_, "arnoldi", 1, "net %s loop",
- network_->pathName(drvr_pin_));
+ debugPrint(debug_, "arnoldi", 1, "net {} loop", network_->pathName(drvr_pin_));
}
// makeRcmodelGetRC
@@ -418,13 +429,12 @@ ArnoldiReduce::getRC()
ts_point *p, *p0 = ts_pointV;
ts_point *pend = p0 + ts_pointN;
ctot_ = 0.0;
- for (p=p0;p!=pend;p++) {
+ for (p = p0; p != pend; p++) {
p->c = 0.0;
p->r = 0.0;
if (p->node_) {
ParasiticNode *node = p->node_;
- double cap = parasitics_->nodeGndCap(node)
- + pinCapacitance(node);
+ double cap = parasitics_->nodeGndCap(node) + pinCapacitance(node);
if (cap > 0.0) {
p->c = cap;
ctot_ += cap;
@@ -433,11 +443,9 @@ ArnoldiReduce::getRC()
p->c = 0.0;
if (p->in_edge && p->in_edge->resistor_)
p->r = parasitics_->value(p->in_edge->resistor_);
- if (!(p->r>=0.0 && p->r<100e+3)) { // 0 < r < 100kohm
- debugPrint(debug_, "arnoldi", 1,
- "R value %g out of range, drvr pin %s",
- p->r,
- network_->pathName(drvr_pin_));
+ if (!(p->r >= 0.0 && p->r < 100e+3)) { // 0 < r < 100kohm
+ debugPrint(debug_, "arnoldi", 1, "R value {:g} out of range, drvr pin {}",
+ p->r, network_->pathName(drvr_pin_));
}
}
}
@@ -466,7 +474,7 @@ ArnoldiReduce::pinCapacitance(ParasiticNode *node)
LibertyPort *lib_port = network_->libertyPort(port);
const Sdc *sdc = scene_->sdc();
if (lib_port)
- pin_cap = sdc->pinCapacitance(pin,rf_, scene_, min_max_);
+ pin_cap = sdc->pinCapacitance(pin, rf_, scene_, min_max_);
else if (network_->isTopLevelPort(pin))
pin_cap = sdc->portExtCap(port, rf_, min_max_);
}
@@ -479,13 +487,15 @@ ArnoldiReduce::setTerms(ts_point *pdrv)
// termV: from drv-ordered to fixed order
// outV: from drv-ordered to ts_pordV
ts_point *p;
- int k,k0;
+ int k, k0;
termV[0] = k0 = pdrv->tindex;
- for (k=1;kts;
}
@@ -498,38 +508,37 @@ ArnoldiReduce::makeRcmodelFromTs()
ts_point *p, *p0 = ts_pointV;
int n = ts_ordN;
int nterms = termN;
- int i,j,k,h;
+ int i, j, k, h;
if (debug_->check("arnoldi", 1)) {
- for (k=0;kts,
- p-p0,
+ debugPrint(debug_, "arnoldi", 1, "T{} P{} c={}", p->ts, p - p0,
units_->capacitanceUnit()->asString(p->c));
if (p->is_term)
- debugPrint(debug_, "arnoldi", 1, " term %d", p->tindex);
+ debugPrint(debug_, "arnoldi", 1, " term {}", p->tindex);
if (p->in_edge)
- debugPrint(debug_, "arnoldi", 1, " from T%d,P%ld r=%s",
- p->in_edge->from->ts,
- p->in_edge->from-p0,
+ debugPrint(debug_, "arnoldi", 1, " from T{} P{} r={}",
+ p->in_edge->from->ts, p->in_edge->from - p0,
units_->resistanceUnit()->asString(p->r));
}
- for (i=0;ic;
- for (j=1;jc;
r[j] = p->r;
@@ -537,92 +546,99 @@ ArnoldiReduce::makeRcmodelFromTs()
}
sum = 0.0;
- for (j=0;jcapacitanceUnit()->asString(sum));
ctot_ = sum;
sqc_ = sqrt(sum);
- double sqrt_ctot_inv = 1.0/sqc_;
- for (j=0;j0;j--) {
- iv[j] += c[j]*u0[j];
+ for (j = n - 1; j > 0; j--) {
+ iv[j] += c[j] * u0[j];
iv[par[j]] += iv[j];
}
- iv[0] += c[0]*u0[0];
+ iv[0] += c[0] * u0[0];
y[0] = 0.0;
- for (j=1;jcheck("arnoldi", 1)) {
- report_->reportLine("tridiagonal reduced matrix, drvr pin %s",
- network_->pathName(drvr_pin_));
- report_->reportLine("order %d n %d",order,n);
- for (h=0;hreportLine(" d[%d] %s e[%d] %s",
- h,
- units_->timeUnit()->asString(d[h]),
- h,
- units_->timeUnit()->asString(e[h]));
+ report_->report("tridiagonal reduced matrix, drvr pin {}",
+ network_->pathName(drvr_pin_));
+ report_->report("order {} n {}", order, n);
+ for (h = 0; h < order; h++) {
+ if (h < order - 1)
+ report_->report(" d[{}] {} e[{}] {}", h,
+ units_->timeUnit()->asString(d[h]), h,
+ units_->timeUnit()->asString(e[h]));
else
- report_->reportLine(" d[%d] %s",
- h,
- units_->timeUnit()->asString(d[h]));
- std::string line = stdstrPrint("U[%d]",h);
- for (i=0;ireportLineString(line);
+ report_->report(" d[{}] {}", h, units_->timeUnit()->asString(d[h]));
+ std::string line = sta::format("U[{}]", h);
+ for (i = 0; i < nterms; i++)
+ line += sta::format(" {:6.2e}", U[h][i]);
+ report_->reportLine(line);
}
}
}
@@ -630,29 +646,33 @@ ArnoldiReduce::makeRcmodelFromTs()
rcmodel *
ArnoldiReduce::makeRcmodelFromW()
{
- int j,h;
+ int j, h;
int n = termN;
rcmodel *mod = new rcmodel();
mod->order = order;
mod->n = n;
- if (order>0) {
- int totd = order + order - 1 + order*n;
- mod->d = (double *)malloc(totd*sizeof(double));
- if (order>1) mod->e = mod->d + order;
- else mod->e = nullptr;
- mod->U = (double **)malloc(order*sizeof(double*));
+ if (order > 0) {
+ int totd = order + order - 1 + order * n;
+ mod->d = (double *)malloc(totd * sizeof(double));
+ if (order > 1)
+ mod->e = mod->d + order;
+ else
+ mod->e = nullptr;
+ mod->U = (double **)malloc(order * sizeof(double *));
mod->U[0] = mod->d + order + order - 1;
- for (h=1;hU[h]=mod->U[0] + h*n;
- for (h=0;hU[h] = mod->U[0] + h * n;
+ for (h = 0; h < order; h++) {
mod->d[h] = d[h];
- if (he[h] = e[h];
- for (j=0;je[h] = e[h];
+ for (j = 0; j < n; j++)
mod->U[h][j] = U[h][j];
}
}
- mod->pinV = (const Pin **)malloc(n*sizeof(const Pin*));
- for (j=0;jpinV = (const Pin **)malloc(n * sizeof(const Pin *));
+ for (j = 0; j < n; j++) {
int k = termV[j];
mod->pinV[j] = pinV[k];
}
@@ -662,4 +682,4 @@ ArnoldiReduce::makeRcmodelFromW()
return mod;
}
-} // namespace
+} // namespace sta
diff --git a/dcalc/CcsCeffDelayCalc.cc b/dcalc/CcsCeffDelayCalc.cc
index 31762fd0..0228df30 100644
--- a/dcalc/CcsCeffDelayCalc.cc
+++ b/dcalc/CcsCeffDelayCalc.cc
@@ -1,25 +1,25 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
-//
+//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-//
+//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
-//
+//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
-//
+//
// This notice may not be removed or altered from any source distribution.
#include "CcsCeffDelayCalc.hh"
@@ -63,10 +63,7 @@ CcsCeffDelayCalc::CcsCeffDelayCalc(StaState *sta) :
{
}
-CcsCeffDelayCalc::~CcsCeffDelayCalc()
-{
- delete table_dcalc_;
-}
+CcsCeffDelayCalc::~CcsCeffDelayCalc() { delete table_dcalc_; }
ArcDelayCalc *
CcsCeffDelayCalc::copy()
@@ -95,8 +92,8 @@ CcsCeffDelayCalc::gateDelay(const Pin *drvr_pin,
OutputWaveforms *output_waveforms = table_model->outputWaveforms();
Parasitics *parasitics = scene->parasitics(min_max);
parasitics->piModel(parasitic, c2_, rpi_, c1_);
- if (output_waveforms
- && rpi_ > 0.0 && c1_ > 0.0
+ if (output_waveforms && rpi_ > 0.0
+ && c1_ > 0.0
// Bounds check because extrapolating waveforms does not work for shit.
&& output_waveforms->slewAxis()->inBounds(in_slew_)
&& output_waveforms->capAxis()->inBounds(c2_)
@@ -107,7 +104,7 @@ CcsCeffDelayCalc::gateDelay(const Pin *drvr_pin,
drvr_rf_ = arc->toEdge()->asRiseFall();
drvr_library->supplyVoltage("VDD", vdd_, vdd_exists);
if (!vdd_exists)
- report_->error(1700, "VDD not defined in library %s", drvr_library->name());
+ report_->error(1700, "VDD not defined in library {}", drvr_library->name());
vth_ = drvr_library->outputThreshold(drvr_rf_) * vdd_;
vl_ = drvr_library->slewLowerThreshold(drvr_rf_) * vdd_;
vh_ = drvr_library->slewUpperThreshold(drvr_rf_) * vdd_;
@@ -115,12 +112,12 @@ CcsCeffDelayCalc::gateDelay(const Pin *drvr_pin,
drvr_cell->ensureVoltageWaveforms(scenes_);
output_waveforms_ = output_waveforms;
ref_time_ = output_waveforms_->referenceTime(in_slew_);
- debugPrint(debug_, "ccs_dcalc", 1, "%s %s",
- drvr_cell->name(),
+ debugPrint(debug_, "ccs_dcalc", 1, "{} {}", drvr_cell->name(),
drvr_rf_->shortName());
double gate_delay, drvr_slew;
gateDelaySlew(drvr_library, drvr_rf_, gate_delay, drvr_slew);
- return makeResult(drvr_library,drvr_rf_,gate_delay,drvr_slew,load_pin_index_map);
+ return makeResult(drvr_library, drvr_rf_, gate_delay, drvr_slew,
+ load_pin_index_map);
}
}
return table_dcalc_->gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic,
@@ -140,19 +137,19 @@ CcsCeffDelayCalc::gateDelaySlew(const LibertyLibrary *drvr_library,
gate_delay = region_times_[region_vth_idx_] - ref_time_;
drvr_slew = std::abs(region_times_[region_vh_idx_] - region_times_[region_vl_idx_]);
debugPrint(debug_, "ccs_dcalc", 2,
- "gate_delay %s drvr_slew %s (initial)",
+ "gate_delay {} drvr_slew {} (initial)",
delayAsString(gate_delay, this),
delayAsString(drvr_slew, this));
float prev_drvr_slew = drvr_slew;
constexpr int max_iterations = 5;
for (int iter = 0; iter < max_iterations; iter++) {
- debugPrint(debug_, "ccs_dcalc", 2, "iteration %d", iter);
+ debugPrint(debug_, "ccs_dcalc", 2, "iteration {}", iter);
// Init drvr ramp model for vl.
for (size_t i = 0; i <= region_count_; i++) {
region_ramp_times_[i] = region_times_[i];
if (i < region_count_)
region_ramp_slopes_[i] = (region_volts_[i + 1] - region_volts_[i])
- / (region_times_[i + 1] - region_times_[i]);
+ / (region_times_[i + 1] - region_times_[i]);
}
for (size_t i = 0; i < region_count_; i++) {
@@ -172,15 +169,14 @@ CcsCeffDelayCalc::gateDelaySlew(const LibertyLibrary *drvr_library,
double q2 = v2 * c2_ + c1_v2 * c1_;
double ceff = (q2 - q1) / (v2 - v1);
- debugPrint(debug_, "ccs_dcalc", 2, "ceff %s",
+ debugPrint(debug_, "ccs_dcalc", 2, "ceff {}",
capacitance_unit_->asString(ceff));
region_ceff_[i] = ceff;
}
findCsmWaveform();
gate_delay = region_times_[region_vth_idx_] - ref_time_;
drvr_slew = std::abs(region_times_[region_vh_idx_] - region_times_[region_vl_idx_]);
- debugPrint(debug_, "ccs_dcalc", 2,
- "gate_delay %s drvr_slew %s",
+ debugPrint(debug_, "ccs_dcalc", 2, "gate_delay {} drvr_slew {}",
delayAsString(gate_delay, this),
delayAsString(drvr_slew, this));
if (std::abs(drvr_slew - prev_drvr_slew) < .01 * prev_drvr_slew)
@@ -215,68 +211,68 @@ CcsCeffDelayCalc::initRegions(const LibertyLibrary *drvr_library,
double vth_vh = (vh_ - vth_);
switch (region_count_) {
- case 4:
- region_vth_idx_ = 2;
- region_volts_ = {0.0, vl_, vth_, vh_, vdd_};
- break;
- case 5: {
- region_vth_idx_ = 2;
- double v1 = vth_ + .7 * vth_vh;
- region_volts_ = {0.0, vl_, vth_, v1, vh_, vdd_};
- break;
- }
- case 6: {
- region_vth_idx_ = 2;
- double v1 = vth_ + .3 * vth_vh;
- double v2 = vth_ + .6 * vth_vh;
- region_volts_ = {0.0, vl_, vth_, v1, v2, vh_, vdd_};
- break;
- }
- case 7: {
- region_vth_idx_ = 2;
- region_vh_idx_ = 5;
- double v1 = vth_ + .3 * vth_vh;
- double v2 = vth_ + .6 * vth_vh;
- double v3 = vh_ + .5 * (vdd_ - vh_);
- region_volts_ = {0.0, vl_, vth_, v1, v2, vh_, v3, vdd_};
- break;
- }
- case 8: {
- region_vth_idx_ = 2;
- region_vh_idx_ = 6;
- double v1 = vth_ + .25 * vth_vh;
- double v2 = vth_ + .50 * vth_vh;
- double v3 = vth_ + .75 * vth_vh;
- double v4 = vh_ + .5 * (vdd_ - vh_);
- region_volts_ = {0.0, vl_, vth_, v1, v2, v3, vh_, v4, vdd_};
- break;
- }
- case 9: {
- region_vth_idx_ = 2;
- region_vh_idx_ = 7;
- double v1 = vth_ + .2 * vth_vh;
- double v2 = vth_ + .4 * vth_vh;
- double v3 = vth_ + .6 * vth_vh;
- double v4 = vth_ + .8 * vth_vh;
- double v5 = vh_ + .5 * (vdd_ - vh_);
- region_volts_ = {0.0, vl_, vth_, v1, v2, v3, v4, vh_, v5, vdd_};
- break;
- }
- case 10: {
- region_vth_idx_ = 2;
- region_vh_idx_ = 7;
- double v1 = vth_ + .2 * vth_vh;
- double v2 = vth_ + .4 * vth_vh;
- double v3 = vth_ + .6 * vth_vh;
- double v4 = vth_ + .8 * vth_vh;
- double v5 = vh_ + .3 * (vdd_ - vh_);
- double v6 = vh_ + .6 * (vdd_ - vh_);
- region_volts_ = {0.0, vl_, vth_, v1, v2, v3, v4, vh_, v5, v6, vdd_};
- break;
- }
- default:
- report_->error(1701, "unsupported ccs region count.");
- break;
+ case 4:
+ region_vth_idx_ = 2;
+ region_volts_ = {0.0, vl_, vth_, vh_, vdd_};
+ break;
+ case 5: {
+ region_vth_idx_ = 2;
+ double v1 = vth_ + .7 * vth_vh;
+ region_volts_ = {0.0, vl_, vth_, v1, vh_, vdd_};
+ break;
+ }
+ case 6: {
+ region_vth_idx_ = 2;
+ double v1 = vth_ + .3 * vth_vh;
+ double v2 = vth_ + .6 * vth_vh;
+ region_volts_ = {0.0, vl_, vth_, v1, v2, vh_, vdd_};
+ break;
+ }
+ case 7: {
+ region_vth_idx_ = 2;
+ region_vh_idx_ = 5;
+ double v1 = vth_ + .3 * vth_vh;
+ double v2 = vth_ + .6 * vth_vh;
+ double v3 = vh_ + .5 * (vdd_ - vh_);
+ region_volts_ = {0.0, vl_, vth_, v1, v2, vh_, v3, vdd_};
+ break;
+ }
+ case 8: {
+ region_vth_idx_ = 2;
+ region_vh_idx_ = 6;
+ double v1 = vth_ + .25 * vth_vh;
+ double v2 = vth_ + .50 * vth_vh;
+ double v3 = vth_ + .75 * vth_vh;
+ double v4 = vh_ + .5 * (vdd_ - vh_);
+ region_volts_ = {0.0, vl_, vth_, v1, v2, v3, vh_, v4, vdd_};
+ break;
+ }
+ case 9: {
+ region_vth_idx_ = 2;
+ region_vh_idx_ = 7;
+ double v1 = vth_ + .2 * vth_vh;
+ double v2 = vth_ + .4 * vth_vh;
+ double v3 = vth_ + .6 * vth_vh;
+ double v4 = vth_ + .8 * vth_vh;
+ double v5 = vh_ + .5 * (vdd_ - vh_);
+ region_volts_ = {0.0, vl_, vth_, v1, v2, v3, v4, vh_, v5, vdd_};
+ break;
+ }
+ case 10: {
+ region_vth_idx_ = 2;
+ region_vh_idx_ = 7;
+ double v1 = vth_ + .2 * vth_vh;
+ double v2 = vth_ + .4 * vth_vh;
+ double v3 = vth_ + .6 * vth_vh;
+ double v4 = vth_ + .8 * vth_vh;
+ double v5 = vh_ + .3 * (vdd_ - vh_);
+ double v6 = vh_ + .6 * (vdd_ - vh_);
+ region_volts_ = {0.0, vl_, vth_, v1, v2, v3, v4, vh_, v5, v6, vdd_};
+ break;
+ }
+ default:
+ report_->error(1701, "unsupported ccs region count.");
+ break;
}
fill(region_ceff_.begin(), region_ceff_.end(), c2_ + c1_);
}
@@ -285,15 +281,15 @@ void
CcsCeffDelayCalc::findCsmWaveform()
{
for (size_t i = 0; i < region_count_; i++) {
- double t1 = output_waveforms_->voltageTime(in_slew_, region_ceff_[i],
- region_volts_[i]);
+ double t1 =
+ output_waveforms_->voltageTime(in_slew_, region_ceff_[i], region_volts_[i]);
double t2 = output_waveforms_->voltageTime(in_slew_, region_ceff_[i],
region_volts_[i + 1]);
region_begin_times_[i] = t1;
region_end_times_[i] = t2;
double time_offset = (i == 0)
- ? 0.0
- : t1 - (region_end_times_[i - 1] - region_time_offsets_[i - 1]);
+ ? 0.0
+ : t1 - (region_end_times_[i - 1] - region_time_offsets_[i - 1]);
region_time_offsets_[i] = time_offset;
if (i == 0)
@@ -312,10 +308,8 @@ CcsCeffDelayCalc::makeResult(const LibertyLibrary *drvr_library,
const LoadPinIndexMap &load_pin_index_map)
{
ArcDcalcResult dcalc_result(load_pin_index_map.size());
- debugPrint(debug_, "ccs_dcalc", 2,
- "gate_delay %s drvr_slew %s",
- delayAsString(gate_delay, this),
- delayAsString(drvr_slew, this));
+ debugPrint(debug_, "ccs_dcalc", 2, "gate_delay {} drvr_slew {}",
+ delayAsString(gate_delay, this), delayAsString(drvr_slew, this));
dcalc_result.setGateDelay(gate_delay);
dcalc_result.setDrvrSlew(drvr_slew);
@@ -342,8 +336,7 @@ CcsCeffDelayCalc::loadDelaySlew(const Pin *load_pin,
bool elmore_exists = false;
float elmore = 0.0;
- if (parasitic_
- && parasitics_->isPiElmore(parasitic_))
+ if (parasitic_ && parasitics_->isPiElmore(parasitic_))
parasitics_->findElmore(parasitic_, load_pin, elmore, elmore_exists);
if (elmore_exists &&
@@ -371,7 +364,7 @@ CcsCeffDelayCalc::loadDelaySlew(const Pin *load_pin,
region_ramp_times_[i] = region_times_[i];
if (i < region_count_)
region_ramp_slopes_[i] = (region_volts_[i + 1] - region_volts_[i])
- / (region_times_[i + 1] - region_times_[i]);
+ / (region_times_[i + 1] - region_times_[i]);
}
vl_fail_ = false;
@@ -387,10 +380,8 @@ CcsCeffDelayCalc::loadDelaySlew(const Pin *load_pin,
slew = drvr_slew;
fail("load delay threshold crossing");
}
- debugPrint(debug_, "ccs_dcalc", 2,
- "load %s delay %s slew %s",
- network_->pathName(load_pin),
- delayAsString(delay, this),
+ debugPrint(debug_, "ccs_dcalc", 2, "load {} delay {} slew {}",
+ network_->pathName(load_pin), delayAsString(delay, this),
delayAsString(slew, this));
}
@@ -455,12 +446,12 @@ CcsCeffDelayCalc::findVlTime(double v,
double t_init = region_ramp_times_[0];
double t_final = region_ramp_times_[region_count_];
bool root_fail = false;
- double time = findRoot([&] (double t,
- double &y,
- double &dy) {
- vl(t, elmore, y, dy);
- y -= v;
- }, t_init, t_final + elmore * 3.0, .001, 20, root_fail);
+ double time = findRoot(
+ [&](double t, double &y, double &dy) {
+ vl(t, elmore, y, dy);
+ y -= v;
+ },
+ t_init, t_final + elmore * 3.0, .001, 20, root_fail);
vl_fail_ |= root_fail;
return time;
}
@@ -485,7 +476,7 @@ PinSeq
CcsCeffDelayCalc::watchPins() const
{
PinSeq pins;
- for (const auto& [pin, values] : watch_pin_values_)
+ for (const auto &[pin, values] : watch_pin_values_)
pins.push_back(pin);
return pins;
}
@@ -521,8 +512,8 @@ CcsCeffDelayCalc::drvrWaveform()
drvr_volts->push_back(v);
}
}
- TableAxisPtr drvr_time_axis = std::make_shared(TableAxisVariable::time,
- std::move(*drvr_times));
+ TableAxisPtr drvr_time_axis =
+ std::make_shared(TableAxisVariable::time, std::move(*drvr_times));
delete drvr_times;
Table drvr_table(drvr_volts, drvr_time_axis);
return drvr_table;
@@ -553,8 +544,8 @@ CcsCeffDelayCalc::loadWaveform(const Pin *load_pin)
double v1 = (drvr_rf_ == RiseFall::rise()) ? v : vdd_ - v;
load_volts->push_back(v1);
}
- TableAxisPtr load_time_axis = std::make_shared(TableAxisVariable::time,
- std::move(*load_times));
+ TableAxisPtr load_time_axis = std::make_shared(
+ TableAxisVariable::time, std::move(*load_times));
delete load_times;
Table load_table(load_volts, load_time_axis);
return load_table;
@@ -576,10 +567,9 @@ CcsCeffDelayCalc::drvrRampWaveform(const Pin *in_pin,
float elmore = 0.0;
if (parasitic_) {
parasitics_->findElmore(parasitic_, load_pin, elmore, elmore_exists);
- bool dcalc_success = makeWaveformPreamble(in_pin, in_rf, drvr_pin,
- drvr_rf, scene, min_max);
- if (dcalc_success
- && elmore_exists) {
+ bool dcalc_success =
+ makeWaveformPreamble(in_pin, in_rf, drvr_pin, drvr_rf, scene, min_max);
+ if (dcalc_success && elmore_exists) {
FloatSeq *load_times = new FloatSeq;
FloatSeq *load_volts = new FloatSeq;
for (size_t j = 0; j <= region_count_; j++) {
@@ -598,8 +588,8 @@ CcsCeffDelayCalc::drvrRampWaveform(const Pin *in_pin,
double v1 = (drvr_rf == RiseFall::rise()) ? v : vdd_ - v;
load_volts->push_back(v1);
}
- TableAxisPtr load_time_axis = std::make_shared(TableAxisVariable::time,
- std::move(*load_times));
+ TableAxisPtr load_time_axis = std::make_shared(
+ TableAxisVariable::time, std::move(*load_times));
delete load_times;
Table load_table(load_volts, load_time_axis);
return load_table;
@@ -628,7 +618,7 @@ CcsCeffDelayCalc::makeWaveformPreamble(const Pin *in_pin,
break;
}
if (edge) {
- TimingArc *arc = nullptr;
+ TimingArc *arc = nullptr;
for (TimingArc *arc1 : edge->timingArcSet()->arcs()) {
if (arc1->fromEdge()->asRiseFall() == in_rf
&& arc1->toEdge()->asRiseFall() == drvr_rf) {
@@ -643,9 +633,9 @@ CcsCeffDelayCalc::makeWaveformPreamble(const Pin *in_pin,
if (parasitic_) {
parasitics_->piModel(parasitic_, c2_, rpi_, c1_);
LoadPinIndexMap load_pin_index_map =
- graph_delay_calc_->makeLoadPinIndexMap(drvr_vertex);
- gateDelay(drvr_pin, arc, in_slew, load_cap_, parasitic_,
- load_pin_index_map, scene, min_max);
+ graph_delay_calc_->makeLoadPinIndexMap(drvr_vertex);
+ gateDelay(drvr_pin, arc, in_slew, load_cap_, parasitic_, load_pin_index_map,
+ scene, min_max);
return true;
}
}
@@ -669,12 +659,12 @@ CcsCeffDelayCalc::reportGateDelay(const Pin *drvr_pin,
Parasitic *pi_elmore = nullptr;
const RiseFall *rf = arc->toEdge()->asRiseFall();
if (parasitic && !parasitics_->isPiElmore(parasitic)) {
- pi_elmore = parasitics_->reduceToPiElmore(parasitic, drvr_pin_, rf,
- scene, min_max);
+ pi_elmore =
+ parasitics_->reduceToPiElmore(parasitic, drvr_pin_, rf, scene, min_max);
}
- std::string report = table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap,
- pi_elmore, load_pin_index_map,
- scene, min_max, digits);
+ std::string report =
+ table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap, pi_elmore,
+ load_pin_index_map, scene, min_max, digits);
parasitics_->deleteDrvrReducedParasitics(drvr_pin);
return report;
}
@@ -684,7 +674,7 @@ CcsCeffDelayCalc::fail(const char *reason)
{
// Report failures with a unique debug flag.
if (debug_->check("ccs_dcalc", 1) || debug_->check("dcalc_error", 1))
- report_->reportLine("delay_calc: CCS failed - %s", reason);
+ report_->report("delay_calc: CCS failed - {}", reason);
}
-} // namespace
+} // namespace sta
diff --git a/dcalc/Delay.cc b/dcalc/Delay.cc
index 7154e3d8..c40bd429 100644
--- a/dcalc/Delay.cc
+++ b/dcalc/Delay.cc
@@ -215,7 +215,7 @@ delayDblAsDelay(DelayDbl &delay)
return Delay(delay.mean(), delay.meanShift(), delay.stdDev2(), delay.skewness());
}
-const char *
+std::string
delayAsString(const Delay &delay,
const StaState *sta)
{
@@ -223,7 +223,7 @@ delayAsString(const Delay &delay,
sta->units()->timeUnit()->digits(), sta);
}
-const char *
+std::string
delayAsString(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta)
@@ -231,7 +231,7 @@ delayAsString(const Delay &delay,
return delayAsString(delay, early_late, sta->units()->timeUnit()->digits(), sta);
}
-const char *
+std::string
delayAsString(const Delay &delay,
const EarlyLate *early_late,
int digits,
@@ -242,7 +242,7 @@ delayAsString(const Delay &delay,
return unit->asString(mean_std_dev, digits);
}
-const char *
+std::string
delayAsString(const Delay &delay,
const EarlyLate *early_late,
bool report_variance,
diff --git a/dcalc/DelayCalc.tcl b/dcalc/DelayCalc.tcl
index 7d15b5a9..3658c219 100644
--- a/dcalc/DelayCalc.tcl
+++ b/dcalc/DelayCalc.tcl
@@ -131,7 +131,7 @@ proc set_delay_calculator { alg } {
if { [is_delay_calc_name $alg] } {
set_delay_calculator_cmd $alg
} else {
- sta_error 195 "delay calculator $alg not found."
+ sta_error 2500 "delay calculator $alg not found."
}
}
@@ -154,38 +154,38 @@ proc set_assigned_delay { args } {
if [info exists keys(-from)] {
set from_pins [get_port_pins_error "from_pins" $keys(-from)]
} else {
- sta_error 196 "set_assigned_delay missing -from argument."
+ sta_error 2501 "set_assigned_delay missing -from argument."
}
if [info exists keys(-to)] {
set to_pins [get_port_pins_error "to_pins" $keys(-to)]
} else {
- sta_error 182 "set_assigned_delay missing -to argument."
+ sta_error 2502 "set_assigned_delay missing -to argument."
}
set delay [lindex $args 0]
if {![string is double $delay]} {
- sta_error 183 "set_assigned_delay delay is not a float."
+ sta_error 2503 "set_assigned_delay delay is not a float."
}
set delay [time_ui_sta $delay]
if {[info exists flags(-cell)] && [info exists flags(-net)]} {
- sta_error 184 "set_annotated_delay -cell and -net options are mutually excluive."
+ sta_error 2504 "set_annotated_delay -cell and -net options are mutually excluive."
} elseif {[info exists flags(-cell)]} {
if { $from_pins != {} } {
set inst [[lindex $from_pins 0] instance]
foreach pin $from_pins {
if {[$pin instance] != $inst} {
- sta_error 185 "set_assigned_delay pin [get_full_name $pin] is not attached to instance [get_full_name $inst]."
+ sta_error 2505 "set_assigned_delay pin [get_full_name $pin] is not attached to instance [get_full_name $inst]."
}
}
foreach pin $to_pins {
if {[$pin instance] != $inst} {
- sta_error 186 "set_assigned_delay pin [get_full_name $pin] is not attached to instance [get_full_name $inst]"
+ sta_error 2506 "set_assigned_delay pin [get_full_name $pin] is not attached to instance [get_full_name $inst]"
}
}
}
} elseif {![info exists flags(-net)]} {
- sta_error 187 "set_assigned_delay -cell or -net required."
+ sta_error 2508 "set_assigned_delay -cell or -net required."
}
foreach from_pin $from_pins {
set from_vertices [$from_pin vertices]
@@ -229,7 +229,7 @@ proc set_assigned_delay2 {from_vertex to_vertex to_rf scene min_max delay} {
}
$edge_iter finish
if { !$matched } {
- sta_error 193 "set_assigned_delay no timing arcs found between from/to pins."
+ sta_error 2509 "set_assigned_delay no timing arcs found between from/to pins."
}
}
@@ -250,7 +250,7 @@ proc set_assigned_check { args } {
if { [info exists keys(-from)] } {
set from_pins [get_port_pins_error "from_pins" $keys(-from)]
} else {
- sta_error 188 "set_assigned_check missing -from argument."
+ sta_error 2510 "set_assigned_check missing -from argument."
}
set from_rf "rise_fall"
if { [info exists keys(-clock)] } {
@@ -259,14 +259,14 @@ proc set_assigned_check { args } {
|| $clk_arg eq "fall" } {
set from_rf $clk_arg
} else {
- sta_error 189 "set_assigned_check -clock must be rise or fall."
+ sta_error 2511 "set_assigned_check -clock must be rise or fall."
}
}
if { [info exists keys(-to)] } {
set to_pins [get_port_pins_error "to_pins" $keys(-to)]
} else {
- sta_error 190 "set_assigned_check missing -to argument."
+ sta_error 2512 "set_assigned_check missing -to argument."
}
set to_rf [parse_rise_fall_flags flags]
set scene [parse_scene keys]
@@ -281,7 +281,7 @@ proc set_assigned_check { args } {
} elseif { [info exists flags(-removal)] } {
set role "removal"
} else {
- sta_error 191 "set_assigned_check missing -setup|-hold|-recovery|-removal check type.."
+ sta_error 2513 "set_assigned_check missing -setup|-hold|-recovery|-removal check type.."
}
set cond ""
if { [info exists key(-cond)] } {
@@ -289,7 +289,7 @@ proc set_assigned_check { args } {
}
set check_value [lindex $args 0]
if { ![string is double $check_value] } {
- sta_error 192 "set_assigned_check check_value is not a float."
+ sta_error 2514 "set_assigned_check check_value is not a float."
}
set check_value [time_ui_sta $check_value]
@@ -341,7 +341,7 @@ proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \
}
$edge_iter finish
if { !$matched } {
- sta_error 194 "set_assigned_check no check arcs found between from/to pins."
+ sta_error 2516 "set_assigned_check no check arcs found between from/to pins."
}
}
@@ -362,7 +362,7 @@ proc set_assigned_transition { args } {
set slew [lindex $args 0]
if {![string is double $slew]} {
- sta_error 210 "set_assigned_transition transition is not a float."
+ sta_error 2518 "set_assigned_transition transition is not a float."
}
set slew [time_ui_sta $slew]
set pins [get_port_pins_error "pins" [lindex $args 1]]
diff --git a/dcalc/DelayCalcBase.cc b/dcalc/DelayCalcBase.cc
index 25429d68..f153e44c 100644
--- a/dcalc/DelayCalcBase.cc
+++ b/dcalc/DelayCalcBase.cc
@@ -123,6 +123,7 @@ DelayCalcBase::thresholdAdjust(const Pin *load_pin,
wire_delay += (rf == RiseFall::rise())
? wire_delay_delta
: -wire_delay_delta;
+
float load_slew_delta = load_library->slewUpperThreshold(rf)
- load_library->slewLowerThreshold(rf);
float drvr_slew_derate = drvr_library->slewDerateFromLibrary();
diff --git a/dcalc/DelayNormal.cc b/dcalc/DelayNormal.cc
index 31f03a52..2c3cb059 100644
--- a/dcalc/DelayNormal.cc
+++ b/dcalc/DelayNormal.cc
@@ -29,6 +29,7 @@
#include "Error.hh"
#include "Fuzzy.hh"
#include "Units.hh"
+#include "Format.hh"
#include "StaState.hh"
#include "Variables.hh"
@@ -217,15 +218,15 @@ DelayOpsNormal::div(float delay1,
return Delay(delay1 / delay2.mean());
}
-const char *
+std::string
DelayOpsNormal::asStringVariance(const Delay &delay,
int digits,
const StaState *sta) const
{
const Unit *unit = sta->units()->timeUnit();
- return stringPrintTmp("%s[%s]",
- unit->asString(delay.mean(), digits),
- unit->asString(delay.stdDev(), digits));
+ return sta::format("{}[{}]",
+ unit->asString(delay.mean(), digits),
+ unit->asString(delay.stdDev(), digits));
}
} // namespace
diff --git a/dcalc/DelayScalar.cc b/dcalc/DelayScalar.cc
index 69346355..6ad49178 100644
--- a/dcalc/DelayScalar.cc
+++ b/dcalc/DelayScalar.cc
@@ -193,7 +193,7 @@ DelayOpsScalar::div(float delay1,
return Delay(delay1 / delay2.mean());
}
-const char *
+std::string
DelayOpsScalar::asStringVariance(const Delay &delay,
int digits,
const StaState *sta) const
diff --git a/dcalc/DelaySkewNormal.cc b/dcalc/DelaySkewNormal.cc
index 82bdfbe4..306634ba 100644
--- a/dcalc/DelaySkewNormal.cc
+++ b/dcalc/DelaySkewNormal.cc
@@ -29,6 +29,7 @@
#include "Error.hh"
#include "Fuzzy.hh"
#include "Units.hh"
+#include "Format.hh"
#include "StaState.hh"
#include "Variables.hh"
@@ -276,17 +277,17 @@ DelayOpsSkewNormal::div(float delay1,
return Delay(delay1 / delay2.mean());
}
-const char *
+std::string
DelayOpsSkewNormal::asStringVariance(const Delay &delay,
int digits,
const StaState *sta) const
{
const Unit *unit = sta->units()->timeUnit();
- return stringPrintTmp("%s[%s,%s,%s]",
- unit->asString(delay.mean(), digits),
- unit->asString(delay.meanShift(), digits),
- unit->asString(delay.stdDev(), digits),
- sta->units()->scalarUnit()->asString(delay.skewness(), digits));
+ return sta::format("{}[{},{},{}]",
+ unit->asString(delay.mean(), digits),
+ unit->asString(delay.meanShift(), digits),
+ unit->asString(delay.stdDev(), digits),
+ sta->units()->scalarUnit()->asString(delay.skewness(), digits));
}
} // namespace
diff --git a/dcalc/DmpCeff.cc b/dcalc/DmpCeff.cc
index 48114895..38c04648 100644
--- a/dcalc/DmpCeff.cc
+++ b/dcalc/DmpCeff.cc
@@ -1,25 +1,25 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
-//
+//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-//
+//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
-//
+//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
-//
+//
// This notice may not be removed or altered from any source distribution.
// "Performance Computation for Precharacterized CMOS Gates with RC Loads",
@@ -36,6 +36,7 @@
#include
#include
+#include "Format.hh"
#include "Report.hh"
#include "Debug.hh"
#include "Units.hh"
@@ -97,7 +98,7 @@ newtonRaphson(const int max_iter,
const int n,
const double x_tol,
// eval(state) is called to fill fvec and fjac.
- std::function eval,
+ std::function eval,
// Temporaries supplied by caller.
double *fvec,
double **fjac,
@@ -122,7 +123,8 @@ luDecomp(double **a,
class DmpAlg : public StaState
{
public:
- DmpAlg(int nr_order, StaState *sta);
+ DmpAlg(int nr_order,
+ StaState *sta);
~DmpAlg() override = default;
virtual const char *name() = 0;
// Set driver model and pi model parameters for delay calculation.
@@ -136,9 +138,9 @@ public:
double c2,
double rpi,
double c1);
- virtual void gateDelaySlew(// Return values.
- double &delay,
- double &slew) = 0;
+ virtual void gateDelaySlew( // Return values.
+ double &delay,
+ double &slew) = 0;
virtual void loadDelaySlew(const Pin *load_pin,
double elmore,
// Return values.
@@ -188,9 +190,9 @@ protected:
void showX();
void showFvec();
void showJacobian();
- void findDriverDelaySlew(// Return values.
- double &delay,
- double &slew);
+ void findDriverDelaySlew( // Return values.
+ double &delay,
+ double &slew);
double findVoCrossing(double vth,
double lower_bound,
double upper_bound);
@@ -260,7 +262,7 @@ protected:
double fjac_storage_[max_nr_order_ * max_nr_order_];
double *fjac_[max_nr_order_];
double scale_[max_nr_order_];
- double p_[max_nr_order_ ];
+ double p_[max_nr_order_];
int index_[max_nr_order_];
// Driver slew used to check load delay.
@@ -274,7 +276,7 @@ protected:
};
DmpAlg::DmpAlg(int nr_order,
- StaState *sta):
+ StaState *sta) :
StaState(sta),
c2_(0.0),
rpi_(0.0),
@@ -328,14 +330,13 @@ DmpAlg::findDriverParams(double ceff)
double t0 = t_vth + std::log(1.0 - vth_) * rd_ * ceff - vth_ * dt;
x_[DmpParam::dt] = dt;
x_[DmpParam::t0] = t0;
- newtonRaphson(100, x_, nr_order_, driver_param_tol,
- [this] () { evalDmpEqns(); },
- fvec_, fjac_, index_, p_, scale_);
+ newtonRaphson(
+ 100, x_, nr_order_, driver_param_tol, [this]() { evalDmpEqns(); }, fvec_,
+ fjac_, index_, p_, scale_);
t0_ = x_[DmpParam::t0];
dt_ = x_[DmpParam::dt];
- debugPrint(debug_, "dmp_ceff", 3, " t0 = %s dt = %s ceff = %s",
- units_->timeUnit()->asString(t0_),
- units_->timeUnit()->asString(dt_),
+ debugPrint(debug_, "dmp_ceff", 3, " t0 = {} dt = {} ceff = {}",
+ units_->timeUnit()->asString(t0_), units_->timeUnit()->asString(dt_),
units_->capacitanceUnit()->asString(x_[DmpParam::ceff]));
if (debug_->check("dmp_ceff", 4))
showVo();
@@ -409,8 +410,7 @@ DmpAlg::dy(double t,
}
else {
dydt0 = -(y0dt(t1, cl) - y0dt(t1 - dt, cl)) / dt;
- dyddt = -(y0(t1, cl) + y0(t1 - dt, cl)) / (dt * dt)
- + y0dt(t1 - dt, cl) / dt;
+ dyddt = -(y0(t1, cl) + y0(t1 - dt, cl)) / (dt * dt) + y0dt(t1 - dt, cl) / dt;
dydcl = (y0dcl(t1, cl) - y0dcl(t1 - dt, cl)) / dt;
}
}
@@ -433,14 +433,14 @@ void
DmpAlg::showX()
{
for (int i = 0; i < nr_order_; i++)
- report_->reportLine("%4s %12.3e", dmp_param_index_strings[i], x_[i]);
+ report_->report("{:4} {:12.3e}", dmp_param_index_strings[i], x_[i]);
}
void
DmpAlg::showFvec()
{
for (int i = 0; i < nr_order_; i++)
- report_->reportLine("%4s %12.3e", dmp_func_index_strings[i], fvec_[i]);
+ report_->report("{:4} {:12.3e}", dmp_func_index_strings[i], fvec_[i]);
}
void
@@ -448,21 +448,21 @@ DmpAlg::showJacobian()
{
std::string line = " ";
for (int j = 0; j < nr_order_; j++)
- line += stdstrPrint("%12s", dmp_param_index_strings[j]);
- report_->reportLineString(line);
+ line += sta::format("{:12}", dmp_param_index_strings[j]);
+ report_->reportLine(line);
line.clear();
for (int i = 0; i < nr_order_; i++) {
- line += stdstrPrint("%4s ", dmp_func_index_strings[i]);
+ line += sta::format("{:4} ", dmp_func_index_strings[i]);
for (int j = 0; j < nr_order_; j++)
- line += stdstrPrint("%12.3e ", fjac_[i][j]);
- report_->reportLineString(line);
+ line += sta::format("{:12.3e} ", fjac_[i][j]);
+ report_->reportLine(line);
}
}
void
-DmpAlg::findDriverDelaySlew(// Return values.
- double &delay,
- double &slew)
+DmpAlg::findDriverDelaySlew( // Return values.
+ double &delay,
+ double &slew)
{
double t_upper = voCrossingUpperBound();
delay = findVoCrossing(vth_, t0_, t_upper);
@@ -478,17 +478,15 @@ DmpAlg::findVoCrossing(double vth,
double t_lower,
double t_upper)
{
- FindRootFunc vo_func = [&] (double t,
- double &y,
- double &dy) {
+ FindRootFunc vo_func = [&](double t, double &y, double &dy) {
double vo, vo_dt;
Vo(t, vo, vo_dt);
y = vo - vth;
dy = vo_dt;
};
bool fail;
- double t_vth = findRoot(vo_func, t_lower, t_upper, vth_time_tol,
- find_root_max_iter, fail);
+ double t_vth =
+ findRoot(vo_func, t_lower, t_upper, vth_time_tol, find_root_max_iter, fail);
if (fail)
throw DmpError("find Vo crossing failed");
return t_vth;
@@ -510,7 +508,7 @@ DmpAlg::Vo(double t,
V0(t1, v0, dv0_dt);
vo = v0 / dt_;
- dvo_dt = dv0_dt / dt_;
+ dvo_dt = dv0_dt / dt_;
}
else {
double v0, dv0_dt;
@@ -527,12 +525,12 @@ DmpAlg::Vo(double t,
void
DmpAlg::showVo()
{
- report_->reportLine(" t vo(t)");
+ report_->report(" t vo(t)");
double ub = voCrossingUpperBound();
for (double t = t0_; t < t0_ + ub; t += dt_ / 10.0) {
double vo, dvo_dt;
Vo(t, vo, dvo_dt);
- report_->reportLine(" %g %g", t, vo);
+ report_->report(" {:g} {:g}", t, vo);
}
}
@@ -581,8 +579,7 @@ DmpAlg::loadDelaySlew(const Pin *,
}
delay = delay1;
slew = slew1;
- }
- catch (DmpError &error) {
+ } catch (DmpError &error) {
fail(error.what());
delay = elmore_;
slew = drvr_slew_;
@@ -596,17 +593,15 @@ DmpAlg::findVlCrossing(double vth,
double t_lower,
double t_upper)
{
- FindRootFunc vl_func = [&] (double t,
- double &y,
- double &dy) {
+ FindRootFunc vl_func = [&](double t, double &y, double &dy) {
double vl, vl_dt;
Vl(t, vl, vl_dt);
y = vl - vth;
dy = vl_dt;
};
bool fail;
- double t_vth = findRoot(vl_func, t_lower, t_upper, vth_time_tol,
- find_root_max_iter, fail);
+ double t_vth =
+ findRoot(vl_func, t_lower, t_upper, vth_time_tol, find_root_max_iter, fail);
if (fail)
throw DmpError("find Vl crossing failed");
return t_vth;
@@ -650,12 +645,12 @@ DmpAlg::Vl(double t,
void
DmpAlg::showVl()
{
- report_->reportLine(" t vl(t)");
+ report_->report(" t vl(t)");
double ub = vlCrossingUpperBound();
for (double t = t0_; t < t0_ + ub * 2.0; t += ub / 10.0) {
double vl, dvl_dt;
Vl(t, vl, dvl_dt);
- report_->reportLine(" %g %g", t, vl);
+ report_->report(" {:g} {:g}", t, vl);
}
}
@@ -664,12 +659,11 @@ DmpAlg::fail(const char *reason)
{
// Report failures with a unique debug flag.
if (debug_->check("dmp_ceff", 1) || debug_->check("dcalc_error", 1))
- report_->reportLine("delay_calc: DMP failed - %s c2=%s rpi=%s c1=%s rd=%s",
- reason,
- units_->capacitanceUnit()->asString(c2_),
- units_->resistanceUnit()->asString(rpi_),
- units_->capacitanceUnit()->asString(c1_),
- units_->resistanceUnit()->asString(rd_));
+ report_->report("delay_calc: DMP failed - {} c2={} rpi={} c1={} rd={}", reason,
+ units_->capacitanceUnit()->asString(c2_),
+ units_->resistanceUnit()->asString(rpi_),
+ units_->capacitanceUnit()->asString(c1_),
+ units_->resistanceUnit()->asString(rd_));
}
////////////////////////////////////////////////////////////////
@@ -690,9 +684,9 @@ public:
double c2,
double rpi,
double c1) override;
- void gateDelaySlew(// Return values.
- double &delay,
- double &slew) override;
+ void gateDelaySlew( // Return values.
+ double &delay,
+ double &slew) override;
void loadDelaySlew(const Pin *,
double elmore,
// Return values.
@@ -712,8 +706,9 @@ private:
double &dvl_dt) override;
};
-DmpCap::DmpCap(StaState *sta):
- DmpAlg(1, sta)
+DmpCap::DmpCap(StaState *sta) :
+ DmpAlg(1,
+ sta)
{
}
@@ -730,17 +725,17 @@ DmpCap::init(const LibertyLibrary *drvr_library,
double c1)
{
debugPrint(debug_, "dmp_ceff", 3, "Using DMP cap");
- DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf,
- rd, in_slew, c2, rpi, c1);
+ DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi,
+ c1);
ceff_ = c1 + c2;
}
void
-DmpCap::gateDelaySlew(// Return values.
- double &delay,
- double &slew)
+DmpCap::gateDelaySlew( // Return values.
+ double &delay,
+ double &slew)
{
- debugPrint(debug_, "dmp_ceff", 3, " ceff = %s",
+ debugPrint(debug_, "dmp_ceff", 3, " ceff = {}",
units_->capacitanceUnit()->asString(ceff_));
gateCapDelaySlew(ceff_, delay, slew);
drvr_slew_ = slew;
@@ -778,7 +773,7 @@ DmpCap::voCrossingUpperBound()
}
void
-DmpCap::Vl0(double ,
+DmpCap::Vl0(double,
// Return values.
double &vl,
double &dvl_dt)
@@ -805,9 +800,9 @@ public:
double c2,
double rpi,
double c1) override;
- void gateDelaySlew(// Return values.
- double &delay,
- double &slew) override;
+ void gateDelaySlew( // Return values.
+ double &delay,
+ double &slew) override;
void evalDmpEqns() override;
double voCrossingUpperBound() override;
@@ -843,7 +838,8 @@ private:
};
DmpPi::DmpPi(StaState *sta) :
- DmpAlg(3, sta),
+ DmpAlg(3,
+ sta),
p1_(0.0),
p2_(0.0),
z1_(0.0),
@@ -871,8 +867,8 @@ DmpPi::init(const LibertyLibrary *drvr_library,
double c1)
{
debugPrint(debug_, "dmp_ceff", 3, "Using DMP Pi");
- DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd,
- in_slew, c2, rpi, c1);
+ DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi,
+ c1);
// Find poles/zeros.
z1_ = 1.0 / (rpi_ * c1_);
@@ -896,9 +892,9 @@ DmpPi::init(const LibertyLibrary *drvr_library,
}
void
-DmpPi::gateDelaySlew(// Return values.
- double &delay,
- double &slew)
+DmpPi::gateDelaySlew( // Return values.
+ double &delay,
+ double &slew)
{
driver_valid_ = false;
try {
@@ -907,23 +903,21 @@ DmpPi::gateDelaySlew(// Return values.
double table_delay, table_slew;
gateCapDelaySlew(ceff_, table_delay, table_slew);
delay = table_delay;
- //slew = table_slew;
+ // slew = table_slew;
try {
double vo_delay, vo_slew;
findDriverDelaySlew(vo_delay, vo_slew);
driver_valid_ = true;
// Save Vo delay to measure load wire delay waveform.
vo_delay_ = vo_delay;
- //delay = vo_delay;
+ // delay = vo_delay;
slew = vo_slew;
- }
- catch (DmpError &error) {
+ } catch (DmpError &error) {
fail(error.what());
// Fall back to table slew.
slew = table_slew;
}
- }
- catch (DmpError &error) {
+ } catch (DmpError &error) {
fail(error.what());
// Driver calculation failed - use Ceff=c1+c2.
ceff_ = c1_ + c2_;
@@ -937,8 +931,7 @@ DmpPi::findDriverParamsPi()
{
try {
findDriverParams(c2_ + c1_);
- }
- catch (DmpError &) {
+ } catch (DmpError &) {
findDriverParams(c2_);
}
}
@@ -981,36 +974,33 @@ DmpPi::evalDmpEqns()
fvec_[DmpFunc::y20] = y20 - vl_;
fjac_[DmpFunc::ipi][DmpParam::t0] = 0.0;
fjac_[DmpFunc::ipi][DmpParam::dt] =
- (-A_ * dt + B_ * dt * exp_p1_dt - (2 * B_ / p1_) * (1.0 - exp_p1_dt)
- + D_ * dt * exp_p2_dt - (2 * D_ / p2_) * (1.0 - exp_p2_dt)
- + rd_ * ceff * (dt + dt * exp_dt_rd_ceff
- - 2 * rd_ * ceff * (1.0 - exp_dt_rd_ceff)))
- / (rd_ * dt * dt * dt);
+ (-A_ * dt + B_ * dt * exp_p1_dt - (2 * B_ / p1_) * (1.0 - exp_p1_dt)
+ + D_ * dt * exp_p2_dt - (2 * D_ / p2_) * (1.0 - exp_p2_dt)
+ + rd_ * ceff
+ * (dt + dt * exp_dt_rd_ceff - 2 * rd_ * ceff * (1.0 - exp_dt_rd_ceff)))
+ / (rd_ * dt * dt * dt);
fjac_[DmpFunc::ipi][DmpParam::ceff] =
- (2 * rd_ * ceff - dt - (2 * rd_ * ceff + dt) * exp2(-dt / (rd_ * ceff)))
- / (dt * dt);
+ (2 * rd_ * ceff - dt - (2 * rd_ * ceff + dt) * exp2(-dt / (rd_ * ceff)))
+ / (dt * dt);
- dy(t_vl, t0, dt, ceff,
- fjac_[DmpFunc::y20][DmpParam::t0],
- fjac_[DmpFunc::y20][DmpParam::dt],
- fjac_[DmpFunc::y20][DmpParam::ceff]);
+ dy(t_vl, t0, dt, ceff, fjac_[DmpFunc::y20][DmpParam::t0],
+ fjac_[DmpFunc::y20][DmpParam::dt], fjac_[DmpFunc::y20][DmpParam::ceff]);
- dy(t_vth, t0, dt, ceff,
- fjac_[DmpFunc::y50][DmpParam::t0],
- fjac_[DmpFunc::y50][DmpParam::dt],
- fjac_[DmpFunc::y50][DmpParam::ceff]);
+ dy(t_vth, t0, dt, ceff, fjac_[DmpFunc::y50][DmpParam::t0],
+ fjac_[DmpFunc::y50][DmpParam::dt], fjac_[DmpFunc::y50][DmpParam::ceff]);
if (debug_->check("dmp_ceff", 4)) {
showX();
showFvec();
showJacobian();
- report_->reportLine(".................");
+ report_->report(".................");
}
}
// Eqn 13, Eqn 14.
double
-DmpPi::ipiIceff(double, double dt,
+DmpPi::ipiIceff(double,
+ double dt,
double ceff_time,
double ceff)
{
@@ -1018,11 +1008,11 @@ DmpPi::ipiIceff(double, double dt,
double exp_p2_dt = exp2(-p2_ * ceff_time);
double exp_dt_rd_ceff = exp2(-ceff_time / (rd_ * ceff));
double ipi = (A_ * ceff_time + (B_ / p1_) * (1.0 - exp_p1_dt)
- + (D_ / p2_) * (1.0 - exp_p2_dt))
- / (rd_ * ceff_time * dt);
- double iceff = (rd_ * ceff * ceff_time - (rd_ * ceff) * (rd_ * ceff)
- * (1.0 - exp_dt_rd_ceff))
- / (rd_ * ceff_time * dt);
+ + (D_ / p2_) * (1.0 - exp_p2_dt))
+ / (rd_ * ceff_time * dt);
+ double iceff =
+ (rd_ * ceff * ceff_time - (rd_ * ceff) * (rd_ * ceff) * (1.0 - exp_dt_rd_ceff))
+ / (rd_ * ceff_time * dt);
return ipi - iceff;
}
@@ -1047,14 +1037,13 @@ DmpPi::Vl0(double t,
double D1 = k0_ * (k1_ - k2_ / p3_);
double D3 = -p3_ * k0_ * k3_ / (p1_ - p3_);
double D4 = -p3_ * k0_ * k4_ / (p2_ - p3_);
- double D5 = k0_ * (k2_ / p3_ - k1_ + p3_ * k3_ / (p1_ - p3_)
- + p3_ * k4_ / (p2_ - p3_));
+ double D5 =
+ k0_ * (k2_ / p3_ - k1_ + p3_ * k3_ / (p1_ - p3_) + p3_ * k4_ / (p2_ - p3_));
double exp_p1 = exp2(-p1_ * t);
double exp_p2 = exp2(-p2_ * t);
double exp_p3 = exp2(-p3_ * t);
vl = D1 + t + D3 * exp_p1 + D4 * exp_p2 + D5 * exp_p3;
- dvl_dt = 1.0 - D3 * p1_ * exp_p1 - D4 * p2_ * exp_p2
- - D5 * p3_ * exp_p3;
+ dvl_dt = 1.0 - D3 * p1_ * exp_p1 - D4 * p2_ * exp_p2 - D5 * p3_ * exp_p3;
}
double
@@ -1076,7 +1065,8 @@ public:
};
DmpOnePole::DmpOnePole(StaState *sta) :
- DmpAlg(2, sta)
+ DmpAlg(2,
+ sta)
{
}
@@ -1100,19 +1090,15 @@ DmpOnePole::evalDmpEqns()
showFvec();
}
- dy(t_vl, t0, dt, ceff_,
- fjac_[DmpFunc::y20][DmpParam::t0],
- fjac_[DmpFunc::y20][DmpParam::dt],
- ignore2);
+ dy(t_vl, t0, dt, ceff_, fjac_[DmpFunc::y20][DmpParam::t0],
+ fjac_[DmpFunc::y20][DmpParam::dt], ignore2);
- dy(t_vth, t0, dt, ceff_,
- fjac_[DmpFunc::y50][DmpParam::t0],
- fjac_[DmpFunc::y50][DmpParam::dt],
- ignore2);
+ dy(t_vth, t0, dt, ceff_, fjac_[DmpFunc::y50][DmpParam::t0],
+ fjac_[DmpFunc::y50][DmpParam::dt], ignore2);
if (debug_->check("dmp_ceff", 4)) {
showJacobian();
- report_->reportLine(".................");
+ report_->report(".................");
}
}
@@ -1140,19 +1126,19 @@ public:
double c2,
double rpi,
double c1) override;
- void gateDelaySlew(// Return values.
- double &delay,
- double &slew) override;
+ void gateDelaySlew( // Return values.
+ double &delay,
+ double &slew) override;
private:
void V0(double t,
// Return values.
double &vo,
double &dvo_dt) override;
- void Vl0(double t,
- // Return values.
- double &vl,
- double &dvl_dt) override;
+ void Vl0(double t,
+ // Return values.
+ double &vl,
+ double &dvl_dt) override;
double voCrossingUpperBound() override;
// Pole/zero.
@@ -1189,8 +1175,8 @@ DmpZeroC2::init(const LibertyLibrary *drvr_library,
double c1)
{
debugPrint(debug_, "dmp_ceff", 3, "Using DMP C2=0");
- DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd,
- in_slew, c2, rpi, c1);
+ DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi,
+ c1);
ceff_ = c1;
z1_ = 1.0 / (rpi_ * c1_);
@@ -1203,9 +1189,9 @@ DmpZeroC2::init(const LibertyLibrary *drvr_library,
}
void
-DmpZeroC2::gateDelaySlew(// Return values.
- double &delay,
- double &slew)
+DmpZeroC2::gateDelaySlew( // Return values.
+ double &delay,
+ double &slew)
{
try {
findDriverParams(c1_);
@@ -1213,8 +1199,7 @@ DmpZeroC2::gateDelaySlew(// Return values.
findDriverDelaySlew(delay, slew);
driver_valid_ = true;
vo_delay_ = delay;
- }
- catch (DmpError &error) {
+ } catch (DmpError &error) {
fail(error.what());
// Fall back to table slew.
driver_valid_ = false;
@@ -1237,9 +1222,9 @@ DmpZeroC2::V0(double t,
void
DmpZeroC2::Vl0(double t,
- // Return values.
- double &vl,
- double &dvl_dt)
+ // Return values.
+ double &vl,
+ double &dvl_dt)
{
double D1 = k0_ * (k1_ - k2_ / p3_);
double D3 = -p3_ * k0_ * k3_ / (p1_ - p3_);
@@ -1267,7 +1252,7 @@ newtonRaphson(const int max_iter,
double x[],
const int size,
const double x_tol,
- std::function eval,
+ std::function eval,
// Temporaries supplied by caller.
double *fvec,
double **fjac,
@@ -1529,12 +1514,13 @@ DmpCeffDelayCalc::gateDelay(const Pin *drvr_pin,
}
else {
ArcDcalcResult dcalc_result =
- LumpedCapDelayCalc::gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic,
- load_pin_index_map, scene, min_max);
- if (parasitic
- && !unsuppored_model_warned_) {
+ LumpedCapDelayCalc::gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic,
+ load_pin_index_map, scene, min_max);
+ if (parasitic && !unsuppored_model_warned_) {
unsuppored_model_warned_ = true;
- report_->warn(1041, "cell %s delay model not supported on SPF parasitics by DMP delay calculator",
+ report_->warn(1041,
+ "cell {} delay model not supported on SPF parasitics by DMP "
+ "delay calculator",
drvr_cell->name());
}
return dcalc_result;
@@ -1570,16 +1556,15 @@ DmpCeffDelayCalc::setCeffAlgorithm(const LibertyLibrary *drvr_library,
}
else
dmp_alg_ = dmp_cap_;
- dmp_alg_->init(drvr_library, drvr_cell, pvt, gate_model,
- rf, rd, in_slew, c2, rpi, c1);
+ dmp_alg_->init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi,
+ c1);
debugPrint(debug_, "dmp_ceff", 3,
- " DMP in_slew = %s c2 = %s rpi = %s c1 = %s Rd = %s (%s alg)",
+ " DMP in_slew = {} c2 = {} rpi = {} c1 = {} Rd = {} ({} alg)",
units_->timeUnit()->asString(in_slew),
units_->capacitanceUnit()->asString(c2),
units_->resistanceUnit()->asString(rpi),
units_->capacitanceUnit()->asString(c1),
- units_->resistanceUnit()->asString(rd),
- dmp_alg_->name());
+ units_->resistanceUnit()->asString(rd), dmp_alg_->name());
}
std::string
@@ -1593,8 +1578,9 @@ DmpCeffDelayCalc::reportGateDelay(const Pin *drvr_pin,
const MinMax *min_max,
int digits)
{
- ArcDcalcResult dcalc_result = gateDelay(drvr_pin, arc, in_slew, load_cap,
- parasitic, load_pin_index_map, scene, min_max);
+ ArcDcalcResult dcalc_result =
+ gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic, load_pin_index_map,
+ scene, min_max);
GateTableModel *model = arc->gateTableModel(scene, min_max);
float c_eff = 0.0;
std::string result;
@@ -1653,9 +1639,9 @@ gateModelRd(const LibertyCell *cell,
}
void
-DmpCeffDelayCalc::gateDelaySlew(// Return values.
- double &delay,
- double &slew)
+DmpCeffDelayCalc::gateDelaySlew( // Return values.
+ double &delay,
+ double &slew)
{
dmp_alg_->gateDelaySlew(delay, slew);
}
@@ -1683,7 +1669,7 @@ DmpCeffDelayCalc::copyState(const StaState *sta)
DmpError::DmpError(const char *what) :
what_(what)
{
- //printf("DmpError %s\n", what);
+ // printf("DmpError %s\n", what);
}
// This saves about 2.5% in overall run time on designs with SPEF.
@@ -1712,4 +1698,4 @@ exp2(double x)
}
}
-} // namespace
+} // namespace sta
diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc
index 9d4cd733..6d859755 100644
--- a/dcalc/GraphDelayCalc.cc
+++ b/dcalc/GraphDelayCalc.cc
@@ -251,8 +251,8 @@ GraphDelayCalc::delayInvalid(const Pin *pin)
void
GraphDelayCalc::delayInvalid(Vertex *vertex)
{
- debugPrint(debug_, "delay_calc", 2, "delay invalid %s",
- vertex->to_string(this).c_str());
+ debugPrint(debug_, "delay_calc", 2, "delay invalid {}",
+ vertex->to_string(this));
if (graph_ && incremental_) {
invalid_delays_.insert(vertex);
// Invalidate driver that triggers dcalc for multi-driver nets.
@@ -340,7 +340,7 @@ GraphDelayCalc::findDelays(Level level)
if (arc_delay_calc_) {
Stats stats(debug_, report_);
int dcalc_count = 0;
- debugPrint(debug_, "delay_calc", 1, "find delays to level %d", level);
+ debugPrint(debug_, "delay_calc", 1, "find delays to level {}", level);
if (!delays_seeded_) {
iter_->clear();
seedRootSlews();
@@ -368,7 +368,7 @@ GraphDelayCalc::findDelays(Level level)
delays_exist_ = true;
incremental_ = true;
- debugPrint(debug_, "delay_calc", 1, "found %d delays", dcalc_count);
+ debugPrint(debug_, "delay_calc", 1, "found {} delays", dcalc_count);
stats.report("Delay calc");
}
}
@@ -404,8 +404,8 @@ GraphDelayCalc::seedDrvrSlew(Vertex *drvr_vertex,
ArcDelayCalc *arc_delay_calc)
{
const Pin *drvr_pin = drvr_vertex->pin();
- debugPrint(debug_, "delay_calc", 2, "seed driver slew %s",
- drvr_vertex->to_string(this).c_str());
+ debugPrint(debug_, "delay_calc", 2, "seed driver slew {}",
+ drvr_vertex->to_string(this));
for (const Scene *scene : scenes_) {
const Sdc *sdc = scene->sdc();
for (const MinMax *min_max : MinMax::range()) {
@@ -527,8 +527,8 @@ void
GraphDelayCalc::seedLoadSlew(Vertex *vertex)
{
const Pin *pin = vertex->pin();
- debugPrint(debug_, "delay_calc", 2, "seed load slew %s",
- vertex->to_string(this).c_str());
+ debugPrint(debug_, "delay_calc", 2, "seed load slew {}",
+ vertex->to_string(this));
initSlew(vertex);
for (const Scene *scene : scenes_) {
const Sdc *sdc = scene->sdc();
@@ -602,7 +602,7 @@ GraphDelayCalc::findInputDriverDelay(const LibertyCell *drvr_cell,
const Scene *scene,
const MinMax *min_max)
{
- debugPrint(debug_, "delay_calc", 2, " driver cell %s %s",
+ debugPrint(debug_, "delay_calc", 2, " driver cell {} {}",
drvr_cell->name(),
rf->shortName());
for (TimingArcSet *arc_set : drvr_cell->timingArcSets(from_port, to_port)) {
@@ -627,12 +627,12 @@ GraphDelayCalc::findInputArcDelay(const Pin *drvr_pin,
const Scene *scene,
const MinMax *min_max)
{
- debugPrint(debug_, "delay_calc", 3, " %s %s -> %s %s (%s)",
+ debugPrint(debug_, "delay_calc", 3, " {} {} -> {} {} ({})",
arc->from()->name(),
- arc->fromEdge()->to_string().c_str(),
+ arc->fromEdge()->to_string(),
arc->to()->name(),
- arc->toEdge()->to_string().c_str(),
- arc->role()->to_string().c_str());
+ arc->toEdge()->to_string(),
+ arc->role()->to_string());
const RiseFall *drvr_rf = arc->toEdge()->asRiseFall();
if (drvr_rf) {
DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max);
@@ -658,7 +658,7 @@ GraphDelayCalc::findInputArcDelay(const Pin *drvr_pin,
const ArcDelay load_delay = delayDiff(gate_delay, intrinsic_delay, this);
debugPrint(debug_, "delay_calc", 3,
- " gate delay = %s intrinsic = %s slew = %s",
+ " gate delay = {} intrinsic = {} slew = {}",
delayAsString(gate_delay, this),
delayAsString(intrinsic_delay, this),
delayAsString(gate_slew, this));
@@ -681,8 +681,8 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
bool propagate)
{
const Pin *pin = vertex->pin();
- debugPrint(debug_, "delay_calc", 2, "find delays %s (%s)",
- vertex->to_string(this).c_str(),
+ debugPrint(debug_, "delay_calc", 2, "find delays {} ({})",
+ vertex->to_string(this),
network_->cellName(network_->instance(pin)));
if (vertex->isRoot())
seedRootSlew(vertex, arc_delay_calc);
@@ -885,7 +885,7 @@ GraphDelayCalc::makeMultiDrvrNet(Vertex *drvr_vertex)
Vertex *drvr = edge->from(graph_);
const Pin *drvr_pin = drvr->pin();
if (isLeafDriver(drvr_pin, network_)) {
- debugPrint(debug_, "delay_calc", 3, " %s",
+ debugPrint(debug_, "delay_calc", 3, " {}",
network_->pathName(drvr_pin));
multi_drvr_net_map_[drvr] = multi_drvr;
drvr_vertices.push_back(drvr);
@@ -977,7 +977,7 @@ GraphDelayCalc::findLatchEdgeDelays(Edge *edge)
Vertex *drvr_vertex = edge->to(graph_);
const Pin *drvr_pin = drvr_vertex->pin();
Instance *drvr_inst = network_->instance(drvr_pin);
- debugPrint(debug_, "delay_calc", 2, "find latch D->Q %s",
+ debugPrint(debug_, "delay_calc", 2, "find latch D->Q {}",
sdc_network_->pathName(drvr_inst));
std::array delay_exists = {false, false};
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex);
@@ -1200,16 +1200,16 @@ GraphDelayCalc::annotateDelaySlew(Edge *edge,
{
DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max);
debugPrint(debug_, "delay_calc", 3,
- " %s %s -> %s %s (%s) scene:%s/%s",
+ " {} {} -> {} {} ({}) scene:{}/{}",
arc->from()->name(),
- arc->fromEdge()->to_string().c_str(),
+ arc->fromEdge()->to_string(),
arc->to()->name(),
- arc->toEdge()->to_string().c_str(),
- arc->role()->to_string().c_str(),
- scene->name().c_str(),
- min_max->to_string().c_str());
+ arc->toEdge()->to_string(),
+ arc->role()->to_string(),
+ scene->name(),
+ min_max->to_string());
debugPrint(debug_, "delay_calc", 3,
- " gate delay = %s slew = %s",
+ " gate delay = {} slew = {}",
delayAsString(gate_delay, this),
delayAsString(gate_slew, this));
bool delay_changed = false;
@@ -1259,8 +1259,8 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
const ArcDelay &wire_delay = dcalc_result.wireDelay(load_idx);
const Slew &load_slew = dcalc_result.loadSlew(load_idx);
debugPrint(debug_, "delay_calc", 3,
- " %s load delay = %s slew = %s",
- load_vertex->to_string(this).c_str(),
+ " {} load delay = {} slew = {}",
+ load_vertex->to_string(this),
delayAsString(wire_delay, this),
delayAsString(load_slew, this));
bool load_changed = false;
@@ -1580,7 +1580,7 @@ GraphDelayCalc::findCheckEdgeDelays(Edge *edge,
TimingArcSet *arc_set = edge->timingArcSet();
const Pin *to_pin = to_vertex->pin();
Instance *inst = network_->instance(to_pin);
- debugPrint(debug_, "delay_calc", 2, "find check %s %s -> %s",
+ debugPrint(debug_, "delay_calc", 2, "find check {} {} -> {}",
sdc_network_->pathName(inst),
network_->portName(from_vertex->pin()),
network_->portName(to_pin));
@@ -1602,16 +1602,16 @@ GraphDelayCalc::findCheckEdgeDelays(Edge *edge,
scene, min_max);
const Slew to_slew = graph_->slew(to_vertex, to_rf, ap_index);
debugPrint(debug_, "delay_calc", 3,
- " %s %s -> %s %s (%s) scene:%s/%s",
+ " {} {} -> {} {} ({}) scene:{}/{}",
arc_set->from()->name(),
- arc->fromEdge()->to_string().c_str(),
+ arc->fromEdge()->to_string(),
arc_set->to()->name(),
- arc->toEdge()->to_string().c_str(),
- arc_set->role()->to_string().c_str(),
- scene->name().c_str(),
- min_max->to_string().c_str());
+ arc->toEdge()->to_string(),
+ arc_set->role()->to_string(),
+ scene->name(),
+ min_max->to_string());
debugPrint(debug_, "delay_calc", 3,
- " from_slew = %s to_slew = %s",
+ " from_slew = {} to_slew = {}",
delayAsString(from_slew, this),
delayAsString(to_slew, this));
float related_out_cap = 0.0;
@@ -1622,7 +1622,7 @@ GraphDelayCalc::findCheckEdgeDelays(Edge *edge,
to_slew, related_out_cap,
scene, min_max);
debugPrint(debug_, "delay_calc", 3,
- " check_delay = %s",
+ " check_delay = {}",
delayAsString(check_delay, this));
graph_->setArcDelay(edge, arc, ap_index, check_delay);
delay_changed = true;
diff --git a/dcalc/LumpedCapDelayCalc.cc b/dcalc/LumpedCapDelayCalc.cc
index 07a68e5b..692c01f0 100644
--- a/dcalc/LumpedCapDelayCalc.cc
+++ b/dcalc/LumpedCapDelayCalc.cc
@@ -133,7 +133,7 @@ LumpedCapDelayCalc::gateDelay(const Pin *drvr_pin,
{
GateTimingModel *model = arc->gateModel(scene, min_max);
debugPrint(debug_, "delay_calc", 3,
- " in_slew = %s load_cap = %s lumped",
+ " in_slew = {} load_cap = {} lumped",
delayAsString(in_slew, this),
units()->capacitanceUnit()->asString(load_cap));
const RiseFall *rf = arc->toEdge()->asRiseFall();
diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc
index 90e31ed3..fc1b0208 100644
--- a/dcalc/PrimaDelayCalc.cc
+++ b/dcalc/PrimaDelayCalc.cc
@@ -1,30 +1,30 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
-//
+//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-//
+//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
-//
+//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
-//
+//
// This notice may not be removed or altered from any source distribution.
#include "PrimaDelayCalc.hh"
-#include // abs
+#include // abs
#include "Debug.hh"
#include "Units.hh"
@@ -38,15 +38,16 @@
#include "Parasitics.hh"
#include "GraphDelayCalc.hh"
#include "DmpDelayCalc.hh"
+#include "Format.hh"
#include
#include
namespace sta {
-using Eigen::SparseLU;
-using Eigen::HouseholderQR;
using Eigen::ColPivHouseholderQR;
+using Eigen::HouseholderQR;
+using Eigen::SparseLU;
// Lawrence Pillage - “Electronic Circuit & System Simulation Methods” 1998
// McGraw-Hill, Inc. New York, NY.
@@ -90,10 +91,7 @@ PrimaDelayCalc::PrimaDelayCalc(const PrimaDelayCalc &dcalc) :
{
}
-PrimaDelayCalc::~PrimaDelayCalc()
-{
- delete table_dcalc_;
-}
+PrimaDelayCalc::~PrimaDelayCalc() { delete table_dcalc_; }
ArcDelayCalc *
PrimaDelayCalc::copy()
@@ -130,8 +128,8 @@ PrimaDelayCalc::findParasitic(const Pin *drvr_pin,
bool has_wire_cap;
graph_delay_calc_->netCaps(drvr_pin, rf, scene, min_max, pin_cap, wire_cap,
fanout, has_wire_cap);
- parasitic = parasitics->makeWireloadNetwork(drvr_pin, wireload,
- fanout, scene, min_max);
+ parasitic =
+ parasitics->makeWireloadNetwork(drvr_pin, wireload, fanout, scene, min_max);
}
return parasitic;
}
@@ -160,8 +158,8 @@ PrimaDelayCalc::inputPortDelay(const Pin *drvr_pin,
LibertyLibrary *drvr_library = network_->defaultLibertyLibrary();
const Parasitic *pi_elmore = nullptr;
if (parasitic && parasitics->isParasiticNetwork(parasitic))
- pi_elmore = parasitics->reduceToPiElmore(parasitic, drvr_pin, rf,
- scene, min_max);
+ pi_elmore =
+ parasitics->reduceToPiElmore(parasitic, drvr_pin, rf, scene, min_max);
for (auto load_pin_index : load_pin_index_map) {
const Pin *load_pin = load_pin_index.first;
@@ -190,12 +188,13 @@ PrimaDelayCalc::gateDelay(const Pin *drvr_pin,
const Parasitic *parasitic,
const LoadPinIndexMap &load_pin_index_map,
const Scene *scene,
- const MinMax *min_max)
+ const MinMax *min_max)
{
ArcDcalcArgSeq dcalc_args;
- dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew, load_cap, parasitic);
- ArcDcalcResultSeq dcalc_results = gateDelays(dcalc_args, load_pin_index_map,
- scene, min_max);
+ dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew, load_cap,
+ parasitic);
+ ArcDcalcResultSeq dcalc_results =
+ gateDelays(dcalc_args, load_pin_index_map, scene, min_max);
return dcalc_results[0];
}
@@ -229,15 +228,15 @@ PrimaDelayCalc::gateDelays(ArcDcalcArgSeq &dcalc_args,
&& output_waveforms->slewAxis()->inBounds(in_slew)
&& output_waveforms->capAxis()->inBounds(dcalc_arg.loadCap())) {
output_waveforms_[drvr_idx] = output_waveforms;
- debugPrint(debug_, "ccs_dcalc", 1, "%s %s",
- dcalc_arg.drvrCell()->name(),
+ 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 %s", drvr_library->name());
+ 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_;
@@ -268,13 +267,13 @@ PrimaDelayCalc::tableDcalcResults()
const Pin *drvr_pin = dcalc_arg.drvrPin();
if (drvr_pin) {
const RiseFall *rf = dcalc_arg.drvrEdge();
- const Parasitic *parasitic = table_dcalc_->findParasitic(drvr_pin, rf,
- scene_, min_max_);
+ const Parasitic *parasitic =
+ table_dcalc_->findParasitic(drvr_pin, rf, scene_, min_max_);
dcalc_arg.setParasitic(parasitic);
}
}
- return table_dcalc_->gateDelays(*dcalc_args_, *load_pin_index_map_,
- scene_, min_max_);
+ return table_dcalc_->gateDelays(*dcalc_args_, *load_pin_index_map_, scene_,
+ min_max_);
}
void
@@ -284,8 +283,7 @@ PrimaDelayCalc::simulate()
stampEqns();
setXinit();
- if (prima_order_ > 0
- && node_count_ > prima_order_) {
+ if (prima_order_ > 0 && node_count_ > prima_order_) {
primaReduce();
simulate1(Gq_, Cq_, Bq_, xq_init_, Vq_, prima_order_);
}
@@ -297,11 +295,11 @@ PrimaDelayCalc::simulate()
void
PrimaDelayCalc::simulate1(const MatrixSd &G,
- const MatrixSd &C,
- const Eigen::MatrixXd &B,
- const Eigen::VectorXd &x_init,
- const Eigen::MatrixXd &x_to_v,
- const size_t order)
+ const MatrixSd &C,
+ const Eigen::MatrixXd &B,
+ const Eigen::VectorXd &x_init,
+ const Eigen::MatrixXd &x_to_v,
+ const size_t order)
{
Eigen::VectorXd x(order);
Eigen::VectorXd x_prev(order);
@@ -315,7 +313,8 @@ PrimaDelayCalc::simulate1(const MatrixSd &G,
v_ = v_prev_ = x_to_v * x_init;
time_step_ = time_step_prev_ = timeStep();
- debugPrint(debug_, "ccs_dcalc", 1, "time step %s", delayAsString(time_step_, this));
+ debugPrint(debug_, "ccs_dcalc", 1, "time step {}",
+ delayAsString(time_step_, this));
MatrixSd A(order, order);
A = G + (2.0 / time_step_) * C;
@@ -336,8 +335,8 @@ PrimaDelayCalc::simulate1(const MatrixSd &G,
v_ = v_prev_ = x_to_v * x_init;
// voltageTime is always for a rising waveform so 0.0v is initial voltage.
- double time_begin = output_waveforms_[0]->voltageTime((*dcalc_args_)[0].inSlewFlt(),
- ceff_[0], 0.0);
+ double time_begin = output_waveforms_[0]->voltageTime(
+ (*dcalc_args_)[0].inSlewFlt(), ceff_[0], 0.0);
// Limit in case load voltage waveforms don't get to final value.
double time_end = time_begin + maxTime();
@@ -349,9 +348,9 @@ PrimaDelayCalc::simulate1(const MatrixSd &G,
rhs = B * u_ + (1.0 / time_step_) * C * (3.0 * x_prev - x_prev2);
x = A_solver.solve(rhs);
v_ = x_to_v * x;
-
+
const ArcDcalcArg &dcalc_arg = (*dcalc_args_)[0];
- debugPrint(debug_, "ccs_dcalc", 3, "%s ceff %s VDrvr %.4f Idrvr %s",
+ debugPrint(debug_, "ccs_dcalc", 3, "{} ceff {} VDrvr {:.4f} Idrvr {}",
delayAsString(time, this),
units_->capacitanceUnit()->asString(ceff_[0]),
voltage(dcalc_arg.drvrPin()),
@@ -384,7 +383,7 @@ double
PrimaDelayCalc::maxTime()
{
return (*dcalc_args_)[0].inSlewFlt()
- + (driverResistance() + resistance_sum_) * load_cap_ * 4;
+ + (driverResistance() + resistance_sum_) * load_cap_ * 4;
}
float
@@ -429,9 +428,8 @@ PrimaDelayCalc::findNodeCount()
const Pin *pin = parasitics_->pin(node);
if (pin) {
pin_node_map_[pin] = node_idx;
- debugPrint(debug_, "ccs_dcalc", 1, "pin %s node %lu",
- network_->pathName(pin),
- node_idx);
+ debugPrint(debug_, "ccs_dcalc", 1, "pin {} node {}",
+ network_->pathName(pin), node_idx);
}
double cap = parasitics_->nodeGndCap(node) + pinCapacitance(node);
node_capacitances_.push_back(cap);
@@ -441,14 +439,12 @@ PrimaDelayCalc::findNodeCount()
for (ParasiticCapacitor *capacitor : parasitics_->capacitors(parasitic_network_)) {
float cap = parasitics_->value(capacitor) * coupling_cap_multiplier_;
ParasiticNode *node1 = parasitics_->node1(capacitor);
- if (node1
- && !parasitics_->isExternal(node1)) {
+ if (node1 && !parasitics_->isExternal(node1)) {
size_t node_idx = node_index_map_[node1];
node_capacitances_[node_idx] += cap;
}
ParasiticNode *node2 = parasitics_->node2(capacitor);
- if (node2
- && !parasitics_->isExternal(node2)) {
+ if (node2 && !parasitics_->isExternal(node2)) {
size_t node_idx = node_index_map_[node2];
node_capacitances_[node_idx] += cap;
}
@@ -496,9 +492,8 @@ PrimaDelayCalc::initCeffIdrvr()
const ArcDcalcArg &dcalc_arg = (*dcalc_args_)[drvr_idx];
ceff_[drvr_idx] = load_cap_;
// voltageTime is always for a rising waveform so 0.0v is initial voltage.
- drvr_current_[drvr_idx] =
- output_waveforms_[drvr_idx]->voltageCurrent(dcalc_arg.inSlewFlt(),
- ceff_[drvr_idx], 0.0);
+ drvr_current_[drvr_idx] = output_waveforms_[drvr_idx]->voltageCurrent(
+ dcalc_arg.inSlewFlt(), ceff_[drvr_idx], 0.0);
}
}
@@ -617,8 +612,7 @@ PrimaDelayCalc::updateCeffIdrvr()
double v2 = voltagePrev(node_idx);
double dv = v1 - v2;
if (drvr_rf_ == RiseFall::rise()) {
- if (drvr_current != 0.0
- && dv > 0.0) {
+ if (drvr_current != 0.0 && dv > 0.0) {
double ceff = drvr_current * time_step_ / dv;
if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff))
ceff_[drvr_idx] = ceff;
@@ -627,13 +621,11 @@ PrimaDelayCalc::updateCeffIdrvr()
// Whoa partner. Head'n for the weeds.
drvr_current_[drvr_idx] = 0.0;
else
- drvr_current_[drvr_idx] =
- output_waveforms_[drvr_idx]->voltageCurrent(dcalc_arg.inSlewFlt(),
- ceff_[drvr_idx], v1);
+ drvr_current_[drvr_idx] = output_waveforms_[drvr_idx]->voltageCurrent(
+ dcalc_arg.inSlewFlt(), ceff_[drvr_idx], v1);
}
else {
- if (drvr_current != 0.0
- && dv < 0.0) {
+ if (drvr_current != 0.0 && dv < 0.0) {
double ceff = drvr_current * time_step_ / dv;
if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff))
ceff_[drvr_idx] = ceff;
@@ -643,10 +635,8 @@ PrimaDelayCalc::updateCeffIdrvr()
drvr_current_[drvr_idx] = 0.0;
}
else
- drvr_current_[drvr_idx] =
- output_waveforms_[drvr_idx]->voltageCurrent(dcalc_arg.inSlewFlt(),
- ceff_[drvr_idx],
- vdd_ - v1);
+ drvr_current_[drvr_idx] = output_waveforms_[drvr_idx]->voltageCurrent(
+ dcalc_arg.inSlewFlt(), ceff_[drvr_idx], vdd_ - v1);
}
}
}
@@ -657,10 +647,8 @@ PrimaDelayCalc::loadWaveformsFinished()
for (auto pin_node : pin_node_map_) {
size_t node_idx = pin_node.second;
double v = voltage(node_idx);
- if ((drvr_rf_ == RiseFall::rise()
- && v < vh_ + (vdd_ - vh_) * .5)
- || (drvr_rf_ == RiseFall::fall()
- && (v > vl_ * .5))) {
+ if ((drvr_rf_ == RiseFall::rise() && v < vh_ + (vdd_ - vh_) * .5)
+ || (drvr_rf_ == RiseFall::fall() && (v > vl_ * .5))) {
return false;
}
}
@@ -678,12 +666,10 @@ PrimaDelayCalc::measureThresholds(double time)
double v_prev = voltagePrev(node_idx);
for (size_t m = 0; m < measure_threshold_count_; m++) {
double th = measure_thresholds_[m];
- if ((v_prev < th && th <= v)
- || (v_prev > th && th >= v)) {
- double t_cross = time - time_step_ + (th - v_prev) * time_step_ / (v - v_prev);
- debugPrint(debug_, "ccs_measure", 1, "node %lu cross %.2f %s",
- node_idx,
- th,
+ if ((v_prev < th && th <= v) || (v_prev > th && th >= v)) {
+ double t_cross =
+ time - time_step_ + (th - v_prev) * time_step_ / (v - v_prev);
+ debugPrint(debug_, "ccs_measure", 1, "node {} cross {:.2f} {}", node_idx, th,
delayAsString(t_cross, this));
threshold_times_[node_idx][m] = t_cross;
}
@@ -726,10 +712,8 @@ PrimaDelayCalc::dcalcResults()
double drvr_slew = std::abs(drvr_times[threshold_vh] - drvr_times[threshold_vl]);
dcalc_result.setGateDelay(gate_delay);
dcalc_result.setDrvrSlew(drvr_slew);
- debugPrint(debug_, "ccs_dcalc", 2,
- "%s gate delay %s slew %s",
- network_->pathName(drvr_pin),
- delayAsString(gate_delay, this),
+ debugPrint(debug_, "ccs_dcalc", 2, "{} gate delay {} slew {}",
+ network_->pathName(drvr_pin), delayAsString(gate_delay, this),
delayAsString(drvr_slew, this));
dcalc_result.setLoadCount(load_pin_index_map_->size());
@@ -741,8 +725,7 @@ PrimaDelayCalc::dcalcResults()
ThresholdTimes &drvr_times = threshold_times_[drvr_node];
double wire_delay = wire_times[threshold_vth] - drvr_times[threshold_vth];
double load_slew = std::abs(wire_times[threshold_vh] - wire_times[threshold_vl]);
- debugPrint(debug_, "ccs_dcalc", 2,
- "load %s %s delay %s slew %s",
+ debugPrint(debug_, "ccs_dcalc", 2, "load {} {} delay {} slew {}",
network_->pathName(load_pin),
drvr_rf_->shortName(),
delayAsString(wire_delay, this),
@@ -849,16 +832,18 @@ PrimaDelayCalc::primaReduce2()
// Modified Gram-Schmidt orthonormalization
for (size_t j = 0; j < k; j++) {
- Eigen::MatrixXd H = Vq.block(0, j * port_count_, order_, port_count_).transpose()
- * Vq.block(0, k * port_count_, order_, port_count_);
+ Eigen::MatrixXd H =
+ Vq.block(0, j * port_count_, order_, port_count_).transpose()
+ * Vq.block(0, k * port_count_, order_, port_count_);
Vq.block(0, k * port_count_, order_, port_count_) =
- Vq.block(0, k * port_count_, order_, port_count_) - Vq.block(0, j * port_count_, order_, port_count_) * H;
+ Vq.block(0, k * port_count_, order_, port_count_)
+ - Vq.block(0, j * port_count_, order_, port_count_) * H;
}
Eigen::MatrixXd Vq_k = Vq.block(0, k * port_count_, order_, port_count_);
Eigen::HouseholderQR Vq_k_solver(Vq_k);
Eigen::MatrixXd VqQ = Vq_k_solver.householderQ();
- Vq.block(0, k * port_count_, order_, port_count_) =
- VqQ.block(0, 0, order_, port_count_);
+ Vq.block(0, k * port_count_, order_, port_count_) =
+ VqQ.block(0, 0, order_, port_count_);
}
Vq_.resize(order_, prima_order_);
Vq_ = Vq.block(0, 0, order_, prima_order_);
@@ -957,8 +942,8 @@ Waveform
PrimaDelayCalc::watchWaveform(const Pin *pin)
{
FloatSeq &voltages = watch_pin_values_[pin];
- TableAxisPtr time_axis = std::make_shared(TableAxisVariable::time,
- FloatSeq(times_));
+ TableAxisPtr time_axis =
+ std::make_shared(TableAxisVariable::time, FloatSeq(times_));
Table waveform(new FloatSeq(voltages), time_axis);
return waveform;
}
@@ -969,7 +954,7 @@ void
PrimaDelayCalc::reportMatrix(const char *name,
MatrixSd &matrix)
{
- report_->reportLine("%s", name);
+ report_->report("{}", name);
reportMatrix(matrix);
}
@@ -977,7 +962,7 @@ void
PrimaDelayCalc::reportMatrix(const char *name,
Eigen::MatrixXd &matrix)
{
- report_->reportLine("%s", name);
+ report_->report("{}", name);
reportMatrix(matrix);
}
@@ -985,7 +970,7 @@ void
PrimaDelayCalc::reportMatrix(const char *name,
Eigen::VectorXd &matrix)
{
- report_->reportLine("%s", name);
+ report_->report("{}", name);
reportMatrix(matrix);
}
@@ -993,22 +978,19 @@ void
PrimaDelayCalc::reportVector(const char *name,
std::vector &matrix)
{
- report_->reportLine("%s", name);
+ report_->report("{}", name);
reportVector(matrix);
}
-
+
void
PrimaDelayCalc::reportMatrix(MatrixSd &matrix)
{
for (Eigen::Index i = 0; i < matrix.rows(); i++) {
std::string line = "| ";
- for (Eigen::Index j = 0; j < matrix.cols(); j++) {
- std::string entry = stdstrPrint("%10.3e", matrix.coeff(i, j));
- line += entry;
- line += " ";
- }
+ for (Eigen::Index j = 0; j < matrix.cols(); j++)
+ line += sta::format("{:10.3e}", matrix.coeff(i, j)) + " ";
line += "|";
- report_->reportLineString(line);
+ report_->reportLine(line);
}
}
@@ -1017,13 +999,10 @@ PrimaDelayCalc::reportMatrix(Eigen::MatrixXd &matrix)
{
for (Eigen::Index i = 0; i < matrix.rows(); i++) {
std::string line = "| ";
- for (Eigen::Index j = 0; j < matrix.cols(); j++) {
- std::string entry = stdstrPrint("%10.3e", matrix.coeff(i, j));
- line += entry;
- line += " ";
- }
+ for (Eigen::Index j = 0; j < matrix.cols(); j++)
+ line += sta::format("{:10.3e}", matrix.coeff(i, j)) + " ";
line += "|";
- report_->reportLineString(line);
+ report_->reportLine(line);
}
}
@@ -1032,25 +1011,21 @@ PrimaDelayCalc::reportMatrix(Eigen::VectorXd &matrix)
{
std::string line = "| ";
for (Eigen::Index i = 0; i < matrix.rows(); i++) {
- std::string entry = stdstrPrint("%10.3e", matrix.coeff(i));
- line += entry;
- line += " ";
+ std::string entry =
+ line += sta::format("{:10.3e}", matrix.coeff(i)) + " ";
}
line += "|";
- report_->reportLineString(line);
+ report_->reportLine(line);
}
void
PrimaDelayCalc::reportVector(std::vector &matrix)
{
std::string line = "| ";
- for (size_t i = 0; i < matrix.size(); i++) {
- std::string entry = stdstrPrint("%10.3e", matrix[i]);
- line += entry;
- line += " ";
- }
+ for (size_t i = 0; i < matrix.size(); i++)
+ line += sta::format("{:10.3e}", matrix[i]) + " ";
line += "|";
- report_->reportLineString(line);
+ report_->reportLine(line);
}
-} // namespace
+} // namespace sta
diff --git a/doc/ApiChanges.txt b/doc/ApiChanges.txt
index 0ac6caa8..83759119 100644
--- a/doc/ApiChanges.txt
+++ b/doc/ApiChanges.txt
@@ -24,6 +24,19 @@
This file summarizes STA API changes for each release.
+2026/03/12
+----------
+
+The Report class used for reporting and error messages now uses std::format
+instead of printf.
+
+sta::format is a wrapper for std::format that will compile on gcc8, which
+centos7 uses and does not support std::format.
+
+stdstrPrint, strintPrint, stringAppend have been removed. Use sta::format.
+
+reportLineString is now reportLine
+
Release 3.0.0 2025/01/03
------------------------
diff --git a/doc/ChangeLog.txt b/doc/ChangeLog.txt
index 1f1871b9..bebf05b6 100644
--- a/doc/ChangeLog.txt
+++ b/doc/ChangeLog.txt
@@ -2,6 +2,7 @@ OpenSTA Timing Analyzer Release Notes
-------------------------------------
This file summarizes user visible changes for each release.
+See ApiChangeLog.txt for changes to the STA api.
Release 3.0.1 2026/03/12
------------------------
diff --git a/etc/FindMessages.tcl b/etc/FindMessages.tcl
index c5fad936..40f00d29 100755
--- a/etc/FindMessages.tcl
+++ b/etc/FindMessages.tcl
@@ -61,7 +61,7 @@ foreach subdir $subdirs {
set files [glob -nocomplain [file join $subdir "*.{cc,hh,yy,ll,i}"]]
set files_c [concat $files_c $files]
}
-set warn_regexp_c {(?:(?:->critical|->warn|->fileWarn|->error|->fileError|criticalError|libWarn|libError)\(|tclArgError\(interp,\s*)([0-9]+),.*(".+")}
+set warn_regexp_c {(?:(?:->critical|->warn|->fileWarn|->error|->fileError|criticalError|warn|error)\(|tclArgError\(interp,\s*)([0-9]+),.*(".+")}
set files_tcl {}
foreach subdir $subdirs {
diff --git a/graph/Graph.cc b/graph/Graph.cc
index 9878c6ac..022504ca 100644
--- a/graph/Graph.cc
+++ b/graph/Graph.cc
@@ -283,7 +283,7 @@ Graph::makeWireEdgesFromPin(const Pin *drvr_pin,
if (isIsolatedNet(drvrs, loads)) {
for (auto drvr_pin : drvrs) {
visited_drvrs.insert(drvr_pin);
- debugPrint(debug_, "graph", 1, "ignoring isolated driver %s",
+ debugPrint(debug_, "graph", 1, "ignoring isolated driver {}",
network_->pathName(drvr_pin));
}
return;
diff --git a/graph/Graph.i b/graph/Graph.i
index cd8188c9..85cb5124 100644
--- a/graph/Graph.i
+++ b/graph/Graph.i
@@ -292,7 +292,7 @@ mode_value()
return self->timingArcSet()->modeValue().c_str();
}
-const char *
+std::string
latch_d_to_q_en()
{
if (self->role() == TimingRole::latchDtoQ()) {
@@ -308,9 +308,7 @@ latch_d_to_q_en()
const RiseFall *enable_rf;
lib_cell->latchEnable(d_q_set, enable_port, enable_func, enable_rf);
if (enable_port)
- return stringPrintTmp("%s %s",
- enable_port->name(),
- enable_rf->shortName());
+ return sta::format("{} {}", enable_port->name(), enable_rf->shortName());
}
return "";
}
diff --git a/include/sta/Clock.hh b/include/sta/Clock.hh
index 2b9efc5e..06215222 100644
--- a/include/sta/Clock.hh
+++ b/include/sta/Clock.hh
@@ -25,6 +25,7 @@
#pragma once
#include