From 134b547501820da4d14e99a5d42f2e6f378d907e Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 15 Mar 2026 14:35:24 -0700 Subject: [PATCH] use std::format squash --- CMakeLists.txt | 12 + app/StaMain.cc | 9 +- dcalc/ArcDcalcWaveforms.cc | 2 +- dcalc/ArcDelayCalc.cc | 12 +- dcalc/ArnoldiDelayCalc.cc | 16 +- dcalc/ArnoldiReduce.cc | 376 +++--- dcalc/CcsCeffDelayCalc.cc | 244 ++-- dcalc/Delay.cc | 8 +- dcalc/DelayCalc.tcl | 32 +- dcalc/DelayCalcBase.cc | 1 + dcalc/DelayNormal.cc | 9 +- dcalc/DelayScalar.cc | 2 +- dcalc/DelaySkewNormal.cc | 13 +- dcalc/DmpCeff.cc | 300 ++--- dcalc/GraphDelayCalc.cc | 72 +- dcalc/LumpedCapDelayCalc.cc | 2 +- dcalc/PrimaDelayCalc.cc | 201 ++- doc/ApiChanges.txt | 13 + doc/ChangeLog.txt | 1 + etc/FindMessages.tcl | 2 +- graph/Graph.cc | 2 +- graph/Graph.i | 6 +- include/sta/Clock.hh | 5 +- include/sta/ClockGroups.hh | 8 +- include/sta/Debug.hh | 22 +- include/sta/Delay.hh | 10 +- include/sta/DelayNormal.hh | 2 +- include/sta/DelayScalar.hh | 2 +- include/sta/DelaySkewNormal.hh | 2 +- include/sta/Error.hh | 21 +- include/sta/ExceptionPath.hh | 29 +- include/sta/Format.hh | 153 +++ include/sta/ParseBus.hh | 21 +- include/sta/PathGroup.hh | 6 +- include/sta/Report.hh | 154 ++- include/sta/ReportTcl.hh | 20 +- include/sta/Sdc.hh | 22 +- include/sta/SdcNetwork.hh | 2 +- include/sta/Sta.hh | 14 +- include/sta/StringUtil.hh | 34 - include/sta/Units.hh | 5 +- include/sta/VerilogNamespace.hh | 16 +- include/sta/VerilogReader.hh | 69 +- liberty/LibExprReader.cc | 19 +- liberty/Liberty.cc | 31 +- liberty/Liberty.i | 7 +- liberty/LibertyBuilder.cc | 8 +- liberty/LibertyParse.yy | 12 +- liberty/LibertyParser.cc | 69 +- liberty/LibertyReader.cc | 442 +++---- liberty/LibertyReaderPvt.hh | 79 +- liberty/LibertyWriter.cc | 356 +++-- liberty/TableModel.cc | 397 +++--- liberty/Units.cc | 15 +- network/ConcreteLibrary.cc | 23 +- network/ConcreteNetwork.cc | 2 +- network/HpinDrvrLoad.cc | 15 +- network/Network.cc | 51 +- network/Network.i | 6 +- network/ParseBus.cc | 103 +- network/SdcNetwork.cc | 92 +- network/VerilogNamespace.cc | 65 +- parasitics/ConcreteParasitics.cc | 6 +- parasitics/Parasitics.cc | 128 +- parasitics/ReduceParasitics.cc | 22 +- parasitics/ReportParasiticAnnotation.cc | 42 +- parasitics/SpefParse.yy | 9 +- parasitics/SpefReader.cc | 111 +- parasitics/SpefReaderPvt.hh | 14 +- power/Power.cc | 615 ++++----- power/ReportPower.cc | 124 +- power/SaifParse.yy | 2 +- power/SaifReader.cc | 42 +- power/VcdParse.cc | 84 +- power/VcdReader.cc | 97 +- sdc/Clock.cc | 4 +- sdc/ClockGroups.cc | 5 +- sdc/CycleAccting.cc | 24 +- sdc/ExceptionPath.cc | 105 +- sdc/Sdc.cc | 156 +-- sdc/Sdc.i | 26 +- sdc/Sdc.tcl | 6 +- sdc/WriteSdc.cc | 596 ++++----- sdf/ReportAnnotation.cc | 134 +- sdf/SdfParse.yy | 3 +- sdf/SdfReader.cc | 203 ++- sdf/SdfReaderPvt.hh | 24 +- sdf/SdfWriter.cc | 178 ++- search/Bfs.cc | 147 +-- search/CheckMinPulseWidths.cc | 16 +- search/CheckTiming.cc | 99 +- search/CheckTiming.hh | 5 +- search/ClkLatency.cc | 84 +- search/ClkSkew.cc | 123 +- search/Crpr.cc | 8 +- search/Genclks.cc | 201 ++- search/Latches.cc | 10 +- search/Levelize.cc | 147 +-- search/MakeTimingModel.cc | 184 ++- search/Path.cc | 95 +- search/PathEnum.cc | 216 ++- search/PathGroup.cc | 18 +- search/Property.cc | 49 +- search/ReportPath.cc | 365 +++--- search/ReportPath.hh | 10 +- search/Search.cc | 853 +++++------- search/Search.i | 6 +- search/Sim.cc | 169 +-- search/Sta.cc | 1592 +++++++++++------------ search/Tag.cc | 4 +- search/TagGroup.cc | 60 +- search/VisitPathEnds.cc | 4 +- search/WorstSlack.cc | 76 +- spice/WritePathSpice.cc | 113 +- spice/WriteSpice.cc | 528 ++++---- spice/WriteSpice.hh | 8 +- tcl/StaTclTypes.i | 67 +- tcl/TclTypeHelpers.cc | 4 +- util/Debug.cc | 15 - util/Error.cc | 19 +- util/MachineLinux.cc | 4 +- util/Report.cc | 226 +--- util/ReportTcl.cc | 6 +- util/Stats.cc | 23 +- util/StringUtil.cc | 140 +- util/Util.i | 28 +- verilog/VerilogParse.yy | 3 +- verilog/VerilogReader.cc | 571 ++++---- verilog/VerilogWriter.cc | 88 +- 129 files changed, 5898 insertions(+), 6990 deletions(-) create mode 100644 include/sta/Format.hh 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 +#include #include "MinMax.hh" #include "RiseFallMinMax.hh" @@ -207,7 +208,7 @@ public: ~ClockEdge(); const RiseFall *transition() const { return rf_; } float time() const { return time_; } - const char *name() const { return name_; } + const std::string &name() const { return name_; } int index() const { return index_; } ClockEdge *opposite() const; // Pulse width if this is the leading edge of the pulse. @@ -221,7 +222,7 @@ private: Clock *clock_; const RiseFall *rf_; - const char *name_; + std::string name_; float time_; int index_; }; diff --git a/include/sta/ClockGroups.hh b/include/sta/ClockGroups.hh index e09cfb91..89159a82 100644 --- a/include/sta/ClockGroups.hh +++ b/include/sta/ClockGroups.hh @@ -24,6 +24,8 @@ #pragma once +#include + #include "SdcCmdComment.hh" #include "SdcClass.hh" @@ -32,7 +34,7 @@ namespace sta { class ClockGroups : public SdcCmdComment { public: - ClockGroups(const char *name, + ClockGroups(const std::string &name, bool logically_exclusive, bool physically_exclusive, bool asynchronous, @@ -40,7 +42,7 @@ public: const char *comment); ~ClockGroups(); void makeClockGroup(ClockSet *clks); - const char *name() const { return name_; } + const std::string &name() const { return name_; } ClockGroupSet *groups() { return &groups_; } bool logicallyExclusive() const { return logically_exclusive_; } bool physicallyExclusive() const { return physically_exclusive_; } @@ -49,7 +51,7 @@ public: void removeClock(Clock *clk); private: - const char *name_; + std::string name_; bool logically_exclusive_; bool physically_exclusive_; bool asynchronous_; diff --git a/include/sta/Debug.hh b/include/sta/Debug.hh index 1c21131e..1ff45934 100644 --- a/include/sta/Debug.hh +++ b/include/sta/Debug.hh @@ -25,10 +25,12 @@ #pragma once #include -#include +#include #include #include +#include "Format.hh" +#include "Report.hh" #include "StringUtil.hh" namespace sta { @@ -48,10 +50,16 @@ public: bool check(const char *what, int level) const; int statsLevel() const { return stats_level_; } - void reportLine(const char *what, - const char *fmt, - ...) - __attribute__((format (printf, 3, 4))); + template + void report(const char *what, + std::string_view fmt, + Args &&...args) + { + std::string msg = sta::format("{}: {}", what, + sta::formatRuntime(fmt, std::forward(args)...)); + std::unique_lock lock(buffer_lock_); + report_->reportLine(msg); + } protected: Report *report_; @@ -63,9 +71,9 @@ protected: // Inlining a varargs function would eval the args, which can // be expensive, so use a macro. -#define debugPrint(debug, what, level, ...) \ +#define debugPrint(debug, what, level, fmt, ...) \ if (debug->check(what, level)) { \ - debug->reportLine(what __VA_OPT__(,) __VA_ARGS__); \ + debug->report(what, fmt __VA_OPT__(,) __VA_ARGS__); \ } } // namespace diff --git a/include/sta/Delay.hh b/include/sta/Delay.hh index 24b97c60..dae429af 100644 --- a/include/sta/Delay.hh +++ b/include/sta/Delay.hh @@ -155,7 +155,7 @@ public: float delay2) const = 0; virtual Delay div(float delay1, const Delay &delay2) const = 0; - virtual const char *asStringVariance(const Delay &delay, + virtual std::string asStringVariance(const Delay &delay, int digits, const StaState *sta) const = 0; @@ -203,19 +203,19 @@ void delaySetMean(Delay &delay, float mean); -const char * +std::string delayAsString(const Delay &delay, const StaState *sta); -const char * +std::string delayAsString(const Delay &delay, const EarlyLate *early_late, const StaState *sta); -const char * +std::string delayAsString(const Delay &delay, const EarlyLate *early_late, int digits, const StaState *sta); -const char * +std::string delayAsString(const Delay &delay, const EarlyLate *early_late, bool report_variance, diff --git a/include/sta/DelayNormal.hh b/include/sta/DelayNormal.hh index 0d102962..3a25cbf7 100644 --- a/include/sta/DelayNormal.hh +++ b/include/sta/DelayNormal.hh @@ -82,7 +82,7 @@ public: float delay2) const override; Delay div(float delay1, const Delay &delay2) const override; - const char *asStringVariance(const Delay &delay, + std::string asStringVariance(const Delay &delay, int digits, const StaState *sta) const override; }; diff --git a/include/sta/DelayScalar.hh b/include/sta/DelayScalar.hh index c7bd07a9..a413c92d 100644 --- a/include/sta/DelayScalar.hh +++ b/include/sta/DelayScalar.hh @@ -82,7 +82,7 @@ public: float delay2) const override; Delay div(float delay1, const Delay &delay2) const override; - const char *asStringVariance(const Delay &delay, + std::string asStringVariance(const Delay &delay, int digits, const StaState *sta) const override; }; diff --git a/include/sta/DelaySkewNormal.hh b/include/sta/DelaySkewNormal.hh index 090f5701..5922e03e 100644 --- a/include/sta/DelaySkewNormal.hh +++ b/include/sta/DelaySkewNormal.hh @@ -82,7 +82,7 @@ public: float delay2) const override; Delay div(float delay1, const Delay &delay2) const override; - const char *asStringVariance(const Delay &delay, + std::string asStringVariance(const Delay &delay, int digits, const StaState *sta) const override; diff --git a/include/sta/Error.hh b/include/sta/Error.hh index d73775f4..a653024d 100644 --- a/include/sta/Error.hh +++ b/include/sta/Error.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include "Report.hh" @@ -42,7 +43,7 @@ public: class ExceptionMsg : public Exception { public: - ExceptionMsg(const char *msg, + ExceptionMsg(const std::string &msg, const bool suppressed); virtual const char *what() const noexcept; virtual bool suppressed() const { return suppressed_; } @@ -55,11 +56,11 @@ private: class ExceptionLine : public Exception { public: - ExceptionLine(const char *filename, + ExceptionLine(const std::string &filename, int line); protected: - const char *filename_; + std::string filename_; int line_; }; @@ -67,29 +68,31 @@ protected: class FileNotReadable : public Exception { public: - FileNotReadable(const char *filename); + FileNotReadable(std::string filename); virtual const char *what() const noexcept; protected: - const char *filename_; + std::string filename_; + std::string msg_; }; // Failure opening filename for writing. class FileNotWritable : public Exception { public: - FileNotWritable(const char *filename); + FileNotWritable(std::string filename); virtual const char *what() const noexcept; protected: - const char *filename_; + std::string filename_; + std::string msg_; }; // Report an error condition that should not be possible. // The default handler prints msg to stderr and exits. // The msg should NOT include a period or return. -// Only for use in those cases where a Report object is not available. -#define criticalError(id,msg) \ +// Only for use in those cases where a Report object is not available. +#define criticalError(id, msg) \ Report::defaultReport()->fileCritical(id, __FILE__, __LINE__, msg) } // namespace diff --git a/include/sta/ExceptionPath.hh b/include/sta/ExceptionPath.hh index b7f7e655..9e4a555c 100644 --- a/include/sta/ExceptionPath.hh +++ b/include/sta/ExceptionPath.hh @@ -24,6 +24,7 @@ #pragma once +#include #include #include "Error.hh" @@ -67,7 +68,7 @@ public: virtual bool isGroupPath() const { return false; } virtual bool isFilter() const { return false; } virtual ExceptionPathType type() const = 0; - virtual const char *asString(const Network *network) const; + virtual std::string to_string(const Network *network) const; ExceptionFrom *from() const { return from_; } ExceptionThruSeq *thrus() const { return thrus_; } ExceptionTo *to() const { return to_; } @@ -127,14 +128,14 @@ public: virtual bool useEndClk() const { return false; } virtual int pathMultiplier() const { return 0; } virtual float delay() const { return 0.0; } - virtual const char *name() const { return nullptr; } + virtual std::string name() const { return ""; } virtual bool isDefault() const { return false; } virtual bool ignoreClkLatency() const { return false; } virtual bool breakPath() const { return false; } protected: virtual const char *typeString() const = 0; - const char *fromThruToString(const Network *network) const; + std::string fromThruToString(const Network *network) const; void makeStates(); ExceptionFrom *from_; @@ -209,7 +210,7 @@ public: bool own_pts) override; bool isPathDelay() const override { return true; } ExceptionPathType type() const override { return ExceptionPathType::path_delay; } - const char *asString(const Network *network) const override; + std::string to_string(const Network *network) const override; const char *typeString() const override; bool mergeable(ExceptionPath *exception) const override; bool overrides(ExceptionPath *exception) const override; @@ -245,7 +246,7 @@ public: ExceptionPathType type() const override { return ExceptionPathType::multi_cycle; } bool matches(const MinMax *min_max, bool exactly) const override; - const char *asString(const Network *network) const override; + std::string to_string(const Network *network) const override; const char *typeString() const override; bool mergeable(ExceptionPath *exception) const override; bool overrides(ExceptionPath *exception) const override; @@ -292,7 +293,7 @@ public: class GroupPath : public ExceptionPath { public: - GroupPath(const char *name, + GroupPath(const std::string &name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, @@ -311,11 +312,11 @@ public: bool overrides(ExceptionPath *exception) const override; int typePriority() const override; bool tighterThan(ExceptionPath *exception) const override; - const char *name() const override { return name_; } + std::string name() const override { return name_; } bool isDefault() const override { return is_default_; } protected: - const char *name_; + std::string name_; bool is_default_; }; @@ -343,7 +344,7 @@ public: // All pins and instance/net pins. virtual PinSet allPins(const Network *network) = 0; virtual int typePriority() const = 0; - virtual const char *asString(const Network *network) const = 0; + virtual std::string to_string(const Network *network) const = 0; virtual size_t objectCount() const = 0; virtual void addPin(const Pin *pin, const Network *network) = 0; @@ -367,8 +368,8 @@ protected: // exception merging. size_t hash_; - // Maximum number of objects for asString() to show. - static const int as_string_max_objects_; + // Maximum number of objects for to_string() to show. + static const int to_string_max_objects_; static const size_t hash_clk = 3; static const size_t hash_pin = 5; static const size_t hash_net = 7; @@ -402,7 +403,7 @@ public: const Network *network) const override; void mergeInto(ExceptionPt *pt, const Network *network) override; - const char *asString(const Network *network) const override; + std::string to_string(const Network *network) const override; size_t objectCount() const override; void deleteClock(Clock *clk); void addPin(const Pin *pin, @@ -467,7 +468,7 @@ public: const Network *network); ExceptionTo *clone(const Network *network); bool isTo() const override { return true; } - const char *asString(const Network *network) const override; + std::string to_string(const Network *network) const override; const RiseFallBoth *endTransition() { return end_rf_; } bool intersectsPts(ExceptionTo *to, const Network *network) const; @@ -512,7 +513,7 @@ public: const Network *network); ~ExceptionThru(); ExceptionThru *clone(const Network *network); - const char *asString(const Network *network) const override; + std::string to_string(const Network *network) const override; bool isThru() const override { return true; } PinSet *pins() override { return pins_; } EdgePinsSet *edges() override { return edges_; } diff --git a/include/sta/Format.hh b/include/sta/Format.hh new file mode 100644 index 00000000..1745f482 --- /dev/null +++ b/include/sta/Format.hh @@ -0,0 +1,153 @@ +// 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. + +#pragma once + +#include +#include +#include +#include + +#include "StaConfig.hh" + +#ifdef ZLIB_FOUND +#include +#endif + +// std::format is not supported in GCC 11 (e.g. Ubuntu 22.04). +// Use fmt library as fallback when __cpp_lib_format is not defined. + +#if defined(__cpp_lib_format) && __cpp_lib_format >= 201907L +#include + +namespace sta { + +template +std::string format(std::format_string fmt, + Args &&...args) { + return std::format(fmt, std::forward(args)...); +} + +template +void print(std::ofstream &stream, + std::format_string fmt, + Args &&...args) { + stream << std::format(fmt, std::forward(args)...); +} + +#ifdef ZLIB_FOUND +template +void print(gzFile stream, + std::format_string fmt, + Args &&...args) { + std::string s = sta::format(fmt, std::forward(args)...); + gzwrite(stream, s.c_str(), s.size()); +} +#endif +template +void print(FILE *stream, + std::format_string fmt, + Args &&...args) { + std::string s = sta::format(fmt, std::forward(args)...); + std::fprintf(stream, "%s", s.c_str()); +} + +inline std::string vformat(std::string_view fmt, + std::format_args args) { + return std::vformat(fmt, args); +} + +template +auto make_format_args(Args &&...args) { + return std::make_format_args(std::forward(args)...); +} + +// Format with runtime format string - captures args to avoid make_format_args +// rvalue reference issues. +template +std::string formatRuntime(std::string_view fmt, + Args &&...args) { + auto args_tuple = std::make_tuple(std::forward(args)...); + return std::apply( + [fmt](auto &...a) { + return std::vformat(fmt, std::make_format_args(a...)); + }, + args_tuple); +} + +} // namespace sta + +#else +#include + +namespace sta { + +template +std::string format(fmt::format_string fmt, + Args &&...args) { + return fmt::format(fmt, std::forward(args)...); +} +template +void print(std::ofstream &stream, + fmt::format_string fmt, + Args &&...args) { + stream << fmt::format(fmt, std::forward(args)...); +} + +#ifdef ZLIB_FOUND +template +void print(gzFile stream, + fmt::format_string fmt, + Args &&...args) { + std::string s = sta::format(fmt, std::forward(args)...); + gzwrite(stream, s.c_str(), s.size()); +} +#endif +template +void print(FILE *stream, + fmt::format_string fmt, + Args &&...args) { + std::string s = sta::format(fmt, std::forward(args)...); + std::fprintf(stream, "%s", s.c_str()); +} + +inline +std::string vformat(std::string_view fmt, + fmt::format_args args) { + return fmt::vformat(fmt, args); +} + +template +auto make_format_args(Args &&...args) { + return fmt::make_format_args(std::forward(args)...); +} + +template +std::string formatRuntime(std::string_view fmt, + Args &&...args) { + return fmt::format(fmt::runtime(fmt), std::forward(args)...); +} + +} // namespace sta +#endif diff --git a/include/sta/ParseBus.hh b/include/sta/ParseBus.hh index d62bd982..9b40063a 100644 --- a/include/sta/ParseBus.hh +++ b/include/sta/ParseBus.hh @@ -25,12 +25,13 @@ #pragma once #include +#include namespace sta { // Return true if name is a bus. bool -isBusName(const char *name, +isBusName(std::string_view name, const char brkt_left, const char brkt_right, char escape); @@ -43,7 +44,7 @@ isBusName(const char *name, // index = bit // Caller must delete returned bus_name string. void -parseBusName(const char *name, +parseBusName(std::string_view name, const char brkt_left, const char brkt_right, char escape, @@ -53,9 +54,9 @@ parseBusName(const char *name, int &index); // Allow multiple different left/right bus brackets. void -parseBusName(const char *name, - const char *brkts_left, - const char *brkts_right, +parseBusName(std::string_view name, + std::string_view brkts_left, + std::string_view brkts_right, char escape, // Return values. bool &is_bus, @@ -66,7 +67,7 @@ parseBusName(const char *name, // bus_name is set to null if name is not a range. // Caller must delete returned bus_name string. void -parseBusName(const char *name, +parseBusName(std::string_view name, const char brkt_left, const char brkt_right, char escape, @@ -81,9 +82,9 @@ parseBusName(const char *name, // brkt_lefts and brkt_rights are corresponding strings of legal // bus brackets such as "[(<" and "])>". void -parseBusName(const char *name, - const char *brkts_left, - const char *brkts_right, +parseBusName(std::string_view name, + std::string_view brkts_left, + std::string_view brkts_right, const char escape, // Return values. bool &is_bus, @@ -95,7 +96,7 @@ parseBusName(const char *name, // Insert escapes before ch1 and ch2 in token. std::string -escapeChars(const char *token, +escapeChars(std::string_view token, const char ch1, const char ch2, const char escape); diff --git a/include/sta/PathGroup.hh b/include/sta/PathGroup.hh index 954bc2cc..d8ba2af6 100644 --- a/include/sta/PathGroup.hh +++ b/include/sta/PathGroup.hh @@ -42,7 +42,7 @@ class PathEndVisitor; using PathGroupIterator = PathEndSeq::iterator; using PathGroupClkMap = std::map; -using PathGroupNamedMap = std::map; +using PathGroupNamedMap = std::map; using PathGroupSeq = std::vector; // A collection of PathEnds grouped and sorted for reporting. @@ -140,7 +140,7 @@ public: bool unconstrained_paths, // Return value. PathEndSeq &path_ends); - PathGroup *findPathGroup(const char *name, + PathGroup *findPathGroup(const std::string &name, const MinMax *min_max) const; PathGroup *findPathGroup(const Clock *clock, const MinMax *min_max) const; @@ -191,7 +191,7 @@ protected: bool gated_clk, bool unconstrained, const MinMax *min_max); - bool reportGroup(const char *group_name, + bool reportGroup(const std::string &group_name, StringSet &group_names) const; static GroupPath *groupPathTo(const PathEnd *path_end, const StaState *sta); diff --git a/include/sta/Report.hh b/include/sta/Report.hh index 3ca8ffe0..fb42f00b 100644 --- a/include/sta/Report.hh +++ b/include/sta/Report.hh @@ -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. #pragma once @@ -27,15 +27,23 @@ #include #include #include +#include #include #include -#include "Machine.hh" // __attribute__ +#include "Machine.hh" // __attribute__ +#include "Format.hh" struct Tcl_Interp; namespace sta { +// Throws ExceptionMsg - implemented in Report.cc to avoid circular include with +// Error.hh +void +reportThrowExceptionMsg(const std::string &msg, + bool suppressed); + // Output streams used for printing. // This is a wrapper for all printing. It supports logging output to // a file and redirection of command output to a file. @@ -45,74 +53,98 @@ public: Report(); virtual ~Report(); - // Print line with return. - virtual void reportLine(const char *fmt, ...) - __attribute__((format (printf, 2, 3))); - virtual void reportLineString(const char *line); - virtual void reportLineString(const std::string &line); + virtual void reportLine(const std::string &line); virtual void reportBlankLine(); + // Print formatted line using std::format (C++20). + template + void report(std::string_view fmt, + Args &&...args) + { + reportLine(sta::vformat(fmt, sta::make_format_args(args...))); + } + //////////////////////////////////////////////////////////////// // Report warning. - virtual void warn(int id, - const char *fmt, ...) - __attribute__((format (printf, 3, 4))); - virtual void vwarn(int id, - const char *fmt, - va_list args); + template + void warn(int id, + std::string_view fmt, + Args &&...args) + { + if (!isSuppressed(id)) { + reportLine(sta::format( + "Warning {}: {}", id, sta::vformat(fmt, sta::make_format_args(args...)))); + } + } // Report warning in a file. - virtual void fileWarn(int id, - const char *filename, - int line, - const char *fmt, ...) - __attribute__((format (printf, 5, 6))); - virtual void vfileWarn(int id, - const char *filename, - int line, - const char *fmt, - va_list args); + template + void fileWarn(int id, + std::string_view filename, + int line, + std::string_view fmt, + Args &&...args) + { + if (!isSuppressed(id)) { + reportLine( + sta::format("Warning {}: {} line {}, {}", id, filename, line, + sta::vformat(fmt, sta::make_format_args(args...)))); + } + } - virtual void error(int id, - const char *fmt, ...) - __attribute__((format (printf, 3, 4))); - virtual void verror(int id, - const char *fmt, - va_list args); + template + void error(int id, + std::string_view fmt, + Args &&...args) + { + std::string msg = sta::vformat(fmt, sta::make_format_args(args...)); + reportThrowExceptionMsg(sta::format("{} {}", id, msg), isSuppressed(id)); + } // Report error in a file. - virtual void fileError(int id, - const char *filename, - int line, - const char *fmt, ...) - __attribute__((format (printf, 5, 6))); - virtual void vfileError(int id, - const char *filename, - int line, - const char *fmt, - va_list args); + template + void fileError(int id, + std::string_view filename, + int line, + std::string_view fmt, + Args &&...args) + { + const std::string msg = sta::vformat(fmt, sta::make_format_args(args...)); + reportThrowExceptionMsg(sta::format("{} {} line {}, {}", id, filename, line, msg), + isSuppressed(id)); + } - // Critical. + // Critical. // Report error condition that should not be possible or that prevents execution. // The default handler prints msg to stderr and exits. - virtual void critical(int id, - const char *fmt, - ...) - __attribute__((format (printf, 3, 4))); - virtual void fileCritical(int id, - const char *filename, - int line, - const char *fmt, - ...) - __attribute__((format (printf, 5, 6))); + template + void critical(int id, + std::string_view fmt, + Args &&...args) + { + reportLine(sta::format("Critical {}: {}", id, + sta::vformat(fmt, sta::make_format_args(args...)))); + exit(1); + } + template + void fileCritical(int id, + std::string_view filename, + int line, + std::string_view fmt, + Args &&...args) + { + reportLine(sta::format("Critical {}: {} line {}, {}", id, filename, line, + sta::vformat(fmt, sta::make_format_args(args...)))); + exit(1); + } // Log output to filename until logEnd is called. - virtual void logBegin(const char *filename); + virtual void logBegin(std::string_view filename); virtual void logEnd(); // Redirect output to filename until redirectFileEnd is called. - virtual void redirectFileBegin(const char *filename); + virtual void redirectFileBegin(std::string_view filename); // Redirect append output to filename until redirectFileEnd is called. - virtual void redirectFileAppendBegin(const char *filename); + virtual void redirectFileAppendBegin(std::string_view filename); virtual void redirectFileEnd(); // Redirect output to a string until redirectStringEnd is called. virtual void redirectStringBegin(); @@ -139,9 +171,7 @@ protected: // Return the number of characters written. virtual size_t printConsole(const char *buffer, size_t length); - void printToBuffer(const char *fmt, - ...) - __attribute__((format (printf, 2, 3))); + void printToBuffer(const char *fmt, ...) __attribute__((format(printf, 2, 3))); void printToBuffer(const char *fmt, va_list args); @@ -169,4 +199,4 @@ protected: friend class Debug; }; -} // namespace +} // namespace sta diff --git a/include/sta/ReportTcl.hh b/include/sta/ReportTcl.hh index 127cb23c..5f4a6cd0 100644 --- a/include/sta/ReportTcl.hh +++ b/include/sta/ReportTcl.hh @@ -44,20 +44,20 @@ class ReportTcl : public Report public: ReportTcl(); virtual ~ReportTcl(); - virtual void logBegin(const char *filename); - virtual void logEnd(); - virtual void redirectFileBegin(const char *filename); - virtual void redirectFileAppendBegin(const char *filename); - virtual void redirectFileEnd(); - virtual void redirectStringBegin(); - virtual const char *redirectStringEnd(); + void logBegin(std::string_view filename) override; + void logEnd() override; + void redirectFileBegin(std::string_view filename) override; + void redirectFileAppendBegin(std::string_view filename) override; + void redirectFileEnd() override; + void redirectStringBegin() override; + const char *redirectStringEnd() override; // This must be called after the Tcl interpreter has been constructed. // It makes the encapsulated channels. - virtual void setTclInterp(Tcl_Interp *interp); + void setTclInterp(Tcl_Interp *interp) override; protected: - virtual size_t printConsole(const char *buffer, - size_t length); + size_t printConsole(const char *buffer, + size_t length) override; void flush(); private: diff --git a/include/sta/Sdc.hh b/include/sta/Sdc.hh index 01e07ca7..64a41375 100644 --- a/include/sta/Sdc.hh +++ b/include/sta/Sdc.hh @@ -179,11 +179,11 @@ using InstDeratingFactorsMap = std::map; using CellDeratingFactorsMap = std::map; using ClockGroupsSet = std::set; using ClockGroupsClkMap = std::map; -using ClockGroupsNameMap = std::map; +using ClockGroupsNameMap = std::map; using ClockSenseMap = std::map; using ClkHpinDisables = std::set; using GroupPathSet = std::set; -using GroupPathMap = std::map; +using GroupPathMap = std::map; using ClockPairSet = std::set; using NetVoltageMap = std::map; @@ -499,7 +499,7 @@ public: Clock *to_clk, const RiseFallBoth *to_rf, const SetupHoldAll *setup_hold); - ClockGroups *makeClockGroups(const char *name, + ClockGroups *makeClockGroups(const std::string &name, bool logically_exclusive, bool physically_exclusive, bool asynchronous, @@ -507,11 +507,13 @@ public: const char *comment); void makeClockGroup(ClockGroups *clk_groups, ClockSet *clks); - void removeClockGroups(const char *name); - // nullptr name removes all. - void removeClockGroupsLogicallyExclusive(const char *name); - void removeClockGroupsPhysicallyExclusive(const char *name); - void removeClockGroupsAsynchronous(const char *name); + void removeClockGroups(const std::string &name); + void removeClockGroupsLogicallyExclusive(); + void removeClockGroupsLogicallyExclusive(const std::string &name); + void removeClockGroupsPhysicallyExclusive(); + void removeClockGroupsPhysicallyExclusive(const std::string &name); + void removeClockGroupsAsynchronous(); + void removeClockGroupsAsynchronous(const std::string &name); bool sameClockGroup(const Clock *clk1, const Clock *clk2) const; // Clocks explicitly excluded by set_clock_group. @@ -756,7 +758,7 @@ public: ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max); - void makeGroupPath(const char *name, + void makeGroupPath(const std::string &name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, @@ -1266,7 +1268,7 @@ protected: void makeClkGroupExclusions(ClockGroupSet *groups); void makeClkGroupSame(ClockGroup *group); void clearClkGroupExclusions(); - char *makeClockGroupsName(); + std::string makeClockGroupsName(); void setClockSense(const Pin *pin, const Clock *clk, ClockSense sense); diff --git a/include/sta/SdcNetwork.hh b/include/sta/SdcNetwork.hh index e462af6d..3c2c84be 100644 --- a/include/sta/SdcNetwork.hh +++ b/include/sta/SdcNetwork.hh @@ -274,7 +274,7 @@ protected: const PatternMatch *pattern, InstanceSeq &matches) const; - const char *staToSdc(const char *sta_name) const; + const char *staToSdc(std::string_view sta_name) const; }; // Encapsulate a network to map names to/from the sdc namespace. diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 4c49b7f3..caffa49d 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -434,19 +434,21 @@ public: const RiseFallBoth *to_rf, const SetupHoldAll *setup_hold, Sdc *sdc); - ClockGroups *makeClockGroups(const char *name, + ClockGroups *makeClockGroups(const std::string &name, bool logically_exclusive, bool physically_exclusive, bool asynchronous, bool allow_paths, const char *comment, Sdc *sdc); - // nullptr name removes all. - void removeClockGroupsLogicallyExclusive(const char *name, + void removeClockGroupsLogicallyExclusive(Sdc *sdc); + void removeClockGroupsLogicallyExclusive(const std::string &name, Sdc *sdc); - void removeClockGroupsPhysicallyExclusive(const char *name, + void removeClockGroupsPhysicallyExclusive(Sdc *sdc); + void removeClockGroupsPhysicallyExclusive(const std::string &name, Sdc *sdc); - void removeClockGroupsAsynchronous(const char *name, + void removeClockGroupsAsynchronous(Sdc *sdc); + void removeClockGroupsAsynchronous(const std::string &name, Sdc *sdc); void makeClockGroup(ClockGroups *clk_groups, ClockSet *clks, @@ -640,7 +642,7 @@ public: float delay, const char *comment, Sdc *sdc); - void makeGroupPath(const char *name, + void makeGroupPath(const std::string &name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, diff --git a/include/sta/StringUtil.hh b/include/sta/StringUtil.hh index b12ae00d..c2cfb13d 100644 --- a/include/sta/StringUtil.hh +++ b/include/sta/StringUtil.hh @@ -143,14 +143,6 @@ public: char * stringCopy(const char *str); -inline void -stringAppend(char *&str1, - const char *str2) -{ - strcpy(str1, str2); - str1 += strlen(str2); -} - void stringDeleteCheck(const char *str); @@ -164,32 +156,6 @@ stringDelete(const char *str) bool isDigits(const char *str); -// Print to a new string. -// Caller owns returned string. -char * -stringPrint(const char *fmt, - ...) __attribute__((format (printf, 1, 2))); -std::string -stdstrPrint(const char *fmt, - ...) __attribute__((format (printf, 1, 2))); -char * -stringPrintArgs(const char *fmt, - va_list args); -void -stringPrint(std::string &str, - const char *fmt, - ...) __attribute__((format (printf, 2, 3))); -// Formated append to std::string. -void -stringAppend(std::string &str, - const char *fmt, - ...) __attribute__((format (printf, 2, 3))); - -// Print to a temporary string. -char * -stringPrintTmp(const char *fmt, - ...) __attribute__((format (printf, 1, 2))); - char * makeTmpString(size_t length); char * diff --git a/include/sta/Units.hh b/include/sta/Units.hh index 3390c103..8c3475f5 100644 --- a/include/sta/Units.hh +++ b/include/sta/Units.hh @@ -56,9 +56,8 @@ public: void setDigits(int digits); // Does not include suffix. int width() const; - const char *asString(float value) const; - const char *asString(double value) const; - const char *asString(float value, + std::string asString(float value) const; + std::string asString(float value, int digits) const; private: diff --git a/include/sta/VerilogNamespace.hh b/include/sta/VerilogNamespace.hh index 8649c2d7..bcdddb52 100644 --- a/include/sta/VerilogNamespace.hh +++ b/include/sta/VerilogNamespace.hh @@ -29,21 +29,21 @@ namespace sta { std::string -cellVerilogName(const char *sta_name); +cellVerilogName(std::string sta_name); std::string -instanceVerilogName(const char *sta_name); +instanceVerilogName(std::string sta_name); std::string -netVerilogName(const char *sta_name); +netVerilogName(std::string sta_name); std::string -portVerilogName(const char *sta_name); +portVerilogName(std::string sta_name); std::string -moduleVerilogToSta(const std::string *sta_name); +moduleVerilogToSta(std::string sta_name); std::string -instanceVerilogToSta(const std::string *sta_name); +instanceVerilogToSta(std::string sta_name); std::string -netVerilogToSta(const std::string *sta_name); +netVerilogToSta(std::string sta_name); std::string -portVerilogToSta(const std::string *sta_name); +portVerilogToSta(std::string sta_name); } // namespace diff --git a/include/sta/VerilogReader.hh b/include/sta/VerilogReader.hh index 35311f6d..64499238 100644 --- a/include/sta/VerilogReader.hh +++ b/include/sta/VerilogReader.hh @@ -25,9 +25,12 @@ #pragma once #include +#include #include #include +#include "Format.hh" +#include "Report.hh" #include "StringUtil.hh" #include "NetworkClass.hh" @@ -59,8 +62,32 @@ class StringRegistry; class VerilogBindingTbl; class VerilogNetNameIterator; class VerilogNetPortRef; -class VerilogError; class LibertyCell; +class VerilogErrorCmp; + +class VerilogError +{ +public: + VerilogError(int id, + std::string_view filename, + int line, + std::string_view msg, + bool warn); + const char *msg() const { return msg_.c_str(); } + const char *filename() const { return filename_.c_str(); } + int id() const { return id_; } + int line() const { return line_; } + bool warn() const { return warn_; } + +private: + int id_; + std::string filename_; + int line_; + std::string msg_; + bool warn_; + + friend class VerilogErrorCmp; +}; using VerilogModuleMap = std::map; using VerilogStmtSeq = std::vector; @@ -148,14 +175,24 @@ public: const char *filename() const { return filename_.c_str(); } void incrLine(); Report *report() const { return report_; } + template void error(int id, - const char *filename, + std::string_view filename, int line, - const char *fmt, ...); + std::string_view fmt, + Args &&...args) + { + report_->fileError(id, filename, line, fmt, std::forward(args)...); + } + template void warn(int id, - const char *filename, + std::string_view filename, int line, - const char *fmt, ...); + std::string_view fmt, + Args &&...args) + { + report_->fileWarn(id, filename, line, fmt, std::forward(args)...); + } const std::string &zeroNetName() const { return zero_net_name_; } const std::string &oneNetName() const { return one_net_name_; } void deleteModules(); @@ -231,16 +268,26 @@ protected: Instance *parent, VerilogBindingTbl *parent_bindings, bool is_leaf); + template void linkWarn(int id, - const char *filename, + std::string_view filename, int line, - const char *msg, ...) - __attribute__((format (printf, 5, 6))); + std::string_view msg, + Args &&...args) + { + std::string msg_str = sta::formatRuntime(msg, std::forward(args)...); + link_errors_.push_back(new VerilogError(id, filename, line, msg_str, true)); + } + template void linkError(int id, - const char *filename, + std::string_view filename, int line, - const char *msg, ...) - __attribute__((format (printf, 5, 6))); + std::string_view msg, + Args &&...args) + { + std::string msg_str = sta::formatRuntime(msg, std::forward(args)...); + link_errors_.push_back(new VerilogError(id, filename, line, msg_str, false)); + } bool reportLinkErrors(); bool haveLinkErrors(); Cell *makeBlackBox(VerilogModuleInst *mod_inst, diff --git a/liberty/LibExprReader.cc b/liberty/LibExprReader.cc index c3e1e5f9..1b2fc037 100644 --- a/liberty/LibExprReader.cc +++ b/liberty/LibExprReader.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 "FuncExpr.hh" @@ -80,8 +80,7 @@ LibExprReader::makeFuncExprPort(const char *port_name) if (port) expr = FuncExpr::makePort(port); else - report_->warn(1130, "%s references unknown port %s.", - error_msg_, port_name); + report_->warn(1130, "{} references unknown port {}.", error_msg_, port_name); stringDelete(port_name); return expr; } @@ -134,7 +133,7 @@ LibExprReader::setResult(FuncExpr *result) void LibExprReader::parseError(const char *msg) { - report_->error(1131, "%s %s.", error_msg_, msg); + report_->error(1131, "{} {}.", error_msg_, msg); } //////////////////////////////////////////////////////////////// @@ -144,4 +143,4 @@ LibExprScanner::LibExprScanner(std::istringstream &stream) : { } -} // namespace +} // namespace sta diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 1c659ad8..5e4328ad 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -25,6 +25,7 @@ #include "Liberty.hh" #include "ContainerHelpers.hh" +#include "Format.hh" #include "Mutex.hh" #include "EnumNameMap.hh" #include "Report.hh" @@ -775,7 +776,7 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1, port1->setScenePort(port2, ap_index); } else - report->warn(1110, "cell %s/%s port %s not found in cell %s/%s.", + report->warn(1110, "cell {}/{} port {} not found in cell {}/{}.", cell1->library()->name(), cell1->name(), port_name, @@ -801,7 +802,7 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1, } } else - report->warn(1111, "cell %s/%s %s -> %s timing group %s not found in cell %s/%s.", + report->warn(1111, "cell {}/{} {} -> {} timing group {} not found in cell {}/{}.", cell1->library()->name(), cell1->name(), arc_set1->from() ? arc_set1->from()->name() : "", @@ -820,7 +821,7 @@ LibertyLibrary::checkScenes(LibertyCell *cell, for (const Scene *scene : scenes) { for (auto min_max : MinMax::range()) { if (!cell->checkSceneCell(scene, min_max)) - report->error(1112, "Liberty cell %s/%s for corner %s/%s not found.", + report->error(1112, "Liberty cell {}/{} for corner {}/{} not found.", cell->libertyLibrary()->name(), cell->name(), scene->name().c_str(), @@ -1703,7 +1704,7 @@ LibertyCell::makeLatchEnables(Report *report, TimingSense en_sense = en_func->portTimingSense(en); if (en_sense == TimingSense::positive_unate && en_rf != RiseFall::rise()) - report->warn(1114, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense.", + report->warn(1114, "cell {}/{} {} -> {} latch enable {}_edge is inconsistent with latch group enable function positive sense.", library_->name(), name(), en->name(), @@ -1711,7 +1712,7 @@ LibertyCell::makeLatchEnables(Report *report, en_rf == RiseFall::rise()?"rising":"falling"); else if (en_sense == TimingSense::negative_unate && en_rf != RiseFall::fall()) - report->warn(1115, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense.", + report->warn(1115, "cell {}/{} {} -> {} latch enable {}_edge is inconsistent with latch group enable function negative sense.", library_->name(), name(), en->name(), @@ -1721,7 +1722,7 @@ LibertyCell::makeLatchEnables(Report *report, } } else - report->warn(1121, "cell %s/%s no latch enable found for %s -> %s.", + report->warn(1121, "cell {}/{} no latch enable found for {} -> {}.", library_->name(), name(), d->name(), @@ -1767,7 +1768,7 @@ LibertyCell::findLatchSetup(const LibertyPort *d, for (TimingArc *arc : arc_set->arcs()) { const RiseFall *from_rf = arc->fromEdge()->asRiseFall(); if (from_rf == en_rf) { - report->warn(1113, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with %s -> %s setup_%s check.", + report->warn(1113, "cell {}/{} {} -> {} latch enable {}_edge is inconsistent with {} -> {} setup_{} check.", library_->name(), name(), en->name(), @@ -1824,7 +1825,7 @@ LibertyCell::makeLatchEnable(LibertyPort *d, latch_check_map_[setup_check] = idx; d->setIsLatchData(true); debugPrint(debug, "liberty_latch", 1, - "latch %s -> %s | %s %s -> %s | %s %s -> %s setup", + "latch {} -> {} | {} {} -> {} | {} {} -> {} setup", d->name(), q->name(), en->name(), @@ -2904,7 +2905,7 @@ ModeDef::defineValue(const char *value, const char *sdf_cond) { std::string key = value; - std::string sdf = sdf_cond ? std::string(sdf_cond) : std::string(); + std::string sdf = sdf_cond ? sdf_cond : std::string(); auto [it, inserted] = values_.try_emplace(key, key, cond, std::move(sdf)); return &it->second; } @@ -3202,27 +3203,27 @@ ScaleFactors::report(Report *report) std::string line = " "; for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) { ScaleFactorPvt pvt = (ScaleFactorPvt) pvt_index; - stringAppend(line, "%10s", scaleFactorPvtName(pvt)); + line += sta::format("{:>10}", scaleFactorPvtName(pvt)); } - report->reportLineString(line); + report->reportLine(line); for (int type_index = 0; type_index < scale_factor_type_count; type_index++) { ScaleFactorType type = (ScaleFactorType) type_index; - stringPrint(line, "%10s ", scaleFactorTypeName(type)); + std::string line = sta::format("{:>10}", scaleFactorTypeName(type)); for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) { if (scaleFactorTypeRiseFallSuffix(type) || scaleFactorTypeRiseFallPrefix(type) || scaleFactorTypeLowHighSuffix(type)) { - stringAppend(line, " %.3f,%.3f", + line += sta::format(" {:.3f},{:.3f}", scales_[type_index][pvt_index][RiseFall::riseIndex()], scales_[type_index][pvt_index][RiseFall::fallIndex()]); } else { - stringAppend(line, " %.3f", + line += sta::format(" {:.3f}", scales_[type_index][pvt_index][0]); } } - report->reportLineString(line); + report->reportLine(line); } } diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 2e1814ee..07529526 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -367,16 +367,13 @@ std::string to_string() { return self->to_string(); } const TimingRole *role() { return self->role(); } const char *sdf_cond() { return self->sdfCond().c_str(); } -const char * +std::string full_name() { const char *from = self->from()->name(); const char *to = self->to()->name(); const char *cell_name = self->libertyCell()->name(); - return stringPrintTmp("%s %s -> %s", - cell_name, - from, - to); + return sta::format("{} {} -> {}", cell_name, from, to); } const std::string diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc index 72a72b1f..52cd97d5 100644 --- a/liberty/LibertyBuilder.cc +++ b/liberty/LibertyBuilder.cc @@ -102,12 +102,8 @@ LibertyBuilder::makeBusPortBit(ConcreteLibrary *library, const char *bus_name, int bit_index) { - std::string bit_name; - stringPrint(bit_name, "%s%c%d%c", - bus_name, - library->busBrktLeft(), - bit_index, - library->busBrktRight()); + std::string bit_name = std::string(bus_name) + library->busBrktLeft() + + std::to_string(bit_index) + library->busBrktRight(); LibertyPort *port = makePort(cell, bit_name.c_str(), bit_index); bus_port->addPortBit(port); cell->addPortBit(port); diff --git a/liberty/LibertyParse.yy b/liberty/LibertyParse.yy index 35ca7180..b20b5c6c 100644 --- a/liberty/LibertyParse.yy +++ b/liberty/LibertyParse.yy @@ -45,7 +45,7 @@ sta::LibertyParse::error(const location_type &loc, const std::string &msg) { reader->report()->fileError(164, reader->filename().c_str(), - loc.begin.line, "%s", msg.c_str()); + loc.begin.line, "{}", msg); } %} @@ -169,13 +169,13 @@ attr_value: /* Crafted to avoid conflicts with expr */ volt_expr: FLOAT volt_op FLOAT - { $$ = sta::stdstrPrint("%e%c%e", $1, $2, $3); } + { $$ = sta::format("{}{}{}", $1, $2, $3); } | string volt_op FLOAT - { $$ = sta::stdstrPrint("%s%c%e", $1.c_str(), $2, $3); } + { $$ = sta::format("{}{}{}", $1, $2, $3); } | FLOAT volt_op string - { $$ = sta::stdstrPrint("%e%c%s", $1, $2, $3.c_str()); } + { $$ = sta::format("{}{}{}", $1, $2, $3); } | volt_expr volt_op FLOAT - { $$ = sta::stdstrPrint("%s%c%e", $1.c_str(), $2, $3); } + { $$ = sta::format("{}{}{}", $1, $2, $3); } ; volt_op: @@ -192,7 +192,7 @@ volt_op: expr: expr_term1 | expr_term1 expr_op expr - { $$ = sta::stdstrPrint("%s%c%s", $1.c_str(), $2, $3.c_str()); } + { $$ = sta::format("{}{}{}", $1.c_str(), $2, $3.c_str()); } ; expr_term: diff --git a/liberty/LibertyParser.cc b/liberty/LibertyParser.cc index 5d16566d..b3cefe9a 100644 --- a/liberty/LibertyParser.cc +++ b/liberty/LibertyParser.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 "LibertyParser.hh" @@ -130,10 +130,8 @@ LibertyParser::groupBegin(const std::string type, LibertyAttrValueSeq *params, int line) { - LibertyGroup *group = - new LibertyGroup(std::move(type), - params ? std::move(*params) : LibertyAttrValueSeq(), - line); + LibertyGroup *group = new LibertyGroup( + std::move(type), params ? std::move(*params) : LibertyAttrValueSeq(), line); delete params; LibertyGroup *parent_group = group_stack_.empty() ? nullptr : group_stack_.back(); group_visitor_->begin(group, parent_group); @@ -145,8 +143,7 @@ LibertyParser::groupEnd() { LibertyGroup *group = this->group(); group_stack_.pop_back(); - LibertyGroup *parent = - group_stack_.empty() ? nullptr : group_stack_.back(); + LibertyGroup *parent = group_stack_.empty() ? nullptr : group_stack_.back(); if (parent) parent->addSubgroup(group); group_visitor_->end(group, parent); @@ -170,8 +167,8 @@ LibertyParser::makeSimpleAttr(const std::string name, const LibertyAttrValue *value, int line) { - LibertySimpleAttr *attr = new LibertySimpleAttr(std::move(name), - std::move(*value), line); + LibertySimpleAttr *attr = + new LibertySimpleAttr(std::move(name), std::move(*value), line); delete value; LibertyGroup *group = this->group(); group->addAttr(attr); @@ -191,9 +188,8 @@ LibertyParser::makeComplexAttr(const std::string name, return nullptr; // Define is not a complex attr; already added to group } else { - LibertyComplexAttr *attr = new LibertyComplexAttr(std::move(name), - std::move(*values), - line); + LibertyComplexAttr *attr = + new LibertyComplexAttr(std::move(name), std::move(*values), line); delete values; LibertyGroup *group = this->group(); group->addAttr(attr); @@ -266,7 +262,7 @@ LibertyScanner::includeBegin() } else { report_->fileWarn(25, filename_.c_str(), yylineno, - "cannot open include file %s.", filename.c_str()); + "cannot open include file {}.", filename); delete stream; } } @@ -291,7 +287,7 @@ LibertyScanner::fileEnd() void LibertyScanner::error(const char *msg) { - report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg); + report_->fileError(1866, filename_.c_str(), lineno(), "{}", msg); } //////////////////////////////////////////////////////////////// @@ -305,10 +301,7 @@ LibertyGroup::LibertyGroup(std::string type, { } -LibertyGroup::~LibertyGroup() -{ - clear(); -} +LibertyGroup::~LibertyGroup() { clear(); } void LibertyGroup::clear() @@ -327,19 +320,15 @@ LibertyGroup::clear() bool LibertyGroup::empty() const { - return subgroups_.empty() - && simple_attr_map_.empty() - && complex_attr_map_.empty() - && define_map_.empty(); + return subgroups_.empty() && simple_attr_map_.empty() && complex_attr_map_.empty() + && define_map_.empty(); } bool LibertyGroup::oneGroupOnly() const { - return subgroups_.size() == 1 - && simple_attr_map_.empty() - && complex_attr_map_.empty() - && define_map_.empty(); + return subgroups_.size() == 1 && simple_attr_map_.empty() + && complex_attr_map_.empty() && define_map_.empty(); } void @@ -483,7 +472,7 @@ LibertyGroup::findAttrFloat(const std::string attr_name, const std::string &float_str = attr_value.stringValue(); char *end = nullptr; value = std::strtof(float_str.c_str(), &end); - if (end) { + if (end) { exists = true; return; } @@ -538,10 +527,7 @@ LibertyComplexAttr::LibertyComplexAttr(std::string name, { } -LibertyComplexAttr::~LibertyComplexAttr() -{ - deleteContents(values_); -} +LibertyComplexAttr::~LibertyComplexAttr() { deleteContents(values_); } const LibertyAttrValue * LibertyComplexAttr::firstValue() const @@ -585,9 +571,9 @@ LibertyAttrValue::floatValue() const } void -LibertyAttrValue::floatValue(// Return values. - float &value, - bool &valid) const +LibertyAttrValue::floatValue( // Return values. + float &value, + bool &valid) const { valid = false; if (string_value_.empty()) { @@ -598,8 +584,7 @@ LibertyAttrValue::floatValue(// Return values. // Some floats are enclosed in quotes. char *end; value = strtof(string_value_.c_str(), &end); - if ((*end == '\0' - || isspace(*end)) + if ((*end == '\0' || isspace(*end)) // strtof support INF as a valid float. && string_value_ != "inf") { valid = true; @@ -631,4 +616,4 @@ LibertyVariable::LibertyVariable(std::string var, { } -} // namespace +} // namespace sta diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index e95ed876..a873a881 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -172,12 +172,12 @@ LibertyReader::endCell(const LibertyGroup *cell_group, const char *name = cell_group->firstName(); if (name) { - debugPrint(debug_, "liberty", 1, "cell %s", name); + debugPrint(debug_, "liberty", 1, "cell {}", name); LibertyCell *cell = builder_.makeCell(library_, name, filename_); readCell(cell, cell_group); } else - libWarn(1193, cell_group, "cell missing name."); + warn(1193, cell_group, "cell missing name."); // Delete the cell group and preceding library attributes // and groups so they are not revisited and reduce memory peak. @@ -267,7 +267,7 @@ LibertyReader::makeLibrary(const LibertyGroup *libary_group) if (name) { LibertyLibrary *library = network_->findLiberty(name); if (library) - libWarn(1140, libary_group, "library %s already exists.", name); + warn(1140, libary_group, "library {} already exists.", name); // Make a new library even if a library with the same name exists. // Both libraries may be accessed by min/max analysis points. library_ = network_->makeLibertyLibrary(name, filename_); @@ -296,7 +296,7 @@ LibertyReader::makeLibrary(const LibertyGroup *libary_group) library_->setDelayModelType(DelayModelType::cmos_linear); } else - libError(1141, libary_group, "library missing name."); + error(1141, libary_group, "library missing name."); } // Energy scale is derived from other units. @@ -366,18 +366,18 @@ LibertyReader::readLibraryUnits(const LibertyGroup *library_group) else if (stringEqual(suffix.c_str(), "pf")) cap_scale_ = scale * 1E-12F; else - libWarn(1154, cap_attr, "capacitive_load_units are not ff or pf."); + warn(1154, cap_attr, "capacitive_load_units are not ff or pf."); } else - libWarn(1155, cap_attr, "capacitive_load_units are not a string."); + warn(1155, cap_attr, "capacitive_load_units are not a string."); } else - libWarn(1157, cap_attr, "capacitive_load_units scale is not a float."); + warn(1157, cap_attr, "capacitive_load_units scale is not a float."); } else if (values.size() == 1) - libWarn(1156, cap_attr, "capacitive_load_units missing suffix."); + warn(1156, cap_attr, "capacitive_load_units missing suffix."); else - libWarn(1158, cap_attr, "capacitive_load_units missing scale and suffix."); + warn(1158, cap_attr, "capacitive_load_units missing scale and suffix."); library_->units()->capacitanceUnit()->setScale(cap_scale_); } } @@ -409,7 +409,7 @@ LibertyReader::readUnit(const char *unit_attr_name, else if (unit_mult == "100") mult = 100.0F; else - libWarn(1150, unit_attr, "unknown unit multiplier %s.", unit_mult.c_str()); + warn(1150, unit_attr, "unknown unit multiplier {}.", unit_mult); } else scale_suffix = *units; @@ -432,13 +432,13 @@ LibertyReader::readUnit(const char *unit_attr_name, else if (scale_char == 'f') scale_mult = 1E-15F; else - libWarn(1151, unit_attr, "unknown unit scale %c.", scale_char); + warn(1151, unit_attr, "unknown unit scale {}.", scale_char); } else - libWarn(1152, unit_attr, "unknown unit suffix %s.", suffix.c_str()); + warn(1152, unit_attr, "unknown unit suffix {}.", suffix); } else if (!stringEqual(scale_suffix.c_str(), unit_suffix)) - libWarn(1153, unit_attr, "unknown unit suffix %s.", scale_suffix.c_str()); + warn(1153, unit_attr, "unknown unit suffix {}.", scale_suffix); scale_var = scale_mult * mult; unit->setScale(scale_var); } @@ -456,23 +456,23 @@ LibertyReader::readDelayModel(const LibertyGroup *library_group) library_->setDelayModelType(DelayModelType::cmos_linear); else if (*type_name == "piecewise_cmos") { library_->setDelayModelType(DelayModelType::cmos_pwl); - libWarn(1160, library_group, "delay_model %s not supported.", type_name->c_str()); + warn(1160, library_group, "delay_model {} not supported.", *type_name); } else if (*type_name == "cmos2") { library_->setDelayModelType(DelayModelType::cmos2); - libWarn(1161, library_group, "delay_model %s not supported.", type_name->c_str()); + warn(1161, library_group, "delay_model {} not supported.", *type_name); } else if (*type_name == "polynomial") { library_->setDelayModelType(DelayModelType::polynomial); - libWarn(1162, library_group, "delay_model %s not supported.", type_name->c_str()); + warn(1162, library_group, "delay_model {} not supported.", *type_name); } // Evil IBM garbage. else if (*type_name == "dcm") { library_->setDelayModelType(DelayModelType::dcm); - libWarn(1163, library_group, "delay_model %s not supported..", type_name->c_str()); + warn(1163, library_group, "delay_model {} not supported..", *type_name); } else - libWarn(1164, library_group, "unknown delay_model %s.", type_name->c_str()); + warn(1164, library_group, "unknown delay_model {}.", *type_name); } } @@ -489,7 +489,7 @@ LibertyReader::readBusStyle(const LibertyGroup *library_group) && (*bus_style)[4] == 'd') library_->setBusBrkts((*bus_style)[2], (*bus_style)[5]); else - libWarn(1165, library_group, "unknown bus_naming_style format."); + warn(1165, library_group, "unknown bus_naming_style format."); } } @@ -511,9 +511,9 @@ LibertyReader::readBusTypes(LibertyCell *cell, library_->makeBusDcl(name, from, to); } else if (!from_exists) - libWarn(1179, type_group, "bus type missing bit_from."); + warn(1179, type_group, "bus type missing bit_from."); else if (!to_exists) - libWarn(1180, type_group, "bus type missing bit_to."); + warn(1180, type_group, "bus type missing bit_to."); } } } @@ -539,13 +539,13 @@ LibertyReader::checkThresholds(const LibertyGroup *library_group) const { for (const RiseFall *rf : RiseFall::range()) { if (library_->inputThreshold(rf) == 0.0) - libWarn(1145, library_group, "input_threshold_pct_%s not found.", rf->name()); + warn(1145, library_group, "input_threshold_pct_{} not found.", rf->name()); if (library_->outputThreshold(rf) == 0.0) - libWarn(1146, library_group, "output_threshold_pct_%s not found.", rf->name()); + warn(1146, library_group, "output_threshold_pct_{} not found.", rf->name()); if (library_->slewLowerThreshold(rf) == 0.0) - libWarn(1147, library_group, "slew_lower_threshold_pct_%s not found.", rf->name()); + warn(1147, library_group, "slew_lower_threshold_pct_{} not found.", rf->name()); if (library_->slewUpperThreshold(rf) == 0.0) - libWarn(1148, library_group, "slew_upper_threshold_pct_%s not found.", rf->name()); + warn(1148, library_group, "slew_upper_threshold_pct_{} not found.", rf->name()); } } @@ -579,7 +579,7 @@ LibertyReader::readTableTemplates(const LibertyGroup *library_group, tbl_template->setAxis3(axis3); } else - libWarn(1175, template_group, "table template missing name."); + warn(1175, template_group, "table template missing name."); } } @@ -592,7 +592,7 @@ LibertyReader::makeTableTemplateAxis(const LibertyGroup *template_group, if (var_name) { TableAxisVariable axis_var = stringTableAxisVariable(var_name->c_str()); if (axis_var == TableAxisVariable::unknown) - libWarn(1297, template_group, "axis type %s not supported.", var_name->c_str()); + warn(1297, template_group, "axis type {} not supported.", *var_name); else { std::string index_attr_name = "index_" + std::to_string(axis_index); const LibertyComplexAttr *index_attr = @@ -605,7 +605,7 @@ LibertyReader::makeTableTemplateAxis(const LibertyGroup *template_group, for (size_t i = 1; i < axis_values.size(); i++) { float value = axis_values[i]; if (value <= prev) { - libWarn(1178, template_group, "non-increasing table index values."); + warn(1178, template_group, "non-increasing table index values."); break; } prev = value; @@ -644,7 +644,7 @@ LibertyReader::readVoltateMaps(const LibertyGroup *library_group) if (valid) library_->addSupplyVoltage(volt_name.c_str(), volt); else - libWarn(1166, volt_attr, "voltage_map voltage is not a float."); + warn(1166, volt_attr, "voltage_map voltage is not a float."); } } } @@ -684,8 +684,8 @@ LibertyReader::readOperatingConds(const LibertyGroup *library_group) if (op_cond) library_->setDefaultOperatingConditions(op_cond); else - libWarn(1144, library_group, "default_operating_condition %s not found.", - default_op_cond->c_str()); + warn(1144, library_group, "default_operating_condition {} not found.", + *default_op_cond); } } @@ -774,11 +774,11 @@ LibertyReader::readWireloads(const LibertyGroup *library_group) if (exists) wireload->addFanoutLength(fanout, length); else - libWarn(1185, fanout_attr, "fanout_length is missing length and fanout."); + warn(1185, fanout_attr, "fanout_length is missing length and fanout."); } } else - libWarn(1184, wl_group, "wire_load missing name."); + warn(1184, wl_group, "wire_load missing name."); } } @@ -810,20 +810,20 @@ LibertyReader::readWireloadSelection(const LibertyGroup *library_group) wireload_selection->addWireloadFromArea(min_area, max_area, wireload); else - libWarn(1187, area_attr, "wireload %s not found.", wireload_name.c_str()); + warn(1187, area_attr, "wireload {} not found.", wireload_name); } else - libWarn(1188, area_attr, + warn(1188, area_attr, "wire_load_from_area wireload name not a string."); } else - libWarn(1189, area_attr, "wire_load_from_area min not a float."); + warn(1189, area_attr, "wire_load_from_area min not a float."); } else - libWarn(1190, area_attr, "wire_load_from_area max not a float."); + warn(1190, area_attr, "wire_load_from_area max not a float."); } else - libWarn(1191, area_attr, "wire_load_from_area missing parameters."); + warn(1191, area_attr, "wire_load_from_area missing parameters."); } } } @@ -837,8 +837,8 @@ LibertyReader::readDefaultWireLoad(const LibertyGroup *library_group) if (wireload) library_->setDefaultWireload(wireload); else - libWarn(1142, library_group, "default_wire_load %s not found.", - wireload_name->c_str()); + warn(1142, library_group, "default_wire_load {} not found.", + *wireload_name); } } @@ -852,8 +852,8 @@ LibertyReader::readDefaultWireLoadMode(const LibertyGroup *library_group) if (mode != WireloadMode::unknown) library_->setDefaultWireloadMode(mode); else - libWarn(1174, library_group, "default_wire_load_mode %s not found.", - wire_load_mode->c_str()); + warn(1174, library_group, "default_wire_load_mode {} not found.", + *wire_load_mode); } } @@ -868,8 +868,8 @@ LibertyReader::readDefaultWireLoadSelection(const LibertyGroup *library_group) if (selection) library_->setDefaultWireloadSelection(selection); else - libWarn(1143, library_group, "default_wire_selection %s not found.", - selection_name->c_str()); + warn(1143, library_group, "default_wire_selection {} not found.", + *selection_name); } } @@ -897,11 +897,11 @@ LibertyReader::readModeDefs(LibertyCell *cell, } } else - libWarn(1264, value_group, "mode value missing name."); + warn(1264, value_group, "mode value missing name."); } } else - libWarn(1263, mode_group, "mode definition missing name."); + warn(1263, mode_group, "mode definition missing name."); } } @@ -920,7 +920,7 @@ LibertyReader::readSlewDegradations(const LibertyGroup *library_group) if (LibertyLibrary::checkSlewDegradationAxes(table_model)) library_->setWireSlewDegradationTable(table_model, rf); else - libWarn(1254, degradation_group, "unsupported model axis."); + warn(1254, degradation_group, "unsupported model axis."); } } } @@ -966,9 +966,9 @@ LibertyReader::readLibAttrFloatWarnZero(const LibertyGroup *library_group, if (value == 0.0F) { const LibertySimpleAttr *attr = library_group->findSimpleAttr(attr_name); if (attr) - libWarn(1171, attr, "%s is 0.0.", attr_name); + warn(1171, attr, "{} is 0.0.", attr_name); else - libWarn(1172, library_group, "%s is 0.0.", attr_name); + warn(1172, library_group, "{} is 0.0.", attr_name); } (library_->*set_func)(value * scale); } @@ -1016,7 +1016,7 @@ LibertyReader::readScaledCell(const LibertyGroup *scaled_cell_group) if (op_cond_name) { OperatingConditions *op_cond = library_->findOperatingConditions(op_cond_name); if (op_cond) { - debugPrint(debug_, "liberty", 1, "scaled cell %s %s", + debugPrint(debug_, "liberty", 1, "scaled cell {} {}", name, op_cond_name); LibertyCell *scaled_cell = library_->makeScaledCell(name, filename_); readCell(scaled_cell, scaled_cell_group); @@ -1025,17 +1025,17 @@ LibertyReader::readScaledCell(const LibertyGroup *scaled_cell_group) owner->addScaledCell(op_cond, scaled_cell); } else - libWarn(1202, scaled_cell_group, "operating conditions %s not found.", + warn(1202, scaled_cell_group, "operating conditions {} not found.", op_cond_name); } else - libWarn(1203, scaled_cell_group, "scaled_cell missing operating condition."); + warn(1203, scaled_cell_group, "scaled_cell missing operating condition."); } else - libWarn(1204, scaled_cell_group, "scaled_cell cell %s has not been defined.", name); + warn(1204, scaled_cell_group, "scaled_cell cell {} has not been defined.", name); } else - libWarn(1205, scaled_cell_group, "scaled_cell missing name."); + warn(1205, scaled_cell_group, "scaled_cell missing name."); } // Minimal check that is not very specific about where the discrepancies are. @@ -1047,20 +1047,20 @@ LibertyReader::checkScaledCell(LibertyCell *scaled_cell, { if (equivCellPorts(scaled_cell, owner)) { if (!equivCellPorts(scaled_cell, owner)) - libWarn(1206, scaled_cell_group, "scaled_cell %s, %s ports do not match cell ports", + warn(1206, scaled_cell_group, "scaled_cell {}, {} ports do not match cell ports", scaled_cell->name(), op_cond_name); if (!equivCellFuncs(scaled_cell, owner)) - libWarn(1206, scaled_cell_group, - "scaled_cell %s, %s port functions do not match cell port functions.", + warn(1206, scaled_cell_group, + "scaled_cell {}, {} port functions do not match cell port functions.", scaled_cell->name(), op_cond_name); } else - libWarn(1207, scaled_cell_group, "scaled_cell ports do not match cell ports."); + warn(1207, scaled_cell_group, "scaled_cell ports do not match cell ports."); if (!equivCellTimingArcSets(scaled_cell, owner)) - libWarn(1208, scaled_cell_group, - "scaled_cell %s, %s timing does not match cell timing.", + warn(1208, scaled_cell_group, + "scaled_cell {}, {} timing does not match cell timing.", scaled_cell->name(), op_cond_name); } @@ -1112,7 +1112,7 @@ LibertyReader::makeBusPort(LibertyCell *cell, if (bus_dcl == nullptr) bus_dcl = library_->findBusDcl(bus_type->c_str()); if (bus_dcl) { - debugPrint(debug_, "liberty", 1, " bus %s", port_name.c_str()); + debugPrint(debug_, "liberty", 1, " bus {}", port_name); LibertyPort *bus_port = makeBusPort(cell, port_name.c_str(), bus_dcl->from(), bus_dcl->to(), bus_dcl); @@ -1121,11 +1121,11 @@ LibertyReader::makeBusPort(LibertyCell *cell, makeBusPinPorts(cell, bus_group, port_group_map); } else - libWarn(1235, bus_type_attr, "bus_type %s not found.", bus_type->c_str()); + warn(1235, bus_type_attr, "bus_type {} not found.", *bus_type); } } else - libWarn(1236, bus_type_attr, "bus_type not found."); + warn(1236, bus_type_attr, "bus_type not found."); } } @@ -1138,7 +1138,7 @@ LibertyReader::makeBusPinPorts(LibertyCell *cell, for (const LibertyAttrValue *param : pin_group->params()) { if (param->isString()) { const std::string pin_name = param->stringValue(); - debugPrint(debug_, "liberty", 1, " bus pin port %s", pin_name.c_str()); + debugPrint(debug_, "liberty", 1, " bus pin port {}", pin_name); // Expand foo[3:0] port names. PortNameBitIterator name_iter(cell, pin_name.c_str(), this, pin_group->line()); while (name_iter.hasNext()) { @@ -1147,11 +1147,11 @@ LibertyReader::makeBusPinPorts(LibertyCell *cell, port_group_map[pin_group].push_back(pin_port); } else - libWarn(1232, pin_group, "pin %s not found.", pin_name.c_str()); + warn(1232, pin_group, "pin {} not found.", pin_name); } } else - libWarn(1233, pin_group, "pin name is not a string."); + warn(1233, pin_group, "pin name is not a string."); } } } @@ -1162,7 +1162,7 @@ LibertyReader::makeBundlePort(LibertyCell *cell, LibertyPortGroupMap &port_group_map) { const std::string &bundle_name = bundle_group->firstName(); - debugPrint(debug_, "liberty", 1, " bundle %s", bundle_name.c_str()); + debugPrint(debug_, "liberty", 1, " bundle {}", bundle_name); const LibertyComplexAttr *member_attr = bundle_group->findComplexAttr("members"); ConcretePortSeq *members = new ConcretePortSeq; @@ -1191,14 +1191,14 @@ LibertyReader::makeBundlePinPorts(LibertyCell *cell, for (LibertyAttrValue *param : pin_group->params()) { if (param->isString()) { const std::string pin_name = param->stringValue(); - debugPrint(debug_, "liberty", 1, " bundle pin port %s", pin_name.c_str()); + debugPrint(debug_, "liberty", 1, " bundle pin port {}", pin_name); LibertyPort *pin_port = cell->findLibertyPort(pin_name.c_str()); if (pin_port == nullptr) pin_port = makePort(cell, pin_name.c_str()); port_group_map[pin_group].push_back(pin_port); } else - libWarn(1234, pin_group, "pin name is not a string."); + warn(1234, pin_group, "pin name is not a string."); } } } @@ -1226,7 +1226,7 @@ LibertyReader::makePgPinPort(LibertyCell *cell, dir = PortDirection::power(); break; case PwrGndType::none: - libError(1291, pg_pin_group, "unknown pg_type."); + error(1291, pg_pin_group, "unknown pg_type."); break; default: break; @@ -1349,10 +1349,10 @@ LibertyReader::readPortAttrBool(const char *attr_name, (port->*set_func)(false); } else - libWarn(1238, attr, "%s attribute is not boolean.", attr_name); + warn(1238, attr, "{} attribute is not boolean.", attr_name); } else - libWarn(1239, attr, "%s attribute is not boolean.", attr_name); + warn(1239, attr, "{} attribute is not boolean.", attr_name); } } @@ -1399,7 +1399,7 @@ LibertyReader::readPulseClock(const LibertyPortSeq &ports, sense = RiseFall::fall(); } else - libWarn(1242, port_group, "pulse_latch unknown pulse type."); + warn(1242, port_group, "pulse_latch unknown pulse type."); if (trigger) { for (LibertyPort *port : ports) port->setPulseClk(trigger, sense); @@ -1437,7 +1437,7 @@ LibertyReader::readSignalType(LibertyCell *cell, else if (*type == "test_scan_out_inverted") signal_type = ScanSignalType::output_inverted; else { - libWarn(1299, port_group, "unknown signal_type %s.", type->c_str()); + warn(1299, port_group, "unknown signal_type {}.", *type); return; } for (LibertyPort *port : ports) @@ -1464,7 +1464,7 @@ LibertyReader::readPortDir(const LibertyPortSeq &ports, else if (*dir == "internal") port_dir = PortDirection::internal(); else - libWarn(1240, dir_attr, "unknown port direction."); + warn(1240, dir_attr, "unknown port direction."); for (LibertyPort *port : ports) port->setDirection(port_dir); } @@ -1522,7 +1522,7 @@ LibertyReader::readCapacitance(const LibertyPortSeq &ports, port_group->findAttrFloat(attr_name, limit, exists); if (exists) { if (min_max == MinMax::max() && limit == 0.0) - libWarn(1241, port_group, "max_transition is 0.0."); + warn(1241, port_group, "max_transition is 0.0."); port->setSlewLimit(limit * time_scale_, min_max); } } @@ -1604,8 +1604,8 @@ LibertyReader::makePortFuncs(LibertyCell *cell, for (LibertyPort *port : ports) { port->setFunction(func_expr); if (func_expr->checkSize(port)) { - libWarn(1195, func_attr->line(), - "port %s function size does not match port size.", + warn(1195, func_attr->line(), + "port {} function size does not match port size.", port->name()); } } @@ -1694,8 +1694,8 @@ LibertyReader::makeSeqFunc(LibertyCell *cell, if (attr) { expr = parseFunc(attr->c_str(), attr_name, cell, seq_group->line()); if (expr && expr->checkSize(size)) { - libWarn(1196, seq_group, "%s %s bus width mismatch.", - seq_group->type().c_str(), attr_name); + warn(1196, seq_group, "{} {} bus width mismatch.", + seq_group->type(), attr_name); delete expr; expr = nullptr; } @@ -1832,8 +1832,7 @@ LibertyReader::readScaleFactors(LibertyCell *cell, if (scale_factors) cell->setScaleFactors(scale_factors); else - libWarn(1230, cell_group, "scaling_factors %s not found.", - scale_factors_name->c_str()); + warn(1230, cell_group, "scaling_factors {} not found.", *scale_factors_name); } } @@ -1878,10 +1877,10 @@ LibertyReader::readCellAttrBool(const char *attr_name, else if (stringEqual(value.c_str(), "false")) (cell->*set_func)(false); else - libWarn(1279, attr, "%s attribute is not boolean.", attr_name); + warn(1279, attr, "{} attribute is not boolean.", attr_name); } else - libWarn(1280, attr, "%s attribute is not boolean.", attr_name); + warn(1280, attr, "{} attribute is not boolean.", attr_name); } } @@ -1906,18 +1905,18 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, for (LibertyPort *to_port : ports) { if (timing_type == TimingType::combinational && to_port->direction()->isInput()) - libWarn(1209, timing_group, "combinational timing to an input port."); + warn(1209, timing_group, "combinational timing to an input port."); if (related_port_names.size() || related_bus_names.size()) { for (const std::string &from_port_name : related_port_names) { - debugPrint(debug_, "liberty", 2, " timing %s -> %s", - from_port_name.c_str(), to_port->name()); + debugPrint(debug_, "liberty", 2, " timing {} -> {}", + from_port_name, to_port->name()); makeTimingArcs(cell, from_port_name, to_port, related_output_port, true, timing_attrs, timing_group->line()); } for (const std::string &from_port_name : related_bus_names) { - debugPrint(debug_, "liberty", 2, " timing %s -> %s", - from_port_name.c_str(), to_port->name()); + debugPrint(debug_, "liberty", 2, " timing {} -> {}", + from_port_name, to_port->name()); makeTimingArcs(cell, from_port_name, to_port, related_output_port, false, timing_attrs, timing_group->line()); } @@ -1926,7 +1925,7 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, || timing_type == TimingType::minimum_period || timing_type == TimingType::min_clock_tree_path || timing_type == TimingType::max_clock_tree_path)) - libWarn(1243, timing_group, "timing group missing related_pin/related_bus_pin."); + warn(1243, timing_group, "timing group missing related_pin/related_bus_pin."); else makeTimingArcs(cell, to_port, related_output_port, timing_attrs, timing_group->line()); @@ -1975,7 +1974,7 @@ LibertyReader::readTimingSense(const LibertyGroup *timing_group, else if (*sense_name == "negative_unate") timing_attrs->setTimingSense(TimingSense::negative_unate); else - libWarn(1245, timing_group, "unknown timing_sense %s.", sense_name->c_str()); + warn(1245, timing_group, "unknown timing_sense {}.", *sense_name); } } } @@ -1991,7 +1990,7 @@ LibertyReader::readTimingType(const LibertyGroup *timing_group, if (type_name) { type = findTimingType(type_name->c_str()); if (type == TimingType::unknown) { - libWarn(1244, type_attr, "unknown timing_type %s.", type_name->c_str()); + warn(1244, type_attr, "unknown timing_type {}.", *type_name); type = TimingType::combinational; } } @@ -2046,16 +2045,16 @@ LibertyReader::readTimingMode(const LibertyGroup *timing_group, if (value->isString()) timing_attrs->setModeName(value->stringValue()); else - libWarn(1248, mode_attr, "mode name is not a string."); + warn(1248, mode_attr, "mode name is not a string."); value = mode_values[1]; if (value->isString()) timing_attrs->setModeValue(value->stringValue()); else - libWarn(1246, mode_attr, "mode value is not a string."); + warn(1246, mode_attr, "mode value is not a string."); } else - libWarn(1249, mode_attr, "mode requirees 2 values."); + warn(1249, mode_attr, "mode requirees 2 values."); } } @@ -2161,9 +2160,9 @@ LibertyReader::makeTableModels(LibertyCell *cell, TimingType timing_type = timing_attrs->timingType(); if (isGateTimingType(timing_type)) { if (slew_model == nullptr) - libWarn(1210, timing_group, "missing %s_transition.", rf->name()); + warn(1210, timing_group, "missing {}_transition.", rf->name()); if (delay_model == nullptr) - libWarn(1211, timing_group, "missing cell_%s.", rf->name()); + warn(1211, timing_group, "missing cell_{}.", rf->name()); } found_model = true; } @@ -2189,7 +2188,7 @@ LibertyReader::makeTableModels(LibertyCell *cell, } } if (!found_model) - libWarn(1311, timing_group, "no table models found in timing group."); + warn(1311, timing_group, "no table models found in timing group."); } bool @@ -2343,7 +2342,7 @@ LibertyReader::readReceiverCapacitance(const LibertyGroup *timing_group, receiver_model->setCapacitanceModel(std::move(*model), index, rf); } else - libWarn(1219, cap_group, "unsupported model axis."); + warn(1219, cap_group, "unsupported model axis."); delete model; } } @@ -2390,13 +2389,13 @@ LibertyReader::readOutputWaveforms(const LibertyGroup *timing_group, output_currents.emplace_back(slew, cap, table1, ref_time); } else - libWarn(1223, vector_group, + warn(1223, vector_group, "vector index_1 and index_2 must have exactly one value."); } delete table; } else - libWarn(1224, vector_group, "vector reference_time not found."); + warn(1224, vector_group, "vector reference_time not found."); } if (!output_currents.empty()) return makeOutputWaveforms(current_group, output_currents, rf); @@ -2448,7 +2447,7 @@ LibertyReader::makeOutputWaveforms(const LibertyGroup *current_group, ref_times[slew_index] = waveform.referenceTime(); } else - libWarn(1221, current_group, "output current waveform %.2e %.2e not found.", + warn(1221, current_group, "output current waveform {:.2e} {:.2e} not found.", waveform.slew(), waveform.cap()); } @@ -2477,13 +2476,13 @@ LibertyReader::readTableModel(const LibertyGroup *table_group, TableModel *table_model = new TableModel(table, tbl_template, scale_factor_type, rf); if (!check_axes(table_model)) { - libWarn(1251, table_group, "unsupported model axis."); + warn(1251, table_group, "unsupported model axis."); } return table_model; } } else - libWarn(1253, table_group, "table template %s not found.", template_name); + warn(1253, table_group, "table template {} not found.", template_name); } return nullptr; } @@ -2522,7 +2521,7 @@ LibertyReader::readTableModel(const LibertyGroup *table_group, } } else - libWarn(1257, table_group, "%s is missing values.", table_group->type().c_str()); + warn(1257, table_group, "{} is missing values.", table_group->type()); return nullptr; } @@ -2535,14 +2534,14 @@ LibertyReader::makeTableAxis(const LibertyGroup *table_group, if (index_attr) { FloatSeq axis_values = readFloatSeq(index_attr, 1.0F); if (axis_values.empty()) - libWarn(1177, index_attr, "missing table index values."); + warn(1177, index_attr, "missing table index values."); else { // Check monotonicity of the values. float prev = axis_values[0]; for (size_t i = 1; i < axis_values.size(); i++) { float value = axis_values[i]; if (value <= prev) - libWarn(1173, index_attr, "non-increasing table index values."); + warn(1173, index_attr, "non-increasing table index values."); prev = value; } @@ -2573,7 +2572,7 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, if (from_port_iter.hasNext()) { LibertyPort *from_port = from_port_iter.next(); if (from_port->direction()->isOutput()) - libWarn(1212, timing_line, "timing group from output port."); + warn(1212, timing_line, "timing group from output port."); builder_.makeTimingArcs(cell, from_port, to_port, related_out_port, timing_attrs, timing_line); } @@ -2583,7 +2582,7 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, while (from_port_iter.hasNext()) { LibertyPort *from_port = from_port_iter.next(); if (from_port->direction()->isOutput()) - libWarn(1213, timing_line, "timing group from output port."); + warn(1213, timing_line, "timing group from output port."); builder_.makeTimingArcs(cell, from_port, to_port, related_out_port, timing_attrs, timing_line); } @@ -2593,7 +2592,7 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, if (from_port_iter.hasNext()) { LibertyPort *from_port = from_port_iter.next(); if (from_port->direction()->isOutput()) - libWarn(1214, timing_line, "timing group from output port."); + warn(1214, timing_line, "timing group from output port."); LibertyPortMemberIterator bit_iter(to_port); while (bit_iter.hasNext()) { LibertyPort *to_port_bit = bit_iter.next(); @@ -2610,8 +2609,8 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, LibertyPortMemberIterator to_port_iter(to_port); // warn about different sizes if (from_size != to_size) - libWarn(1216, timing_line, - "timing port %s and related port %s are different sizes.", + warn(1216, timing_line, + "timing port {} and related port {} are different sizes.", from_port_name.c_str(), to_port->name()); // align to/from iterators for one-to-one mapping @@ -2628,7 +2627,7 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, LibertyPort *from_port_bit = from_port_iter.next(); LibertyPort *to_port_bit = to_port_iter.next(); if (from_port_bit->direction()->isOutput()) - libWarn(1215, timing_line, "timing group from output port."); + warn(1215, timing_line, "timing group from output port."); builder_.makeTimingArcs(cell, from_port_bit, to_port_bit, related_out_port, timing_attrs, timing_line); @@ -2688,7 +2687,7 @@ LibertyReader::readLeagageGrouops(LibertyCell *cell, cell->makeLeakagePower(related_pg_port, when, power * power_scale_); } else - libWarn(1307, leak_group, "leakage_power missing value."); + warn(1307, leak_group, "leakage_power missing value."); } } @@ -2769,7 +2768,7 @@ LibertyReader::findLibertyPort(LibertyCell *cell, if (port) return port; else - libWarn(1290, attr, "port %s not found.", port_name->c_str()); + warn(1290, attr, "port {} not found.", *port_name); } } return nullptr; @@ -2801,7 +2800,7 @@ LibertyReader::findLibertyPorts(LibertyCell *cell, if (port) ports.push_back(port); else - libWarn(1306, group, "port %s not found.", port_name.c_str()); + warn(1306, group, "port {} not found.", port_name); } return ports; } @@ -2837,12 +2836,12 @@ LibertyReader::checkLatchEnableSense(FuncExpr *enable_func, case TimingSense::negative_unate: break; case TimingSense::non_unate: - libWarn(1200, line, "latch enable function is non-unate for port %s.", + warn(1200, line, "latch enable function is non-unate for port {}.", enable_port->name()); break; case TimingSense::none: case TimingSense::unknown: - libWarn(1201, line, "latch enable function is unknown for port %s.", + warn(1201, line, "latch enable function is unknown for port {}.", enable_port->name()); break; } @@ -2861,19 +2860,19 @@ LibertyReader::readNormalizedDriverWaveform(const LibertyGroup *library_group) TableTemplate *tbl_template = library_->findTableTemplate(template_name, TableTemplateType::delay); if (!tbl_template) { - libWarn(1256, waveform_group, "table template %s not found.", template_name); + warn(1256, waveform_group, "table template {} not found.", template_name); continue; } TablePtr table = readTableModel(waveform_group, tbl_template, time_scale_); if (!table) continue; if (table->axis1()->variable() != TableAxisVariable::input_net_transition) { - libWarn(1265, waveform_group, + warn(1265, waveform_group, "normalized_driver_waveform variable_1 must be input_net_transition"); continue; } if (table->axis2()->variable() != TableAxisVariable::normalized_voltage) { - libWarn(1225, waveform_group, + warn(1225, waveform_group, "normalized_driver_waveform variable_2 must be normalized_voltage"); continue; } @@ -2884,7 +2883,7 @@ LibertyReader::readNormalizedDriverWaveform(const LibertyGroup *library_group) library_->makeDriverWaveform(driver_waveform_name, table); } else - libWarn(1227, waveform_group, "normalized_driver_waveform missing template."); + warn(1227, waveform_group, "normalized_driver_waveform missing template."); } } @@ -2903,7 +2902,7 @@ LibertyReader::readLevelShifterType(LibertyCell *cell, else if (*level_shifter_type == "HL_LH") cell->setLevelShifterType(LevelShifterType::HL_LH); else - libWarn(1228, cell_group, "level_shifter_type must be HL, LH, or HL_LH"); + warn(1228, cell_group, "level_shifter_type must be HL, LH, or HL_LH"); } } @@ -2918,7 +2917,7 @@ LibertyReader::readSwitchCellType(LibertyCell *cell, else if (*switch_cell_type == "fine_grain") cell->setSwitchCellType(SwitchCellType::fine_grain); else - libWarn(1229, cell_group, "switch_cell_type must be coarse_grain or fine_grain"); + warn(1229, cell_group, "switch_cell_type must be coarse_grain or fine_grain"); } } @@ -2934,8 +2933,8 @@ LibertyReader::readCellOcvDerateGroup(LibertyCell *cell, if (derate) cell->setOcvDerate(derate); else - libWarn(1237, cell_group, "OCV derate group named %s not found.", - derate_name->c_str()); + warn(1237, cell_group, "OCV derate group named {} not found.", + *derate_name); } } @@ -2964,25 +2963,25 @@ LibertyReader::readStatetable(LibertyCell *cell, for (const std::string &row : table_rows) { const StringSeq row_groups = parseTokens(row, ':'); if (row_groups.size() != 3) { - libWarn(1300, table_attr, "table row must have 3 groups separated by ':'."); + warn(1300, table_attr, "table row must have 3 groups separated by ':'."); break; } StringSeq inputs = parseTokens(row_groups[0], ' '); if (inputs.size() != input_count) { - libWarn(1301,table_attr,"table row has %zu input values but %zu are required.", + warn(1301, table_attr, "table row has {} input values but {} are required.", inputs.size(), input_count); break; } StringSeq currents = parseTokens(row_groups[1], ' '); if (currents.size() != internal_count) { - libWarn(1302,table_attr, - "table row has %zu current values but %zu are required.", + warn(1302,table_attr, + "table row has {} current values but {} are required.", currents.size(), internal_count); break; } StringSeq nexts = parseTokens(row_groups[2], ' '); if (nexts.size() != internal_count) { - libWarn(1303, table_attr, "table row has %zu next values but %zu are required.", + warn(1303, table_attr, "table row has {} next values but {} are required.", nexts.size(), internal_count); break; } @@ -3002,8 +3001,8 @@ LibertyReader::readStatetable(LibertyCell *cell, if (port) input_port_ptrs.push_back(port); else - libWarn(1298, statetable_group, "statetable input port %s not found.", - input.c_str()); + warn(1298, statetable_group, "statetable input port {} not found.", + input); } LibertyPortSeq internal_port_ptrs; for (const std::string &internal : internal_ports) { @@ -3024,7 +3023,7 @@ LibertyReader::readTestCell(LibertyCell *cell, const LibertyGroup *test_cell_group = cell_group->findSubgroup("test_cell"); if (test_cell_group) { if (cell->testCell()) - libWarn(1262, test_cell_group, "cell %s test_cell redefinition.", cell->name()); + warn(1262, test_cell_group, "cell {} test_cell redefinition.", cell->name()); else { std::string test_cell_name = std::string(cell->name()) + "/test_cell"; TestCell *test_cell = new TestCell(cell->libertyLibrary(), @@ -3131,8 +3130,8 @@ LibertyReader::parseStateInputValues(StringSeq &inputs, StateInputValue value; state_input_value_name_map.find(input.c_str(), value, exists); if (!exists) { - libWarn(1304, attr, "table input value '%s' not recognized.", - input.c_str()); + warn(1304, attr, "table input value '{}' not recognized.", + input); value = StateInputValue::dont_care; } input_values.push_back(value); @@ -3150,8 +3149,8 @@ LibertyReader::parseStateInternalValues(StringSeq &states, StateInternalValue value; state_internal_value_name_map.find(state.c_str(), value, exists); if (!exists) { - libWarn(1305, attr, "table internal value '%s' not recognized.", - state.c_str()); + warn(1305, attr, "table internal value '{}' not recognized.", + state); value = StateInternalValue::unknown; } state_values.push_back(value); @@ -3178,11 +3177,11 @@ LibertyReader::makeFloatTable(const LibertyComplexAttr *values_attr, else if (value->isFloat()) row.push_back(value->floatValue() * scale); else - libWarn(1258, values_attr, "%s is not a list of floats.", - values_attr->name().c_str()); + warn(1258, values_attr, "{} is not a list of floats.", + values_attr->name()); if (row.size() != cols) { - libWarn(1259, values_attr, "%s row has %zu columns but axis has %zu.", - table_group->type().c_str(), + warn(1259, values_attr, "{} row has {} columns but axis has {}.", + table_group->type(), row.size(), cols); for (size_t c = row.size(); c < cols; c++) @@ -3192,11 +3191,11 @@ LibertyReader::makeFloatTable(const LibertyComplexAttr *values_attr, } if (table.size() != rows) { if (rows == 0) - libWarn(1260, values_attr, "%s missing axis values.", - table_group->type().c_str()); + warn(1260, values_attr, "{} missing axis values.", + table_group->type()); else - libWarn(1261, values_attr, "%s has %zu rows but axis has %zu.", - table_group->type().c_str(), + warn(1261, values_attr, "{} has {} rows but axis has {}.", + table_group->type(), table.size(), rows); for (size_t r = table.size(); r < rows; r++) { @@ -3224,7 +3223,7 @@ LibertyReader::getAttrInt(const LibertySimpleAttr *attr, exists = true; } else - libWarn(1268, attr, "%s attribute is not an integer.",attr->name().c_str()); + warn(1268, attr, "{} attribute is not an integer.", attr->name()); } // Get two floats in a complex attribute. @@ -3242,15 +3241,15 @@ LibertyReader::getAttrFloat2(const LibertyComplexAttr *attr, LibertyAttrValue *value = values[0]; getAttrFloat(attr, value, value1, exists); if (!exists) - libWarn(1272, attr, "%s is not a float.", attr->name().c_str()); + warn(1272, attr, "{} is not a float.", attr->name()); value = values[1]; getAttrFloat(attr, value, value2, exists); if (!exists) - libWarn(1273, attr, "%s is not a float.", attr->name().c_str()); + warn(1273, attr, "{} is not a float.", attr->name()); } else - libWarn(1274, attr, "%s requires 2 valules.", attr->name().c_str()); + warn(1274, attr, "{} requires 2 valules.", attr->name()); } void @@ -3272,9 +3271,9 @@ LibertyReader::getAttrFloat(const LibertyComplexAttr *attr, value = strtof(str.c_str(), &end); if ((*end && !isspace(*end)) || str == "inf") - libWarn(1183, attr->line(), "%s value %s is not a float.", - attr->name().c_str(), - str.c_str()); + warn(1183, attr->line(), "{} value {} is not a float.", + attr->name(), + str); valid = true; } } @@ -3308,7 +3307,7 @@ LibertyReader::parseStringFloatList(const std::string &float_list, for (const char *t = token; t <= end; t++) token_end += *t; } - libWarn(1310, attr, "%s is not a float.", token_end.c_str()); + warn(1310, attr, "{} is not a float.", token_end); token += token_end.size(); } else { @@ -3345,7 +3344,7 @@ LibertyReader::parseStringFloatList(const std::string &float_list, for (const char *t = token; t <= end; t++) token_end += *t; } - libWarn(1275, attr, "%s is not a float.", token_end.c_str()); + warn(1275, attr, "{} is not a float.", token_end); token += token_end.size(); } else { @@ -3373,7 +3372,7 @@ LibertyReader::readFloatSeq(const LibertyComplexAttr *attr, values.push_back(value->floatValue() * scale); } else - libWarn(1276, attr, "%s is missing values.", attr->name().c_str()); + warn(1276, attr, "{} is missing values.", attr->name()); } else if (attr_values.size() > 1) { for (LibertyAttrValue *val : attr_values) { @@ -3386,7 +3385,7 @@ LibertyReader::readFloatSeq(const LibertyComplexAttr *attr, } } else - libWarn(1277, attr, "%s has no values.", attr->name().c_str()); + warn(1277, attr, "{} has no values.", attr->name()); return values; } @@ -3411,10 +3410,10 @@ LibertyReader::getAttrBool(const LibertySimpleAttr *attr, exists = true; } else - libWarn(1288, attr, "%s attribute is not boolean.", attr->name().c_str()); + warn(1288, attr, "{} attribute is not boolean.", attr->name()); } else - libWarn(1289, attr, "%s attribute is not boolean.", attr->name().c_str()); + warn(1289, attr, "{} attribute is not boolean.", attr->name()); } // Read L/H/X string attribute values as bool. @@ -3430,8 +3429,8 @@ LibertyReader::getAttrLogicValue(const LibertySimpleAttr *attr) else if (*str == "X") return LogicValue::unknown; else - libWarn(1282, attr, "attribute %s value %s not recognized.", - attr->name().c_str(), str->c_str()); + warn(1282, attr, "attribute {} value {} not recognized.", + attr->name(), *str); // fall thru } return LogicValue::unknown; @@ -3448,7 +3447,7 @@ LibertyReader::getAttrEarlyLate(const LibertySimpleAttr *attr) else if (*value == "early_and_late") return EarlyLateAll::all(); else { - libWarn(1283, attr, "unknown early/late value."); + warn(1283, attr, "unknown early/late value."); return EarlyLateAll::all(); } } @@ -3461,11 +3460,10 @@ LibertyReader::parseFunc(const char *func, const LibertyCell *cell, int line) { - std::string error_msg; - stringPrint(error_msg, "%s, line %d %s", - filename_, - line, - attr_name); + std::string error_msg = format("{}, line {}{}", + filename_, + line, + attr_name); return parseFuncExpr(func, cell, error_msg.c_str(), report_); } @@ -3491,92 +3489,6 @@ LibertyReader::variableValue(const char *var, //////////////////////////////////////////////////////////////// -void -LibertyReader::libWarn(int id, - const LibertyGroup *group, - const char *fmt, - ...) const -{ - va_list args; - va_start(args, fmt); - report_->vfileWarn(id, filename_, group->line(), fmt, args); - va_end(args); -} - -void -LibertyReader::libWarn(int id, - const LibertySimpleAttr *attr, - const char *fmt, - ...) const -{ - va_list args; - va_start(args, fmt); - report_->vfileWarn(id, filename_, attr->line(), fmt, args); - va_end(args); -} - -void -LibertyReader::libWarn(int id, - const LibertyComplexAttr *attr, - const char *fmt, - ...) const -{ - va_list args; - va_start(args, fmt); - report_->vfileWarn(id, filename_, attr->line(), fmt, args); - va_end(args); -} - -void -LibertyReader::libWarn(int id, - int line, - const char *fmt, - ...) const -{ - va_list args; - va_start(args, fmt); - report_->vfileWarn(id, filename_, line, fmt, args); - va_end(args); -} - -void -LibertyReader::libError(int id, - const LibertyGroup *group, - const char *fmt, - ...) const -{ - va_list args; - va_start(args, fmt); - report_->vfileError(id, filename_, group->line(), fmt, args); - va_end(args); -} - -void -LibertyReader::libError(int id, - const LibertySimpleAttr *attr, - const char *fmt, - ...) const -{ - va_list args; - va_start(args, fmt); - report_->vfileError(id, filename_, attr->line(), fmt, args); - va_end(args); -} - -void -LibertyReader::libError(int id, - const LibertyComplexAttr *attr, - const char *fmt, - ...) const -{ - va_list args; - va_start(args, fmt); - report_->vfileError(id, filename_, attr->line(), fmt, args); - va_end(args); -} - -//////////////////////////////////////////////////////////////// - void LibertyReader::readDefaultOcvDerateGroup(const LibertyGroup *library_group) { @@ -3587,8 +3499,8 @@ LibertyReader::readDefaultOcvDerateGroup(const LibertyGroup *library_group) if (derate) library_->setDefaultOcvDerate(derate); else - libWarn(1284, library_group, "OCV derate group named %s not found.", - derate_name->c_str()); + warn(1284, library_group, "OCV derate group named {} not found.", + *derate_name); } } @@ -3616,7 +3528,7 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, else if (*rf_attr == "rise_and_fall") rf_type = RiseFallBoth::riseFall(); else - libError(1286, factors_group, "unknown rise/fall."); + error(1286, factors_group, "unknown rise/fall."); } const EarlyLateAll *derate_type = EarlyLateAll::all(); @@ -3629,7 +3541,7 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, else if (*derate_attr == "early_and_late") derate_type = EarlyLateAll::all(); else { - libWarn(1309, factors_group, "unknown early/late value."); + warn(1309, factors_group, "unknown early/late value."); } } @@ -3643,7 +3555,7 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, else if (*path_attr == "clock_and_data") path_type = PathType::clk_and_data; else - libWarn(1287, factors_group, "unknown derate type."); + warn(1287, factors_group, "unknown derate type."); } const char *template_name = factors_group->firstName(); @@ -3666,12 +3578,12 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, } } else - libWarn(1308, factors_group, "table template %s not found.", template_name); + warn(1308, factors_group, "table template {} not found.", template_name); } } } else - libWarn(1285, ocv_derate_group, "ocv_derate missing name."); + warn(1285, ocv_derate_group, "ocv_derate missing name."); } } @@ -3725,13 +3637,13 @@ PortNameBitIterator::init(const char *port_name) range_bit_ = from; } else - visitor_->libWarn(1292, line_, "port %s subscript out of range.", + visitor_->warn(1292, line_, "port {} subscript out of range.", port_name); } else - visitor_->libWarn(1293, line_, "port range %s of non-bus port %s.", + visitor_->warn(1293, line_, "port range {} of non-bus port {}.", port_name, - bus_name.c_str()); + bus_name); } else { range_bus_name_ = bus_name; @@ -3743,7 +3655,7 @@ PortNameBitIterator::init(const char *port_name) size_ = std::abs(from - to) + 1; } else - visitor_->libWarn(1294, line_, "port %s not found.", port_name); + visitor_->warn(1294, line_, "port {} not found.", port_name); } } @@ -3809,7 +3721,7 @@ PortNameBitIterator::findRangeBusNameNext() range_bit_++; } else - visitor_->libWarn(1295, line_, "port %s not found.", bus_bit_name.c_str()); + visitor_->warn(1295, line_, "port {} not found.", bus_bit_name); } else range_name_next_ = nullptr; diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index 070b28e7..e1307b7d 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ #include "LibertyParser.hh" #include "LibertyReader.hh" #include "LibertyBuilder.hh" +#include "Report.hh" namespace sta { @@ -451,38 +453,65 @@ protected: const char *attr_name, const LibertyCell *cell, int line); - void libWarn(int id, + template + void warn(int id, const LibertyGroup *group, - const char *fmt, - ...) const - __attribute__((format (printf, 4, 5))); - void libWarn(int id, + std::string_view fmt, + Args &&...args) const + { + report_->fileWarn(id, filename_, group->line(), fmt, std::forward(args)...); + } + template + void warn(int id, const LibertySimpleAttr *attr, - const char *fmt, - ...) const - __attribute__((format (printf, 4, 5))); - void libWarn(int id, + std::string_view fmt, + Args &&...args) const + { + report_->fileWarn(id, filename_, attr->line(), fmt, std::forward(args)...); + } + template + void warn(int id, const LibertyComplexAttr *attr, - const char *fmt, - ...) const - __attribute__((format (printf, 4, 5))); - void libWarn(int id, + std::string_view fmt, + Args &&...args) const + { + report_->fileWarn(id, filename_, attr->line(), fmt, std::forward(args)...); + } + template + void warn(int id, int line, - const char *fmt, - ...) const - __attribute__((format (printf, 4, 5))); - void libError(int id, + std::string_view fmt, + Args &&...args) const + { + report_->fileWarn(id, filename_, line, fmt, std::forward(args)...); + } + template + void error(int id, const LibertyGroup *group, - const char *fmt, ...) const - __attribute__((format (printf, 4, 5))); - void libError(int id, + std::string_view fmt, + Args &&...args) const + { + report_->fileError(id, filename_, group->line(), fmt, + std::forward(args)...); + } + template + void error(int id, const LibertySimpleAttr *attr, - const char *fmt, ...) const - __attribute__((format (printf, 4, 5))); - void libError(int id, + std::string_view fmt, + Args &&...args) const + { + report_->fileError(id, filename_, attr->line(), fmt, + std::forward(args)...); + } + template + void error(int id, const LibertyComplexAttr *attr, - const char *fmt, ...) const - __attribute__((format (printf, 4, 5))); + std::string_view fmt, + Args &&...args) const + { + report_->fileError(id, filename_, attr->line(), fmt, + std::forward(args)...); + } const char *filename_; bool infer_latches_; diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index ada26b09..5e22ce6d 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -1,32 +1,34 @@ // 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 "LibertyWriter.hh" #include #include +#include +#include "Format.hh" #include "Units.hh" #include "FuncExpr.hh" #include "PortDirection.hh" @@ -44,7 +46,7 @@ class LibertyWriter public: LibertyWriter(const LibertyLibrary *lib, const char *filename, - FILE *stream, + std::ofstream &stream, Report *report); void writeLibrary(); @@ -80,7 +82,7 @@ protected: const LibertyLibrary *library_; const char *filename_; - FILE *stream_; + std::ofstream &stream_; Report *report_; const Unit *time_unit_; const Unit *cap_unit_; @@ -91,11 +93,10 @@ writeLiberty(LibertyLibrary *lib, const char *filename, StaState *sta) { - FILE *stream = fopen(filename, "w"); - if (stream) { + std::ofstream stream(filename); + if (stream.is_open()) { LibertyWriter writer(lib, filename, stream, sta->report()); writer.writeLibrary(); - fclose(stream); } else throw FileNotWritable(filename); @@ -103,7 +104,7 @@ writeLiberty(LibertyLibrary *lib, LibertyWriter::LibertyWriter(const LibertyLibrary *lib, const char *filename, - FILE *stream, + std::ofstream &stream, Report *report) : library_(lib), filename_(filename), @@ -118,87 +119,87 @@ void LibertyWriter::writeLibrary() { writeHeader(); - fprintf(stream_, "\n"); + sta::print(stream_, "\n"); writeTableTemplates(); writeBusDcls(); - fprintf(stream_, "\n"); + sta::print(stream_, "\n"); writeCells(); writeFooter(); } - + void LibertyWriter::writeHeader() { - fprintf(stream_, "library (%s) {\n", library_->name()); - fprintf(stream_, " comment : \"\";\n"); - fprintf(stream_, " delay_model : table_lookup;\n"); - fprintf(stream_, " simulation : false;\n"); + sta::print(stream_, "library ({}) {{\n", library_->name()); + sta::print(stream_, " comment : \"\";\n"); + sta::print(stream_, " delay_model : table_lookup;\n"); + sta::print(stream_, " simulation : false;\n"); const Unit *cap_unit = library_->units()->capacitanceUnit(); - fprintf(stream_, " capacitive_load_unit (1,%s);\n", - cap_unit->scaleAbbrevSuffix().c_str()); - fprintf(stream_, " leakage_power_unit : 1pW;\n"); + sta::print(stream_, " capacitive_load_unit (1,{});\n", + cap_unit->scaleAbbrevSuffix()); + sta::print(stream_, " leakage_power_unit : 1pW;\n"); const Unit *current_unit = library_->units()->currentUnit(); - fprintf(stream_, " current_unit : \"1%s\";\n", - current_unit->scaleAbbrevSuffix().c_str()); + sta::print(stream_, " current_unit : \"1{}\";\n", + current_unit->scaleAbbrevSuffix()); const Unit *res_unit = library_->units()->resistanceUnit(); - fprintf(stream_, " pulling_resistance_unit : \"1%s\";\n", - res_unit->scaleAbbrevSuffix().c_str()); + sta::print(stream_, " pulling_resistance_unit : \"1{}\";\n", + res_unit->scaleAbbrevSuffix()); const Unit *time_unit = library_->units()->timeUnit(); - fprintf(stream_, " time_unit : \"1%s\";\n", - time_unit->scaleAbbrevSuffix().c_str()); + sta::print(stream_, " time_unit : \"1{}\";\n", + time_unit->scaleAbbrevSuffix()); const Unit *volt_unit = library_->units()->voltageUnit(); - fprintf(stream_, " voltage_unit : \"1%s\";\n", - volt_unit->scaleAbbrevSuffix().c_str()); - fprintf(stream_, " library_features(report_delay_calculation);\n"); - fprintf(stream_, "\n"); + sta::print(stream_, " voltage_unit : \"1{}\";\n", + volt_unit->scaleAbbrevSuffix()); + sta::print(stream_, " library_features(report_delay_calculation);\n"); + sta::print(stream_, "\n"); - fprintf(stream_, " input_threshold_pct_rise : %.0f;\n", - library_->inputThreshold(RiseFall::rise()) * 100); - fprintf(stream_, " input_threshold_pct_fall : %.0f;\n", - library_->inputThreshold(RiseFall::fall()) * 100); - fprintf(stream_, " output_threshold_pct_rise : %.0f;\n", - library_->inputThreshold(RiseFall::rise()) * 100); - fprintf(stream_, " output_threshold_pct_fall : %.0f;\n", - library_->inputThreshold(RiseFall::fall()) * 100); - fprintf(stream_, " slew_lower_threshold_pct_rise : %.0f;\n", - library_->slewLowerThreshold(RiseFall::rise()) * 100); - fprintf(stream_, " slew_lower_threshold_pct_fall : %.0f;\n", - library_->slewLowerThreshold(RiseFall::fall()) * 100); - fprintf(stream_, " slew_upper_threshold_pct_rise : %.0f;\n", - library_->slewUpperThreshold(RiseFall::rise()) * 100); - fprintf(stream_, " slew_upper_threshold_pct_fall : %.0f;\n", - library_->slewUpperThreshold(RiseFall::rise()) * 100); - fprintf(stream_, " slew_derate_from_library : %.1f;\n", - library_->slewDerateFromLibrary()); - fprintf(stream_, "\n"); + sta::print(stream_, " input_threshold_pct_rise : {:.0f};\n", + library_->inputThreshold(RiseFall::rise()) * 100); + sta::print(stream_, " input_threshold_pct_fall : {:.0f};\n", + library_->inputThreshold(RiseFall::fall()) * 100); + sta::print(stream_, " output_threshold_pct_rise : {:.0f};\n", + library_->inputThreshold(RiseFall::rise()) * 100); + sta::print(stream_, " output_threshold_pct_fall : {:.0f};\n", + library_->inputThreshold(RiseFall::fall()) * 100); + sta::print(stream_, " slew_lower_threshold_pct_rise : {:.0f};\n", + library_->slewLowerThreshold(RiseFall::rise()) * 100); + sta::print(stream_, " slew_lower_threshold_pct_fall : {:.0f};\n", + library_->slewLowerThreshold(RiseFall::fall()) * 100); + sta::print(stream_, " slew_upper_threshold_pct_rise : {:.0f};\n", + library_->slewUpperThreshold(RiseFall::rise()) * 100); + sta::print(stream_, " slew_upper_threshold_pct_fall : {:.0f};\n", + library_->slewUpperThreshold(RiseFall::rise()) * 100); + sta::print(stream_, " slew_derate_from_library : {:.1f};\n", + library_->slewDerateFromLibrary()); + sta::print(stream_, "\n"); bool exists; float max_fanout; library_->defaultFanoutLoad(max_fanout, exists); if (exists) - fprintf(stream_, " default_max_fanout : %.0f;\n", max_fanout); + sta::print(stream_, " default_max_fanout : {:.0f};\n", max_fanout); float max_slew; library_->defaultMaxSlew(max_slew, exists); if (exists) - fprintf(stream_, " default_max_transition : %s;\n", - time_unit_->asString(max_slew, 3)); + sta::print(stream_, " default_max_transition : {};\n", + time_unit_->asString(max_slew, 3)); float max_cap; library_->defaultMaxCapacitance(max_cap, exists); if (exists) - fprintf(stream_, " default_max_capacitance : %s;\n", - cap_unit_->asString(max_cap, 3)); + sta::print(stream_, " default_max_capacitance : {};\n", + cap_unit_->asString(max_cap, 3)); float fanout_load; library_->defaultFanoutLoad(fanout_load, exists); if (exists) - fprintf(stream_, " default_fanout_load : %.2f;\n", fanout_load); - fprintf(stream_, "\n"); + sta::print(stream_, " default_fanout_load : {:.2f};\n", fanout_load); + sta::print(stream_, "\n"); - fprintf(stream_, " nom_process : %.1f;\n", - library_->nominalProcess()); - fprintf(stream_, " nom_temperature : %.1f;\n", - library_->nominalTemperature()); - fprintf(stream_, " nom_voltage : %.2f;\n", - library_->nominalVoltage()); + sta::print(stream_, " nom_process : {:.1f};\n", + library_->nominalProcess()); + sta::print(stream_, " nom_temperature : {:.1f};\n", + library_->nominalTemperature()); + sta::print(stream_, " nom_voltage : {:.2f};\n", + library_->nominalVoltage()); } void @@ -216,22 +217,22 @@ LibertyWriter::writeTableTemplate(const TableTemplate *tbl_template) const TableAxis *axis3 = tbl_template->axis3(); // skip scalar templates if (axis1) { - fprintf(stream_, " lu_table_template(%s) {\n", tbl_template->name().c_str()); - fprintf(stream_, " variable_1 : %s;\n", - tableVariableString(axis1->variable())); + sta::print(stream_, " lu_table_template({}) {{\n", tbl_template->name()); + sta::print(stream_, " variable_1 : {};\n", + tableVariableString(axis1->variable())); if (axis2) - fprintf(stream_, " variable_2 : %s;\n", - tableVariableString(axis2->variable())); + sta::print(stream_, " variable_2 : {};\n", + tableVariableString(axis2->variable())); if (axis3) - fprintf(stream_, " variable_3 : %s;\n", - tableVariableString(axis3->variable())); + sta::print(stream_, " variable_3 : {};\n", + tableVariableString(axis3->variable())); if (axis1 && !axis1->values().empty()) writeTableAxis4(axis1, 1); if (axis2 && !axis2->values().empty()) writeTableAxis4(axis2, 2); if (axis3 && !axis3->values().empty()) writeTableAxis4(axis3, 3); - fprintf(stream_, " }\n"); + sta::print(stream_, " }}\n"); } } @@ -240,16 +241,16 @@ void LibertyWriter::writeTableAxis4(const TableAxis *axis, int index) { - fprintf(stream_, " index_%d(\"", index); + sta::print(stream_, " index_{}(\"", index); const Unit *unit = tableVariableUnit(axis->variable(), library_->units()); bool first = true; for (size_t i = 0; i < axis->size(); i++) { if (!first) - fprintf(stream_, ", "); - fprintf(stream_, "%s", unit->asString(axis->axisValue(i), 5)); + sta::print(stream_, ", "); + sta::print(stream_, "{}", unit->asString(axis->axisValue(i), 5)); first = false; } - fprintf(stream_, "\");\n"); + sta::print(stream_, "\");\n"); } // indent 10 @@ -257,7 +258,7 @@ void LibertyWriter::writeTableAxis10(const TableAxis *axis, int index) { - fprintf(stream_, " "); + sta::print(stream_, " "); writeTableAxis4(axis, index); } @@ -266,13 +267,13 @@ LibertyWriter::writeBusDcls() { BusDclSeq dcls = library_->busDcls(); for (BusDcl *dcl : dcls) { - fprintf(stream_, " type (\"%s\") {\n", dcl->name().c_str()); - fprintf(stream_, " base_type : array;\n"); - fprintf(stream_, " data_type : bit;\n"); - fprintf(stream_, " bit_width : %d;\n", std::abs(dcl->from() - dcl->to() + 1)); - fprintf(stream_, " bit_from : %d;\n", dcl->from()); - fprintf(stream_, " bit_to : %d;\n", dcl->to()); - fprintf(stream_, " }\n"); + sta::print(stream_, " type (\"{}\") {{\n", dcl->name()); + sta::print(stream_, " base_type : array;\n"); + sta::print(stream_, " data_type : bit;\n"); + sta::print(stream_, " bit_width : {};\n", std::abs(dcl->from() - dcl->to() + 1)); + sta::print(stream_, " bit_from : {};\n", dcl->from()); + sta::print(stream_, " bit_to : {};\n", dcl->to()); + sta::print(stream_, " }}\n"); } } @@ -289,21 +290,20 @@ LibertyWriter::writeCells() void LibertyWriter::writeCell(const LibertyCell *cell) { - fprintf(stream_, " cell (\"%s\") {\n", cell->name()); + sta::print(stream_, " cell (\"{}\") {{\n", cell->name()); float area = cell->area(); if (area > 0.0) - fprintf(stream_, " area : %.3f \n", area); + sta::print(stream_, " area : {:.3f} \n", area); if (cell->isMacro()) - fprintf(stream_, " is_macro_cell : true;\n"); + sta::print(stream_, " is_macro_cell : true;\n"); if (cell->interfaceTiming()) - fprintf(stream_, " interface_timing : true;\n"); + sta::print(stream_, " interface_timing : true;\n"); const char *footprint = cell->footprint(); if (footprint) - fprintf(stream_, " cell_footprint : \"%s\";\n", footprint); + sta::print(stream_, " cell_footprint : \"{}\";\n", footprint); const char *user_function_class = cell->userFunctionClass(); if (user_function_class) - fprintf(stream_, " user_function_class : \"%s\";\n", - user_function_class); + sta::print(stream_, " user_function_class : \"{}\";\n", user_function_class); LibertyCellPortIterator port_iter(cell); while (port_iter.hasNext()) { @@ -314,24 +314,23 @@ LibertyWriter::writeCell(const LibertyCell *cell) else if (port->isBus()) writeBusPort(port); else if (port->isBundle()) - report_->error(1340, "%s/%s bundled ports not supported.", - library_->name(), + report_->error(1340, "{}/{} bundled ports not supported.", library_->name(), cell->name()); else writePort(port); } } - fprintf(stream_, " }\n"); - fprintf(stream_, "\n"); + sta::print(stream_, " }}\n"); + sta::print(stream_, "\n"); } void LibertyWriter::writeBusPort(const LibertyPort *port) { - fprintf(stream_, " bus(\"%s\") {\n", port->name()); + sta::print(stream_, " bus(\"{}\") {{\n", port->name()); if (port->busDcl()) - fprintf(stream_, " bus_type : %s;\n", port->busDcl()->name().c_str()); + sta::print(stream_, " bus_type : {};\n", port->busDcl()->name()); writePortAttrs(port); LibertyPortMemberIterator member_iter(port); @@ -339,56 +338,53 @@ LibertyWriter::writeBusPort(const LibertyPort *port) LibertyPort *member = member_iter.next(); writePort(member); } - fprintf(stream_, " }\n"); + sta::print(stream_, " }}\n"); } void LibertyWriter::writePort(const LibertyPort *port) { - fprintf(stream_, " pin(\"%s\") {\n", port->name()); + sta::print(stream_, " pin(\"{}\") {{\n", port->name()); writePortAttrs(port); - fprintf(stream_, " }\n"); + sta::print(stream_, " }}\n"); } void LibertyWriter::writePortAttrs(const LibertyPort *port) { - fprintf(stream_, " direction : %s;\n" , asString(port->direction())); + sta::print(stream_, " direction : {};\n", asString(port->direction())); auto func = port->function(); if (func // cannot ref internal ports until sequentials are written - && !(func->port() - && func->port()->direction()->isInternal())) - fprintf(stream_, " function : \"%s\";\n", func->to_string().c_str()); + && !(func->port() && func->port()->direction()->isInternal())) + sta::print(stream_, " function : \"{}\";\n", func->to_string()); auto tristate_enable = port->tristateEnable(); if (tristate_enable) { if (tristate_enable->op() == FuncExpr::Op::not_) { FuncExpr *three_state = tristate_enable->left(); - fprintf(stream_, " three_state : \"%s\";\n", - three_state->to_string().c_str()); + sta::print(stream_, " three_state : \"{}\";\n", + three_state->to_string()); } else { FuncExpr *three_state = tristate_enable->copy()->invert(); - fprintf(stream_, " three_state : \"%s\";\n", - three_state->to_string().c_str()); + sta::print(stream_, " three_state : \"{}\";\n", + three_state->to_string()); delete three_state; } } if (port->isClock()) - fprintf(stream_, " clock : true;\n"); - fprintf(stream_, " capacitance : %s;\n", - cap_unit_->asString(port->capacitance(), 4)); - + sta::print(stream_, " clock : true;\n"); + sta::print(stream_, " capacitance : {};\n", + cap_unit_->asString(port->capacitance(), 4)); + float limit; bool exists; port->slewLimit(MinMax::max(), limit, exists); if (exists) - fprintf(stream_, " max_transition : %s;\n", - time_unit_->asString(limit, 3)); + sta::print(stream_, " max_transition : {};\n", time_unit_->asString(limit, 3)); port->capacitanceLimit(MinMax::max(), limit, exists); if (exists) - fprintf(stream_, " max_capacitance : %s;\n", - cap_unit_->asString(limit, 3)); + sta::print(stream_, " max_capacitance : {};\n", cap_unit_->asString(limit, 3)); for (TimingArcSet *arc_set : port->libertyCell()->timingArcSetsTo(port)) { if (!isAutoWidthArc(port, arc_set)) @@ -399,10 +395,10 @@ LibertyWriter::writePortAttrs(const LibertyPort *port) void LibertyWriter::writePwrGndPort(const LibertyPort *port) { - fprintf(stream_, " pg_pin(\"%s\") {\n", port->name()); - fprintf(stream_, " pg_type : \"%s\";\n", pwrGndTypeName(port->pwrGndType())); - fprintf(stream_, " voltage_name : \"%s\";\n", port->voltageName()); - fprintf(stream_, " }\n"); + sta::print(stream_, " pg_pin(\"{}\") {{\n", port->name()); + sta::print(stream_, " pg_type : \"{}\";\n", pwrGndTypeName(port->pwrGndType())); + sta::print(stream_, " voltage_name : \"{}\";\n", port->voltageName()); + sta::print(stream_, " }}\n"); } // Check if arc is added for port min_pulse_width_high/low attribute. @@ -423,30 +419,27 @@ LibertyWriter::isAutoWidthArc(const LibertyPort *port, void LibertyWriter::writeTimingArcSet(const TimingArcSet *arc_set) { - fprintf(stream_, " timing() {\n"); + sta::print(stream_, " timing() {{\n"); if (arc_set->from()) - fprintf(stream_, " related_pin : \"%s\";\n", arc_set->from()->name()); + sta::print(stream_, " related_pin : \"{}\";\n", arc_set->from()->name()); TimingSense sense = arc_set->sense(); - if (sense != TimingSense::unknown - && sense != TimingSense::non_unate) - fprintf(stream_, " timing_sense : %s;\n", - to_string(sense)); + if (sense != TimingSense::unknown && sense != TimingSense::non_unate) + sta::print(stream_, " timing_sense : {};\n", to_string(sense)); const char *timing_type = timingTypeString(arc_set); if (timing_type) - fprintf(stream_, " timing_type : %s;\n", timing_type); + sta::print(stream_, " timing_type : {};\n", timing_type); for (const RiseFall *rf : RiseFall::range()) { TimingArc *arc = arc_set->arcTo(rf); if (arc) { // Min pulse width arcs are wrt to the leading edge of the pulse. - const RiseFall *model_rf = (arc_set->role() == TimingRole::width()) - ? rf->opposite() - : rf; + const RiseFall *model_rf = + (arc_set->role() == TimingRole::width()) ? rf->opposite() : rf; writeTimingModels(arc, model_rf); } } - fprintf(stream_, " }\n"); + sta::print(stream_, " }}\n"); } void @@ -454,54 +447,53 @@ LibertyWriter::writeTimingModels(const TimingArc *arc, const RiseFall *rf) { TimingModel *model = arc->model(); - const GateTableModel *gate_model = dynamic_cast(model); - const CheckTableModel *check_model = dynamic_cast(model); + const GateTableModel *gate_model = dynamic_cast(model); + const CheckTableModel *check_model = dynamic_cast(model); if (gate_model) { const TableModel *delay_model = gate_model->delayModel(); const std::string &template_name = delay_model->tblTemplate()->name(); - fprintf(stream_, " cell_%s(%s) {\n", rf->name(), template_name.c_str()); + sta::print(stream_, " cell_{}({}) {{\n", rf->name(), template_name); writeTableModel(delay_model); - fprintf(stream_, " }\n"); + sta::print(stream_, " }}\n"); const TableModel *slew_model = gate_model->slewModel(); if (slew_model) { const std::string &slew_template_name = slew_model->tblTemplate()->name(); - fprintf(stream_, " %s_transition(%s) {\n", rf->name(), - slew_template_name.c_str()); + sta::print(stream_, " {}_transition({}) {{\n", rf->name(), + slew_template_name); writeTableModel(slew_model); - fprintf(stream_, " }\n"); + sta::print(stream_, " }}\n"); } } else if (check_model) { const TableModel *model = check_model->checkModel(); const std::string &template_name = model->tblTemplate()->name(); - fprintf(stream_, " %s_constraint(%s) {\n", rf->name(), template_name.c_str()); + sta::print(stream_, " {}_constraint({}) {{\n", rf->name(), + template_name); writeTableModel(model); - fprintf(stream_, " }\n"); + sta::print(stream_, " }}\n"); } else - report_->error(1341, "%s/%s/%s timing model not supported.", - library_->name(), - arc->from()->libertyCell()->name(), - arc->from()->name()); + report_->error(1341, "{}/{}/{} timing model not supported.", library_->name(), + arc->from()->libertyCell()->name(), arc->from()->name()); } void LibertyWriter::writeTableModel(const TableModel *model) { switch (model->order()) { - case 0: - writeTableModel0(model); - break; - case 1: - writeTableModel1(model); - break; - case 2: - writeTableModel2(model); - break; - case 3: - report_->error(1342, "3 axis table models not supported."); - break; + case 0: + writeTableModel0(model); + break; + case 1: + writeTableModel1(model); + break; + case 2: + writeTableModel2(model); + break; + case 3: + report_->error(1342, "3 axis table models not supported."); + break; } } @@ -509,24 +501,23 @@ void LibertyWriter::writeTableModel0(const TableModel *model) { float value = model->value(0, 0, 0); - fprintf(stream_, " values(\"%s\");\n", - time_unit_->asString(value, 5)); + sta::print(stream_, " values(\"{}\");\n", time_unit_->asString(value, 5)); } void LibertyWriter::writeTableModel1(const TableModel *model) { writeTableAxis10(model->axis1(), 1); - fprintf(stream_, " values(\""); + sta::print(stream_, " values(\""); bool first_col = true; for (size_t index1 = 0; index1 < model->axis1()->size(); index1++) { float value = model->value(index1, 0, 0); if (!first_col) - fprintf(stream_, ","); - fprintf(stream_, "%s", time_unit_->asString(value, 5)); + sta::print(stream_, ","); + sta::print(stream_, "{}", time_unit_->asString(value, 5)); first_col = false; } - fprintf(stream_, "\");\n"); + sta::print(stream_, "\");\n"); } void @@ -534,31 +525,31 @@ LibertyWriter::writeTableModel2(const TableModel *model) { writeTableAxis10(model->axis1(), 1); writeTableAxis10(model->axis2(), 2); - fprintf(stream_, " values(\""); + sta::print(stream_, " values(\""); bool first_row = true; for (size_t index1 = 0; index1 < model->axis1()->size(); index1++) { if (!first_row) { - fprintf(stream_, "\\\n"); - fprintf(stream_, " \""); + sta::print(stream_, "\\\n"); + sta::print(stream_, " \""); } bool first_col = true; for (size_t index2 = 0; index2 < model->axis2()->size(); index2++) { float value = model->value(index1, index2, 0); if (!first_col) - fprintf(stream_, ","); - fprintf(stream_, "%s", time_unit_->asString(value, 5)); + sta::print(stream_, ","); + sta::print(stream_, "{}", time_unit_->asString(value, 5)); first_col = false; } - fprintf(stream_, "\""); + sta::print(stream_, "\""); first_row = false; } - fprintf(stream_, ");\n"); + sta::print(stream_, ");\n"); } void LibertyWriter::writeFooter() { - fprintf(stream_, "}\n"); + sta::print(stream_, "}}\n"); } const char * @@ -572,15 +563,13 @@ LibertyWriter::asString(const PortDirection *dir) { if (dir == PortDirection::input()) return "input"; - else if (dir == PortDirection::output() - || (dir == PortDirection::tristate())) + else if (dir == PortDirection::output() || (dir == PortDirection::tristate())) return "output"; else if (dir == PortDirection::internal()) return "internal"; else if (dir == PortDirection::bidirect()) return "inout"; - else if (dir == PortDirection::ground() - || dir == PortDirection::power()) + else if (dir == PortDirection::ground() || dir == PortDirection::power()) return "input"; return "unknown"; } @@ -595,8 +584,7 @@ LibertyWriter::timingTypeString(const TimingArcSet *arc_set) return "three_state_disable"; else if (role == TimingRole::tristateEnable()) return "three_state_enable"; - else if (role == TimingRole::regClkToQ() - || role == TimingRole::latchEnToQ()) { + else if (role == TimingRole::regClkToQ() || role == TimingRole::latchEnToQ()) { const TimingArc *arc = arc_set->arcs()[0]; if (arc->fromEdge()->asRiseFall() == RiseFall::rise()) return "rising_edge"; @@ -612,16 +600,14 @@ LibertyWriter::timingTypeString(const TimingArcSet *arc_set) else return "clear"; } - else if (role == TimingRole::setup() - || role == TimingRole::recovery()) { + else if (role == TimingRole::setup() || role == TimingRole::recovery()) { const TimingArc *arc = arc_set->arcs()[0]; if (arc->fromEdge()->asRiseFall() == RiseFall::rise()) return "setup_rising"; else return "setup_falling"; } - else if (role == TimingRole::hold() - || role == TimingRole::removal()) { + else if (role == TimingRole::hold() || role == TimingRole::removal()) { const TimingArc *arc = arc_set->arcs()[0]; if (arc->fromEdge()->asRiseFall() == RiseFall::rise()) return "hold_rising"; @@ -649,13 +635,11 @@ LibertyWriter::timingTypeString(const TimingArcSet *arc_set) else if (role == TimingRole::width()) return "min_pulse_width"; else { - report_->error(1343, "%s/%s/%s timing arc type %s not supported.", - library_->name(), - arc_set->to()->libertyCell()->name(), - arc_set->to()->name(), - role->to_string().c_str()); + report_->error(1343, "{}/{}/{} timing arc type {} not supported.", + library_->name(), arc_set->to()->libertyCell()->name(), + arc_set->to()->name(), role->to_string()); return nullptr; } } -} // namespace +} // namespace sta diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index a235dcb4..46dd6d6b 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.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 "TableModel.hh" @@ -250,12 +250,12 @@ GateTableModel::reportTableLookup(const char *result_name, { if (model) { float axis_value1, axis_value2, axis_value3; - findAxisValues(model, in_slew, load_cap, related_out_cap, - axis_value1, axis_value2, axis_value3); + findAxisValues(model, in_slew, load_cap, related_out_cap, axis_value1, + axis_value2, axis_value3); const LibertyLibrary *library = cell_->libertyLibrary(); return model->reportValue(result_name, cell_, pvt, axis_value1, nullptr, - axis_value2, axis_value3, - library->units()->timeUnit(), digits); + axis_value2, axis_value3, library->units()->timeUnit(), + digits); } return ""; } @@ -269,8 +269,8 @@ GateTableModel::findValue(const Pvt *pvt, { if (model) { float axis_value1, axis_value2, axis_value3; - findAxisValues(model, in_slew, load_cap, related_out_cap, - axis_value1, axis_value2, axis_value3); + findAxisValues(model, in_slew, load_cap, related_out_cap, axis_value1, + axis_value2, axis_value3); return model->findValue(cell_, pvt, axis_value1, axis_value2, axis_value3); } else @@ -288,37 +288,31 @@ GateTableModel::findAxisValues(const TableModel *model, float &axis_value3) const { switch (model->order()) { - case 0: - axis_value1 = 0.0; - axis_value2 = 0.0; - axis_value3 = 0.0; - break; - case 1: - axis_value1 = axisValue(model->axis1(), in_slew, load_cap, - related_out_cap); - axis_value2 = 0.0; - axis_value3 = 0.0; - break; - case 2: - axis_value1 = axisValue(model->axis1(), in_slew, load_cap, - related_out_cap); - axis_value2 = axisValue(model->axis2(), in_slew, load_cap, - related_out_cap); - axis_value3 = 0.0; - break; - case 3: - axis_value1 = axisValue(model->axis1(), in_slew, load_cap, - related_out_cap); - axis_value2 = axisValue(model->axis2(), in_slew, load_cap, - related_out_cap); - axis_value3 = axisValue(model->axis3(), in_slew, load_cap, - related_out_cap); - break; - default: - axis_value1 = 0.0; - axis_value2 = 0.0; - axis_value3 = 0.0; - criticalError(239, "unsupported table order"); + case 0: + axis_value1 = 0.0; + axis_value2 = 0.0; + axis_value3 = 0.0; + break; + case 1: + axis_value1 = axisValue(model->axis1(), in_slew, load_cap, related_out_cap); + axis_value2 = 0.0; + axis_value3 = 0.0; + break; + case 2: + axis_value1 = axisValue(model->axis1(), in_slew, load_cap, related_out_cap); + axis_value2 = axisValue(model->axis2(), in_slew, load_cap, related_out_cap); + axis_value3 = 0.0; + break; + case 3: + axis_value1 = axisValue(model->axis1(), in_slew, load_cap, related_out_cap); + axis_value2 = axisValue(model->axis2(), in_slew, load_cap, related_out_cap); + axis_value3 = axisValue(model->axis3(), in_slew, load_cap, related_out_cap); + break; + default: + axis_value1 = 0.0; + axis_value2 = 0.0; + axis_value3 = 0.0; + criticalError(239, "unsupported table order"); } } @@ -348,12 +342,12 @@ GateTableModel::maxCapSlew(float in_slew, slew = findValue(pvt, model, in_slew, cap, 0.0); } else if (axis2 - && axis2->variable()==TableAxisVariable::total_output_net_capacitance) { + && axis2->variable() == TableAxisVariable::total_output_net_capacitance) { cap = axis2->axisValue(axis2->size() - 1); slew = findValue(pvt, model, in_slew, cap, 0.0); } else if (axis3 - && axis3->variable()==TableAxisVariable::total_output_net_capacitance) { + && axis3->variable() == TableAxisVariable::total_output_net_capacitance) { cap = axis3->axisValue(axis3->size() - 1); slew = findValue(pvt, model, in_slew, cap, 0.0); } @@ -408,9 +402,9 @@ GateTableModel::checkAxis(const TableAxis *axis) { TableAxisVariable var = axis->variable(); return var == TableAxisVariable::total_output_net_capacitance - || var == TableAxisVariable::input_transition_time - || var == TableAxisVariable::input_net_transition - || var == TableAxisVariable::related_out_total_output_net_capacitance; + || var == TableAxisVariable::input_transition_time + || var == TableAxisVariable::input_net_transition + || var == TableAxisVariable::related_out_total_output_net_capacitance; } //////////////////////////////////////////////////////////////// @@ -435,12 +429,13 @@ ReceiverModel::checkAxes(const TableModel *table) const TableAxis *axis2 = table->axis2(); const TableAxis *axis3 = table->axis3(); return (axis1 && axis1->variable() == TableAxisVariable::input_net_transition - && axis2 == nullptr + && axis2 == nullptr && axis3 == nullptr) + || (axis1 && axis1->variable() == TableAxisVariable::input_net_transition + && axis2 + && axis2->variable() == TableAxisVariable::total_output_net_capacitance && axis3 == nullptr) - || (axis1 && axis1->variable() == TableAxisVariable::input_net_transition - && axis2 && axis2->variable() == TableAxisVariable::total_output_net_capacitance - && axis3 == nullptr) - || (axis1 && axis1->variable() == TableAxisVariable::total_output_net_capacitance + || (axis1 + && axis1->variable() == TableAxisVariable::total_output_net_capacitance && axis2 && axis2->variable() == TableAxisVariable::input_net_transition && axis3 == nullptr); } @@ -488,7 +483,8 @@ CheckTableModel::checkDelay(const Pvt *pvt, if (std_dev_model == nullptr) std_dev_model = check_models_->sigma(min_max); if (std_dev_model) { - float std_dev = findValue(pvt, std_dev_model, from_slew, to_slew, related_out_cap); + float std_dev = findValue(pvt, std_dev_model, from_slew, + to_slew, related_out_cap); check_delay.setStdDev(std_dev); } break; @@ -529,8 +525,8 @@ CheckTableModel::findValue(const Pvt *pvt, { if (model) { float axis_value1, axis_value2, axis_value3; - findAxisValues(from_slew, to_slew, related_out_cap, - axis_value1, axis_value2, axis_value3); + findAxisValues(from_slew, to_slew, related_out_cap, axis_value1, axis_value2, + axis_value3); return model->findValue(cell_, pvt, axis_value1, axis_value2, axis_value3); } else @@ -580,8 +576,8 @@ CheckTableModel::reportTableDelay(const char *result_name, { if (model) { float axis_value1, axis_value2, axis_value3; - findAxisValues(from_slew, to_slew, related_out_cap, - axis_value1, axis_value2, axis_value3); + findAxisValues(from_slew, to_slew, related_out_cap, axis_value1, axis_value2, + axis_value3); std::string result = reportPvt(cell_, pvt, digits); const Unit *time_unit = cell_->libertyLibrary()->units()->timeUnit(); result += check_models_->model()->reportValue(result_name, cell_, pvt, @@ -675,8 +671,8 @@ CheckTableModel::checkAxis(const TableAxis *axis) { TableAxisVariable var = axis->variable(); return var == TableAxisVariable::constrained_pin_transition - || var == TableAxisVariable::related_pin_transition - || var == TableAxisVariable::related_out_total_output_net_capacitance; + || var == TableAxisVariable::related_pin_transition + || var == TableAxisVariable::related_out_total_output_net_capacitance; } //////////////////////////////////////////////////////////////// @@ -837,7 +833,7 @@ TableModel::findValue(const LibertyCell *cell, float axis_value3) const { return table_->findValue(axis_value1, axis_value2, axis_value3) - * scaleFactor(cell, pvt); + * scaleFactor(cell, pvt); } float @@ -849,8 +845,8 @@ TableModel::scaleFactor(const LibertyCell *cell, // nominal pvt. return 1.0F; else - return cell->libertyLibrary()->scaleFactor(static_cast(scale_factor_type_), - rf_index_, cell, pvt); + return cell->libertyLibrary()->scaleFactor( + static_cast(scale_factor_type_), rf_index_, cell, pvt); } std::string @@ -864,14 +860,16 @@ TableModel::reportValue(const char *result_name, const Unit *table_unit, int digits) const { - std::string result = table_->reportValue("Table value", cell, pvt, value1, - comment1, value2, value3, table_unit, digits); + std::string result = + table_->reportValue("Table value", cell, pvt, value1, comment1, value2, value3, + table_unit, digits); result += reportPvtScaleFactor(cell, pvt, digits); result += result_name; result += " = "; - result += table_unit->asString(findValue(cell, pvt, value1, value2, value3), digits); + result += + table_unit->asString(findValue(cell, pvt, value1, value2, value3), digits); result += '\n'; return result; } @@ -884,14 +882,11 @@ reportPvt(const LibertyCell *cell, const LibertyLibrary *library = cell->libertyLibrary(); if (pvt == nullptr) pvt = library->defaultOperatingConditions(); - if (pvt) { - std::string result; - stringPrint(result, "P = %.*f V = %.*f T = %.*f\n", - digits, pvt->process(), - digits, pvt->voltage(), - digits, pvt->temperature()); - return result; - } + if (pvt) + return sta::format("P = {:.{}f} V = {:.{}f} T = {:.{}f}\n", + pvt->process(), digits, + pvt->voltage(), digits, + pvt->temperature(), digits); return ""; } @@ -902,13 +897,9 @@ TableModel::reportPvtScaleFactor(const LibertyCell *cell, { if (pvt == nullptr) pvt = cell->libertyLibrary()->defaultOperatingConditions(); - if (pvt) { - std::string result; - stringPrint(result, "PVT scale factor = %.*f\n", - digits, - scaleFactor(cell, pvt)); - return result; - } + if (pvt) + return sta::formatRuntime("PVT scale factor = {:.{}f}\n", + scaleFactor(cell, pvt), digits); return ""; } @@ -1189,13 +1180,10 @@ Table::findValueOrder3(float axis_value1, } return (1 - dx1) * (1 - dx2) * (1 - dx3) * y000 - + (1 - dx1) * (1 - dx2) * dx3 * y001 - + (1 - dx1) * dx2 * (1 - dx3) * y010 - + (1 - dx1) * dx2 * dx3 * y011 - + dx1 * (1 - dx2) * (1 - dx3) * y100 - + dx1 * (1 - dx2) * dx3 * y101 - + dx1 * dx2 * (1 - dx3) * y110 - + dx1 * dx2 * dx3 * y111; + + (1 - dx1) * (1 - dx2) * dx3 * y001 + (1 - dx1) * dx2 * (1 - dx3) * y010 + + (1 - dx1) * dx2 * dx3 * y011 + dx1 * (1 - dx2) * (1 - dx3) * y100 + + dx1 * (1 - dx2) * dx3 * y101 + dx1 * dx2 * (1 - dx3) * y110 + + dx1 * dx2 * dx3 * y111; } void @@ -1279,14 +1267,14 @@ Table::reportValue(const char *result_name, case 0: return reportValueOrder0(result_name, comment1, table_unit, digits); case 1: - return reportValueOrder1(result_name, cell, value1, comment1, - value2, value3, table_unit, digits); + return reportValueOrder1(result_name, cell, value1, comment1, value2, value3, + table_unit, digits); case 2: - return reportValueOrder2(result_name, cell, value1, comment1, - value2, value3, table_unit, digits); + return reportValueOrder2(result_name, cell, value1, comment1, value2, value3, + table_unit, digits); case 3: - return reportValueOrder3(result_name, cell, value1, comment1, - value2, value3, table_unit, digits); + return reportValueOrder3(result_name, cell, value1, comment1, value2, value3, + table_unit, digits); default: return ""; } @@ -1453,12 +1441,12 @@ Table::reportValueOrder3(const char *result_name, result += " "; result += unit1->asString(axis1_->axisValue(axis_index1 + 1), digits); result += " v / "; - result += table_unit->asString(value(axis_index1 + 1, axis_index2, - axis_index3), digits); + result += table_unit->asString(value(axis_index1 + 1, axis_index2, axis_index3), + digits); if (axis3_->size() != 1) { result += " "; - result += table_unit->asString(value(axis_index1 + 1, axis_index2, - axis_index3 + 1), digits); + result += table_unit->asString( + value(axis_index1 + 1, axis_index2, axis_index3 + 1), digits); } } else { @@ -1470,22 +1458,22 @@ Table::reportValueOrder3(const char *result_name, result += " "; result += unit2->asString(axis2_->axisValue(axis_index2), digits); result += " | "; - result += table_unit->asString(value(axis_index1, axis_index2, - axis_index3), digits); + result += + table_unit->asString(value(axis_index1, axis_index2, axis_index3), digits); if (axis3_->size() != 1) { result += " "; - result += table_unit->asString(value(axis_index1, axis_index2, - axis_index3 + 1), digits); + result += table_unit->asString(value(axis_index1, axis_index2, axis_index3 + 1), + digits); } result += '\n'; result += " |/ "; if (axis1_->size() != 1 && axis2_->size() != 1) { - result += table_unit->asString(value(axis_index1 + 1, axis_index2 + 1, - axis_index3), digits); + result += table_unit->asString( + value(axis_index1 + 1, axis_index2 + 1, axis_index3), digits); if (axis3_->size() != 1) { result += " "; - result += table_unit->asString(value(axis_index1 + 1, axis_index2 + 1, - axis_index3 + 1), digits); + result += table_unit->asString( + value(axis_index1 + 1, axis_index2 + 1, axis_index3 + 1), digits); } } result += '\n'; @@ -1493,12 +1481,12 @@ Table::reportValueOrder3(const char *result_name, result += unit2->asString(axis2_->axisValue(axis_index2 + 1), digits); result += " | "; if (axis2_->size() != 1) { - result += table_unit->asString(value(axis_index1, axis_index2 + 1, - axis_index3), digits); + result += table_unit->asString(value(axis_index1, axis_index2 + 1, axis_index3), + digits); if (axis3_->size() != 1) { result += " "; - result += table_unit->asString(value(axis_index1, axis_index2 + 1, - axis_index3 + 1), digits); + result += table_unit->asString( + value(axis_index1, axis_index2 + 1, axis_index3 + 1), digits); } } result += '\n'; @@ -1516,38 +1504,38 @@ Table::report(const Units *units, int digits = 4; const Unit *table_unit = units->timeUnit(); if (order_ == 0) { - report->reportLine("%s", table_unit->asString(value_, digits)); + report->report("{}", table_unit->asString(value_, digits)); return; } if (order_ == 1) { const Unit *unit1 = axis1_->unit(units); - report->reportLine("%s", tableVariableString(axis1_->variable())); - report->reportLine("------------------------------"); + report->report("{}", tableVariableString(axis1_->variable())); + report->report("------------------------------"); std::string line; for (size_t index1 = 0; index1 < axis1_->size(); index1++) { line += unit1->asString(axis1_->axisValue(index1), digits); line += " "; } - report->reportLineString(line); + report->reportLine(line); line.clear(); for (size_t index1 = 0; index1 < axis1_->size(); index1++) { line += table_unit->asString(value(index1), digits); line += " "; } - report->reportLineString(line); + report->reportLine(line); return; } if (order_ == 2) { const Unit *unit1 = axis1_->unit(units); const Unit *unit2 = axis2_->unit(units); - report->reportLine("%s", tableVariableString(axis2_->variable())); - report->reportLine(" ------------------------------"); + report->report("{}", tableVariableString(axis2_->variable())); + report->report(" ------------------------------"); std::string line = " "; for (size_t index2 = 0; index2 < axis2_->size(); index2++) { line += unit2->asString(axis2_->axisValue(index2), digits); line += " "; } - report->reportLineString(line); + report->reportLine(line); for (size_t index1 = 0; index1 < axis1_->size(); index1++) { line = unit1->asString(axis1_->axisValue(index1), digits); line += " |"; @@ -1555,7 +1543,7 @@ Table::report(const Units *units, line += table_unit->asString(value(index1, index2), digits); line += " "; } - report->reportLineString(line); + report->reportLine(line); } return; } @@ -1564,24 +1552,25 @@ Table::report(const Units *units, const Unit *unit2 = axis2_->unit(units); const Unit *unit3 = axis3_->unit(units); for (size_t axis_index1 = 0; axis_index1 < axis1_->size(); axis_index1++) { - report->reportLine("%s %s", tableVariableString(axis1_->variable()), - unit1->asString(axis1_->axisValue(axis_index1), digits)); - report->reportLine("%s", tableVariableString(axis3_->variable())); - report->reportLine(" ------------------------------"); + report->report("{} {}", tableVariableString(axis1_->variable()), + unit1->asString(axis1_->axisValue(axis_index1), digits)); + report->report("{}", tableVariableString(axis3_->variable())); + report->report(" ------------------------------"); std::string line = " "; for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) { line += unit3->asString(axis3_->axisValue(axis_index3), digits); line += " "; } - report->reportLineString(line); + report->reportLine(line); for (size_t axis_index2 = 0; axis_index2 < axis2_->size(); axis_index2++) { line = unit2->asString(axis2_->axisValue(axis_index2), digits); line += " |"; for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) { - line += table_unit->asString(value(axis_index1, axis_index2, axis_index3), digits); + line += table_unit->asString(value(axis_index1, axis_index2, axis_index3), + digits); line += " "; } - report->reportLineString(line); + report->reportLine(line); } } } @@ -1626,9 +1615,7 @@ bool TableAxis::inBounds(float value) const { size_t size = values_.size(); - return size > 1 - && value >= values_[0] - && value <= values_[size - 1]; + return size > 1 && value >= values_[0] && value <= values_[size - 1]; } size_t @@ -1670,9 +1657,7 @@ TableAxis::findAxisIndex(float value, bool &exists) const { size_t size = values_.size(); - if (size != 0 - && value >= values_[0] - && value <= values_[size - 1]) { + if (size != 0 && value >= values_[0] && value <= values_[size - 1]) { int lower = -1; int upper = size; while (upper - lower > 1) { @@ -1730,27 +1715,28 @@ TableAxis::unit(const Units *units) //////////////////////////////////////////////////////////////// -static EnumNameMap table_axis_variable_map = - {{TableAxisVariable::total_output_net_capacitance, "total_output_net_capacitance"}, - {TableAxisVariable::equal_or_opposite_output_net_capacitance, "equal_or_opposite_output_net_capacitance"}, - {TableAxisVariable::input_net_transition, "input_net_transition"}, - {TableAxisVariable::input_transition_time, "input_transition_time"}, - {TableAxisVariable::related_pin_transition, "related_pin_transition"}, - {TableAxisVariable::constrained_pin_transition, "constrained_pin_transition"}, - {TableAxisVariable::output_pin_transition, "output_pin_transition"}, - {TableAxisVariable::connect_delay, "connect_delay"}, - {TableAxisVariable::related_out_total_output_net_capacitance, - "related_out_total_output_net_capacitance"}, - {TableAxisVariable::time, "time"}, - {TableAxisVariable::iv_output_voltage, "iv_output_voltage"}, - {TableAxisVariable::input_noise_width, "input_noise_width"}, - {TableAxisVariable::input_noise_height, "input_noise_height"}, - {TableAxisVariable::input_voltage, "input_voltage"}, - {TableAxisVariable::output_voltage, "output_voltage"}, - {TableAxisVariable::path_depth, "path_depth"}, - {TableAxisVariable::path_distance, "path_distance"}, - {TableAxisVariable::normalized_voltage, "normalized_voltage"} - }; +static EnumNameMap table_axis_variable_map = { + {TableAxisVariable::total_output_net_capacitance, + "total_output_net_capacitance"}, + {TableAxisVariable::equal_or_opposite_output_net_capacitance, + "equal_or_opposite_output_net_capacitance"}, + {TableAxisVariable::input_net_transition, "input_net_transition"}, + {TableAxisVariable::input_transition_time, "input_transition_time"}, + {TableAxisVariable::related_pin_transition, "related_pin_transition"}, + {TableAxisVariable::constrained_pin_transition, "constrained_pin_transition"}, + {TableAxisVariable::output_pin_transition, "output_pin_transition"}, + {TableAxisVariable::connect_delay, "connect_delay"}, + {TableAxisVariable::related_out_total_output_net_capacitance, + "related_out_total_output_net_capacitance"}, + {TableAxisVariable::time, "time"}, + {TableAxisVariable::iv_output_voltage, "iv_output_voltage"}, + {TableAxisVariable::input_noise_width, "input_noise_width"}, + {TableAxisVariable::input_noise_height, "input_noise_height"}, + {TableAxisVariable::input_voltage, "input_voltage"}, + {TableAxisVariable::output_voltage, "output_voltage"}, + {TableAxisVariable::path_depth, "path_depth"}, + {TableAxisVariable::path_distance, "path_distance"}, + {TableAxisVariable::normalized_voltage, "normalized_voltage"}}; TableAxisVariable stringTableAxisVariable(const char *variable) @@ -1769,30 +1755,30 @@ tableVariableUnit(TableAxisVariable variable, const Units *units) { switch (variable) { - case TableAxisVariable::total_output_net_capacitance: - case TableAxisVariable::related_out_total_output_net_capacitance: - case TableAxisVariable::equal_or_opposite_output_net_capacitance: - return units->capacitanceUnit(); - case TableAxisVariable::input_net_transition: - case TableAxisVariable::input_transition_time: - case TableAxisVariable::related_pin_transition: - case TableAxisVariable::constrained_pin_transition: - case TableAxisVariable::output_pin_transition: - case TableAxisVariable::connect_delay: - case TableAxisVariable::time: - case TableAxisVariable::input_noise_height: - return units->timeUnit(); - case TableAxisVariable::input_voltage: - case TableAxisVariable::output_voltage: - case TableAxisVariable::iv_output_voltage: - case TableAxisVariable::input_noise_width: - return units->voltageUnit(); - case TableAxisVariable::path_distance: - return units->distanceUnit(); - case TableAxisVariable::path_depth: - case TableAxisVariable::normalized_voltage: - case TableAxisVariable::unknown: - return units->scalarUnit(); + case TableAxisVariable::total_output_net_capacitance: + case TableAxisVariable::related_out_total_output_net_capacitance: + case TableAxisVariable::equal_or_opposite_output_net_capacitance: + return units->capacitanceUnit(); + case TableAxisVariable::input_net_transition: + case TableAxisVariable::input_transition_time: + case TableAxisVariable::related_pin_transition: + case TableAxisVariable::constrained_pin_transition: + case TableAxisVariable::output_pin_transition: + case TableAxisVariable::connect_delay: + case TableAxisVariable::time: + case TableAxisVariable::input_noise_height: + return units->timeUnit(); + case TableAxisVariable::input_voltage: + case TableAxisVariable::output_voltage: + case TableAxisVariable::iv_output_voltage: + case TableAxisVariable::input_noise_width: + return units->voltageUnit(); + case TableAxisVariable::path_distance: + return units->distanceUnit(); + case TableAxisVariable::path_depth: + case TableAxisVariable::normalized_voltage: + case TableAxisVariable::unknown: + return units->scalarUnit(); } // Prevent warnings from lame compilers. return nullptr; @@ -1828,12 +1814,13 @@ OutputWaveforms::checkAxes(const TableTemplate *tbl_template) const TableAxis *axis2 = tbl_template->axis2(); const TableAxis *axis3 = tbl_template->axis3(); return (axis1 && axis1->variable() == TableAxisVariable::input_net_transition - && axis2->variable() == TableAxisVariable::time - && axis3 == nullptr) - || (axis1 && axis1->variable() == TableAxisVariable::input_net_transition - && axis2 && axis2->variable() == TableAxisVariable::total_output_net_capacitance + && axis2->variable() == TableAxisVariable::time && axis3 == nullptr) + || (axis1 && axis1->variable() == TableAxisVariable::input_net_transition + && axis2 + && axis2->variable() == TableAxisVariable::total_output_net_capacitance && axis3->variable() == TableAxisVariable::time) - || (axis1 && axis1->variable() == TableAxisVariable::total_output_net_capacitance + || (axis1 + && axis1->variable() == TableAxisVariable::total_output_net_capacitance && axis2 && axis2->variable() == TableAxisVariable::input_net_transition && axis3->variable() == TableAxisVariable::time); } @@ -1886,8 +1873,8 @@ OutputWaveforms::findVoltages(size_t wave_index, // Make voltage -> current table. FloatSeq axis_volts = volts; - TableAxisPtr volt_axis = - std::make_shared(TableAxisVariable::input_voltage, std::move(axis_volts)); + TableAxisPtr volt_axis = std::make_shared( + TableAxisVariable::input_voltage, std::move(axis_volts)); FloatSeq *currents1 = new FloatSeq(*currents->values()); Table *volt_currents = new Table(currents1, volt_axis); voltage_currents_[wave_index] = volt_currents; @@ -1906,7 +1893,8 @@ OutputWaveforms::currentWaveform(float slew, times->push_back(time); currents->push_back(current); } - TableAxisPtr time_axis = std::make_shared(TableAxisVariable::time, std::move(*times)); + TableAxisPtr time_axis = + std::make_shared(TableAxisVariable::time, std::move(*times)); delete times; return Table(currents, time_axis); } @@ -1988,11 +1976,8 @@ OutputWaveforms::voltageTime1(double volt, double y01 = voltageTime2(volt, wave_index01); double y10 = voltageTime2(volt, wave_index10); double y11 = voltageTime2(volt, wave_index11); - double time - = (1 - dx1) * (1 - dx2) * y00 - + dx1 * (1 - dx2) * y10 - + dx1 * dx2 * y11 - + (1 - dx1) * dx2 * y01; + double time = (1 - dx1) * (1 - dx2) * y00 + dx1 * (1 - dx2) * y10 + dx1 * dx2 * y11 + + (1 - dx1) * dx2 * y01; return time; } @@ -2057,11 +2042,8 @@ OutputWaveforms::waveformValue(float slew, double y01 = waveform01->findValueClip(axis_value); double y10 = waveform10->findValueClip(axis_value); double y11 = waveform11->findValueClip(axis_value); - double wave_value - = (1 - dx1) * (1 - dx2) * y00 - + dx1 * (1 - dx2) * y10 - + dx1 * dx2 * y11 - + (1 - dx1) * dx2 * y01; + double wave_value = (1 - dx1) * (1 - dx2) * y00 + dx1 * (1 - dx2) * y10 + + dx1 * dx2 * y11 + (1 - dx1) * dx2 * y01; return wave_value; } @@ -2083,8 +2065,8 @@ OutputWaveforms::voltageWaveform(float slew, times.push_back(time); volts.push_back(volt); } - TableAxisPtr time_axis = std::make_shared(TableAxisVariable::time, - std::move(times)); + TableAxisPtr time_axis = + std::make_shared(TableAxisVariable::time, std::move(times)); return Table(std::move(volts), time_axis); } @@ -2101,8 +2083,8 @@ OutputWaveforms::voltageWaveformRaw(float slew, float OutputWaveforms::voltageTime(float slew, - float cap, - float volt) + float cap, + float volt) { size_t slew_index = slew_axis_->findAxisIndex(slew); size_t cap_index = cap_axis_->findAxisIndex(cap); @@ -2187,11 +2169,8 @@ OutputWaveforms::beginEndTime(float slew, y11 = waveform11->axis1()->max(); } - float wave_value - = (1 - dx1) * (1 - dx2) * y00 - + dx1 * (1 - dx2) * y10 - + dx1 * dx2 * y11 - + (1 - dx1) * dx2 * y01; + float wave_value = (1 - dx1) * (1 - dx2) * y00 + dx1 * (1 - dx2) * y10 + + dx1 * dx2 * y11 + (1 - dx1) * dx2 * y01; return wave_value; } @@ -2207,8 +2186,8 @@ OutputWaveforms::voltageCurrentWaveform(float slew, volts->push_back(volt); currents->push_back(current); } - TableAxisPtr volt_axis = - std::make_shared(TableAxisVariable::input_voltage, std::move(*volts)); + TableAxisPtr volt_axis = std::make_shared( + TableAxisVariable::input_voltage, std::move(*volts)); delete volts; return Table(currents, volt_axis); } @@ -2250,11 +2229,11 @@ DriverWaveform::waveform(float slew) time_values->push_back(time); volt_values->push_back(volt); } - TableAxisPtr time_axis = std::make_shared(TableAxisVariable::time, - std::move(*time_values)); + TableAxisPtr time_axis = + std::make_shared(TableAxisVariable::time, std::move(*time_values)); delete time_values; Table waveform(volt_values, time_axis); return waveform; } -} // namespace +} // namespace sta diff --git a/liberty/Units.cc b/liberty/Units.cc index 98cad0aa..fb3fcdb6 100644 --- a/liberty/Units.cc +++ b/liberty/Units.cc @@ -26,6 +26,7 @@ #include // abs +#include "Format.hh" #include "StringUtil.hh" #include "MinMax.hh" // INF #include "Fuzzy.hh" @@ -127,7 +128,7 @@ Unit::scaleString() const else if (fuzzyEqual(scale_, 1E-15)) return "1f"; else - return stdstrPrint("%.1e", scale_); + return sta::format("{:.1e}", scale_); } std::string @@ -155,19 +156,13 @@ Unit::width() const return digits_ + 2; } -const char * +std::string Unit::asString(float value) const { return asString(value, digits_); } -const char * -Unit::asString(double value) const -{ - return asString(static_cast(value), digits_); -} - -const char * +std::string Unit::asString(float value, int digits) const { @@ -179,7 +174,7 @@ Unit::asString(float value, // prevent "-0.00" on slowaris if (std::abs(scaled_value) < 1E-6) scaled_value = 0.0; - return stringPrintTmp("%.*f", digits, scaled_value); + return sta::formatRuntime("{:.{}f}", scaled_value, digits); } } diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index 50bc62b2..1d18d24d 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -222,12 +222,10 @@ ConcreteCell::makeBusPortBit(ConcretePort *bus_port, const char *bus_name, int bit_index) { - std::string bit_name; - stringPrint(bit_name, "%s%c%d%c", - bus_name, - library_->busBrktLeft(), - bit_index, - library_->busBrktRight()); + std::string bit_name = std::string(bus_name) + + library_->busBrktLeft() + + std::to_string(bit_index) + + library_->busBrktRight(); ConcretePort *port = makePort(bit_name.c_str(), bit_index); bus_port->addPortBit(port); addPortBit(port); @@ -465,12 +463,13 @@ ConcretePort::busName() const { if (is_bus_) { ConcreteLibrary *lib = cell_->library(); - return stringPrintTmp("%s%c%d:%d%c", - name(), - lib->busBrktLeft(), - from_index_, - to_index_, - lib->busBrktRight()); + std::string bus_name = sta::format("{}{}{}:{}{}", + name(), + lib->busBrktLeft(), + from_index_, + to_index_, + lib->busBrktRight()); + return makeTmpString(bus_name); } else return name(); diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index de4b0464..6291d5bc 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -2003,7 +2003,7 @@ ConcreteNetwork::linkNetwork(const char *top_cell_name, return top_instance_ != nullptr; } else { - report->error(1000, "cell type %s can not be linked.", top_cell_name); + report->error(1000, "cell type {} can not be linked.", top_cell_name); return false; } } diff --git a/network/HpinDrvrLoad.cc b/network/HpinDrvrLoad.cc index 2c98c5fa..ab76900d 100644 --- a/network/HpinDrvrLoad.cc +++ b/network/HpinDrvrLoad.cc @@ -293,15 +293,16 @@ HpinDrvrLoad::~HpinDrvrLoad() void HpinDrvrLoad::report(const Network *network) { - printf("%s -> %s: ", - drvr_ ? network->pathName(drvr_) : "-", - load_ ? network->pathName(load_) : "-"); + Report *report = network->report(); + std::string line = sta::format("{} -> {}: ", + drvr_ ? network->pathName(drvr_) : "-", + load_ ? network->pathName(load_) : "-"); for (const Pin *pin : *hpins_from_drvr_) - printf("%s ", network->pathName(pin)); - printf("* "); + line += sta::format("{} ", network->pathName(pin)); + line += "* "; for (const Pin *pin : *hpins_to_load_) - printf("%s ", network->pathName(pin)); - printf("\n"); + line += sta::format("{} ", network->pathName(pin)); + report->report(line); } void diff --git a/network/Network.cc b/network/Network.cc index fe9a9c1d..b0a7d635 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -262,24 +262,15 @@ Network::pathName(const Instance *instance) const { InstanceSeq inst_path; path(instance, inst_path); - size_t name_length = 0; - for (const Instance *inst : inst_path) - name_length += strlen(name(inst)) + 1; - char *path_name = makeTmpString(name_length + 1); - char *path_ptr = path_name; - // Top instance has null string name, so terminate the string here. - *path_name = '\0'; + std::string path_name; while (inst_path.size()) { const Instance *inst = inst_path.back(); - const char *inst_name = name(inst); - strcpy(path_ptr, inst_name); - path_ptr += strlen(inst_name); + path_name += name(inst); inst_path.pop_back(); - if (inst_path.size()) - *path_ptr++ = pathDivider(); - *path_ptr = '\0'; + if (!inst_path.empty()) + path_name += pathDivider(); } - return path_name; + return makeTmpString(path_name); } bool @@ -376,18 +367,10 @@ Network::pathName(const Pin *pin) const { const Instance *inst = instance(pin); if (inst && inst != topInstance()) { - const char *inst_name = pathName(inst); - size_t inst_name_length = strlen(inst_name); - const char *port_name = portName(pin); - size_t port_name_length = strlen(port_name); - size_t path_name_length = inst_name_length + port_name_length + 2; - char *path_name = makeTmpString(path_name_length); - char *path_ptr = path_name; - strcpy(path_ptr, inst_name); - path_ptr += inst_name_length; - *path_ptr++ = pathDivider(); - strcpy(path_ptr, port_name); - return path_name; + std::string path_name = pathName(inst); + path_name += pathDivider(); + path_name += portName(pin); + return makeTmpString(path_name); } else return portName(pin); @@ -464,18 +447,10 @@ Network::pathName(const Net *net) const { const Instance *inst = instance(net); if (inst && inst != topInstance()) { - const char *inst_name = pathName(inst); - size_t inst_name_length = strlen(inst_name); - const char *net_name = name(net); - size_t net_name_length = strlen(net_name); - size_t path_name_length = inst_name_length + net_name_length + 2; - char *path_name = makeTmpString(path_name_length); - char *path_ptr = path_name; - strcpy(path_ptr, inst_name); - path_ptr += inst_name_length; - *path_ptr++ = pathDivider(); - strcpy(path_ptr, net_name); - return path_name; + std::string path_name = pathName(inst); + path_name += pathDivider(); + path_name += name(net); + return makeTmpString(path_name); } else return name(net); diff --git a/network/Network.i b/network/Network.i index 6495ec8b..870399df 100644 --- a/network/Network.i +++ b/network/Network.i @@ -511,7 +511,7 @@ net_pins(Net *net) return pins; } -const char * +std::string pin_location(const Pin *pin) { Network *network = Sta::sta()->ensureLinked(); @@ -520,12 +520,12 @@ pin_location(const Pin *pin) network->location(pin, x, y, exists); // return x/y as tcl list if (exists) - return sta::stringPrintTmp("%f %f", x, y); + return std::format("{} {}", x, y); else return ""; } -const char * +std::string port_location(const Port *port) { Network *network = Sta::sta()->ensureLinked(); diff --git a/network/ParseBus.cc b/network/ParseBus.cc index 83f097b3..7bbab7a0 100644 --- a/network/ParseBus.cc +++ b/network/ParseBus.cc @@ -24,35 +24,34 @@ #include "ParseBus.hh" -#include -#include #include +#include #include "StringUtil.hh" namespace sta { bool -isBusName(const char *name, +isBusName(std::string_view name, const char brkt_left, const char brkt_right, char escape) { - size_t len = strlen(name); + size_t len = name.size(); // Shortest bus name is a[0]. if (len >= 4 // Escaped bus brackets are not buses. && name[len - 2] != escape && name[len - 1] == brkt_right) { - const char *left = strrchr(name, brkt_left); - return left != nullptr; + size_t left = name.rfind(brkt_left); + return left != std::string_view::npos; } else return false; } void -parseBusName(const char *name, +parseBusName(std::string_view name, const char brkt_left, const char brkt_right, const char escape, @@ -61,16 +60,15 @@ parseBusName(const char *name, std::string &bus_name, int &index) { - const char brkts_left[2] = {brkt_left, '\0'}; - const char brkts_right[2] = {brkt_right, '\0'}; - parseBusName(name, brkts_left, brkts_right, escape, + parseBusName(name, std::string_view(&brkt_left, 1), + std::string_view(&brkt_right, 1), escape, is_bus, bus_name, index); } void -parseBusName(const char *name, - const char *brkts_left, - const char *brkts_right, +parseBusName(std::string_view name, + std::string_view brkts_left, + std::string_view brkts_right, char escape, // Return values. bool &is_bus, @@ -78,30 +76,28 @@ parseBusName(const char *name, int &index) { is_bus = false; - size_t len = strlen(name); + size_t len = name.size(); // Shortest bus name is a[0]. if (len >= 4 // Escaped bus brackets are not buses. && name[len - 2] != escape) { char last_ch = name[len - 1]; - const char *brkt_right_ptr = strchr(brkts_right, last_ch); - if (brkt_right_ptr) { - size_t brkt_index = brkt_right_ptr - brkts_right; - char brkt_left = brkts_left[brkt_index]; - const char *left = strrchr(name, brkt_left); - if (left) { + size_t brkt_index = brkts_right.find(last_ch); + if (brkt_index != std::string_view::npos) { + char brkt_left_ch = brkts_left[brkt_index]; + size_t left = name.rfind(brkt_left_ch); + if (left != std::string_view::npos) { is_bus = true; - size_t bus_name_len = left - name; - bus_name.append(name, bus_name_len); + bus_name.append(name.data(), left); // Simple bus subscript. - index = atoi(left + 1); + index = std::stoi(std::string(name.substr(left + 1))); } } } } void -parseBusName(const char *name, +parseBusName(std::string_view name, const char brkt_left, const char brkt_right, char escape, @@ -113,16 +109,15 @@ parseBusName(const char *name, int &to, bool &subscript_wild) { - const char brkts_left[2] = {brkt_left, '\0'}; - const char brkts_right[2] = {brkt_right, '\0'}; - parseBusName(name, brkts_left, brkts_right, escape, + parseBusName(name, std::string_view(&brkt_left, 1), + std::string_view(&brkt_right, 1), escape, is_bus, is_range, bus_name, from, to, subscript_wild); } void -parseBusName(const char *name, - const char *brkts_left, - const char *brkts_right, +parseBusName(std::string_view name, + std::string_view brkts_left, + std::string_view brkts_right, char escape, // Return values. bool &is_bus, @@ -135,36 +130,31 @@ parseBusName(const char *name, is_bus = false; is_range = false; subscript_wild = false; - size_t len = strlen(name); + size_t len = name.size(); // Shortest bus is a[0]. if (len >= 4 // Escaped bus brackets are not buses. && name[len - 2] != escape) { char last_ch = name[len - 1]; - const char *brkt_right_ptr = strchr(brkts_right, last_ch); - if (brkt_right_ptr) { - size_t brkt_index = brkt_right_ptr - brkts_right; - char brkt_left = brkts_left[brkt_index]; - const char *left = strrchr(name, brkt_left); - if (left) { + size_t brkt_index = brkts_right.find(last_ch); + if (brkt_index != std::string_view::npos) { + char brkt_left_ch = brkts_left[brkt_index]; + size_t left = name.rfind(brkt_left_ch); + if (left != std::string_view::npos) { is_bus = true; + bus_name.append(name.data(), left); // Check for bus range. - const char range_sep = ':'; - const char *range = strchr(name, range_sep); - if (range) { + size_t range = name.find(':', left); + if (range != std::string_view::npos) { is_range = true; - bus_name.append(name, left - name); - // No need to terminate bus subscript because atoi stops - // scanning at first non-digit character. - from = atoi(left + 1); - to = atoi(range + 1); + from = std::stoi(std::string(name.substr(left + 1))); + to = std::stoi(std::string(name.substr(range + 1))); } else { - bus_name.append(name, left - name); - if (left[1] == '*') + if (left + 1 < len && name[left + 1] == '*') subscript_wild = true; else - from = to = atoi(left + 1); + from = to = std::stoi(std::string(name.substr(left + 1))); } } } @@ -172,22 +162,23 @@ parseBusName(const char *name, } std::string -escapeChars(const char *token, +escapeChars(std::string_view token, const char ch1, const char ch2, const char escape) { std::string escaped; - for (const char *s = token; *s; s++) { - char ch = *s; + escaped.reserve(token.size()); + for (size_t i = 0; i < token.size(); i++) { + char ch = token[i]; if (ch == escape) { - char next_ch = s[1]; - // Make sure we don't skip the null if escape is the last char. - if (next_ch != '\0') { + if (i + 1 < token.size()) { escaped += ch; - escaped += next_ch; - s++; + escaped += token[i + 1]; + i++; } + else + escaped += ch; } else if (ch == ch1 || ch == ch2) { escaped += escape; diff --git a/network/SdcNetwork.cc b/network/SdcNetwork.cc index 5200367e..4cdef63e 100644 --- a/network/SdcNetwork.cc +++ b/network/SdcNetwork.cc @@ -640,28 +640,27 @@ SdcNetwork::SdcNetwork(Network *network) : // Translate sta namespace to sdc namespace. // Remove all escapes. const char * -SdcNetwork::staToSdc(const char *sta_name) const +SdcNetwork::staToSdc(std::string_view sta_name) const { char escape = pathEscape(); - char *sdc_name = makeTmpString(strlen(sta_name) + 1); - char *d = sdc_name; - for (const char *s = sta_name; *s; s++) { - char ch = s[0]; + size_t sta_length = sta_name.length(); + std::string sdc_name; + for (size_t i = 0; i < sta_length; i++) { + char ch = sta_name[i]; if (ch == escape) { - char next_ch = s[1]; + char next_ch = sta_name[i + 1]; // Escaped escape. if (next_ch == escape) { - *d++ = ch; - *d++ = next_ch; - s++; + sdc_name += ch; + sdc_name += next_ch; + i++; } } else // Non escape. - *d++ = ch; + sdc_name += ch; } - *d++ = '\0'; - return sdc_name; + return makeTmpString(sdc_name); } Port * @@ -680,11 +679,11 @@ SdcNetwork::findPort(const Cell *cell, port = network_->findPort(cell, escaped1.c_str()); if (port == nullptr) { // Try escaping base foo\[0\][1] - std::string escaped2; std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); - stringPrint(escaped2, "%s[%d]", - escaped_bus_name.c_str(), - index); + std::string escaped2 = escaped_bus_name + + '[' + + std::to_string(index) + + ']'; port = network_->findPort(cell, escaped2.c_str()); } } @@ -966,8 +965,10 @@ SdcNetwork::findPin(const Instance *instance, if (pin == nullptr) { // Try escaping base foo\[0\][1] std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); - std::string escaped2; - stringPrint(escaped2, "%s[%d]", escaped_bus_name.c_str(), index); + std::string escaped2 = escaped_bus_name + + '[' + + std::to_string(index) + + ']'; pin = network_->findPin(instance, escaped2.c_str()); } } @@ -1149,46 +1150,39 @@ SdcNetwork::parsePath(const char *path, const char *&path_tail) const { Instance *parent = topInstance(); + std::string inst_path; // Leave room to escape all the dividers and '\0'. - int inst_path_length = path_length + divider_count + 1; - char *inst_path = new char[inst_path_length]; + inst_path.reserve(path_length + divider_count + 1); inst = nullptr; path_tail = path; - char *p = inst_path; for (const char *s = path; *s; s++) { char ch = *s; if (ch == escape_) { // Make sure we don't skip the null if escape is the last char. if (s[1] != '\0') { - *p++ = ch; - *p++ = s[1]; + inst_path += ch; + inst_path += s[1]; s++; } } else if (ch == divider_) { - // Terminate the sub-path up to this divider. - *p = '\0'; - Instance *child = findChild(parent, inst_path); + Instance *child = findChild(parent, inst_path.c_str()); if (child) { // Found an instance for the sub-path up to this divider. parent = inst = child; // Reset the instance path. - p = inst_path; + inst_path.clear(); path_tail = s + 1; } else { // No match for sub-path. Escape the divider and keep looking. - *p++ = escape_; - *p++ = divider_; + inst_path += escape_; + inst_path += divider_; } } else - *p++ = ch; - if (p - inst_path + 1 > inst_path_length) - report_->critical(1500, "inst path std::string lenth estimate busted"); + inst_path += ch; } - *p = '\0'; - stringDelete(inst_path); } // Helper to visit instance path matches. @@ -1207,11 +1201,9 @@ SdcNetwork::visitMatches(const Instance *parent, { int divider_count, path_length; scanPath(pattern->pattern(), divider_count, path_length); - + std::string inst_path; // Leave room to escape all the dividers and '\0'. - int inst_path_length = path_length + divider_count + 1; - char *inst_path = new char[inst_path_length]; - char *p = inst_path; + inst_path.reserve(path_length + divider_count + 1); bool has_brkts = false; bool found_match = false; for (const char *s = pattern->pattern(); *s; s++) { @@ -1219,20 +1211,18 @@ SdcNetwork::visitMatches(const Instance *parent, if (ch == escape_) { // Make sure we don't skip the null if escape is the last char. if (s[1] != '\0') { - *p++ = ch; - *p++ = s[1]; + inst_path += ch; + inst_path += s[1]; s++; } } else if (ch == divider_) { - // Terminate the sub-path up to this divider. - *p = '\0'; - PatternMatch matcher(inst_path, pattern); + PatternMatch matcher(inst_path.c_str(), pattern); InstanceSeq matches; network_->findChildrenMatching(parent, &matcher, matches); if (has_brkts && matches.empty()) { // Look for matches after escaping brackets. - std::string escaped_brkts = escapeBrackets(inst_path, this); + std::string escaped_brkts = escapeBrackets(inst_path.c_str(), this); const PatternMatch escaped_pattern(escaped_brkts, pattern); network_->findChildrenMatching(parent, &escaped_pattern, matches); } @@ -1245,29 +1235,25 @@ SdcNetwork::visitMatches(const Instance *parent, found_match |= visitMatches(match, &tail_pattern, visit_tail); } // Escape the divider and keep looking. - *p++ = escape_; - *p++ = divider_; + inst_path += escape_; + inst_path += divider_; } else { if (ch == '[' || ch == ']') has_brkts = true; - *p++ = ch; + inst_path += ch; } - if (p - inst_path + 1 > inst_path_length) - report_->critical(1501, "inst path std::string lenth estimate exceeded"); } - *p = '\0'; if (!found_match) { - PatternMatch tail_pattern(inst_path, pattern); + PatternMatch tail_pattern(inst_path.c_str(), pattern); found_match |= visit_tail(parent, &tail_pattern); if (!found_match && has_brkts) { // Look for matches after escaping brackets. - std::string escaped_path = escapeBrackets(inst_path, this); + std::string escaped_path = escapeBrackets(inst_path.c_str(), this); const PatternMatch escaped_tail(escaped_path, pattern); found_match |= visit_tail(parent, &escaped_tail); } } - stringDelete(inst_path); return found_match; } diff --git a/network/VerilogNamespace.cc b/network/VerilogNamespace.cc index a018782e..702ca6d2 100644 --- a/network/VerilogNamespace.cc +++ b/network/VerilogNamespace.cc @@ -34,35 +34,34 @@ namespace sta { constexpr char verilog_escape = '\\'; static std::string -staToVerilog(const char *sta_name); +staToVerilog(std::string sta_name); static std::string -staToVerilog2(const char *sta_name); +staToVerilog2(std::string sta_name); static std::string -verilogToSta(const std::string *verilog_name); +verilogToSta(const std::string verilog_name); std::string -cellVerilogName(const char *sta_name) +cellVerilogName(std::string sta_name) { return staToVerilog(sta_name); } std::string -instanceVerilogName(const char *sta_name) +instanceVerilogName(std::string sta_name) { return staToVerilog(sta_name); } std::string -netVerilogName(const char *sta_name) +netVerilogName(std::string sta_name) { bool is_bus; std::string bus_name; int index; - parseBusName(sta_name, '[', ']', verilog_escape, is_bus, bus_name, index); + parseBusName(sta_name.c_str(), '[', ']', verilog_escape, is_bus, bus_name, index); if (is_bus) { std::string bus_vname = staToVerilog(bus_name.c_str()); - std::string vname; - stringPrint(vname, "%s[%d]", bus_vname.c_str(), index); + std::string vname = bus_vname + '[' + std::to_string(index) + ']'; return vname; } else @@ -70,27 +69,28 @@ netVerilogName(const char *sta_name) } std::string -portVerilogName(const char *sta_name) +portVerilogName(std::string sta_name) { return staToVerilog2(sta_name); } static std::string -staToVerilog(const char *sta_name) +staToVerilog(std::string sta_name) { // Leave room for leading escape and trailing space if the name // needs to be escaped. // Assume the name has to be escaped and start copying while scanning. std::string escaped_name = "\\"; bool escaped = false; - for (const char *s = sta_name; *s ; s++) { - char ch = s[0]; + size_t sta_length = sta_name.size(); + for (size_t i = 0; i < sta_length; i++) { + char ch = sta_name[i]; if (ch == verilog_escape) { escaped = true; - char next_ch = s[1]; + char next_ch = sta_name[i + 1]; if (next_ch == verilog_escape) { escaped_name += next_ch; - s++; + i++; } } else { @@ -105,11 +105,11 @@ staToVerilog(const char *sta_name) return escaped_name; } else - return std::string(sta_name); + return sta_name; } static std::string -staToVerilog2(const char *sta_name) +staToVerilog2(std::string sta_name) { constexpr char bus_brkt_left = '['; constexpr char bus_brkt_right = ']'; @@ -118,14 +118,15 @@ staToVerilog2(const char *sta_name) std::string escaped_name = "\\"; // Assume the name has to be escaped and start copying while scanning. bool escaped = false; - for (const char *s = sta_name; *s ; s++) { - char ch = s[0]; + size_t sta_length = sta_name.size(); + for (size_t i = 0; i < sta_length; i++) { + char ch = sta_name[i]; if (ch == verilog_escape) { escaped = true; - char next_ch = s[1]; + char next_ch = sta_name[i + 1]; if (next_ch == verilog_escape) { escaped_name += next_ch; - s++; + i++; } } else { @@ -142,50 +143,50 @@ staToVerilog2(const char *sta_name) return escaped_name; } else - return std::string(sta_name); + return sta_name; } //////////////////////////////////////////////////////////////// std::string -moduleVerilogToSta(const std::string *module_name) +moduleVerilogToSta(std::string module_name) { return verilogToSta(module_name); } std::string -instanceVerilogToSta(const std::string *inst_name) +instanceVerilogToSta(std::string inst_name) { return verilogToSta(inst_name); } std::string -netVerilogToSta(const std::string *net_name) +netVerilogToSta(std::string net_name) { return verilogToSta(net_name); } std::string -portVerilogToSta(const std::string *port_name) +portVerilogToSta(std::string port_name) { return verilogToSta(port_name); } static std::string -verilogToSta(const std::string *verilog_name) +verilogToSta(std::string verilog_name) { - if (verilog_name->front() == '\\') { + 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())) + size_t verilog_name_length = verilog_name.size(); + if (isspace(verilog_name.back())) verilog_name_length--; std::string sta_name; // Ignore leading '\'. for (size_t i = 1; i < verilog_name_length; i++) { - char ch = verilog_name->at(i); + char ch = verilog_name[i]; if (ch == bus_brkt_left || ch == bus_brkt_right || ch == divider @@ -197,7 +198,7 @@ verilogToSta(const std::string *verilog_name) return sta_name; } else - return std::string(*verilog_name); + return verilog_name; } } // namespace diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index db291c53..e85036ee 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -410,8 +410,10 @@ const char * ConcreteParasiticNode::name(const Network *network) const { if (is_net_) { - const char *net_name = network->pathName(net_pin_.net_); - return stringPrintTmp("%s:%d", net_name, id_); + std::string name = std::string(network->pathName(net_pin_.net_)) + + ':' + + std::to_string(id_); + return makeTmpString(name); } else return network->pathName(net_pin_.pin_); diff --git a/parasitics/Parasitics.cc b/parasitics/Parasitics.cc index 8aaf5fc0..ab304bda 100644 --- a/parasitics/Parasitics.cc +++ b/parasitics/Parasitics.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 "Parasitics.hh" @@ -49,38 +49,29 @@ Parasitics::report(const Parasitic *parasitic) const { if (isParasiticNetwork(parasitic)) { const Unit *cap_unit = units_->capacitanceUnit(); - report_->reportLine("Net %s %s", - network_->pathName(net(parasitic)), - cap_unit->asString(capacitance(parasitic))); - report_->reportLine("Nodes:"); + report_->report("Net {} {}", network_->pathName(net(parasitic)), + cap_unit->asString(capacitance(parasitic))); + report_->report("Nodes:"); for (ParasiticNode *node : nodes(parasitic)) - report_->reportLine("%s%s %s", - name(node), - isExternal(node) ? " (ext)" : "", - cap_unit->asString(nodeGndCap(node))); - report_->reportLine("Resistors:"); + report_->report("{}{} {}", name(node), isExternal(node) ? " (ext)" : "", + cap_unit->asString(nodeGndCap(node))); + report_->report("Resistors:"); for (ParasiticResistor *res : resistors(parasitic)) { ParasiticNode *node1 = this->node1(res); ParasiticNode *node2 = this->node2(res); - report_->reportLine("%zu %s%s %s%s %s", - id(res), - name(node1), - isExternal(node1) ? " (ext)" : "", - name(node2), - isExternal(node2) ? " (ext)" : "", - units_->resistanceUnit()->asString(value(res))); + report_->report("{} {}{} {}{} {}", id(res), name(node1), + isExternal(node1) ? " (ext)" : "", name(node2), + isExternal(node2) ? " (ext)" : "", + units_->resistanceUnit()->asString(value(res))); } - report_->reportLine("Coupling Capacitors:"); + report_->report("Coupling Capacitors:"); for (ParasiticCapacitor *cap : capacitors(parasitic)) { ParasiticNode *node1 = this->node1(cap); ParasiticNode *node2 = this->node2(cap); - report_->reportLine("%zu %s%s %s%s %s", - id(cap), - name(node1), - isExternal(node1) ? " (ext)" : "", - name(node2), - isExternal(node2) ? " (ext)" : "", - cap_unit->asString(value(cap))); + report_->report("{} {}{} {}{} {}", id(cap), name(node1), + isExternal(node1) ? " (ext)" : "", name(node2), + isExternal(node2) ? " (ext)" : "", + cap_unit->asString(value(cap))); } } } @@ -138,10 +129,10 @@ Parasitics::parasiticNodeResistorMap(const Parasitic *parasitic) const return resistor_map; } -ParasiticNodeCapacitorMap +ParasiticNodeCapacitorMap Parasitics::parasiticNodeCapacitorMap(const Parasitic *parasitic) const { - ParasiticNodeCapacitorMap capacitor_map; + ParasiticNodeCapacitorMap capacitor_map; for (ParasiticCapacitor *capacitor : capacitors(parasitic)) { ParasiticNode *n1 = node1(capacitor); ParasiticNode *n2 = node2(capacitor); @@ -186,9 +177,8 @@ Parasitics::reduceToPiElmore(const Parasitic *parasitic, const Scene *scene, const MinMax *min_max) { - return sta::reduceToPiElmore(parasitic, drvr_pin, rf, - coupling_cap_factor_, - scene, min_max, this); + return sta::reduceToPiElmore(parasitic, drvr_pin, rf, coupling_cap_factor_, scene, + min_max, this); } Parasitic * @@ -198,8 +188,7 @@ Parasitics::reduceToPiPoleResidue2(const Parasitic *parasitic, const Scene *scene, const MinMax *min_max) { - return sta::reduceToPiPoleResidue2(parasitic, drvr_pin, rf, - coupling_cap_factor_, + return sta::reduceToPiPoleResidue2(parasitic, drvr_pin, rf, coupling_cap_factor_, scene, min_max, this); } @@ -217,10 +206,9 @@ Parasitics::estimatePiElmore(const Pin *drvr_pin, EstimateParasitics estimate(this); float c2, rpi, c1, elmore_res, elmore_cap; bool elmore_use_load_cap; - estimate.estimatePiElmore(drvr_pin, rf, wireload, fanout, net_pin_cap, - scene, min_max, - c2, rpi, c1, - elmore_res, elmore_cap, elmore_use_load_cap); + estimate.estimatePiElmore(drvr_pin, rf, wireload, fanout, net_pin_cap, scene, + min_max, c2, rpi, c1, elmore_res, elmore_cap, + elmore_use_load_cap); if (c1 > 0.0 || c2 > 0.0) { Parasitic *parasitic = makePiElmore(drvr_pin, rf, min_max, c2, rpi, c1); @@ -265,19 +253,19 @@ Parasitics::makeWireloadNetwork(const Pin *drvr_pin, if (op_cond) tree = op_cond->wireloadTree(); switch (tree) { - case WireloadTree::worst_case: - makeWireloadNetworkWorst(parasitic, drvr_pin, net, wireload_cap, - wireload_res, fanout); - break; - case WireloadTree::balanced: - makeWireloadNetworkBalanced(parasitic, drvr_pin, wireload_cap, - wireload_res, fanout); - break; - case WireloadTree::best_case: - case WireloadTree::unknown: - makeWireloadNetworkBest(parasitic, drvr_pin, wireload_cap, - wireload_res, fanout); - break; + case WireloadTree::worst_case: + makeWireloadNetworkWorst(parasitic, drvr_pin, net, wireload_cap, + wireload_res, fanout); + break; + case WireloadTree::balanced: + makeWireloadNetworkBalanced(parasitic, drvr_pin, wireload_cap, wireload_res, + fanout); + break; + case WireloadTree::best_case: + case WireloadTree::unknown: + makeWireloadNetworkBest(parasitic, drvr_pin, wireload_cap, wireload_res, + fanout); + break; } } return parasitic; @@ -298,12 +286,10 @@ Parasitics::makeWireloadNetworkWorst(Parasitic *parasitic, ParasiticNode *load_node = ensureParasiticNode(parasitic, net, 0, network_); makeResistor(parasitic, resistor_index++, wireload_res, drvr_node, load_node); incrCap(load_node, wireload_cap); - PinConnectedPinIterator *load_iter = - network_->connectedPinIterator(drvr_pin); + PinConnectedPinIterator *load_iter = network_->connectedPinIterator(drvr_pin); while (load_iter->hasNext()) { const Pin *load_pin = load_iter->next(); - if (load_pin != drvr_pin - && network_->isLoad(load_pin)) { + if (load_pin != drvr_pin && network_->isLoad(load_pin)) { ParasiticNode *load_node1 = ensureParasiticNode(parasitic, load_pin, network_); makeResistor(parasitic, resistor_index++, 0.0, load_node, load_node1); } @@ -320,13 +306,11 @@ Parasitics::makeWireloadNetworkBest(Parasitic *parasitic, { ParasiticNode *drvr_node = ensureParasiticNode(parasitic, drvr_pin, network_); incrCap(drvr_node, wireload_cap); - PinConnectedPinIterator *load_iter = - network_->connectedPinIterator(drvr_pin); + PinConnectedPinIterator *load_iter = network_->connectedPinIterator(drvr_pin); size_t resistor_index = 1; while (load_iter->hasNext()) { const Pin *load_pin = load_iter->next(); - if (load_pin != drvr_pin - && network_->isLoad(load_pin)) { + if (load_pin != drvr_pin && network_->isLoad(load_pin)) { ParasiticNode *load_node1 = ensureParasiticNode(parasitic, load_pin, network_); makeResistor(parasitic, resistor_index++, 0.0, drvr_node, load_node1); } @@ -345,15 +329,13 @@ Parasitics::makeWireloadNetworkBalanced(Parasitic *parasitic, float fanout_cap = wireload_cap / fanout; float fanout_res = wireload_res / fanout; ParasiticNode *drvr_node = ensureParasiticNode(parasitic, drvr_pin, network_); - PinConnectedPinIterator *load_iter = - network_->connectedPinIterator(drvr_pin); + PinConnectedPinIterator *load_iter = network_->connectedPinIterator(drvr_pin); size_t resistor_index = 1; while (load_iter->hasNext()) { const Pin *load_pin = load_iter->next(); - if (load_pin != drvr_pin - && network_->isLoad(load_pin)) { + if (load_pin != drvr_pin && network_->isLoad(load_pin)) { ParasiticNode *load_node1 = ensureParasiticNode(parasitic, load_pin, network_); - makeResistor(parasitic, resistor_index++, fanout_res, drvr_node, load_node1); + makeResistor(parasitic, resistor_index++, fanout_res, drvr_node, load_node1); incrCap(load_node1, fanout_cap); } } @@ -391,12 +373,10 @@ ParasiticNodeLess::operator()(const ParasiticNode *node1, unsigned id1 = parasitics_->netId(node1); unsigned id2 = parasitics_->netId(node2); return (pin1 == nullptr && pin2) - || (pin1 && pin2 - && network_->id(pin1) < network_->id(pin2)) - || (pin1 == nullptr && pin2 == nullptr - && (network_->id(net1) < network_->id(net2) - || (net1 == net2 - && id1 < id2))); + || (pin1 && pin2 && network_->id(pin1) < network_->id(pin2)) + || (pin1 == nullptr && pin2 == nullptr + && (network_->id(net1) < network_->id(net2) + || (net1 == net2 && id1 < id2))); } -} // namespace +} // namespace sta diff --git a/parasitics/ReduceParasitics.cc b/parasitics/ReduceParasitics.cc index 6dbab37d..4282a7f4 100644 --- a/parasitics/ReduceParasitics.cc +++ b/parasitics/ReduceParasitics.cc @@ -147,7 +147,7 @@ ReduceToPi::reduceToPi(const Parasitic *parasitic_network, rpi = -y3 * y3 / (y2 * y2 * y2); } debugPrint(debug_, "parasitic_reduce", 2, - " Pi model c2=%.3g rpi=%.3g c1=%.3g max_r=%.3g", + " Pi model c2={:.3g} rpi={:.3g} c1={:.3g} max_r={:.3g}", c2, rpi, c1, max_resistance); } @@ -185,7 +185,7 @@ ReduceToPi::reducePiDfs(const Pin *drvr_pin, && resistor != from_res) { if (isVisited(onode)) { // Resistor loop. - debugPrint(debug_, "parasitic_reduce", 2, " loop detected thru resistor %zu", + debugPrint(debug_, "parasitic_reduce", 2, " loop detected thru resistor {}", parasitics_->id(resistor)); markLoopResistor(resistor); } @@ -208,7 +208,7 @@ ReduceToPi::reducePiDfs(const Pin *drvr_pin, setDownstreamCap(node, dwn_cap); leave(node); debugPrint(debug_, "parasitic_reduce", 3, - " node %s y1=%.3g y2=%.3g y3=%.3g cap=%.3g", + " node {} y1={:.3g} y2={:.3g} y3={:.3g} cap={:.3g}", parasitics_->name(node), y1, y2, y3, dwn_cap); } @@ -309,10 +309,10 @@ reduceToPiElmore(const Parasitic *parasitic_network, ParasiticNode *drvr_node = parasitics->findParasiticNode(parasitic_network, drvr_pin); if (drvr_node) { - debugPrint(sta->debug(), "parasitic_reduce", 1, "Reduce driver %s %s %s", + debugPrint(sta->debug(), "parasitic_reduce", 1, "Reduce driver {} {} {}", sta->network()->pathName(drvr_pin), rf->shortName(), - min_max->to_string().c_str()); + min_max->to_string()); ReduceToPiElmore reducer(sta); return reducer.makePiElmore(parasitic_network, drvr_pin, drvr_node, coupling_cap_factor, rf, scene, min_max); @@ -356,7 +356,7 @@ ReduceToPiElmore::reduceElmoreDfs(const Pin *drvr_pin, const Pin *pin = parasitics_->pin(node); if (from_res && pin) { if (network_->isLoad(pin)) { - debugPrint(debug_, "parasitic_reduce", 2, " Load %s elmore=%.3g", + debugPrint(debug_, "parasitic_reduce", 2, " Load {} elmore={:.3g}", network_->pathName(pin), elmore); parasitics_->setElmore(pi_elmore, pin, elmore); @@ -456,7 +456,7 @@ reduceToPiPoleResidue2(const Parasitic *parasitic_network, ParasiticNode *drvr_node = parasitics->findParasiticNode(parasitic_network, drvr_pin); if (drvr_node) { - debugPrint(sta->debug(), "parasitic_reduce", 1, "Reduce driver %s", + debugPrint(sta->debug(), "parasitic_reduce", 1, "Reduce driver {}", sta->network()->pathName(drvr_pin)); ReduceToPiPoleResidue2 reducer(sta); return reducer.makePiPoleResidue2(parasitic_network, drvr_pin, drvr_node, @@ -564,7 +564,7 @@ ReduceToPiPoleResidue2::findBranchCurrents(const Pin *drvr_pin, leave(node); if (from_res) { setCurrent(from_res, branch_i); - debugPrint(debug_, "parasitic_reduce", 3, " res i=%.3g", branch_i); + debugPrint(debug_, "parasitic_reduce", 3, " res i={:.3g}", branch_i); } return branch_i; } @@ -589,7 +589,7 @@ ReduceToPiPoleResidue2::findMoments(const Pin *drvr_pin, double r_volt = r * current(resistor); double onode_volt = from_volt - r_volt; setMoment(onode, onode_volt, moment_index); - debugPrint(debug_, "parasitic_reduce", 3, " moment %s %d %.3g", + debugPrint(debug_, "parasitic_reduce", 3, " moment {} {} {:.3g}", parasitics_->name(onode), moment_index, onode_volt); @@ -655,7 +655,7 @@ ReduceToPiPoleResidue2::findPolesResidues(Parasitic *pi_pole_residue, || m1 / m2 == m2 / m3) { double p1 = -1.0 / m1; double k1 = 1.0; - debugPrint(debug_, "parasitic_reduce", 3, " load %s p1=%.3g k1=%.3g", + debugPrint(debug_, "parasitic_reduce", 3, " load {} p1={:.3g} k1={:.3g}", network_->pathName(load_pin), p1, k1); ComplexFloatSeq *poles = new ComplexFloatSeq(1); ComplexFloatSeq *residues = new ComplexFloatSeq(1); @@ -675,7 +675,7 @@ ReduceToPiPoleResidue2::findPolesResidues(Parasitic *pi_pole_residue, k1 = k; } debugPrint(debug_, "parasitic_reduce", 3, - " load %s p1=%.3g p2=%.3g k1=%.3g k2=%.3g", + " load {} p1={:.3g} p2={:.3g} k1={:.3g} k2={:.3g}", network_->pathName(load_pin), p1, p2, k1, k2); ComplexFloatSeq *poles = new ComplexFloatSeq(2); diff --git a/parasitics/ReportParasiticAnnotation.cc b/parasitics/ReportParasiticAnnotation.cc index a6726911..f91db926 100644 --- a/parasitics/ReportParasiticAnnotation.cc +++ b/parasitics/ReportParasiticAnnotation.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 "ReportParasiticAnnotation.hh" @@ -65,8 +65,8 @@ reportParasiticAnnotation(Parasitics *parasitics, const Scene *scene, StaState *sta) { - ReportParasiticAnnotation report_annotation(parasitics, report_unannotated, - scene, sta); + ReportParasiticAnnotation report_annotation(parasitics, report_unannotated, scene, + sta); report_annotation.report(); } @@ -92,25 +92,26 @@ ReportParasiticAnnotation::report() void ReportParasiticAnnotation::reportAnnotationCounts() { - report_->reportLine("Found %zu unannotated drivers.", unannotated_.size()); + report_->report("Found {} unannotated drivers.", unannotated_.size()); if (report_unannotated_) { sort(unannotated_, PinPathNameLess(network_)); for (const Pin *drvr_pin : unannotated_) - report_->reportLine(" %s", network_->pathName(drvr_pin)); + report_->report(" {}", network_->pathName(drvr_pin)); } - report_->reportLine("Found %zu partially unannotated drivers.", - partially_annotated_.size()); + report_->report("Found {} partially unannotated drivers.", + partially_annotated_.size()); if (report_unannotated_) { sort(partially_annotated_, PinPathNameLess(network_)); for (const Pin *drvr_pin : partially_annotated_) { - report_->reportLine(" %s", network_->pathName(drvr_pin)); + report_->report(" {}", network_->pathName(drvr_pin)); Parasitic *parasitic = parasitics_->findParasiticNetwork(drvr_pin); if (parasitic) { - PinSet unannotated_loads = parasitics_->unannotatedLoads(parasitic, drvr_pin); + PinSet unannotated_loads = + parasitics_->unannotatedLoads(parasitic, drvr_pin); for (const Pin *load_pin : unannotated_loads) - report_->reportLine(" %s", network_->pathName(load_pin)); + report_->report(" {}", network_->pathName(load_pin)); } } } @@ -124,21 +125,20 @@ ReportParasiticAnnotation::findCounts() Vertex *vertex = vertex_iter.next(); Pin *pin = vertex->pin(); PortDirection *dir = network_->direction(pin); - if (vertex->isDriver(network_) - && !dir->isInternal()) { + if (vertex->isDriver(network_) && !dir->isInternal()) { Parasitic *parasitic = parasitics_->findParasiticNetwork(pin); if (parasitic == nullptr) - parasitic = arc_delay_calc_->findParasitic(pin, RiseFall::rise(), - scene_, min_max_); + parasitic = + arc_delay_calc_->findParasitic(pin, RiseFall::rise(), scene_, min_max_); if (parasitic) { PinSet unannotated_loads = parasitics_->unannotatedLoads(parasitic, pin); if (unannotated_loads.size() > 0) partially_annotated_.push_back(pin); } - else + else unannotated_.push_back(pin); } } } -} // namespace +} // namespace sta diff --git a/parasitics/SpefParse.yy b/parasitics/SpefParse.yy index 42983f0b..a88e2d26 100755 --- a/parasitics/SpefParse.yy +++ b/parasitics/SpefParse.yy @@ -41,8 +41,7 @@ void sta::SpefParse::error(const location_type &loc, const std::string &msg) { - reader->report()->fileError(164,reader->filename().c_str(), - loc.begin.line,"%s",msg.c_str()); + reader->report()->fileError(1670,reader->filename(), loc.begin. line, "{}", msg); } %} @@ -831,7 +830,7 @@ pos_integer: INTEGER { int value = $1; if (value < 0) - reader->warn(1525, "%d is not positive.", value); + reader->warn(1525, "{} is not positive.", value); $$ = value; } ; @@ -840,13 +839,13 @@ pos_number: INTEGER { float value = static_cast($1); if (value < 0) - reader->warn(1526, "%.4f is not positive.", value); + reader->warn(1526, "{:.4f} is not positive.", value); $$ = value; } | FLOAT { float value = static_cast($1); if (value < 0) - reader->warn(1527, "%.4f is not positive.", value); + reader->warn(1527, "{:.4f} is not positive.", value); $$ = value; } ; diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 99c53633..2bc516ae 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.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 "SpefReader.hh" @@ -55,9 +55,8 @@ readSpefFile(const std::string &filename, Parasitics *parasitics, StaState *sta) { - SpefReader reader(filename, instance, pin_cap_included, - keep_coupling_caps, coupling_cap_factor, - reduce, scene, min_max, parasitics, sta); + SpefReader reader(filename, instance, pin_cap_included, keep_coupling_caps, + coupling_cap_factor, reduce, scene, min_max, parasitics, sta); bool success = reader.read(); return success; } @@ -98,9 +97,7 @@ SpefReader::SpefReader(const std::string &filename, parasitics->setCouplingCapFactor(coupling_cap_factor); } -SpefReader::~SpefReader() -{ -} +SpefReader::~SpefReader() {} bool SpefReader::read() @@ -112,13 +109,13 @@ SpefReader::read() SpefScanner scanner(&stream, filename_, this, report_); scanner_ = &scanner; SpefParse parser(&scanner, this); - //parser.set_debug_level(1); - // yyparse returns 0 on success. + // parser.set_debug_level(1); + // yyparse returns 0 on success. success = (parser.parse() == 0); stats.report("Read spef"); } else - throw FileNotReadable(filename_.c_str()); + throw FileNotReadable(filename_); return success; } @@ -138,12 +135,9 @@ void SpefReader::setBusBrackets(char left, char right) { - if (!((left == '[' && right == ']') - || (left == '{' && right == '}') - || (left == '(' && right == ')') - || (left == '<' && right == '>') - || (left == ':' && right == '\0') - || (left == '.' && right == '\0'))) + if (!((left == '[' && right == ']') || (left == '{' && right == '}') + || (left == '(' && right == ')') || (left == '<' && right == '>') + || (left == ':' && right == '\0') || (left == '.' && right == '\0'))) warn(1640, "illegal bus delimiters."); bus_brkt_left_ = left; bus_brkt_right_ = right; @@ -181,19 +175,16 @@ SpefReader::findPortPinRelative(const char *name) char * SpefReader::translated(const char *token) { - return spefToSta(token, divider_, network_->pathDivider(), - network_->pathEscape()); + return spefToSta(token, divider_, network_->pathDivider(), network_->pathEscape()); } -void -SpefReader::warn(int id, const char *fmt, ...) +int +SpefReader::warnLine() const { - va_list args; - va_start(args, fmt); - report_->vfileWarn(id, filename_.c_str(), scanner_->line(), fmt, args); - va_end(args); + return scanner_->line(); } + void SpefReader::setTimeScale(float scale, const char *units) @@ -203,7 +194,7 @@ SpefReader::setTimeScale(float scale, else if (stringEq(units, "PS")) time_scale_ = scale * 1E-12F; else - warn(1641, "unknown units %s.", units); + warn(1641, "unknown units {}.", units); stringDelete(units); } @@ -216,7 +207,7 @@ SpefReader::setCapScale(float scale, else if (stringEq(units, "FF")) cap_scale_ = scale * 1E-15F; else - warn(1642, "unknown units %s.", units); + warn(1642, "unknown units {}.", units); stringDelete(units); } @@ -229,7 +220,7 @@ SpefReader::setResScale(float scale, else if (stringEq(units, "KOHM")) res_scale_ = scale * 1E+3F; else - warn(1643, "unknown units %s.", units); + warn(1643, "unknown units {}.", units); stringDelete(units); } @@ -244,7 +235,7 @@ SpefReader::setInductScale(float scale, else if (stringEq(units, "UH")) induct_scale_ = scale * 1E-6F; else - warn(1644, "unknown units %s.", units); + warn(1644, "unknown units {}.", units); stringDelete(units); } @@ -267,7 +258,7 @@ SpefReader::nameMapLookup(const char *name) if (itr != name_map_.end()) return itr->second.c_str(); else { - warn(1645, "no name map entry for %d.", index); + warn(1645, "no name map entry for {}.", index); return nullptr; } } @@ -286,7 +277,7 @@ SpefReader::portDirection(char *spef_dir) else if (stringEq(spef_dir, "B")) direction = PortDirection::bidirect(); else - warn(1646, "unknown port direction %s.", spef_dir); + warn(1646, "unknown port direction {}.", spef_dir); return direction; } @@ -314,16 +305,16 @@ SpefReader::findPin(char *name) if (inst) { pin = network_->findPin(inst, port_name); if (pin == nullptr) - warn(1647, "pin %s not found.", name1); + warn(1647, "pin {} not found.", name1); } else - warn(1648, "instance %s not found.", name1); + warn(1648, "instance {} not found.", name1); } } else { pin = findPortPinRelative(name); if (pin == nullptr) - warn(1649, "pin %s not found.", name); + warn(1649, "pin {} not found.", name); } } return pin; @@ -337,7 +328,7 @@ SpefReader::findNet(const char *name) if (name1) { net = findNetRelative(name1); if (net == nullptr) - warn(1650, "net %s not found.", name1); + warn(1650, "net {} not found.", name1); } return net; } @@ -366,9 +357,7 @@ SpefReader::rspfDrvrBegin(Pin *drvr_pin, float rpi = pi->r1()->value(triple_index_) * res_scale_; float c1 = pi->c1()->value(triple_index_) * cap_scale_; // Only one parasitic, save it under rise transition. - parasitic_ = parasitics_->makePiElmore(drvr_pin, - RiseFall::rise(), - MinMax::max(), + parasitic_ = parasitics_->makePiElmore(drvr_pin, RiseFall::rise(), MinMax::max(), c2, rpi, c1); } delete pi; @@ -412,8 +401,8 @@ SpefReader::dspfBegin(Net *net, delete term_iter; parasitic_ = parasitics_->findParasiticNetwork(parasitic_owner); if (parasitic_ == nullptr) - parasitic_ = parasitics_->makeParasiticNetwork(parasitic_owner, - pin_cap_included_); + parasitic_ = + parasitics_->makeParasiticNetwork(parasitic_owner, pin_cap_included_); } net_ = net; } @@ -451,16 +440,15 @@ SpefReader::findParasiticNode(char *name, // : Pin *pin = network_->findPin(inst, name2); if (pin) { - if (local_only - && !network_->isConnected(net_, pin)) - warn(1651, "%s not connected to net %s.", - name1, sdc_network_->pathName(net_)); + if (local_only && !network_->isConnected(net_, pin)) + warn(1651, "{} not connected to net {}.", name1, + sdc_network_->pathName(net_)); return parasitics_->ensureParasiticNode(parasitic_, pin, network_); } else { // Replace delimiter for error message. *delim = delimiter_; - warn(1652, "pin %s not found.", name1); + warn(1652, "pin {} not found.", name1); } } else { @@ -472,15 +460,13 @@ SpefReader::findParasiticNode(char *name, const char *id_str = delim + 1; if (isDigits(id_str)) { int id = atoi(id_str); - if (local_only - && !network_->isConnected(net, net_)) - warn(1653, "%s not connected to net %s.", - name1, + if (local_only && !network_->isConnected(net, net_)) + warn(1653, "{} not connected to net {}.", name1, network_->pathName(net_)); return parasitics_->ensureParasiticNode(parasitic_, net, id, network_); } else - warn(1654, "node %s not a pin or net:number", name1); + warn(1654, "node {} not a pin or net:number", name1); } } } @@ -491,23 +477,24 @@ SpefReader::findParasiticNode(char *name, if (name1) { Pin *pin = findPortPinRelative(name1); if (pin) { - if (local_only - && !network_->isConnected(net_, pin)) - warn(1655, "%s not connected to net %s.", name1, network_->pathName(net_)); + if (local_only && !network_->isConnected(net_, pin)) + warn(1655, "{} not connected to net {}.", name1, + network_->pathName(net_)); return parasitics_->ensureParasiticNode(parasitic_, pin, network_); } else - warn(1656, "pin %s not found.", name1); + warn(1656, "pin {} not found.", name1); } else - warn(1657, "pin %s not found.", name); + warn(1657, "pin {} not found.", name); } } return nullptr; } void -SpefReader::makeCapacitor(int, char *node_name, +SpefReader::makeCapacitor(int, + char *node_name, SpefTriple *cap) { ParasiticNode *node = findParasiticNode(node_name, true); @@ -622,7 +609,7 @@ SpefScanner::SpefScanner(std::istream *stream, void SpefScanner::error(const char *msg) { - report_->fileError(1867, filename_.c_str(), lineno(), "%s", msg); + report_->fileError(1658, filename_.c_str(), lineno(), "{}", msg); } -} // namespace +} // namespace sta diff --git a/parasitics/SpefReaderPvt.hh b/parasitics/SpefReaderPvt.hh index cf58eb51..7b01fda6 100644 --- a/parasitics/SpefReaderPvt.hh +++ b/parasitics/SpefReaderPvt.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include "Zlib.hh" #include "StringUtil.hh" @@ -65,10 +66,6 @@ public: const std::string &filename() const { return filename_; } // Translate from spf/spef namespace to sta namespace. char *translated(const char *token); - void warn(int id, - const char *fmt, - ...) - __attribute__((format (printf, 3, 4))); void setBusBrackets(char left, char right); void setTimeScale(float scale, @@ -108,6 +105,15 @@ public: char *node_name2, SpefTriple *res); PortDirection *portDirection(char *spef_dir); + int warnLine() const; + template + void warn(int id, + std::string_view fmt, + Args &&...args) + { + report_->fileWarn(id, filename_, warnLine(), fmt, + std::forward(args)...); + } private: Pin *findPinRelative(const char *name); diff --git a/power/Power.cc b/power/Power.cc index 7a3de2af..d4dd239c 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -1,31 +1,31 @@ // 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 "Power.hh" -#include // max -#include // abs +#include // max +#include // abs #include "cudd.h" #include "ContainerHelpers.hh" @@ -74,26 +74,28 @@ namespace sta { static bool isPositiveUnate(const LibertyCell *cell, - const LibertyPort *from, - const LibertyPort *to); + const LibertyPort *from, + const LibertyPort *to); -static EnumNameMap pwr_activity_origin_map = - {{PwrActivityOrigin::global, "global"}, - {PwrActivityOrigin::input, "input"}, - {PwrActivityOrigin::user, "user"}, - {PwrActivityOrigin::vcd, "vcd"}, - {PwrActivityOrigin::saif, "saif"}, - {PwrActivityOrigin::propagated, "propagated"}, - {PwrActivityOrigin::clock, "clock"}, - {PwrActivityOrigin::constant, "constant"}, - {PwrActivityOrigin::unknown, "unknown"}}; +static EnumNameMap pwr_activity_origin_map = { + {PwrActivityOrigin::global, "global"}, + {PwrActivityOrigin::input, "input"}, + {PwrActivityOrigin::user, "user"}, + {PwrActivityOrigin::vcd, "vcd"}, + {PwrActivityOrigin::saif, "saif"}, + {PwrActivityOrigin::propagated, "propagated"}, + {PwrActivityOrigin::clock, "clock"}, + {PwrActivityOrigin::constant, "constant"}, + {PwrActivityOrigin::unknown, "unknown"}}; Power::Power(StaState *sta) : StaState(sta), scene_(nullptr), global_activity_(), - input_activity_(), // default set in ensureActivities. - seq_activity_map_(100, SeqPinHash(network_), SeqPinEqual()), + input_activity_(), // default set in ensureActivities. + seq_activity_map_(100, + SeqPinHash(network_), + SeqPinEqual()), activities_valid_(false), bdd_(sta), instance_powers_(InstanceIdLess(network_)), @@ -123,12 +125,12 @@ Power::activitiesInvalid() void Power::setGlobalActivity(float density, - float duty) + float duty) { global_activity_.set(density, duty, PwrActivityOrigin::global); activitiesInvalid(); } - + void Power::unsetGlobalActivity() { @@ -138,7 +140,7 @@ Power::unsetGlobalActivity() void Power::setInputActivity(float density, - float duty) + float duty) { input_activity_.set(density, duty, PwrActivityOrigin::input); activitiesInvalid(); @@ -153,8 +155,8 @@ Power::unsetInputActivity() void Power::setInputPortActivity(const Port *input_port, - float density, - float duty) + float density, + float duty) { Instance *top_inst = network_->topInstance(); const Pin *pin = network_->findPin(top_inst, input_port); @@ -206,12 +208,10 @@ Power::hasUserActivity(const Pin *pin) void Power::setActivity(const Pin *pin, - PwrActivity &activity) + PwrActivity &activity) { - debugPrint(debug_, "power_activity", 3, "set %s %.2e %.2f %s", - network_->pathName(pin), - activity.density(), - activity.duty(), + debugPrint(debug_, "power_activity", 3, "set {} {:.2e} {:.2f} {}", + network_->pathName(pin), activity.density(), activity.duty(), pwr_activity_origin_map.find(activity.origin())); activity_map_[pin] = activity; } @@ -232,8 +232,8 @@ Power::hasActivity(const Pin *pin) // activities are stored by instance/liberty_port pairs. void Power::setSeqActivity(const Instance *reg, - LibertyPort *output, - PwrActivity &activity) + LibertyPort *output, + PwrActivity &activity) { seq_activity_map_[SeqPin(reg, output)] = activity; activitiesInvalid(); @@ -241,14 +241,14 @@ Power::setSeqActivity(const Instance *reg, bool Power::hasSeqActivity(const Instance *reg, - LibertyPort *output) + LibertyPort *output) { return seq_activity_map_.contains(SeqPin(reg, output)); } PwrActivity & Power::seqActivity(const Instance *reg, - LibertyPort *output) + LibertyPort *output) { return seq_activity_map_[SeqPin(reg, output)]; } @@ -261,18 +261,17 @@ SeqPinHash::SeqPinHash(const Network *network) : size_t SeqPinHash::operator()(const SeqPin &pin) const { - const auto& [inst, port] = pin; + const auto &[inst, port] = pin; return hashSum(network_->id(inst), port->id()); } bool SeqPinEqual::operator()(const SeqPin &pin1, - const SeqPin &pin2) const + const SeqPin &pin2) const { - const auto& [inst1, port1] = pin1; - const auto& [inst2, port2] = pin2; - return inst1 == inst2 - && port1 == port2; + const auto &[inst1, port1] = pin1; + const auto &[inst2, port2] = pin2; + return inst1 == inst2 && port1 == port2; } //////////////////////////////////////////////////////////////// @@ -284,7 +283,8 @@ Power::reportDesign(const Scene *scene, PowerResult total, sequential, combinational, clock, macro, pad; power(scene, total, sequential, combinational, clock, macro, pad); ReportPower report_power(this); - report_power.reportDesign(total, sequential, combinational, clock, macro, pad, digits); + report_power.reportDesign(total, sequential, combinational, clock, macro, pad, + digits); } void @@ -313,15 +313,15 @@ Power::reportDesignJson(const Scene *scene, { PowerResult total, sequential, combinational, clock, macro, pad; power(scene, total, sequential, combinational, clock, macro, pad); - - report_->reportLine("{"); + + report_->report("{{"); reportPowerRowJson("Sequential", sequential, digits, ","); reportPowerRowJson("Combinational", combinational, digits, ","); reportPowerRowJson("Clock", clock, digits, ","); reportPowerRowJson("Macro", macro, digits, ","); reportPowerRowJson("Pad", pad, digits, ","); reportPowerRowJson("Total", total, digits, ""); - report_->reportLine("}"); + report_->report("}}"); } void @@ -330,17 +330,17 @@ Power::reportInstsJson(const InstanceSeq &insts, int digits) { InstPowers inst_pwrs = sortInstsByPower(insts, scene); - - report_->reportLine("["); + + report_->report("["); bool first = true; for (const InstPower &inst_pwr : inst_pwrs) { if (!first) { - report_->reportLine(","); + report_->report(","); } first = false; reportPowerInstJson(inst_pwr.first, inst_pwr.second, digits); } - report_->reportLine("]"); + report_->report("]"); } void @@ -353,16 +353,16 @@ Power::reportPowerRowJson(const char *name, float switching = power.switching(); float leakage = power.leakage(); float total = power.total(); - - report_->reportLine(" \"%s\": {", name); - report_->reportLine(" \"internal\": %.*e,", digits, internal); - report_->reportLine(" \"switching\": %.*e,", digits, switching); - report_->reportLine(" \"leakage\": %.*e,", digits, leakage); - report_->reportLine(" \"total\": %.*e", digits, total); + + report_->report(" \"{}\": {{", name); + report_->report(" \"internal\": {:.{}e},", internal, digits); + report_->report(" \"switching\": {:.{}e},", switching, digits); + report_->report(" \"leakage\": {:.{}e},", leakage, digits); + report_->report(" \"total\": {:.{}e}", total, digits); std::string line = " }"; if (separator && separator[0] != '\0') line += separator; - report_->reportLineString(line); + report_->reportLine(line); } void @@ -374,15 +374,15 @@ Power::reportPowerInstJson(const Instance *inst, float switching = power.switching(); float leakage = power.leakage(); float total = power.total(); - + const char *inst_name = network_->pathName(inst); - report_->reportLine("{"); - report_->reportLine(" \"name\": \"%s\",", inst_name); - report_->reportLine(" \"internal\": %.*e,", digits, internal); - report_->reportLine(" \"switching\": %.*e,", digits, switching); - report_->reportLine(" \"leakage\": %.*e,", digits, leakage); - report_->reportLine(" \"total\": %.*e", digits, total); - report_->reportLine("}"); + report_->report("{{"); + report_->report(" \"name\": \"{}\",", inst_name); + report_->report(" \"internal\": {:.{}e},", internal, digits); + report_->report(" \"switching\": {:.{}e},", switching, digits); + report_->report(" \"leakage\": {:.{}e},", leakage, digits); + report_->report(" \"total\": {:.{}e}", total, digits); + report_->report("}}"); } static bool @@ -402,7 +402,7 @@ Power::sortInstsByPower(const InstanceSeq &insts, PowerResult inst_power = power(inst, scene); inst_pwrs.push_back(std::make_pair(inst, inst_power)); } - + // Sort by total power (descending) sort(inst_pwrs, instPowerGreater); return inst_pwrs; @@ -412,13 +412,13 @@ Power::sortInstsByPower(const InstanceSeq &insts, void Power::power(const Scene *scene, - // Return values. - PowerResult &total, - PowerResult &sequential, - PowerResult &combinational, + // Return values. + PowerResult &total, + PowerResult &sequential, + PowerResult &combinational, PowerResult &clock, - PowerResult ¯o, - PowerResult &pad) + PowerResult ¯o, + PowerResult &pad) { total.clear(); sequential.clear(); @@ -433,18 +433,16 @@ Power::power(const Scene *scene, for (auto [inst, inst_power] : instance_powers_) { LibertyCell *cell = network_->libertyCell(inst); if (cell) { - if (cell->isMacro() - || cell->isMemory() - || cell->interfaceTiming()) - macro.incr(inst_power); + if (cell->isMacro() || cell->isMemory() || cell->interfaceTiming()) + macro.incr(inst_power); else if (cell->isPad()) - pad.incr(inst_power); + pad.incr(inst_power); else if (inClockNetwork(inst, clk_network)) - clock.incr(inst_power); + clock.incr(inst_power); else if (cell->hasSequentials()) - sequential.incr(inst_power); + sequential.incr(inst_power); else - combinational.incr(inst_power); + combinational.incr(inst_power); total.incr(inst_power); } } @@ -457,8 +455,7 @@ Power::inClockNetwork(const Instance *inst, InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { const Pin *pin = pin_iter->next(); - if (network_->direction(pin)->isAnyOutput() - && !clk_network->isClock(pin)) { + if (network_->direction(pin)->isAnyOutput() && !clk_network->isClock(pin)) { delete pin_iter; return false; } @@ -553,12 +550,9 @@ ActivitySrchPred::searchThru(Edge *edge, { const Sdc *sdc = mode->sdc(); const TimingRole *role = edge->role(); - return !(edge->role()->isTimingCheck() - || sdc->isDisabledConstraint(edge) - || sdc->isDisabledCondDefault(edge) - || edge->isBidirectInstPath() - || edge->isDisabledLoop() - || role == TimingRole::regClkToQ() + return !(edge->role()->isTimingCheck() || sdc->isDisabledConstraint(edge) + || sdc->isDisabledCondDefault(edge) || edge->isBidirectInstPath() + || edge->isDisabledLoop() || role == TimingRole::regClkToQ() || role->isLatchDtoQ()); } @@ -576,7 +570,7 @@ class PropActivityVisitor : public VertexVisitor, StaState public: PropActivityVisitor(Power *power, const Mode *mode, - BfsFwdIterator *bfs); + BfsFwdIterator *bfs); virtual VertexVisitor *copy() const; virtual void visit(Vertex *vertex); InstanceSet &visitedRegs() { return visited_regs_; } @@ -599,7 +593,7 @@ private: PropActivityVisitor::PropActivityVisitor(Power *power, const Mode *mode, - BfsFwdIterator *bfs) : + BfsFwdIterator *bfs) : StaState(power), visited_regs_(network_), max_change_(0.0), @@ -628,8 +622,8 @@ PropActivityVisitor::visit(Vertex *vertex) { Pin *pin = vertex->pin(); Instance *inst = network_->instance(pin); - debugPrint(debug_, "power_activity", 3, "visit %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "power_activity", 3, "visit {}", + vertex->to_string(this)); bool changed = false; if (power_->hasUserActivity(pin)) { PwrActivity &activity = power_->userActivity(pin); @@ -639,22 +633,21 @@ PropActivityVisitor::visit(Vertex *vertex) if (network_->isLoad(pin)) { VertexInEdgeIterator edge_iter(vertex, graph_); if (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->isWire()) { - Vertex *from_vertex = edge->from(graph_); + Edge *edge = edge_iter.next(); + if (edge->isWire()) { + Vertex *from_vertex = edge->from(graph_); const Pin *from_pin = from_vertex->pin(); - PwrActivity &from_activity = power_->activity(from_pin); - PwrActivity to_activity(from_activity.density(), - from_activity.duty(), - PwrActivityOrigin::propagated); - changed = setActivityCheck(pin, to_activity); - } + PwrActivity &from_activity = power_->activity(from_pin); + PwrActivity to_activity(from_activity.density(), from_activity.duty(), + PwrActivityOrigin::propagated); + changed = setActivityCheck(pin, to_activity); + } } } if (network_->isDriver(pin)) { LibertyPort *port = network_->libertyPort(pin); if (port) { - FuncExpr *func = port->function(); + FuncExpr *func = port->function(); if (func == nullptr) { LibertyCell *test_cell = port->libertyCell()->testCell(); if (test_cell) { @@ -663,10 +656,10 @@ PropActivityVisitor::visit(Vertex *vertex) func = port->function(); } } - if (func) { + if (func) { PwrActivity activity = power_->evalActivity(func, inst); - changed = setActivityCheck(pin, activity); - } + changed = setActivityCheck(pin, activity); + } if (port->isClockGateOut()) { const Pin *enable, *clk, *gclk; power_->clockGatePins(inst, enable, clk, gclk); @@ -676,12 +669,10 @@ PropActivityVisitor::visit(Vertex *vertex) float p1 = activity1.duty(); float p2 = activity2.duty(); PwrActivity activity(activity1.density() * p2 + activity2.density() * p1, - p1 * p2, - PwrActivityOrigin::propagated); + p1 * p2, PwrActivityOrigin::propagated); changed = setActivityCheck(gclk, activity); - debugPrint(debug_, "power_activity", 3, "gated_clk %s %.2e %.2f", - network_->pathName(gclk), - activity.density(), + debugPrint(debug_, "power_activity", 3, "gated_clk {} {:.2e} {:.2f}", + network_->pathName(gclk), activity.density(), activity.duty()); } } @@ -693,22 +684,20 @@ PropActivityVisitor::visit(Vertex *vertex) if (cell) { LibertyCell *test_cell = cell->libertyCell()->testCell(); if (network_->isLoad(pin)) { - if (cell->hasSequentials() - || (test_cell - && test_cell->hasSequentials())) { - debugPrint(debug_, "power_activity", 3, "pending seq %s", - network_->pathName(inst)); - visited_regs_.insert(inst); - } - // Gated clock cells latch the enable so there is no EN->GCLK timing arc. - if (cell->isClockGate()) { - const Pin *enable, *clk, *gclk; - power_->clockGatePins(inst, enable, clk, gclk); - if (gclk) { - Vertex *gclk_vertex = graph_->pinDrvrVertex(gclk); - bfs_->enqueue(gclk_vertex); - } - } + if (cell->hasSequentials() || (test_cell && test_cell->hasSequentials())) { + debugPrint(debug_, "power_activity", 3, "pending seq {}", + network_->pathName(inst)); + visited_regs_.insert(inst); + } + // Gated clock cells latch the enable so there is no EN->GCLK timing arc. + if (cell->isClockGate()) { + const Pin *enable, *clk, *gclk; + power_->clockGatePins(inst, enable, clk, gclk); + if (gclk) { + Vertex *gclk_vertex = graph_->pinDrvrVertex(gclk); + bfs_->enqueue(gclk_vertex); + } + } } bfs_->enqueueAdjacentVertices(vertex, mode_); } @@ -739,8 +728,7 @@ PropActivityVisitor::setActivityCheck(const Pin *pin, if (activity.density() > max_density) activity.setDensity(max_density); PwrActivity &prev_activity = power_->activity(pin); - float density_delta = percentChange(activity.density(), - prev_activity.density()); + float density_delta = percentChange(activity.density(), prev_activity.density()); float duty_delta = percentChange(activity.duty(), prev_activity.duty()); if (density_delta > max_change_) { max_change_ = density_delta; @@ -750,9 +738,9 @@ PropActivityVisitor::setActivityCheck(const Pin *pin, max_change_ = duty_delta; max_change_pin_ = pin; } - bool changed = density_delta > change_tolerance_ - || duty_delta > change_tolerance_ - || activity.origin() != prev_activity.origin();; + bool changed = density_delta > change_tolerance_ || duty_delta > change_tolerance_ + || activity.origin() != prev_activity.origin(); + ; power_->setActivity(pin, activity); return changed; } @@ -787,10 +775,10 @@ Power::clockGatePins(const Instance *inst, PwrActivity Power::evalActivity(FuncExpr *expr, - const Instance *inst) + const Instance *inst) { LibertyPort *func_port = expr->port(); - if (func_port && func_port->direction()->isInternal()) + if (func_port && func_port->direction()->isInternal()) return findSeqActivity(inst, func_port); else { DdNode *bdd = bdd_.funcBdd(expr); @@ -843,7 +831,7 @@ Power::evalBddDuty(DdNode *bdd, int var_index = Cudd_ReadPerm(bdd_.cuddMgr(), index); const LibertyPort *port = bdd_.varIndexPort(var_index); if (port->direction()->isInternal()) - return findSeqActivity(inst, const_cast(port)).duty(); + return findSeqActivity(inst, const_cast(port)).duty(); else { const Pin *pin = findLinkPin(inst, port); if (pin) { @@ -878,10 +866,8 @@ Power::evalBddActivity(DdNode *bdd, Cudd_RecursiveDeref(bdd_.cuddMgr(), diff); float var_density = var_activity.density() * diff_duty; density += var_density; - debugPrint(debug_, "power_activity", 3, "%s %.3e * %.3f = %.3e", - network_->pathName(pin), - var_activity.density(), - diff_duty, + debugPrint(debug_, "power_activity", 3, "{} {:.3e} * {:.3f} = {:.3e}", + network_->pathName(pin), var_activity.density(), diff_duty, var_density); } } @@ -911,9 +897,8 @@ Power::ensureActivities(const Scene *scene) // unless it has been set by command. if (input_activity_.origin() == PwrActivityOrigin::unknown) { float min_period = clockMinPeriod(scene_->mode()->sdc()); - float density = 0.1 / (min_period != 0.0 - ? min_period - : units_->timeUnit()->scale()); + float density = + 0.1 / (min_period != 0.0 ? min_period : units_->timeUnit()->scale()); input_activity_.set(density, 0.5, PwrActivityOrigin::input); } ActivitySrchPred activity_srch_pred(this); @@ -927,17 +912,15 @@ Power::ensureActivities(const Scene *scene) int pass = 1; while (!regs.empty() && pass < max_activity_passes_) { visitor.init(); - for (const Instance *reg : regs) - // Propagate activiities across register D->Q. - seedRegOutputActivities(reg, bfs); - // Propagate register output activities through - // combinational logic. - bfs.visit(levelize_->maxLevel(), &visitor); + for (const Instance *reg : regs) + // Propagate activiities across register D->Q. + seedRegOutputActivities(reg, bfs); + // Propagate register output activities through + // combinational logic. + bfs.visit(levelize_->maxLevel(), &visitor); regs = std::move(visitor.visitedRegs()); - debugPrint(debug_, "power_activity", 1, "Pass %d change %.2f %s", - pass, - visitor.maxChange(), - network_->pathName(visitor.maxChangePin())); + debugPrint(debug_, "power_activity", 1, "Pass {} change {:.2f} {}", pass, + visitor.maxChange(), network_->pathName(visitor.maxChangePin())); pass++; } } @@ -953,14 +936,14 @@ Power::seedActivities(BfsFwdIterator &bfs) const Pin *pin = vertex->pin(); // Clock activities are baked in. if (!scene_->mode()->sdc()->isLeafPinClock(pin) - && !network_->direction(pin)->isInternal()) { - debugPrint(debug_, "power_activity", 3, "seed %s", - vertex->to_string(this).c_str()); + && !network_->direction(pin)->isInternal()) { + debugPrint(debug_, "power_activity", 3, "seed {}", + vertex->to_string(this)); if (hasUserActivity(pin)) - setActivity(pin, userActivity(pin)); + setActivity(pin, userActivity(pin)); else - // Default inputs without explicit activities to the input default. - setActivity(pin, input_activity_); + // Default inputs without explicit activities to the input default. + setActivity(pin, input_activity_); Vertex *vertex = graph_->pinDrvrVertex(pin); bfs.enqueueAdjacentVertices(vertex, scene_->mode()); } @@ -969,7 +952,7 @@ Power::seedActivities(BfsFwdIterator &bfs) void Power::seedRegOutputActivities(const Instance *inst, - BfsFwdIterator &bfs) + BfsFwdIterator &bfs) { LibertyCell *cell = network_->libertyCell(inst); const SequentialSeq &seqs = cell->sequentials(); @@ -1004,12 +987,10 @@ Power::seedRegOutputActivities(const Instance *inst, if (port) { FuncExpr *func = port->function(); Vertex *vertex = graph_->pinDrvrVertex(pin); - if (vertex - && func - && (func->port() == seq.output() - || func->port() == seq.outputInv())) { - debugPrint(debug_, "power_reg", 1, "enqueue reg output %s", - vertex->to_string(this).c_str()); + if (vertex && func + && (func->port() == seq.output() || func->port() == seq.outputInv())) { + debugPrint(debug_, "power_reg", 1, "enqueue reg output {}", + vertex->to_string(this)); bfs.enqueue(vertex); } } @@ -1020,9 +1001,9 @@ Power::seedRegOutputActivities(const Instance *inst, void Power::seedRegOutputActivities(const Instance *reg, - const Sequential &seq, - LibertyPort *output, - bool invert) + const Sequential &seq, + LibertyPort *output, + bool invert) { const Pin *out_pin = network_->findPin(reg, output); if (!hasUserActivity(out_pin)) { @@ -1041,9 +1022,8 @@ Power::seedRegOutputActivities(const Instance *reg, PwrActivity clk_activity = evalActivity(seq.clock(), reg); float clk_duty = clk_activity.duty(); FuncExpr *clk_func = seq.clock(); - bool clk_invert = clk_func - && clk_func->op() == FuncExpr::Op::not_ - && clk_func->left()->op() == FuncExpr::Op::port; + bool clk_invert = clk_func && clk_func->op() == FuncExpr::Op::not_ + && clk_func->left()->op() == FuncExpr::Op::port; if (clk_invert) out_density = in_density * (1 - clk_duty); else @@ -1087,10 +1067,10 @@ Power::findInstPowers() PowerResult Power::power(const Instance *inst, - LibertyCell *cell, + LibertyCell *cell, const Scene *scene) { - debugPrint(debug_, "power", 2, "find power %s", sdc_network_->pathName(inst)); + debugPrint(debug_, "power", 2, "find power {}", sdc_network_->pathName(inst)); PowerResult result; findInternalPower(inst, cell, scene, result); findSwitchingPower(inst, cell, scene, result); @@ -1128,15 +1108,15 @@ Power::findInternalPower(const Instance *inst, LibertyPort *to_port = network_->libertyPort(to_pin); if (to_port) { float load_cap = to_port->direction()->isAnyOutput() - ? graph_delay_calc_->loadCap(to_pin, scene, MinMax::max()) - : 0.0; + ? graph_delay_calc_->loadCap(to_pin, scene, MinMax::max()) + : 0.0; PwrActivity activity = findActivity(to_pin); if (to_port->direction()->isAnyOutput()) - findOutputInternalPower(to_port, inst, cell, activity, - load_cap, scene, result); + findOutputInternalPower(to_port, inst, cell, activity, load_cap, scene, + result); if (to_port->direction()->isAnyInput()) - findInputInternalPower(to_pin, to_port, inst, cell, activity, - load_cap, scene, result); + findInputInternalPower(to_pin, to_port, inst, cell, activity, load_cap, + scene, result); } } delete pin_iter; @@ -1144,24 +1124,24 @@ Power::findInternalPower(const Instance *inst, void Power::findInputInternalPower(const Pin *pin, - LibertyPort *port, - const Instance *inst, - LibertyCell *cell, - PwrActivity &activity, - float load_cap, + LibertyPort *port, + const Instance *inst, + LibertyCell *cell, + PwrActivity &activity, + float load_cap, const Scene *scene, - // Return values. - PowerResult &result) + // Return values. + PowerResult &result) { const MinMax *min_max = MinMax::max(); LibertyCell *scene_cell = cell->sceneCell(scene, min_max); const LibertyPort *scene_port = port->scenePort(scene, min_max); if (scene_cell && scene_port) { - const InternalPowerPtrSeq &internal_pwrs = scene_cell->internalPowers(scene_port); + const InternalPowerPtrSeq &internal_pwrs = + scene_cell->internalPowers(scene_port); if (!internal_pwrs.empty()) { - debugPrint(debug_, "power", 2, "internal input %s/%s cap %s", - network_->pathName(inst), - port->name(), + debugPrint(debug_, "power", 2, "internal input {}/{} cap {}", + network_->pathName(inst), port->name(), units_->capacitanceUnit()->asString(load_cap)); debugPrint(debug_, "power", 2, " when act/ns duty energy power"); const Pvt *pvt = scene->sdc()->operatingConditions(MinMax::max()); @@ -1180,8 +1160,8 @@ Power::findInputInternalPower(const Pin *pin, } } if (rf_count) - energy /= rf_count; // average non-inf energies - float duty = 1.0; // fallback default + energy /= rf_count; // average non-inf energies + float duty = 1.0; // fallback default FuncExpr *when = pwr->when(); if (when) { const LibertyPort *out_scene_port = findExprOutPort(when); @@ -1199,13 +1179,9 @@ Power::findInputInternalPower(const Pin *pin, duty = evalActivity(when, inst).duty(); } float port_internal = energy * duty * activity.density(); - debugPrint(debug_, "power", 2, " %3s %6s %.2f %.2f %9.2e %9.2e %s", - port->name(), - when ? when->to_string().c_str() : "", - activity.density() * 1e-9, - duty, - energy, - port_internal, + debugPrint(debug_, "power", 2, " {} {} {:.2f} {:.2f} {:9.2e} {:9.2e} {}", + port->name(), when ? when->to_string() : "", + activity.density() * 1e-9, duty, energy, port_internal, related_pg_pin ? related_pg_pin->name() : "no pg_pin"); internal += port_internal; } @@ -1219,7 +1195,6 @@ Power::getSlew(Vertex *vertex, const RiseFall *rf, const Scene *scene) { - const MinMax *min_max = MinMax::max(); const Pin *pin = vertex->pin(); const ClkNetwork *clk_network = scene->mode()->clkNetwork(); @@ -1259,46 +1234,45 @@ Power::findExprOutPort(FuncExpr *expr) { LibertyPort *port; switch (expr->op()) { - case FuncExpr::Op::port: - port = expr->port(); - if (port && port->direction()->isAnyOutput()) - return expr->port(); - return nullptr; - case FuncExpr::Op::not_: - port = findExprOutPort(expr->left()); - if (port) - return port; - return nullptr; - case FuncExpr::Op::or_: - case FuncExpr::Op::and_: - case FuncExpr::Op::xor_: - port = findExprOutPort(expr->left()); - if (port) - return port; - port = findExprOutPort(expr->right()); - if (port) - return port; - return nullptr; - case FuncExpr::Op::one: - case FuncExpr::Op::zero: - return nullptr; + case FuncExpr::Op::port: + port = expr->port(); + if (port && port->direction()->isAnyOutput()) + return expr->port(); + return nullptr; + case FuncExpr::Op::not_: + port = findExprOutPort(expr->left()); + if (port) + return port; + return nullptr; + case FuncExpr::Op::or_: + case FuncExpr::Op::and_: + case FuncExpr::Op::xor_: + port = findExprOutPort(expr->left()); + if (port) + return port; + port = findExprOutPort(expr->right()); + if (port) + return port; + return nullptr; + case FuncExpr::Op::one: + case FuncExpr::Op::zero: + return nullptr; } return nullptr; } void Power::findOutputInternalPower(const LibertyPort *to_port, - const Instance *inst, - LibertyCell *cell, - PwrActivity &to_activity, - float load_cap, + const Instance *inst, + LibertyCell *cell, + PwrActivity &to_activity, + float load_cap, const Scene *scene, - // Return values. - PowerResult &result) + // Return values. + PowerResult &result) { - debugPrint(debug_, "power", 2, "internal output %s/%s cap %s", - network_->pathName(inst), - to_port->name(), + debugPrint(debug_, "power", 2, "internal output {}/{} cap {}", + network_->pathName(inst), to_port->name(), units_->capacitanceUnit()->asString(load_cap)); const MinMax *min_max = MinMax::max(); const Pvt *pvt = scene->sdc()->operatingConditions(min_max); @@ -1306,7 +1280,7 @@ Power::findOutputInternalPower(const LibertyPort *to_port, const LibertyPort *to_scene_port = to_port->scenePort(scene, min_max); FuncExpr *func = to_port->function(); - std::map pg_duty_sum; + std::map pg_duty_sum; for (const InternalPower *pwr : scene_cell->internalPowers(to_scene_port)) { const LibertyPort *from_scene_port = pwr->relatedPort(); if (from_scene_port) { @@ -1334,7 +1308,7 @@ Power::findOutputInternalPower(const LibertyPort *to_port, positive_unate = isPositiveUnate(scene_cell, from_scene_port, to_scene_port); from_pin = findLinkPin(inst, from_scene_port); if (from_pin) - from_vertex = graph_->pinLoadVertex(from_pin); + from_vertex = graph_->pinLoadVertex(from_pin); } float energy = 0.0; int rf_count = 0; @@ -1351,26 +1325,21 @@ Power::findOutputInternalPower(const LibertyPort *to_port, } } if (rf_count) - energy /= rf_count; // average non-inf energies + energy /= rf_count; // average non-inf energies auto duty_sum_iter = pg_duty_sum.find(related_pg_pin); float weight = 0.0; if (duty_sum_iter != pg_duty_sum.end()) { float duty_sum = duty_sum_iter->second; if (duty_sum != 0.0 && from_pin) { float from_density = findActivity(from_pin).density(); - weight = from_density * duty / duty_sum; + weight = from_density * duty / duty_sum; } } float port_internal = weight * energy * to_activity.density(); - debugPrint(debug_, "power", 2, "%3s -> %-3s %6s %.3f %.3f %.3f %9.2e %9.2e %s", - from_scene_port ? from_scene_port->name() : "-" , - to_port->name(), - when ? when->to_string().c_str() : "", - to_activity.density() * 1e-9, - duty, - weight, - energy, - port_internal, + debugPrint(debug_, "power", 2, "{} -> {} {} {:.3f} {:.3f} {:.3f} {:9.2e} {:9.2e} {}", + from_scene_port ? from_scene_port->name() : "-", to_port->name(), + when ? when->to_string() : "", to_activity.density() * 1e-9, + duty, weight, energy, port_internal, related_pg_pin ? related_pg_pin->name() : "no pg_pin"); internal += port_internal; } @@ -1384,20 +1353,20 @@ Power::findInputDuty(const Instance *inst, { const LibertyPort *from_scene_port = pwr->relatedPort(); if (from_scene_port) { - LibertyPort *from_port = findLinkPort(network_->libertyCell(inst), - from_scene_port); + LibertyPort *from_port = + findLinkPort(network_->libertyCell(inst), from_scene_port); const Pin *from_pin = network_->findPin(inst, from_port); if (from_pin) { FuncExpr *when = pwr->when(); Vertex *from_vertex = graph_->pinLoadVertex(from_pin); if (func && func->hasPort(from_port)) { - float duty = evalDiffDuty(func, from_port, inst); - return duty; + float duty = evalDiffDuty(func, from_port, inst); + return duty; } else if (when) - return evalActivity(when, inst).duty(); + return evalActivity(when, inst).duty(); else if (scene_->mode()->clkNetwork()->isClock(from_vertex->pin())) - return 0.5; + return 0.5; return 0.5; } } @@ -1423,14 +1392,13 @@ Power::findLinkPin(const Instance *inst, static bool isPositiveUnate(const LibertyCell *cell, - const LibertyPort *from, - const LibertyPort *to) + const LibertyPort *from, + const LibertyPort *to) { const TimingArcSetSeq &arc_sets = cell->timingArcSets(from, to); if (!arc_sets.empty()) { TimingSense sense = arc_sets[0]->sense(); - return sense == TimingSense::positive_unate - || sense == TimingSense::non_unate; + return sense == TimingSense::positive_unate || sense == TimingSense::non_unate; } // default return true; @@ -1452,18 +1420,15 @@ Power::findSwitchingPower(const Instance *inst, const LibertyPort *to_port = network_->libertyPort(to_pin); if (to_port) { float load_cap = to_port->direction()->isAnyOutput() - ? graph_delay_calc_->loadCap(to_pin, scene, MinMax::max()) - : 0.0; + ? graph_delay_calc_->loadCap(to_pin, scene, MinMax::max()) + : 0.0; PwrActivity activity = findActivity(to_pin); if (to_port->direction()->isAnyOutput()) { float volt = portVoltage(scene_cell, to_port, scene, MinMax::max()); float switching = .5 * load_cap * volt * volt * activity.density(); - debugPrint(debug_, "power", 2, "switching %s/%s activity = %.2e volt = %.2f %.3e", - cell->name(), - to_port->name(), - activity.density(), - volt, - switching); + debugPrint(debug_, "power", 2, + "switching {}/{} activity = {:.2e} volt = {:.2f} {:.3e}", cell->name(), + to_port->name(), activity.density(), volt, switching); result.incrSwitching(switching); } } @@ -1473,7 +1438,6 @@ Power::findSwitchingPower(const Instance *inst, //////////////////////////////////////////////////////////////// - // Leakage totals for one power/gnd pin. class LeakageSummary { @@ -1502,41 +1466,34 @@ LeakageSummary::LeakageSummary() : void Power::findLeakagePower(const Instance *inst, - LibertyCell *cell, + LibertyCell *cell, const Scene *scene, - // Return values. - PowerResult &result) + // Return values. + PowerResult &result) { LibertyCell *scene_cell = cell->sceneCell(scene, MinMax::max()); - std::map leakage_summaries; + std::map leakage_summaries; Sim *sim = scene->mode()->sim(); for (const LeakagePower &pwr : scene_cell->leakagePowers()) { LibertyPort *pg_port = pwr.relatedPgPort(); - if (pg_port == nullptr - || pg_port->pwrGndType() == PwrGndType::primary_power) { + if (pg_port == nullptr || pg_port->pwrGndType() == PwrGndType::primary_power) { LeakageSummary &sum = leakage_summaries[pg_port]; float leakage = pwr.power(); FuncExpr *when = pwr.when(); if (when) { LogicValue when_value = sim->evalExpr(when, inst); if (when_value == LogicValue::one) { - debugPrint(debug_, "power", 2, "leakage %s/%s %s=1 %.3e", - cell->name(), - pg_port->name(), - when->to_string().c_str(), - leakage); + debugPrint(debug_, "power", 2, "leakage {}/{} {}=1 {:.3e}", cell->name(), + pg_port->name(), when->to_string(), leakage); sum.cond_true_leakage = leakage; sum.cond_true_exists = true; } else { PwrActivity cond_activity = evalActivity(when, inst); float cond_duty = cond_activity.duty(); - debugPrint(debug_, "power", 2, "leakage %s %s %s %.3e * %.2f", - cell->name(), - pg_port->name(), - when->to_string().c_str(), - leakage, - cond_duty); + debugPrint(debug_, "power", 2, "leakage {} {} {} {:.3e} * {:.2f}", + cell->name(), pg_port->name(), when->to_string(), + leakage, cond_duty); // Leakage power average weighted by duty. sum.cond_leakage += leakage * cond_duty; if (leakage > 0.0) @@ -1545,10 +1502,8 @@ Power::findLeakagePower(const Instance *inst, } } else { - debugPrint(debug_, "power", 2, "leakage %s %s -- %.3e", - cell->name(), - pg_port->name(), - leakage); + debugPrint(debug_, "power", 2, "leakage {} {} -- {:.3e}", cell->name(), + pg_port->name(), leakage); sum.uncond_leakage = leakage; sum.uncond_exists = true; } @@ -1574,10 +1529,8 @@ Power::findLeakagePower(const Instance *inst, // Ignore unconditional leakage unless there are no conditional leakage groups. else if (sum.uncond_exists) leakage = sum.uncond_leakage; - debugPrint(debug_, "power", 2, "leakage %s/%s %.3e", - cell->name(), - pg_port->name(), - leakage); + debugPrint(debug_, "power", 2, "leakage {}/{} {:.3e}", cell->name(), + pg_port->name(), leakage); result.incrLeakage(leakage); } } @@ -1601,8 +1554,7 @@ Power::findActivity(const Pin *pin) Vertex *vertex = graph_->pinLoadVertex(pin); if (vertex && mode->clkNetwork()->isClock(pin)) { PwrActivity *activity = findKeyValuePtr(activity_map_, pin); - if (activity - && activity->origin() != PwrActivityOrigin::unknown) + if (activity && activity->origin() != PwrActivityOrigin::unknown) return *activity; const Clock *clk = findClk(pin); float duty = clockDuty(clk); @@ -1612,8 +1564,7 @@ Power::findActivity(const Pin *pin) return global_activity_; else { PwrActivity *activity = findKeyValuePtr(activity_map_, pin); - if (activity - && activity->origin() != PwrActivityOrigin::unknown) + if (activity && activity->origin() != PwrActivityOrigin::unknown) return *activity; } return PwrActivity(0.0, 0.0, PwrActivityOrigin::unknown); @@ -1625,7 +1576,7 @@ Power::clockDuty(const Clock *clk) if (clk->isGenerated()) { const Clock *master = clk->masterClk(); if (master == nullptr) - return 0.5; // punt + return 0.5; // punt else return clockDuty(master); } @@ -1640,7 +1591,7 @@ Power::clockDuty(const Clock *clk) PwrActivity Power::findSeqActivity(const Instance *inst, - LibertyPort *port) + LibertyPort *port) { if (global_activity_.isSet()) return global_activity_; @@ -1653,7 +1604,7 @@ Power::findSeqActivity(const Instance *inst, float Power::portVoltage(LibertyCell *cell, - const LibertyPort *port, + const LibertyPort *port, const Scene *scene, const MinMax *min_max) { @@ -1662,7 +1613,7 @@ Power::portVoltage(LibertyCell *cell, float Power::pgNameVoltage(LibertyCell *cell, - const char *pg_port_name, + const char *pg_port_name, const Scene *scene, const MinMax *min_max) { @@ -1675,7 +1626,7 @@ Power::pgNameVoltage(LibertyCell *cell, bool exists; library->supplyVoltage(volt_name, voltage, exists); if (exists) - return voltage; + return voltage; } } @@ -1698,10 +1649,8 @@ Power::findClk(const Pin *to_pin) while (path_iter.hasNext()) { Path *path = path_iter.next(); const Clock *path_clk = path->clock(this); - if (path_clk - && (clk == nullptr - || path_clk->period() < clk->period())) - clk = path_clk; + if (path_clk && (clk == nullptr || path_clk->period() < clk->period())) + clk = path_clk; } } return clk; @@ -1716,45 +1665,43 @@ Power::reportActivityAnnotation(bool report_unannotated, size_t vcd_count = 0; size_t saif_count = 0; size_t input_count = 0; - for (auto const& [pin, activity] : user_activity_map_) { + for (auto const &[pin, activity] : user_activity_map_) { PwrActivityOrigin origin = activity.origin(); switch (origin) { - case PwrActivityOrigin::vcd: - vcd_count++; - break; - case PwrActivityOrigin::saif: - saif_count++; - break; - case PwrActivityOrigin::user: - input_count++; - break; - default: - break; + case PwrActivityOrigin::vcd: + vcd_count++; + break; + case PwrActivityOrigin::saif: + saif_count++; + break; + case PwrActivityOrigin::user: + input_count++; + break; + default: + break; } } if (vcd_count > 0) - report_->reportLine("vcd %5zu", vcd_count); + report_->report("vcd {:>5}", vcd_count); if (saif_count > 0) - report_->reportLine("saif %5zu", saif_count); + report_->report("saif {:>5}", saif_count); if (input_count > 0) - report_->reportLine("input %5zu", input_count); + report_->report("input {:>5}", input_count); size_t pin_count = pinCount(); size_t unannotated_count = pin_count - vcd_count - saif_count - input_count; - report_->reportLine("unannotated %5zu", unannotated_count); + report_->report("unannotated {:>5}", unannotated_count); if (report_annotated) { PinSeq annotated_pins; - for (auto const& [pin, activity] : user_activity_map_) + for (auto const &[pin, activity] : user_activity_map_) annotated_pins.push_back(pin); sort(annotated_pins, PinPathNameLess(sdc_network_)); - report_->reportLine("Annotated pins:"); + report_->report("Annotated pins:"); for (const Pin *pin : annotated_pins) { const PwrActivity &activity = user_activity_map_[pin]; PwrActivityOrigin origin = activity.origin(); const char *origin_name = pwr_activity_origin_map.find(origin); - report_->reportLine("%5s %s", - origin_name, - sdc_network_->pathName(pin)); + report_->report("{:>5} {}", origin_name, sdc_network_->pathName(pin)); } } if (report_unannotated) { @@ -1768,9 +1715,9 @@ Power::reportActivityAnnotation(bool report_unannotated, delete inst_iter; sort(unannotated_pins, PinPathNameLess(sdc_network_)); - report_->reportLine("Unannotated pins:"); + report_->report("Unannotated pins:"); for (const Pin *pin : unannotated_pins) { - report_->reportLine(" %s", sdc_network_->pathName(pin)); + report_->report(" {}", sdc_network_->pathName(pin)); } } } @@ -1784,8 +1731,8 @@ Power::findUnannotatedPins(const Instance *inst, const Pin *pin = pin_iter->next(); LibertyPort *liberty_port = sdc_network_->libertyPort(pin); if (!network_->direction(pin)->isInternal() - && !network_->direction(pin)->isPowerGround() - && !(liberty_port && liberty_port->isPwrGnd()) + && !network_->direction(pin)->isPowerGround() + && !(liberty_port && liberty_port->isPwrGnd()) && !user_activity_map_.contains(pin)) unannotated_pins.push_back(pin); } @@ -1805,8 +1752,8 @@ Power::pinCount() const Pin *pin = pin_iter->next(); LibertyPort *liberty_port = sdc_network_->libertyPort(pin); if (!network_->direction(pin)->isInternal() - && !network_->direction(pin)->isPowerGround() - && !(liberty_port && liberty_port->isPwrGnd())) + && !network_->direction(pin)->isPowerGround() + && !(liberty_port && liberty_port->isPwrGnd())) count++; } delete pin_iter; @@ -1855,7 +1802,7 @@ PowerResult::PowerResult() : } void -PowerResult::clear() +PowerResult::clear() { internal_ = 0.0; switching_ = 0.0; @@ -1897,8 +1844,8 @@ PowerResult::incr(PowerResult &result) //////////////////////////////////////////////////////////////// PwrActivity::PwrActivity(float density, - float duty, - PwrActivityOrigin origin) : + float duty, + PwrActivityOrigin origin) : density_(density), duty_(duty), origin_(origin) @@ -1941,8 +1888,8 @@ PwrActivity::init() void PwrActivity::set(float density, - float duty, - PwrActivityOrigin origin) + float duty, + PwrActivityOrigin origin) { density_ = density; duty_ = duty; @@ -1972,4 +1919,4 @@ PwrActivity::originName() const return pwr_activity_origin_map.find(origin_); } -} // namespace +} // namespace sta diff --git a/power/ReportPower.cc b/power/ReportPower.cc index 3f0d0d76..cf4803b7 100644 --- a/power/ReportPower.cc +++ b/power/ReportPower.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 "ReportPower.hh" @@ -29,7 +29,7 @@ #include "Report.hh" #include "Network.hh" -#include "StringUtil.hh" +#include "Format.hh" namespace sta { @@ -51,32 +51,31 @@ ReportPower::reportDesign(PowerResult &total, float design_switching = total.switching(); float design_leakage = total.leakage(); float design_total = total.total(); - + int field_width = std::max(digits + 6, 10); - - reportTitle5("Group", "Internal", "Switching", "Leakage", "Total", - field_width); + + reportTitle5("Group", "Internal", "Switching", "Leakage", "Total", field_width); reportTitle5Units(" ", "Power", "Power", "Power", "Power", "(Watts)", field_width); reportTitleDashes5(field_width); - + reportRow("Sequential", sequential, design_total, field_width, digits); reportRow("Combinational", combinational, design_total, field_width, digits); reportRow("Clock", clock, design_total, field_width, digits); reportRow("Macro", macro, design_total, field_width, digits); reportRow("Pad", pad, design_total, field_width, digits); - + reportTitleDashes5(field_width); - + // Report total row using the totals PowerResult reportRow("Total", total, design_total, field_width, digits); - + // Report percentage line - std::string percent_line = stdstrPrint("%-20s", ""); + std::string percent_line = sta::format("{:<20}", ""); percent_line += powerColPercent(design_internal, design_total, field_width); percent_line += powerColPercent(design_switching, design_total, field_width); percent_line += powerColPercent(design_leakage, design_total, field_width); - report_->reportLineString(percent_line); + report_->reportLine(percent_line); } void @@ -84,13 +83,11 @@ ReportPower::reportInsts(const InstPowers &inst_pwrs, int digits) { int field_width = std::max(digits + 6, 10); - - reportTitle4("Internal", "Switching", "Leakage", "Total", - field_width); - reportTitle4Units("Power", "Power", "Power", "Power", "(Watts)", - field_width); + + reportTitle4("Internal", "Switching", "Leakage", "Total", field_width); + reportTitle4Units("Power", "Power", "Power", "Power", "(Watts)", field_width); reportTitleDashes4(field_width); - + for (const InstPower &inst_pwr : inst_pwrs) { reportInst(inst_pwr.first, inst_pwr.second, field_width, digits); } @@ -106,14 +103,14 @@ ReportPower::reportInst(const Instance *inst, float switching = power.switching(); float leakage = power.leakage(); float total = power.total(); - + std::string line = powerCol(internal, field_width, digits); line += powerCol(switching, field_width, digits); line += powerCol(leakage, field_width, digits); line += powerCol(total, field_width, digits); line += " "; line += network_->pathName(inst); - report_->reportLineString(line); + report_->reportLine(line); } std::string @@ -122,9 +119,9 @@ ReportPower::powerCol(float pwr, int digits) { if (std::isnan(pwr)) - return stdstrPrint(" %*s", field_width, "NaN"); + return sta::format(" {:>{}}", "NaN", field_width); else - return stdstrPrint(" %*.*e", field_width, digits, pwr); + return sta::format(" {:{}.{}e}", pwr, field_width, digits); } std::string @@ -136,41 +133,33 @@ ReportPower::powerColPercent(float col_total, if (total != 0.0 && !std::isnan(total)) { percent = col_total / total * 100.0; } - return stdstrPrint("%*.*f%%", field_width, 1, percent); + return sta::format("{:{}.1f}%", percent, field_width); } void ReportPower::reportTitle5(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *title5, - int field_width) + const char *title2, + const char *title3, + const char *title4, + const char *title5, + int field_width) { - report_->reportLine("%-20s %*s %*s %*s %*s", - title1, - field_width, title2, - field_width, title3, - field_width, title4, - field_width, title5); + report_->report("{:<20} {:>{}} {:>{}} {:>{}} {:>{}}", title1, title2, field_width, + title3, field_width, title4, field_width, title5, field_width); } void ReportPower::reportTitle5Units(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *title5, - const char *units, - int field_width) + const char *title2, + const char *title3, + const char *title4, + const char *title5, + const char *units, + int field_width) { - report_->reportLine("%-20s %*s %*s %*s %*s %s", - title1, - field_width, title2, - field_width, title3, - field_width, title4, - field_width, title5, - units); + report_->report("{:<20} {:>{}} {:>{}} {:>{}} {:>{}} {}", title1, title2, + field_width, title3, field_width, title4, field_width, title5, + field_width, units); } void @@ -178,7 +167,7 @@ ReportPower::reportTitleDashes5(int field_width) { int count = 20 + (field_width + 1) * 4; std::string dashes(count, '-'); - report_->reportLineString(dashes); + report_->reportLine(dashes); } void @@ -192,18 +181,18 @@ ReportPower::reportRow(const char *type, float switching = power.switching(); float leakage = power.leakage(); float total = power.total(); - + float percent = 0.0; if (design_total != 0.0 && !std::isnan(design_total)) percent = total / design_total * 100.0; - - std::string line = stdstrPrint("%-20s", type); + + std::string line = sta::format("{:<20}", type); line += powerCol(internal, field_width, digits); line += powerCol(switching, field_width, digits); line += powerCol(leakage, field_width, digits); line += powerCol(total, field_width, digits); - line += stdstrPrint(" %5.1f%%", percent); - report_->reportLineString(line); + line += sta::format(" {:5.1f}%", percent); + report_->reportLine(line); } void @@ -213,11 +202,8 @@ ReportPower::reportTitle4(const char *title1, const char *title4, int field_width) { - report_->reportLine(" %*s %*s %*s %*s", - field_width, title1, - field_width, title2, - field_width, title3, - field_width, title4); + report_->report(" {:>{}} {:>{}} {:>{}} {:>{}}", title1, field_width, title2, + field_width, title3, field_width, title4, field_width); } void @@ -228,12 +214,8 @@ ReportPower::reportTitle4Units(const char *title1, const char *units, int field_width) { - report_->reportLine(" %*s %*s %*s %*s %s", - field_width, title1, - field_width, title2, - field_width, title3, - field_width, title4, - units); + report_->report(" {:>{}} {:>{}} {:>{}} {:>{}} {}", title1, field_width, title2, + field_width, title3, field_width, title4, field_width, units); } void @@ -241,7 +223,7 @@ ReportPower::reportTitleDashes4(int field_width) { int count = (field_width + 1) * 4; std::string dashes(count, '-'); - report_->reportLineString(dashes); + report_->reportLine(dashes); } -} // namespace +} // namespace sta diff --git a/power/SaifParse.yy b/power/SaifParse.yy index be4f723f..6012d59a 100644 --- a/power/SaifParse.yy +++ b/power/SaifParse.yy @@ -42,7 +42,7 @@ void sta::SaifParse::error(const location_type &loc, const std::string &msg) { - reader->report()->fileError(169,reader->filename(),loc.begin.line,"%s",msg.c_str()); + reader->report()->fileError(169,reader->filename(),loc.begin.line,{}, msg); } %} diff --git a/power/SaifReader.cc b/power/SaifReader.cc index 17345229..c06cb512 100644 --- a/power/SaifReader.cc +++ b/power/SaifReader.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 "power/SaifReader.hh" @@ -61,7 +61,7 @@ SaifReader::SaifReader(const char *filename, scope_(scope), divider_('/'), escape_('\\'), - timescale_(1.0E-9F), // default units of ns + timescale_(1.0E-9F), // default units of ns duration_(0.0), in_scope_level_(0), power_(sta->power()) @@ -78,7 +78,7 @@ SaifReader::read() SaifParse parser(&scanner, this); // yyparse returns 0 on success. bool success = (parser.parse() == 0); - report_->reportLine("Annotated %zu pin activities.", annotated_pins_.size()); + report_->report("Annotated {} pin activities.", annotated_pins_.size()); return success; } else @@ -95,9 +95,7 @@ void SaifReader::setTimescale(uint64_t multiplier, const char *units) { - if (multiplier == 1 - || multiplier == 10 - || multiplier == 100) { + if (multiplier == 1 || multiplier == 10 || multiplier == 100) { if (stringEq(units, "us")) timescale_ = multiplier * 1E-6; else if (stringEq(units, "ns")) @@ -107,10 +105,10 @@ SaifReader::setTimescale(uint64_t multiplier, else if (stringEq(units, "fs")) timescale_ = multiplier * 1E-15; else - report_->error(180, "SAIF TIMESCALE units not us, ns, or ps."); + report_->error(1861, "SAIF TIMESCALE units not us, ns, or ps."); } else - report_->error(181, "SAIF TIMESCALE multiplier not 1, 10, or 100."); + report_->error(1862, "SAIF TIMESCALE multiplier not 1, 10, or 100."); stringDelete(units); } @@ -168,8 +166,7 @@ SaifReader::setNetDurations(const char *net_name, std::string unescaped_name = unescaped(net_name); const Pin *pin = sdc_network_->findPin(parent, unescaped_name.c_str()); LibertyPort *liberty_port = pin ? sdc_network_->libertyPort(pin) : nullptr; - if (pin - && !sdc_network_->isHierarchical(pin) + if (pin && !sdc_network_->isHierarchical(pin) && !sdc_network_->direction(pin)->isInternal() && !(liberty_port && liberty_port->isPwrGnd())) { double t1 = durations[static_cast(SaifState::T1)]; @@ -177,13 +174,8 @@ SaifReader::setNetDurations(const char *net_name, double tc = durations[static_cast(SaifState::TC)]; float density = tc / (duration_ * timescale_); debugPrint(debug_, "read_saif", 2, - "%s duty %.0f / %" PRIu64 " = %.2f tc %.0f density %.2f", - sdc_network_->pathName(pin), - t1, - duration_, - duty, - tc, - density); + "{} duty {:.0f} / {} = {:.2f} tc {:.0f} density {:.2f}", + sdc_network_->pathName(pin), t1, duration_, duty, tc, density); power_->setUserActivity(pin, density, duty, PwrActivityOrigin::saif); annotated_pins_.insert(pin); } @@ -202,7 +194,7 @@ SaifReader::unescaped(const char *token) // Just the normal noises. unescaped += ch; } - debugPrint(debug_, "saif_name", 1, "token %s -> %s", token, unescaped.c_str()); + debugPrint(debug_, "saif_name", 1, "token {} -> {}", token, unescaped); return unescaped; } @@ -222,7 +214,7 @@ SaifScanner::SaifScanner(std::istream *stream, void SaifScanner::error(const char *msg) { - report_->fileError(1868, filename_.c_str(), lineno(), "%s", msg); + report_->fileError(1860, filename_.c_str(), lineno(), "{}", msg); } -} // namespace +} // namespace sta diff --git a/power/VcdParse.cc b/power/VcdParse.cc index 1227e1b2..c82423cf 100644 --- a/power/VcdParse.cc +++ b/power/VcdParse.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 "VcdParse.hh" @@ -80,16 +80,14 @@ VcdParse::read(const char *filename, else if (token[0] == '#') { try { time_ = stoll(token.substr(1)); + } catch (std::invalid_argument &error) { + report_->fileError(805, filename_, file_line_, "invalid time {}", + token.substr(1)); + } catch (std::out_of_range &error) { + report_->fileError(806, filename_, file_line_, "time out of range {}", + token.substr(1)); } - catch (std::invalid_argument &error) { - report_->fileError(805, filename_, file_line_, "invalid time %s", - token.substr(1).c_str()); - } - catch (std::out_of_range &error) { - report_->fileError(806, filename_, file_line_, "time out of range %s", - token.substr(1).c_str()); - } - reader_->setTimeMin(time_); + reader_->setTimeMin(time_); prev_time_ = time_; } else if (token[0] == '$') @@ -151,37 +149,34 @@ VcdParse::setTimeUnit(const std::string &time_unit, reader_->setTimeUnit(time_unit, time_unit_scale, time_scale); } -static EnumNameMap vcd_var_type_map = - {{VcdVarType::wire, "wire"}, - {VcdVarType::reg, "reg"}, - {VcdVarType::parameter, "parameter"}, - {VcdVarType::integer, "integer"}, - {VcdVarType::real, "real"}, - {VcdVarType::supply0, "supply0"}, - {VcdVarType::supply1, "supply1"}, - {VcdVarType::time, "time"}, - {VcdVarType::tri, "tri"}, - {VcdVarType::triand, "triand"}, - {VcdVarType::trior, "trior"}, - {VcdVarType::trireg, "trireg"}, - {VcdVarType::tri0, "tri0"}, - {VcdVarType::tri1, "tri1"}, - {VcdVarType::wand, "wand"}, - {VcdVarType::wor, "wor"} - }; +static EnumNameMap vcd_var_type_map = { + {VcdVarType::wire, "wire"}, + {VcdVarType::reg, "reg"}, + {VcdVarType::parameter, "parameter"}, + {VcdVarType::integer, "integer"}, + {VcdVarType::real, "real"}, + {VcdVarType::supply0, "supply0"}, + {VcdVarType::supply1, "supply1"}, + {VcdVarType::time, "time"}, + {VcdVarType::tri, "tri"}, + {VcdVarType::triand, "triand"}, + {VcdVarType::trior, "trior"}, + {VcdVarType::trireg, "trireg"}, + {VcdVarType::tri0, "tri0"}, + {VcdVarType::tri1, "tri1"}, + {VcdVarType::wand, "wand"}, + {VcdVarType::wor, "wor"}}; void VcdParse::parseVar() { std::vector tokens = readStmtTokens(); - if (tokens.size() == 4 - || tokens.size() == 5) { + if (tokens.size() == 4 || tokens.size() == 5) { std::string type_name = tokens[0]; VcdVarType type = vcd_var_type_map.find(type_name, VcdVarType::unknown); if (type == VcdVarType::unknown) - report_->fileWarn(1370, filename_, file_line_, - "Unknown variable type %s.", - type_name.c_str()); + report_->fileWarn(809, filename_, file_line_, "Unknown variable type {}.", + type_name); else { size_t width = std::stoi(tokens[1]); std::string &id = tokens[2]; @@ -229,23 +224,18 @@ VcdParse::parseVarValues() if (time_ > prev_time_) reader_->varMinDeltaTime(time_ - prev_time_); } - else if (char0 == '0' - || char0 == '1' - || char0 == 'X' - || char0 == 'U' + else if (char0 == '0' || char0 == '1' || char0 == 'X' || char0 == 'U' || char0 == 'Z') { std::string id = token.substr(1); if (!reader_->varIdValid(id)) - report_->fileError(805, filename_, file_line_, - "unknown variable %s", id.c_str()); + report_->fileError(808, filename_, file_line_, "unknown variable {}", id); reader_->varAppendValue(id, time_, char0); } else if (char0 == 'B') { std::string bus_value = token.substr(1); std::string id = getToken(); if (!reader_->varIdValid(id)) - report_->fileError(807, filename_, file_line_, - "unknown variable %s", id.c_str()); + report_->fileError(807, filename_, file_line_, "unknown variable {}", id); else { // Reverse the bus value to match the bit order in the VCD file. std::reverse(bus_value.begin(), bus_value.end()); @@ -327,4 +317,4 @@ VcdValue::setValue(VcdTime time, value_ = value; } -} // namespace +} // namespace sta diff --git a/power/VcdReader.cc b/power/VcdReader.cc index 7a1b312a..fd5ed1cd 100644 --- a/power/VcdReader.cc +++ b/power/VcdReader.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 "VcdReader.hh" @@ -89,12 +89,10 @@ VcdCount::incrCounts(VcdTime time, if (prev_value_ == '1') high_time_ += time - prev_time_; if (value != prev_value_) - transition_count_ += (value == 'X' - || value == 'Z' - || prev_value_ == 'X' - || prev_value_ == 'Z') - ? .5 - : 1.0; + transition_count_ += + (value == 'X' || value == 'Z' || prev_value_ == 'X' || prev_value_ == 'Z') + ? .5 + : 1.0; } prev_time_ = time; prev_value_ = value; @@ -216,8 +214,7 @@ VcdCountReader::makeVar(const VcdScope &scope, size_t width, const std::string &id) { - if (type == VcdVarType::wire - || type == VcdVarType::reg) { + if (type == VcdVarType::wire || type == VcdVarType::reg) { std::string path_name; bool first = true; for (const std::string &context : scope) { @@ -228,24 +225,23 @@ VcdCountReader::makeVar(const VcdScope &scope, } size_t scope_length = scope_.size(); // string::starts_with in c++20 - if (scope_length == 0 - || path_name.substr(0, scope_length) == scope_) { + if (scope_length == 0 || path_name.substr(0, scope_length) == scope_) { path_name += '/'; path_name += name; // Strip the scope from the name. std::string var_scoped = path_name.substr(scope_length + 1); if (width == 1) { - std::string pin_name = netVerilogToSta(&var_scoped); + std::string pin_name = netVerilogToSta(var_scoped); addVarPin(pin_name, id, width, 0); } else { bool is_bus, is_range, subscript_wild; std::string bus_name; int from, to; - parseBusName(var_scoped.c_str(), '[', ']', '\\', - is_bus, is_range, bus_name, from, to, subscript_wild); + parseBusName(var_scoped.c_str(), '[', ']', '\\', is_bus, is_range, bus_name, + from, to, subscript_wild); if (is_bus) { - std::string sta_bus_name = netVerilogToSta(&bus_name); + std::string sta_bus_name = netVerilogToSta(bus_name); int bit_idx = 0; if (to < from) { for (int bus_bit = to; bus_bit <= from; bus_bit++) { @@ -269,7 +265,7 @@ VcdCountReader::makeVar(const VcdScope &scope, } } else - report_->warn(1451, "problem parsing bus %s.", var_scoped.c_str()); + report_->warn(1451, "problem parsing bus {}.", var_scoped); } } } @@ -283,17 +279,14 @@ VcdCountReader::addVarPin(const std::string &pin_name, { const Pin *pin = sdc_network_->findPin(pin_name.c_str()); LibertyPort *liberty_port = pin ? sdc_network_->libertyPort(pin) : nullptr; - if (pin - && !sdc_network_->isHierarchical(pin) + if (pin && !sdc_network_->isHierarchical(pin) && !sdc_network_->direction(pin)->isInternal() && !sdc_network_->direction(pin)->isPowerGround() && !(liberty_port && liberty_port->isPwrGnd())) { VcdCounts &vcd_counts = vcd_count_map_[id]; vcd_counts.resize(width); vcd_counts[bit_idx].addPin(pin); - debugPrint(debug_, "read_vcd", 2, "id %s pin %s", - id.c_str(), - pin_name.c_str()); + debugPrint(debug_, "read_vcd", 2, "id {} pin {}", id, pin_name); } } @@ -309,10 +302,8 @@ VcdCountReader::varAppendValue(const std::string &id, for (size_t bit_idx = 0; bit_idx < vcd_counts.size(); bit_idx++) { VcdCount &vcd_count = vcd_counts[bit_idx]; for (const Pin *pin : vcd_count.pins()) { - debugPrint(debug_, "read_vcd", 3, "%s time %" PRIu64 " value %c", - sdc_network_->pathName(pin), - time, - value); + debugPrint(debug_, "read_vcd", 3, "{} time {} value {}", + sdc_network_->pathName(pin), time, value); } } } @@ -335,7 +326,7 @@ VcdCountReader::varAppendBusValue(const std::string &id, char bit_value; if (bus_value.size() == 1) bit_value = bus_value[0]; - else if (bit_idx < bus_value.size()) + else if (bit_idx < bus_value.size()) bit_value = bus_value[bit_idx]; else bit_value = '0'; @@ -343,10 +334,8 @@ VcdCountReader::varAppendBusValue(const std::string &id, vcd_count.incrCounts(time, bit_value); if (debug_->check("read_vcd", 3)) { for (const Pin *pin : vcd_count.pins()) { - debugPrint(debug_, "read_vcd", 3, "%s time %" PRIu64 " value %c", - sdc_network_->pathName(pin), - time, - bit_value); + debugPrint(debug_, "read_vcd", 3, "{} time {} value {}", + sdc_network_->pathName(pin), time, bit_value); } } } @@ -371,7 +360,7 @@ private: const std::string filename_; - std::set annotated_pins_; + std::set annotated_pins_; VcdCountReader vcd_reader_; VcdParse vcd_parse_; const Sdc *sdc_; @@ -398,8 +387,12 @@ ReadVcdActivities::ReadVcdActivities(const std::string &filename, Sta *sta) : StaState(sta), filename_(filename), - vcd_reader_(scope, sdc_network_, report_, debug_), - vcd_parse_(report_, debug_), + vcd_reader_(scope, + sdc_network_, + report_, + debug_), + vcd_parse_(report_, + debug_), sdc_(sdc), power_(sta->power()) { @@ -418,7 +411,7 @@ ReadVcdActivities::readActivities() setActivities(); else report_->warn(1450, "VCD max time is zero."); - report_->reportLine("Annotated %zu pin activities.", annotated_pins_.size()); + report_->report("Annotated {} pin activities.", annotated_pins_.size()); } void @@ -428,7 +421,7 @@ ReadVcdActivities::setActivities() VcdTime time_max = vcd_reader_.timeMax(); VcdTime time_delta = time_max - time_min; double time_scale = vcd_reader_.timeScale(); - for (auto& [id, vcd_counts] : vcd_reader_.countMap()) { + for (auto &[id, vcd_counts] : vcd_reader_.countMap()) { for (const VcdCount &vcd_count : vcd_counts) { double transition_count = vcd_count.transitionCount(); VcdTime high_time = vcd_count.highTime(time_max); @@ -437,11 +430,8 @@ ReadVcdActivities::setActivities() if (debug_->check("read_vcd", 1)) { for (const Pin *pin : vcd_count.pins()) { debugPrint(debug_, "read_vcd", 1, - "%s transitions %.1f activity %.2f duty %.2f", - sdc_network_->pathName(pin), - transition_count, - density, - duty); + "{} transitions {:.1f} activity {:.2f} duty {:.2f}", + sdc_network_->pathName(pin), transition_count, density, duty); } } for (const Pin *pin : vcd_count.pins()) { @@ -463,23 +453,24 @@ ReadVcdActivities::checkClkPeriod(const Pin *pin, VcdTime time_max = vcd_reader_.timeMax(); VcdTime time_min = vcd_reader_.timeMin(); double time_scale = vcd_reader_.timeScale(); - double sim_period = (time_max - time_min) * time_scale / (transition_count / 2.0); + double sim_period = + (time_max - time_min) * time_scale / (transition_count / 2.0); for (Clock *clk : *clks) { if (transition_count == 0) - report_->warn(1453, "clock %s pin %s has no vcd transitions.", - clk->name(), + report_->warn(1453, "clock {} pin {} has no vcd transitions.", clk->name(), sdc_network_->pathName(pin)); else { double clk_period = clk->period(); - if (std::abs((clk_period - sim_period) / clk_period) > sim_clk_period_tolerance_) + if (std::abs((clk_period - sim_period) / clk_period) + > sim_clk_period_tolerance_) // Warn if sim clock period differs from SDC by more than 10%. - report_->warn(1452, "clock %s vcd period %s differs from SDC clock period %s", - clk->name(), - delayAsString(sim_period, this), + report_->warn(1452, + "clock {} vcd period {} differs from SDC clock period {}", + clk->name(), delayAsString(sim_period, this), delayAsString(clk_period, this)); } } } } -} // namespace +} // namespace sta diff --git a/sdc/Clock.cc b/sdc/Clock.cc index b54f4302..df161fc2 100644 --- a/sdc/Clock.cc +++ b/sdc/Clock.cc @@ -28,6 +28,7 @@ #include "ContainerHelpers.hh" #include "Error.hh" +#include "Format.hh" #include "StringUtil.hh" #include "MinMax.hh" #include "Transition.hh" @@ -531,7 +532,7 @@ ClockEdge::ClockEdge(Clock *clock, const RiseFall *rf) : clock_(clock), rf_(rf), - name_(stringPrint("%s %s", clock_->name(), rf_->shortName())), + name_(sta::format("{} {}", clock_->name(), rf_->shortName())), time_(0.0), index_(clock_->index() * RiseFall::index_count + rf_->index()) { @@ -539,7 +540,6 @@ ClockEdge::ClockEdge(Clock *clock, ClockEdge::~ClockEdge() { - stringDelete(name_); } void diff --git a/sdc/ClockGroups.cc b/sdc/ClockGroups.cc index 9729a15c..0bf76c38 100644 --- a/sdc/ClockGroups.cc +++ b/sdc/ClockGroups.cc @@ -29,14 +29,14 @@ namespace sta { -ClockGroups::ClockGroups(const char *name, +ClockGroups::ClockGroups(const std::string &name, bool logically_exclusive, bool physically_exclusive, bool asynchronous, bool allow_paths, const char *comment) : SdcCmdComment(comment), - name_(stringCopy(name)), + name_(name), logically_exclusive_(logically_exclusive), physically_exclusive_(physically_exclusive), asynchronous_(asynchronous), @@ -46,7 +46,6 @@ ClockGroups::ClockGroups(const char *name, ClockGroups::~ClockGroups() { - stringDelete(name_); deleteContents(groups_); } diff --git a/sdc/CycleAccting.cc b/sdc/CycleAccting.cc index 3c674e05..a3baf716 100644 --- a/sdc/CycleAccting.cc +++ b/sdc/CycleAccting.cc @@ -93,7 +93,7 @@ CycleAcctings::reportClkToClkMaxCycleWarnings(Report *report) ClockPair clk_pair2(tgt_clk, src_clk); if (!clk_warnings.contains(clk_pair1) && !clk_warnings.contains(clk_pair2)) { - report->warn(1010, "No common period was found between clocks %s and %s.", + report->warn(1010, "No common period was found between clocks {} and {}.", src_clk->name(), tgt_clk->name()); clk_warnings.insert(clk_pair1); @@ -126,7 +126,7 @@ CycleAccting::findDelays(StaState *sta) { Debug *debug = sta->debug(); const Unit *time_unit = sta->units()->timeUnit(); - debugPrint(debug, "cycle_acct", 1, "%s -> %s", + debugPrint(debug, "cycle_acct", 1, "{} -> {}", src_->name(), tgt_->name()); const int setup_index = TimingRole::setup()->index(); @@ -167,14 +167,14 @@ CycleAccting::findDelays(StaState *sta) if (tgt_past_src && src_past_tgt // Synchronicity achieved. && fuzzyEqual(src_cycle_start, tgt_cycle_start)) { - debugPrint(debug, "cycle_acct", 1, " setup = %s, required = %s", + debugPrint(debug, "cycle_acct", 1, " setup = {}, required = {}", time_unit->asString(delay_[setup_index]), time_unit->asString(required_[setup_index])); - debugPrint(debug, "cycle_acct", 1, " hold = %s, required = %s", + debugPrint(debug, "cycle_acct", 1, " hold = {}, required = {}", time_unit->asString(delay_[hold_index]), time_unit->asString(required_[hold_index])); debugPrint(debug, "cycle_acct", 1, - " converged at src cycles = %d tgt cycles = %d", + " converged at src cycles = {} tgt cycles = {}", src_cycle, tgt_cycle); return; } @@ -182,13 +182,13 @@ CycleAccting::findDelays(StaState *sta) if (fuzzyGreater(src_cycle_start, tgt_cycle_start + tgt_period) && src_past_tgt) break; - debugPrint(debug, "cycle_acct", 2, " %s src cycle %d %s + %s = %s", + debugPrint(debug, "cycle_acct", 2, " {} src cycle {} {} + {} = {}", src_->name(), src_cycle, time_unit->asString(src_cycle_start), time_unit->asString(src_->time()), time_unit->asString(src_time)); - debugPrint(debug, "cycle_acct", 2, " %s tgt cycle %d %s + %s = %s", + debugPrint(debug, "cycle_acct", 2, " {} tgt cycle {} {} + {} = {}", tgt_->name(), tgt_cycle, time_unit->asString(tgt_cycle_start), @@ -203,7 +203,7 @@ CycleAccting::findDelays(StaState *sta) double required = tgt_time - src_cycle_start; setSetupAccting(src_cycle, tgt_cycle, delay, required); debugPrint(debug, "cycle_acct", 2, - " setup min delay = %s, required = %s", + " setup min delay = {}, required = {}", time_unit->asString(delay_[setup_index]), time_unit->asString(required_[setup_index])); } @@ -239,7 +239,7 @@ CycleAccting::findDelays(StaState *sta) setAccting(TimingRole::latchSetup(), src_cycle, latch_tgt_cycle, delay, required); debugPrint(debug, "cycle_acct", 2, - " latch setup min delay = %s, required = %s", + " latch setup min delay = {}, required = {}", time_unit->asString(delay_[latch_setup_index]), time_unit->asString(required_[latch_setup_index])); } @@ -253,7 +253,7 @@ CycleAccting::findDelays(StaState *sta) double required = tgt_time - src_cycle_start; setHoldAccting(src_cycle, tgt_cycle, delay, required); debugPrint(debug, "cycle_acct", 2, - " hold min delay = %s, required = %s", + " hold min delay = {}, required = {}", time_unit->asString(delay_[hold_index]), time_unit->asString(required_[hold_index])); } @@ -268,7 +268,7 @@ CycleAccting::findDelays(StaState *sta) setAccting(TimingRole::gatedClockHold(), src_cycle, tgt_cycle, delay, required); debugPrint(debug, "cycle_acct", 2, - " gated clk hold min delay = %s, required = %s", + " gated clk hold min delay = {}, required = {}", time_unit->asString(delay_[gclk_hold_index]), time_unit->asString(required_[gclk_hold_index])); } @@ -278,7 +278,7 @@ CycleAccting::findDelays(StaState *sta) } max_cycles_exceeded_ = true; debugPrint(debug, "cycle_acct", 1, - " max cycles exceeded after %d src cycles, %d tgt_cycles", + " max cycles exceeded after {} src cycles, {} tgt_cycles", src_cycle, tgt_cycle); } else if (tgt_period > 0.0) diff --git a/sdc/ExceptionPath.cc b/sdc/ExceptionPath.cc index 4ca26e4e..83bb6055 100644 --- a/sdc/ExceptionPath.cc +++ b/sdc/ExceptionPath.cc @@ -26,6 +26,7 @@ #include +#include "Format.hh" #include "ContainerHelpers.hh" #include "MinMax.hh" #include "TimingRole.hh" @@ -121,17 +122,10 @@ ExceptionPath::~ExceptionPath() } } -const char * -ExceptionPath::asString(const Network *network) const +std::string +ExceptionPath::to_string(const Network *network) const { - const char *from_thru_to = fromThruToString(network); - const char *type = typeString(); - size_t length = strlen(type) + strlen(from_thru_to) + 1; - char *result = makeTmpString(length); - char *r = result; - stringAppend(r, type); - stringAppend(r, from_thru_to); - return result; + return sta::format("{}{}", typeString(), fromThruToString(network)); } void @@ -321,7 +315,7 @@ ExceptionPath::intersectsPts(ExceptionPath *exception, return false; } -const char * +std::string ExceptionPath::fromThruToString(const Network *network) const { std::string str; @@ -331,7 +325,7 @@ ExceptionPath::fromThruToString(const Network *network) const } if (from_) - str += from_->asString(network); + str += from_->to_string(network); if (thrus_) { str += " -thru"; @@ -341,7 +335,7 @@ ExceptionPath::fromThruToString(const Network *network) const if (!first_thru) str += " &&"; str += " {"; - str += thru->asString(network); + str += thru->to_string(network); str += "}"; first_thru = false; } @@ -349,11 +343,9 @@ ExceptionPath::fromThruToString(const Network *network) const } if (to_) - str += to_->asString(network); + str += to_->to_string(network); - char *result = makeTmpString(str.size() + 1); - strcpy(result, str.c_str()); - return result; + return str; } ExceptionState * @@ -524,14 +516,12 @@ PathDelay::tighterThan(ExceptionPath *exception) const return delay_ < exception->delay(); } -const char * -PathDelay::asString(const Network *network) const +std::string +PathDelay::to_string(const Network *network) const { - const char *from_thru_to = fromThruToString(network); - const char *result = stringPrintTmp("PathDelay %.3fns%s", - delay_ * 1E+9F, - from_thru_to); - return result; + return sta::format("PathDelay {:.3f}ns{}", + delay_ * 1E+9F, + fromThruToString(network)); } const char * @@ -728,15 +718,13 @@ MultiCyclePath::matches(const MinMax *min_max, || (!exactly && min_max == MinMax::min()); } -const char * -MultiCyclePath::asString(const Network *network) const +std::string +MultiCyclePath::to_string(const Network *network) const { - const char *from_thru_to = fromThruToString(network); - const char *result = stringPrintTmp("Multicycle %s %d%s", - (use_end_clk_) ? "-end" : "-start", - path_multiplier_, - from_thru_to); - return result; + return sta::format("Multicycle {} {}{}", + (use_end_clk_) ? "-end" : "-start", + path_multiplier_, + fromThruToString(network)); } const char * @@ -826,7 +814,7 @@ FilterPath::resetMatch(ExceptionFrom *, //////////////////////////////////////////////////////////////// -GroupPath::GroupPath(const char *name, +GroupPath::GroupPath(const std::string &name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, @@ -836,14 +824,13 @@ GroupPath::GroupPath(const char *name, ExceptionPath(from, thrus, to, MinMaxAll::all(), own_pts, groupPathPriority() + fromThruToPriority(from, thrus, to), comment), - name_(stringCopy(name)), + name_(name), is_default_(is_default) { } GroupPath::~GroupPath() { - stringDelete(name_); } const char * @@ -877,7 +864,7 @@ GroupPath::tighterThan(ExceptionPath *) const bool GroupPath::mergeable(ExceptionPath *exception) const { - return stringEqIf(name_, exception->name()) + return name_ == exception->name() && ExceptionPath::mergeable(exception) && overrides(exception); } @@ -887,12 +874,12 @@ GroupPath::overrides(ExceptionPath *exception) const { return exception->isGroupPath() && is_default_ == exception->isDefault() - && stringEqIf(name_, exception->name()); + && name_ == exception->name(); } //////////////////////////////////////////////////////////////// -const int ExceptionPt::as_string_max_objects_ = 20; +const int ExceptionPt::to_string_max_objects_ = 20; ExceptionPt::ExceptionPt(const RiseFallBoth *rf, bool own_pts) : @@ -1181,8 +1168,8 @@ ExceptionFromTo::deletePinBefore(const Pin *pin, deletePin(pin, network); } -const char * -ExceptionFromTo::asString(const Network *network) const +std::string +ExceptionFromTo::to_string(const Network *network) const { std::string str; str += " "; @@ -1199,7 +1186,7 @@ ExceptionFromTo::asString(const Network *network) const str += network->pathName(pin); first = false; obj_count++; - if (obj_count > as_string_max_objects_) + if (obj_count > to_string_max_objects_) break; } } @@ -1211,7 +1198,7 @@ ExceptionFromTo::asString(const Network *network) const str += clk->name(); first = false; obj_count++; - if (obj_count > as_string_max_objects_) + if (obj_count > to_string_max_objects_) break; } } @@ -1223,18 +1210,16 @@ ExceptionFromTo::asString(const Network *network) const str += network->pathName(inst); first = false; obj_count++; - if (obj_count > as_string_max_objects_) + if (obj_count > to_string_max_objects_) break; } } - if (obj_count == as_string_max_objects_) + if (obj_count == to_string_max_objects_) str += ", ..."; str += "}"; - char *result = makeTmpString(str.size() + 1); - strcpy(result, str.c_str()); - return result; + return str; } size_t @@ -1355,19 +1340,17 @@ ExceptionTo::clone(const Network *network) return new ExceptionTo(pins, clks, insts, rf_, end_rf_, true, network); } -const char * -ExceptionTo::asString(const Network *network) const +std::string +ExceptionTo::to_string(const Network *network) const { std::string str; if (hasObjects()) - str += ExceptionFromTo::asString(network); + str += ExceptionFromTo::to_string(network); if (end_rf_ != RiseFallBoth::riseFall()) str += (end_rf_ == RiseFallBoth::rise()) ? " -rise" : " -fall"; - char *result = makeTmpString(str.size() + 1); - strcpy(result, str.c_str()); - return result; + return str; } bool @@ -1674,8 +1657,8 @@ ExceptionThru::~ExceptionThru() } } -const char * -ExceptionThru::asString(const Network *network) const +std::string +ExceptionThru::to_string(const Network *network) const { std::string str; bool first = true; @@ -1688,7 +1671,7 @@ ExceptionThru::asString(const Network *network) const str += network->pathName(pin); first = false; obj_count++; - if (obj_count > as_string_max_objects_) + if (obj_count > to_string_max_objects_) break; } } @@ -1700,7 +1683,7 @@ ExceptionThru::asString(const Network *network) const str += network->pathName(net); first = false; obj_count++; - if (obj_count > as_string_max_objects_) + if (obj_count > to_string_max_objects_) break; } } @@ -1712,20 +1695,18 @@ ExceptionThru::asString(const Network *network) const str += network->pathName(inst); first = false; obj_count++; - if (obj_count > as_string_max_objects_) + if (obj_count > to_string_max_objects_) break; } } - if (obj_count == as_string_max_objects_) + if (obj_count == to_string_max_objects_) str += ", ..."; if (rf_ == RiseFallBoth::rise()) str += " rise"; else if (rf_ == RiseFallBoth::fall()) str += " fall"; - char *result = makeTmpString(str.size() + 1); - strcpy(result, str.c_str()); - return result; + return str; } ExceptionThruSeq * diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 6d035b05..8889f177 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -1941,40 +1941,38 @@ ClockInsertionkLess::operator()(const ClockInsertion *insert1, //////////////////////////////////////////////////////////////// ClockGroups * -Sdc::makeClockGroups(const char *name, +Sdc::makeClockGroups(const std::string &name, bool logically_exclusive, bool physically_exclusive, bool asynchronous, bool allow_paths, const char *comment) { - char *gen_name = nullptr; - if (name == nullptr - || name[0] == '\0') - name = gen_name = makeClockGroupsName(); + std::string group_name; + if (name.empty()) + group_name = makeClockGroupsName(); else { - ClockGroups *groups = findKey(clk_groups_name_map_, name); + group_name = name; + ClockGroups *groups = findKey(clk_groups_name_map_, group_name); if (groups) removeClockGroups(groups); } - ClockGroups *groups = new ClockGroups(name, logically_exclusive, + ClockGroups *groups = new ClockGroups(group_name, logically_exclusive, physically_exclusive, asynchronous, allow_paths, comment); clk_groups_name_map_[groups->name()] = groups; - stringDelete(gen_name); return groups; } // Generate a name for the clock group. -char * +std::string Sdc::makeClockGroupsName() { - char *name = nullptr; + std::string name; int i = 0; do { i++; - stringDelete(name); - name = stringPrint("group%d", i); + name = sta::format("group{}", i); } while (clk_groups_name_map_.contains(name)); return name; } @@ -1990,7 +1988,7 @@ void Sdc::ensureClkGroupExclusions() { if (clk_group_exclusions_.empty()) { - for (const auto [name, clk_groups] : clk_groups_name_map_) + for (const auto &[name, clk_groups] : clk_groups_name_map_) makeClkGroupExclusions(clk_groups); } } @@ -2087,7 +2085,7 @@ Sdc::sameClockGroupExplicit(const Clock *clk1, } void -Sdc::removeClockGroups(const char *name) +Sdc::removeClockGroups(const std::string &name) { ClockGroups *clk_groups = findKey(clk_groups_name_map_, name); if (clk_groups) @@ -2095,51 +2093,55 @@ Sdc::removeClockGroups(const char *name) } void -Sdc::removeClockGroupsLogicallyExclusive(const char *name) +Sdc::removeClockGroupsLogicallyExclusive() { - if (name) { - ClockGroups *groups = findKey(clk_groups_name_map_, name); - if (groups && groups->logicallyExclusive()) + + for (const auto &[name, groups] : clk_groups_name_map_) { + if (groups->logicallyExclusive()) removeClockGroups(groups); } - else { - for (const auto [name, groups] : clk_groups_name_map_) { - if (groups->logicallyExclusive()) - removeClockGroups(groups); - } - } } void -Sdc::removeClockGroupsPhysicallyExclusive(const char *name) +Sdc::removeClockGroupsLogicallyExclusive(const std::string &name) { - if (name) { - ClockGroups *groups = findKey(clk_groups_name_map_, name); - if (groups && groups->physicallyExclusive()) + ClockGroups *groups = findKey(clk_groups_name_map_, name); + if (groups && groups->logicallyExclusive()) + removeClockGroups(groups); +} + +void +Sdc::removeClockGroupsPhysicallyExclusive() +{ + for (const auto &[name, groups] : clk_groups_name_map_) { + if (groups->physicallyExclusive()) removeClockGroups(groups); } - else { - for (const auto [name, groups] : clk_groups_name_map_) { - if (groups->physicallyExclusive()) - removeClockGroups(groups); - } - } } void -Sdc::removeClockGroupsAsynchronous(const char *name) +Sdc::removeClockGroupsPhysicallyExclusive(const std::string &name) { - if (name) { - ClockGroups *groups = findKey(clk_groups_name_map_, name); - if (groups && groups->asynchronous()) + ClockGroups *groups = findKey(clk_groups_name_map_, name); + if (groups && groups->physicallyExclusive()) + removeClockGroups(groups); +} + +void +Sdc::removeClockGroupsAsynchronous() +{ + for (const auto &[name, groups] : clk_groups_name_map_) { + if (groups->asynchronous()) removeClockGroups(groups); } - else { - for (const auto [name, groups] : clk_groups_name_map_) { - if (groups->asynchronous()) - removeClockGroups(groups); - } - } +} + +void +Sdc::removeClockGroupsAsynchronous(const std::string &name) +{ + ClockGroups *groups = findKey(clk_groups_name_map_, name); + if (groups && groups->asynchronous()) + removeClockGroups(groups); } void @@ -2155,7 +2157,7 @@ Sdc::removeClockGroups(ClockGroups *groups) void Sdc::clockGroupsDeleteClkRefs(Clock *clk) { - for (const auto [name, groups] : clk_groups_name_map_) + for (const auto &[name, groups] : clk_groups_name_map_) groups->removeClock(clk); clearClkGroupExclusions(); } @@ -4080,9 +4082,7 @@ void Sdc::clearGroupPathMap() { // GroupPath exceptions are deleted with other exceptions. - // Delete group_path name strings. for (auto [name, groups] : group_path_map_) { - stringDelete(name); deleteContents(*groups); delete groups; } @@ -4090,7 +4090,7 @@ Sdc::clearGroupPathMap() } void -Sdc::makeGroupPath(const char *name, +Sdc::makeGroupPath(const std::string &name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, @@ -4098,9 +4098,9 @@ Sdc::makeGroupPath(const char *name, const char *comment) { checkFromThrusTo(from, thrus, to); - if (name && is_default) + if (!name.empty() && is_default) report_->critical(1490, "group path name and is_default are mutually exclusive."); - else if (name) { + else if (!name.empty()) { GroupPath *group_path = new GroupPath(name, is_default, from, thrus, to, true, comment); // Clone the group_path because it may get merged and hence deleted @@ -4115,7 +4115,7 @@ Sdc::makeGroupPath(const char *name, GroupPathSet *groups = findKey(group_path_map_, name); if (groups == nullptr) { groups = new GroupPathSet(network_); - group_path_map_[stringCopy(name)] = groups; + group_path_map_[name] = groups; } if (groups->contains(group_path)) // Exact copy of existing group path. @@ -4226,7 +4226,7 @@ void Sdc::makeLoopExceptionThru(const Pin *pin, ExceptionThruSeq *thrus) { - debugPrint(debug_, "levelize", 2, " %s", network_->pathName(pin)); + debugPrint(debug_, "levelize", 2, " {}", network_->pathName(pin)); PinSet *pins = new PinSet(network_); pins->insert(pin); ExceptionThru *thru = makeExceptionThru(pins, nullptr, nullptr, @@ -4254,8 +4254,8 @@ Sdc::deleteLoopExceptions() void Sdc::addException(ExceptionPath *exception) { - debugPrint(debug_, "exception_merge", 1, "add exception for %s", - exception->asString(network_)); + debugPrint(debug_, "exception_merge", 1, "add exception for {}", + exception->to_string(network_)); if (exception->isPathDelay()) { recordPathDelayInternalFrom(exception); @@ -4282,8 +4282,8 @@ Sdc::addException(ExceptionPath *exception) ExceptionTo *to = exception->to(); ExceptionTo *to1 = to ? to->clone(network_) : nullptr; ExceptionPath *exception1 = exception->clone(from1, thrus1, to1, true); - debugPrint(debug_, "exception_merge", 1, " split exception for %s", - exception1->asString(network_)); + debugPrint(debug_, "exception_merge", 1, " split exception for {}", + exception1->to_string(network_)); addException1(exception1); ClockSet *clks2 = new ClockSet(*from->clks()); @@ -4292,8 +4292,8 @@ Sdc::addException(ExceptionPath *exception) ExceptionThruSeq *thrus2 = exceptionThrusClone(exception->thrus(), network_); ExceptionTo *to2 = to ? to->clone(network_) : nullptr; ExceptionPath *exception2 = exception->clone(from2, thrus2, to2, true); - debugPrint(debug_, "exception_merge", 1, " split exception for %s", - exception2->asString(network_)); + debugPrint(debug_, "exception_merge", 1, " split exception for {}", + exception2->to_string(network_)); addException1(exception2); delete exception; @@ -4316,8 +4316,8 @@ Sdc::addException1(ExceptionPath *exception) ExceptionTo *to1 = new ExceptionTo(pins1, nullptr, insts1, to->transition(), to->endTransition(), true, network_); ExceptionPath *exception1 = exception->clone(from1, thrus1, to1, true); - debugPrint(debug_, "exception_merge", 1, " split exception for %s", - exception1->asString(network_)); + debugPrint(debug_, "exception_merge", 1, " split exception for {}", + exception1->to_string(network_)); addException2(exception1); ExceptionFrom *from2 = exception->from() ? exception->from()->clone(network_):nullptr; @@ -4326,8 +4326,8 @@ Sdc::addException1(ExceptionPath *exception) ExceptionTo *to2 = new ExceptionTo(nullptr, clks2, nullptr, to->transition(), to->endTransition(), true, network_); ExceptionPath *exception2 = exception->clone(from2, thrus2, to2, true); - debugPrint(debug_, "exception_merge", 1, " split exception for %s", - exception2->asString(network_)); + debugPrint(debug_, "exception_merge", 1, " split exception for {}", + exception2->to_string(network_)); addException2(exception2); delete exception; @@ -4389,8 +4389,8 @@ Sdc::addException2(ExceptionPath *exception) void Sdc::deleteMatchingExceptions(ExceptionPath *exception) { - debugPrint(debug_, "exception_merge", 1, "find matches for %s", - exception->asString(network_)); + debugPrint(debug_, "exception_merge", 1, "find matches for {}", + exception->to_string(network_)); ExceptionPathSet matches; findMatchingExceptions(exception, matches); @@ -4676,10 +4676,10 @@ Sdc::recordMergeHash(ExceptionPath *exception, { size_t hash = exception->hash(missing_pt); debugPrint(debug_, "exception_merge", 3, - "record merge hash %zu %s missing %s", + "record merge hash {} {} missing {}", hash, - exception->asString(network_), - missing_pt->asString(network_)); + exception->to_string(network_), + missing_pt->to_string(network_)); ExceptionPathSet &set = exception_merge_hash_[hash]; set.insert(exception); } @@ -4860,10 +4860,10 @@ Sdc::findMergeMatch(ExceptionPath *exception) // search at the endpoint. && exception->mergeable(match) && match->mergeablePts(exception, missing_pt, match_missing_pt)) { - debugPrint(debug_, "exception_merge", 1, "merge %s", - exception->asString(network_)); - debugPrint(debug_, "exception_merge", 1, " with %s", - match->asString(network_)); + debugPrint(debug_, "exception_merge", 1, "merge {}", + exception->to_string(network_)); + debugPrint(debug_, "exception_merge", 1, " with {}", + match->to_string(network_)); // Unrecord the exception that is being merged away. unrecordException(exception); unrecordMergeHashes(match); @@ -4965,8 +4965,8 @@ Sdc::deleteExceptionsReferencing(Clock *clk) void Sdc::deleteException(ExceptionPath *exception) { - debugPrint(debug_, "exception_merge", 2, "delete %s", - exception->asString(network_)); + debugPrint(debug_, "exception_merge", 2, "delete {}", + exception->to_string(network_)); unrecordException(exception); delete exception; } @@ -4996,10 +4996,10 @@ Sdc::unrecordMergeHash(ExceptionPath *exception, { size_t hash = exception->hash(missing_pt); debugPrint(debug_, "exception_merge", 3, - "unrecord merge hash %zu %s missing %s", + "unrecord merge hash {} {} missing {}", hash, - exception->asString(network_), - missing_pt->asString(network_)); + exception->to_string(network_), + missing_pt->to_string(network_)); auto itr = exception_merge_hash_.find(hash); if (itr != exception_merge_hash_.end()) { ExceptionPathSet &matches = itr->second; @@ -5214,8 +5214,8 @@ Sdc::resetPath(ExceptionFrom *from, for (auto itr = exceptions_.begin(); itr != exceptions_.end(); ) { ExceptionPath *match = *itr; if (match->resetMatch(from, thrus, to, min_max, network_)) { - debugPrint(debug_, "exception_match", 3, "reset match %s", - match->asString(network_)); + debugPrint(debug_, "exception_match", 3, "reset match {}", + match->to_string(network_)); ExceptionPathSet expansions; expandException(match, expansions); itr = exceptions_.erase(itr); diff --git a/sdc/Sdc.i b/sdc/Sdc.i index 1347ac25..0b0251f1 100644 --- a/sdc/Sdc.i +++ b/sdc/Sdc.i @@ -860,8 +860,6 @@ make_group_path(const char *name, { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); - if (name[0] == '\0') - name = nullptr; sta->makeGroupPath(name, is_default, from, thrus, to, comment, sdc); } @@ -975,6 +973,14 @@ clock_groups_make_group(ClockGroups *clk_groups, sta->makeClockGroup(clk_groups, clks, sdc); } +void +unset_clock_groups_logically_exclusive() +{ + Sta *sta = Sta::sta(); + Sdc *sdc = sta->cmdSdc(); + sta->removeClockGroupsLogicallyExclusive(sdc); +} + void unset_clock_groups_logically_exclusive(const char *name) { @@ -983,6 +989,14 @@ unset_clock_groups_logically_exclusive(const char *name) sta->removeClockGroupsLogicallyExclusive(name, sdc); } +void +unset_clock_groups_physically_exclusive() +{ + Sta *sta = Sta::sta(); + Sdc *sdc = sta->cmdSdc(); + sta->removeClockGroupsPhysicallyExclusive(sdc); +} + void unset_clock_groups_physically_exclusive(const char *name) { @@ -991,6 +1005,14 @@ unset_clock_groups_physically_exclusive(const char *name) sta->removeClockGroupsPhysicallyExclusive(name, sdc); } +void +unset_clock_groups_asynchronous() +{ + Sta *sta = Sta::sta(); + Sdc *sdc = sta->cmdSdc(); + sta->removeClockGroupsAsynchronous(sdc); +} + void unset_clock_groups_asynchronous(const char *name) { diff --git a/sdc/Sdc.tcl b/sdc/Sdc.tcl index 50f49e95..26196d2f 100644 --- a/sdc/Sdc.tcl +++ b/sdc/Sdc.tcl @@ -1435,11 +1435,11 @@ proc unset_clk_groups_cmd { cmd cmd_args } { if { $all } { if { $logically_exclusive } { - unset_clock_groups_logically_exclusive "NULL" + unset_clock_groups_logically_exclusive_all } elseif { $physically_exclusive } { - unset_clock_groups_physically_exclusive "NULL" + unset_clock_groups_physically_exclusive_all } elseif { $asynchronous } { - unset_clock_groups_asynchronous "NULL" + unset_clock_groups_asynchronous_all } } else { foreach name $names { diff --git a/sdc/WriteSdc.cc b/sdc/WriteSdc.cc index cd58f136..7688fc68 100644 --- a/sdc/WriteSdc.cc +++ b/sdc/WriteSdc.cc @@ -32,6 +32,7 @@ #include #include "ContainerHelpers.hh" +#include "Format.hh" #include "Zlib.hh" #include "Report.hh" #include "Error.hh" @@ -148,7 +149,7 @@ void WriteGetPinAndClkKey::write() const { writer_->writeClockKey(clk_); - gzprintf(writer_->stream(), " "); + sta::print(writer_->stream(), " "); writer_->writeGetPin(pin_, map_hpin_to_drvr_); } @@ -356,18 +357,18 @@ void WriteSdc::writeHeader() const { writeCommentSeparator(); - gzprintf(stream_, "# Created by %s\n", creator_); + sta::print(stream_, "# Created by {}\n", creator_); if (!no_timestamp_) { time_t now; time(&now); char *time_str = ctime(&now); // Remove trailing \n. time_str[strlen(time_str) - 1] = '\0'; - gzprintf(stream_, "# %s\n", time_str); + sta::print(stream_, "# {}\n", time_str); } writeCommentSeparator(); - gzprintf(stream_, "current_design %s\n", sdc_network_->name(cell_)); + sta::print(stream_, "current_design {}\n", sdc_network_->name(cell_)); } //////////////////////////////////////////////////////////////// @@ -404,9 +405,9 @@ WriteSdc::writeClocks() const writeClockSlews(clk); writeClockUncertainty(clk); if (clk->isPropagated()) { - gzprintf(stream_, "set_propagated_clock "); + sta::print(stream_, "set_propagated_clock "); writeGetClock(clk); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } } @@ -414,69 +415,69 @@ WriteSdc::writeClocks() const void WriteSdc::writeClock(Clock *clk) const { - gzprintf(stream_, "create_clock -name %s", - clk->name()); + sta::print(stream_, "create_clock -name {}", + clk->name()); if (clk->addToPins()) - gzprintf(stream_, " -add"); - gzprintf(stream_, " -period "); + sta::print(stream_, " -add"); + sta::print(stream_, " -period "); float period = clk->period(); writeTime(period); FloatSeq *waveform = clk->waveform(); if (!(waveform->size() == 2 && (*waveform)[0] == 0.0 && fuzzyEqual((*waveform)[1], period / 2.0))) { - gzprintf(stream_, " -waveform "); + sta::print(stream_, " -waveform "); writeFloatSeq(waveform, scaleTime(1.0)); } writeCmdComment(clk); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeClockPins(clk); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void WriteSdc::writeGeneratedClock(Clock *clk) const { - gzprintf(stream_, "create_generated_clock -name %s", - clk->name()); + sta::print(stream_, "create_generated_clock -name {}", + clk->name()); if (clk->addToPins()) - gzprintf(stream_, " -add"); - gzprintf(stream_, " -source "); + sta::print(stream_, " -add"); + sta::print(stream_, " -source "); writeGetPin(clk->srcPin(), true); Clock *master = clk->masterClk(); if (master && !clk->masterClkInfered()) { - gzprintf(stream_, " -master_clock "); + sta::print(stream_, " -master_clock "); writeGetClock(master); } if (clk->combinational()) - gzprintf(stream_, " -combinational"); + sta::print(stream_, " -combinational"); int divide_by = clk->divideBy(); if (divide_by != 0) - gzprintf(stream_, " -divide_by %d", divide_by); + sta::print(stream_, " -divide_by {}", divide_by); int multiply_by = clk->multiplyBy(); if (multiply_by != 0) - gzprintf(stream_, " -multiply_by %d", multiply_by); + sta::print(stream_, " -multiply_by {}", multiply_by); float duty_cycle = clk->dutyCycle(); if (duty_cycle != 0.0) { - gzprintf(stream_, " -duty_cycle "); + sta::print(stream_, " -duty_cycle "); writeFloat(duty_cycle); } if (clk->invert()) - gzprintf(stream_, " -invert"); + sta::print(stream_, " -invert"); IntSeq *edges = clk->edges(); if (edges && !edges->empty()) { - gzprintf(stream_, " -edges "); + sta::print(stream_, " -edges "); writeIntSeq(edges); FloatSeq *edge_shifts = clk->edgeShifts(); if (edge_shifts && !edge_shifts->empty()) { - gzprintf(stream_, " -edge_shift "); + sta::print(stream_, " -edge_shift "); writeFloatSeq(edge_shifts, scaleTime(1.0)); } } writeCmdComment(clk); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeClockPins(clk); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void @@ -485,7 +486,7 @@ WriteSdc::writeClockPins(const Clock *clk) const const PinSet &pins = clk->pins(); if (!pins.empty()) { if (pins.size() > 1) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetPins(&pins, true); } } @@ -523,9 +524,9 @@ WriteSdc::writeClockUncertainty(const Clock *clk, const char *setup_hold, float value) const { - gzprintf(stream_, "set_clock_uncertainty %s", setup_hold); + sta::print(stream_, "set_clock_uncertainty {}", setup_hold); writeTime(value); - gzprintf(stream_, " %s\n", clk->name()); + sta::print(stream_, " {}\n", clk->name()); } void @@ -560,11 +561,11 @@ WriteSdc::writeClockUncertaintyPin(const Pin *pin, const char *setup_hold, float value) const { - gzprintf(stream_, "set_clock_uncertainty %s", setup_hold); + sta::print(stream_, "set_clock_uncertainty {}", setup_hold); writeTime(value); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPin(pin, true); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void @@ -633,9 +634,9 @@ void WriteSdc::writePropagatedClkPins() const { for (const Pin *pin : sdc_->propagated_clk_pins_) { - gzprintf(stream_, "set_propagated_clock "); + sta::print(stream_, "set_propagated_clock "); writeGetPin(pin, true); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } @@ -659,13 +660,13 @@ writeInterClockUncertainty(InterClockUncertainty *uncertainty) const float value; if (src_rise->equal(src_fall) && src_rise->isOneValue(value)) { - gzprintf(stream_, "set_clock_uncertainty -from "); + sta::print(stream_, "set_clock_uncertainty -from "); writeGetClock(src_clk); - gzprintf(stream_, " -to "); + sta::print(stream_, " -to "); writeGetClock(tgt_clk); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeTime(value); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } else { for (auto src_rf : RiseFall::range()) { @@ -676,16 +677,16 @@ writeInterClockUncertainty(InterClockUncertainty *uncertainty) const sdc_->clockUncertainty(src_clk, src_rf, tgt_clk, tgt_rf, setup_hold, value, exists); if (exists) { - gzprintf(stream_, "set_clock_uncertainty -%s_from ", - src_rf == RiseFall::rise() ? "rise" : "fall"); + sta::print(stream_, "set_clock_uncertainty -{}_from ", + src_rf == RiseFall::rise() ? "rise" : "fall"); writeGetClock(uncertainty->src()); - gzprintf(stream_, " -%s_to ", - tgt_rf == RiseFall::rise() ? "rise" : "fall"); + sta::print(stream_, " -{}_to ", + tgt_rf == RiseFall::rise() ? "rise" : "fall"); writeGetClock(uncertainty->target()); - gzprintf(stream_, " %s ", - setupHoldFlag(setup_hold)); + sta::print(stream_, " {} ", + setupHoldFlag(setup_hold)); writeTime(value); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } } @@ -794,25 +795,25 @@ WriteSdc::writePortDelay(PortDelay *port_delay, const MinMaxAll *min_max, const char *sdc_cmd) const { - gzprintf(stream_, "%s ", sdc_cmd); + sta::print(stream_, "{} ", sdc_cmd); writeTime(delay); const ClockEdge *clk_edge = port_delay->clkEdge(); if (clk_edge) { writeClockKey(clk_edge->clock()); if (clk_edge->transition() == RiseFall::fall()) - gzprintf(stream_, " -clock_fall"); + sta::print(stream_, " -clock_fall"); } - gzprintf(stream_, "%s%s -add_delay ", - transRiseFallFlag(rf), - minMaxFlag(min_max)); + sta::print(stream_, "{}{} -add_delay ", + transRiseFallFlag(rf), + minMaxFlag(min_max)); const Pin *ref_pin = port_delay->refPin(); if (ref_pin) { - gzprintf(stream_, "-reference_pin "); + sta::print(stream_, "-reference_pin "); writeGetPin(ref_pin, true); - gzprintf(stream_, " "); + sta::print(stream_, " "); } writeGetPin(port_delay->pin(), is_input_delay); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } class PinClockPairNameLess @@ -876,15 +877,15 @@ WriteSdc::writeClockSense(PinClockPair &pin_clk, flag = "-negative"; else if (sense == ClockSense::stop) flag = "-stop_propagation"; - gzprintf(stream_, "set_sense -type clock %s ", flag); + sta::print(stream_, "set_sense -type clock {} ", flag); const Clock *clk = pin_clk.second; if (clk) { - gzprintf(stream_, "-clock "); + sta::print(stream_, "-clock "); writeGetClock(clk); - gzprintf(stream_, " "); + sta::print(stream_, " "); } writeGetPin(pin_clk.first, true); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } class ClockGroupLess @@ -935,22 +936,22 @@ ClockGroupLess::operator()(const ClockGroup *clk_group1, void WriteSdc::writeClockGroups() const { - for (const auto [name, clk_groups] : sdc_->clk_groups_name_map_) + for (const auto &[name, clk_groups] : sdc_->clk_groups_name_map_) writeClockGroups(clk_groups); } void WriteSdc::writeClockGroups(ClockGroups *clk_groups) const { - gzprintf(stream_, "set_clock_groups -name %s ", clk_groups->name()); + sta::print(stream_, "set_clock_groups -name {} ", clk_groups->name()); if (clk_groups->logicallyExclusive()) - gzprintf(stream_, "-logically_exclusive \\\n"); + sta::print(stream_, "-logically_exclusive \\\n"); else if (clk_groups->physicallyExclusive()) - gzprintf(stream_, "-physically_exclusive \\\n"); + sta::print(stream_, "-physically_exclusive \\\n"); else if (clk_groups->asynchronous()) - gzprintf(stream_, "-asynchronous \\\n"); + sta::print(stream_, "-asynchronous \\\n"); if (clk_groups->allowPaths()) - gzprintf(stream_, "-allow_paths \\\n"); + sta::print(stream_, "-allow_paths \\\n"); std::vector groups; for (ClockGroup *clk_group : *clk_groups->groups()) groups.push_back(clk_group); @@ -958,13 +959,13 @@ WriteSdc::writeClockGroups(ClockGroups *clk_groups) const bool first = true; for (ClockGroup *clk_group : groups) { if (!first) - gzprintf(stream_, "\\\n"); - gzprintf(stream_, " -group "); + sta::print(stream_, "\\\n"); + sta::print(stream_, " -group "); writeGetClocks(clk_group); first = false; } writeCmdComment(clk_groups); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } //////////////////////////////////////////////////////////////// @@ -987,46 +988,46 @@ WriteSdc::writeDisabledCells() const for (const DisabledCellPorts *disable : disables) { const LibertyCell *cell = disable->cell(); if (disable->all()) { - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); writeGetLibCell(cell); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } if (disable->fromTo()) { LibertyPortPairSeq from_tos = sortByName(disable->fromTo()); for (const LibertyPortPair &from_to : from_tos) { const LibertyPort *from = from_to.first; const LibertyPort *to = from_to.second; - gzprintf(stream_, "set_disable_timing -from {%s} -to {%s} ", - from->name(), - to->name()); + sta::print(stream_, "set_disable_timing -from {{{}}} -to {{{}}} ", + from->name(), + to->name()); writeGetLibCell(cell); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } if (disable->from()) { LibertyPortSeq from = sortByName(disable->from()); for (const LibertyPort *from_port : from) { - gzprintf(stream_, "set_disable_timing -from {%s} ", - from_port->name()); + sta::print(stream_, "set_disable_timing -from {{{}}} ", + from_port->name()); writeGetLibCell(cell); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } if (disable->to()) { LibertyPortSeq to = sortByName(disable->to()); for (const LibertyPort *to_port : to) { - gzprintf(stream_, "set_disable_timing -to {%s} ", - to_port->name()); + sta::print(stream_, "set_disable_timing -to {{{}}} ", + to_port->name()); writeGetLibCell(cell); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } if (disable->timingArcSets()) { // The only syntax to disable timing arc sets disables all of the // cell's timing arc sets. - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); writeGetTimingArcsOfOjbects(cell); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } } @@ -1036,9 +1037,9 @@ WriteSdc::writeDisabledPorts() const { const PortSeq ports = sortByName(sdc_->disabledPorts(), sdc_network_); for (const Port *port : ports) { - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); writeGetPort(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } @@ -1047,9 +1048,9 @@ WriteSdc::writeDisabledLibPorts() const { LibertyPortSeq ports = sortByName(sdc_->disabledLibPorts()); for (LibertyPort *port : ports) { - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); writeGetLibPin(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } @@ -1061,38 +1062,38 @@ WriteSdc::writeDisabledInstances() const for (DisabledInstancePorts *disable : disables) { Instance *inst = disable->instance(); if (disable->all()) { - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); writeGetInstance(inst); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } else if (disable->fromTo()) { LibertyPortPairSeq from_tos = sortByName(disable->fromTo()); for (LibertyPortPair &from_to : from_tos) { const LibertyPort *from_port = from_to.first; const LibertyPort *to_port = from_to.second; - gzprintf(stream_, "set_disable_timing -from {%s} -to {%s} ", - from_port->name(), - to_port->name()); + sta::print(stream_, "set_disable_timing -from {{{}}} -to {{{}}} ", + from_port->name(), + to_port->name()); writeGetInstance(inst); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } if (disable->from()) { LibertyPortSeq from = sortByName(disable->from()); for (const LibertyPort *from_port : from) { - gzprintf(stream_, "set_disable_timing -from {%s} ", - from_port->name()); + sta::print(stream_, "set_disable_timing -from {{{}}} ", + from_port->name()); writeGetInstance(inst); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } if (disable->to()) { LibertyPortSeq to = sortByName(disable->to()); for (const LibertyPort *to_port : to) { - gzprintf(stream_, "set_disable_timing -to {%s} ", - to_port->name()); + sta::print(stream_, "set_disable_timing -to {{{}}} ", + to_port->name()); writeGetInstance(inst); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } } @@ -1103,9 +1104,9 @@ WriteSdc::writeDisabledPins() const { PinSeq pins = sortByPathName(sdc_->disabledPins(), sdc_network_); for (const Pin *pin : pins) { - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); writeGetPin(pin, false); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } @@ -1156,20 +1157,19 @@ WriteSdc::edgeSenseIsUnique(Edge *edge, void WriteSdc::writeDisabledEdge(Edge *edge) const { - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); writeGetTimingArcs(edge); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void WriteSdc::writeDisabledEdgeSense(Edge *edge) const { - gzprintf(stream_, "set_disable_timing "); + sta::print(stream_, "set_disable_timing "); const char *sense = to_string(edge->sense()); - std::string filter; - stringPrint(filter, "sense == %s", sense); + std::string filter = sta::format("sense == {}", sense); writeGetTimingArcs(edge, filter.c_str()); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } //////////////////////////////////////////////////////////////// @@ -1202,44 +1202,44 @@ WriteSdc::writeException(ExceptionPath *exception) const writeExceptionTo(exception->to()); writeExceptionValue(exception); writeCmdComment(exception); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void WriteSdc::writeExceptionCmd(ExceptionPath *exception) const { if (exception->isFalse()) { - gzprintf(stream_, "set_false_path"); + sta::print(stream_, "set_false_path"); writeSetupHoldFlag(exception->minMax()); } else if (exception->isMultiCycle()) { - gzprintf(stream_, "set_multicycle_path"); + sta::print(stream_, "set_multicycle_path"); const MinMaxAll *min_max = exception->minMax(); writeSetupHoldFlag(min_max); if (min_max == MinMaxAll::min()) { // For hold MCPs default is -start. if (exception->useEndClk()) - gzprintf(stream_, " -end"); + sta::print(stream_, " -end"); } else { // For setup MCPs default is -end. if (!exception->useEndClk()) - gzprintf(stream_, " -start"); + sta::print(stream_, " -start"); } } else if (exception->isPathDelay()) { if (exception->minMax() == MinMaxAll::max()) - gzprintf(stream_, "set_max_delay"); + sta::print(stream_, "set_max_delay"); else - gzprintf(stream_, "set_min_delay"); + sta::print(stream_, "set_min_delay"); if (exception->ignoreClkLatency()) - gzprintf(stream_, " -ignore_clock_latency"); + sta::print(stream_, " -ignore_clock_latency"); } else if (exception->isGroupPath()) { if (exception->isDefault()) - gzprintf(stream_, "group_path -default"); + sta::print(stream_, "group_path -default"); else - gzprintf(stream_, "group_path -name %s", exception->name()); + sta::print(stream_, "group_path -name {}", exception->name()); } else report_->critical(1620, "unknown exception type"); @@ -1249,10 +1249,10 @@ void WriteSdc::writeExceptionValue(ExceptionPath *exception) const { if (exception->isMultiCycle()) - gzprintf(stream_, " %d", - exception->pathMultiplier()); + sta::print(stream_, " {}", + exception->pathMultiplier()); else if (exception->isPathDelay()) { - gzprintf(stream_, " "); + sta::print(stream_, " "); writeTime(exception->delay()); } } @@ -1268,7 +1268,7 @@ WriteSdc::writeExceptionTo(ExceptionTo *to) const { const RiseFallBoth *end_rf = to->endTransition(); if (end_rf != RiseFallBoth::riseFall()) - gzprintf(stream_, "%s ", transRiseFallFlag(end_rf)); + sta::print(stream_, "{} ", transRiseFallFlag(end_rf)); if (to->hasObjects()) writeExceptionFromTo(to, "to", false); } @@ -1284,19 +1284,19 @@ WriteSdc::writeExceptionFromTo(ExceptionFromTo *from_to, rf_prefix = "-rise_"; else if (rf == RiseFallBoth::fall()) rf_prefix = "-fall_"; - gzprintf(stream_, "\\\n %s%s ", rf_prefix, from_to_key); + sta::print(stream_, "\\\n {}{} ", rf_prefix, from_to_key); bool multi_objs = ((from_to->pins() ? from_to->pins()->size() : 0) + (from_to->clks() ? from_to->clks()->size() : 0) + (from_to->instances() ? from_to->instances()->size() : 0)) > 1; if (multi_objs) - gzprintf(stream_, "[list "); + sta::print(stream_, "[list "); bool first = true; if (from_to->pins()) { PinSeq pins = sortByPathName(from_to->pins(), sdc_network_); for (const Pin *pin : pins) { if (multi_objs && !first) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetPin(pin, map_hpin_to_drvr); first = false; } @@ -1307,13 +1307,13 @@ WriteSdc::writeExceptionFromTo(ExceptionFromTo *from_to, InstanceSeq insts = sortByPathName(from_to->instances(), sdc_network_); for (const Instance *inst : insts) { if (multi_objs && !first) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetInstance(inst); first = false; } } if (multi_objs) - gzprintf(stream_, "]"); + sta::print(stream_, "]"); } void @@ -1325,7 +1325,7 @@ WriteSdc::writeExceptionThru(ExceptionThru *thru) const rf_prefix = "-rise_"; else if (rf == RiseFallBoth::fall()) rf_prefix = "-fall_"; - gzprintf(stream_, "\\\n %sthrough ", rf_prefix); + sta::print(stream_, "\\\n {}through ", rf_prefix); PinSeq pins; mapThruHpins(thru, pins); bool multi_objs = @@ -1333,12 +1333,12 @@ WriteSdc::writeExceptionThru(ExceptionThru *thru) const + (thru->nets() ? thru->nets()->size() : 0) + (thru->instances() ? thru->instances()->size() : 0)) > 1; if (multi_objs) - gzprintf(stream_, "[list "); + sta::print(stream_, "[list "); bool first = true; sort(pins, PinPathNameLess(network_)); for (const Pin *pin : pins) { if (multi_objs && !first) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetPin(pin); first = false; } @@ -1347,7 +1347,7 @@ WriteSdc::writeExceptionThru(ExceptionThru *thru) const NetSeq nets = sortByPathName(thru->nets(), sdc_network_); for (const Net *net : nets) { if (multi_objs && !first) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetNet(net); first = false; } @@ -1356,13 +1356,13 @@ WriteSdc::writeExceptionThru(ExceptionThru *thru) const InstanceSeq insts = sortByPathName(thru->instances(), sdc_network_); for (const Instance *inst : insts) { if (multi_objs && !first) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetInstance(inst); first = false; } } if (multi_objs) - gzprintf(stream_, "]"); + sta::print(stream_, "]"); } void @@ -1446,19 +1446,19 @@ WriteSdc::writeDataCheck(DataCheck *check, from_key = "-rise_from"; else if (from_rf == RiseFallBoth::fall()) from_key = "-fall_from"; - gzprintf(stream_, "set_data_check %s ", from_key); + sta::print(stream_, "set_data_check {} ", from_key); writeGetPin(check->from(), true); const char *to_key = "-to"; if (to_rf == RiseFallBoth::rise()) to_key = "-rise_to"; else if (to_rf == RiseFallBoth::fall()) to_key = "-fall_to"; - gzprintf(stream_, " %s ", to_key); + sta::print(stream_, " {} ", to_key); writeGetPin(check->to(), false); - gzprintf(stream_, "%s ", - setupHoldFlag(setup_hold)); + sta::print(stream_, "{} ", + setupHoldFlag(setup_hold)); writeTime(margin); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } //////////////////////////////////////////////////////////////// @@ -1486,7 +1486,7 @@ WriteSdc::writeOperatingConditions() const { OperatingConditions *cond = sdc_->operatingConditions(MinMax::max()); if (cond) - gzprintf(stream_, "set_operating_conditions %s\n", cond->name()); + sta::print(stream_, "set_operating_conditions {}\n", cond->name()); } void @@ -1494,8 +1494,8 @@ WriteSdc::writeWireload() const { WireloadMode wireload_mode = sdc_->wireloadMode(); if (wireload_mode != WireloadMode::unknown) - gzprintf(stream_, "set_wire_load_mode \"%s\"\n", - wireloadModeString(wireload_mode)); + sta::print(stream_, "set_wire_load_mode \"{}\"\n", + wireloadModeString(wireload_mode)); } void @@ -1523,12 +1523,12 @@ WriteSdc::writeNetLoad(const Net *net, const MinMaxAll *min_max, float cap) const { - gzprintf(stream_, "set_load "); - gzprintf(stream_, "%s ", minMaxFlag(min_max)); + sta::print(stream_, "set_load "); + sta::print(stream_, "{} ", minMaxFlag(min_max)); writeCapacitance(cap); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetNet(net); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void @@ -1572,12 +1572,12 @@ WriteSdc::writeDriveResistances() const float res; bool exists; drive->driveResistance(rf, MinMax::max(), res, exists); - gzprintf(stream_, "set_drive %s ", - transRiseFallFlag(rf)); + sta::print(stream_, "set_drive {} ", + transRiseFallFlag(rf)); writeResistance(res); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPort(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } else { for (auto min_max : MinMax::range()) { @@ -1585,13 +1585,13 @@ WriteSdc::writeDriveResistances() const bool exists; drive->driveResistance(rf, min_max, res, exists); if (exists) { - gzprintf(stream_, "set_drive %s %s ", - transRiseFallFlag(rf), - minMaxFlag(min_max)); + sta::print(stream_, "set_drive {} {} ", + transRiseFallFlag(rf), + minMaxFlag(min_max)); writeResistance(res); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPort(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } } @@ -1668,27 +1668,27 @@ WriteSdc::writeDrivingCell(Port *port, const LibertyPort *to_port = drive_cell->toPort(); float *from_slews = drive_cell->fromSlews(); const LibertyLibrary *lib = drive_cell->library(); - gzprintf(stream_, "set_driving_cell"); + sta::print(stream_, "set_driving_cell"); if (rf) - gzprintf(stream_, " %s", transRiseFallFlag(rf)); + sta::print(stream_, " {}", transRiseFallFlag(rf)); if (min_max) - gzprintf(stream_, " %s", minMaxFlag(min_max)); + sta::print(stream_, " {}", minMaxFlag(min_max)); // Only write -library if it was specified in the sdc. if (lib) - gzprintf(stream_, " -library %s", lib->name()); - gzprintf(stream_, " -lib_cell %s", cell->name()); + sta::print(stream_, " -library {}", lib->name()); + sta::print(stream_, " -lib_cell {}", cell->name()); if (from_port) - gzprintf(stream_, " -from_pin {%s}", - from_port->name()); - gzprintf(stream_, - " -pin {%s} -input_transition_rise ", - to_port->name()); + sta::print(stream_, " -from_pin {{{}}}", + from_port->name()); + sta::print(stream_, + " -pin {{{}}} -input_transition_rise ", + to_port->name()); writeTime(from_slews[RiseFall::riseIndex()]); - gzprintf(stream_, " -input_transition_fall "); + sta::print(stream_, " -input_transition_fall "); writeTime(from_slews[RiseFall::fallIndex()]); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPort(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void @@ -1736,11 +1736,11 @@ WriteSdc::writeNetResistance(const Net *net, const MinMaxAll *min_max, float res) const { - gzprintf(stream_, "set_resistance "); + sta::print(stream_, "set_resistance "); writeResistance(res); - gzprintf(stream_, "%s ", minMaxFlag(min_max)); + sta::print(stream_, "{} ", minMaxFlag(min_max)); writeGetNet(net); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void @@ -1756,9 +1756,9 @@ void WriteSdc::writeConstant(const Pin *pin) const { const char *cmd = setConstantCmd(pin); - gzprintf(stream_, "%s ", cmd); + sta::print(stream_, "{} ", cmd); writeGetPin(pin, false); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } const char * @@ -1796,9 +1796,9 @@ void WriteSdc::writeCaseAnalysis(const Pin *pin) const { const char *value_str = caseAnalysisValueStr(pin); - gzprintf(stream_, "set_case_analysis %s ", value_str); + sta::print(stream_, "set_case_analysis {} ", value_str); writeGetPin(pin, false); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } const char * @@ -1882,9 +1882,9 @@ WriteSdc::writeDerating(DeratingFactorsGlobal *factors) const && (!cell_check_factors->hasValue() || (check_is_one_value && check_value == 1.0))) { if (delay_value != 1.0) { - gzprintf(stream_, "set_timing_derate %s ", earlyLateFlag(early_late)); + sta::print(stream_, "set_timing_derate {} ", earlyLateFlag(early_late)); writeFloat(delay_value); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } else { @@ -1923,15 +1923,15 @@ WriteSdc::writeDerating(DeratingFactors *factors, factors->isOneValue(early_late, is_one_value, value); if (is_one_value) { if (value != 1.0) { - gzprintf(stream_, "set_timing_derate %s %s ", - type_key, - earlyLateFlag(early_late)); + sta::print(stream_, "set_timing_derate {} {} ", + type_key, + earlyLateFlag(early_late)); writeFloat(value); if (write_obj) { - gzprintf(stream_, " "); + sta::print(stream_, " "); write_obj->write(); } - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } else { @@ -1944,16 +1944,16 @@ WriteSdc::writeDerating(DeratingFactors *factors, factors->isOneValue(clk_data, early_late, is_one_value, value); if (is_one_value) { if (value != 1.0) { - gzprintf(stream_, "set_timing_derate %s %s %s ", - type_key, - earlyLateFlag(early_late), - clk_data_key); + sta::print(stream_, "set_timing_derate {} {} {} ", + type_key, + earlyLateFlag(early_late), + clk_data_key); writeFloat(value); if (write_obj) { - gzprintf(stream_, " "); + sta::print(stream_, " "); write_obj->write(); } - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } else { @@ -1962,17 +1962,17 @@ WriteSdc::writeDerating(DeratingFactors *factors, bool exists; factors->factor(clk_data, rf, early_late, factor, exists); if (exists) { - gzprintf(stream_, "set_timing_derate %s %s %s %s ", - type_key, - clk_data_key, - transRiseFallFlag(rf), - earlyLateFlag(early_late)); + sta::print(stream_, "set_timing_derate {} {} {} {} ", + type_key, + clk_data_key, + transRiseFallFlag(rf), + earlyLateFlag(early_late)); writeFloat(factor); if (write_obj) { - gzprintf(stream_, " "); + sta::print(stream_, " "); write_obj->write(); } - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } } @@ -1998,11 +1998,11 @@ WriteSdc::writeVoltages() const if (exists_max) { sdc_->voltage(MinMax::min(), voltage_min, exists_min); if (exists_min) - gzprintf(stream_, "set_voltage -min %.3f %.3f\n", - voltage_min, - voltage_max); + sta::print(stream_, "set_voltage -min {:.3f} {:.3f}\n", + voltage_min, + voltage_max); else - gzprintf(stream_, "set_voltage %.3f\n", voltage_max); + sta::print(stream_, "set_voltage {:.3f}\n", voltage_max); } for (const auto& [net, volts] : sdc_->net_voltage_map_) { @@ -2010,14 +2010,14 @@ WriteSdc::writeVoltages() const if (exists_max) { volts.value(MinMax::min(), voltage_min, exists_min); if (exists_min) - gzprintf(stream_, "set_voltage -object_list %s -min %.3f %.3f\n", - sdc_network_->pathName(net), - voltage_min, - voltage_max); + sta::print(stream_, "set_voltage -object_list {} -min {:.3f} {:.3f}\n", + sdc_network_->pathName(net), + voltage_min, + voltage_max); else - gzprintf(stream_, "set_voltage -object_list %s %.3f\n", - sdc_network_->pathName(net), - voltage_max); + sta::print(stream_, "set_voltage -object_list {} {:.3f}\n", + sdc_network_->pathName(net), + voltage_max); } } } @@ -2079,11 +2079,11 @@ WriteSdc::writeMinPulseWidth(const char *hi_low, float value, WriteSdcObject &write_obj) const { - gzprintf(stream_, "set_min_pulse_width %s", hi_low); + sta::print(stream_, "set_min_pulse_width {}", hi_low); writeTime(value); - gzprintf(stream_, " "); + sta::print(stream_, " "); write_obj.write(); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } //////////////////////////////////////////////////////////////// @@ -2092,27 +2092,27 @@ void WriteSdc::writeLatchBorowLimits() const { for (const auto [pin, limit] : sdc_->pin_latch_borrow_limit_map_) { - gzprintf(stream_, "set_max_time_borrow "); + sta::print(stream_, "set_max_time_borrow "); writeTime(limit); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPin(pin, false); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } for (const auto [inst, limit] : sdc_->inst_latch_borrow_limit_map_) { - gzprintf(stream_, "set_max_time_borrow "); + sta::print(stream_, "set_max_time_borrow "); writeTime(limit); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetInstance(inst); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } for (const auto [clk, limit] : sdc_->clk_latch_borrow_limit_map_) { - gzprintf(stream_, "set_max_time_borrow "); + sta::print(stream_, "set_max_time_borrow "); writeTime(limit); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetClock(clk); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } @@ -2126,9 +2126,9 @@ WriteSdc::writeSlewLimits() const bool exists; sdc_->slewLimit(cell_, min_max, slew, exists); if (exists) { - gzprintf(stream_, "set_max_transition "); + sta::print(stream_, "set_max_transition "); writeTime(slew); - gzprintf(stream_, " [current_design]\n"); + sta::print(stream_, " [current_design]\n"); } CellPortBitIterator *port_iter = sdc_network_->portBitIterator(cell_); @@ -2136,11 +2136,11 @@ WriteSdc::writeSlewLimits() const Port *port = port_iter->next(); sdc_->slewLimit(port, min_max, slew, exists); if (exists) { - gzprintf(stream_, "set_max_transition "); + sta::print(stream_, "set_max_transition "); writeTime(slew); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPort(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } delete port_iter; @@ -2200,11 +2200,11 @@ WriteSdc::writeClkSlewLimit(const char *clk_data, const Clock *clk, float limit) const { - gzprintf(stream_, "set_max_transition %s%s", clk_data, rise_fall); + sta::print(stream_, "set_max_transition {}{}", clk_data, rise_fall); writeTime(limit); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetClock(clk); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void @@ -2222,9 +2222,9 @@ WriteSdc::writeCapLimits(const MinMax *min_max, bool exists; sdc_->capacitanceLimit(cell_, min_max, cap, exists); if (exists) { - gzprintf(stream_, "%s ", cmd); + sta::print(stream_, "{} ", cmd); writeCapacitance(cap); - gzprintf(stream_, " [current_design]\n"); + sta::print(stream_, " [current_design]\n"); } for (const auto [port, limits] : sdc_->port_cap_limit_map_) { @@ -2232,11 +2232,11 @@ WriteSdc::writeCapLimits(const MinMax *min_max, bool exists; limits.value(min_max, cap, exists); if (exists) { - gzprintf(stream_, "%s ", cmd); + sta::print(stream_, "{} ", cmd); writeCapacitance(cap); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPort(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } @@ -2245,11 +2245,11 @@ WriteSdc::writeCapLimits(const MinMax *min_max, bool exists; limits.value(min_max, cap, exists); if (exists) { - gzprintf(stream_, "%s ", cmd); + sta::print(stream_, "{} ", cmd); writeCapacitance(cap); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPin(pin, false); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } } @@ -2259,9 +2259,9 @@ WriteSdc::writeMaxArea() const { float max_area = sdc_->maxArea(); if (max_area > 0.0) { - gzprintf(stream_, "set_max_area "); + sta::print(stream_, "set_max_area "); writeFloat(max_area); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } @@ -2280,9 +2280,9 @@ WriteSdc::writeFanoutLimits(const MinMax *min_max, bool exists; sdc_->fanoutLimit(cell_, min_max, fanout, exists); if (exists) { - gzprintf(stream_, "%s ", cmd); + sta::print(stream_, "{} ", cmd); writeFloat(fanout); - gzprintf(stream_, " [current_design]\n"); + sta::print(stream_, " [current_design]\n"); } else { CellPortBitIterator *port_iter = sdc_network_->portBitIterator(cell_); @@ -2290,11 +2290,11 @@ WriteSdc::writeFanoutLimits(const MinMax *min_max, Port *port = port_iter->next(); sdc_->fanoutLimit(port, min_max, fanout, exists); if (exists) { - gzprintf(stream_, "%s ", cmd); + sta::print(stream_, "{} ", cmd); writeFloat(fanout); - gzprintf(stream_, " "); + sta::print(stream_, " "); writeGetPort(port); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } } delete port_iter; @@ -2308,15 +2308,15 @@ WriteSdc::writeVariables() const { if (variables_->propagateAllClocks()) { if (native_) - gzprintf(stream_, "set sta_propagate_all_clocks 1\n"); + sta::print(stream_, "set sta_propagate_all_clocks 1\n"); else - gzprintf(stream_, "set timing_all_clocks_propagated true\n"); + sta::print(stream_, "set timing_all_clocks_propagated true\n"); } if (variables_->presetClrArcsEnabled()) { if (native_) - gzprintf(stream_, "set sta_preset_clear_arcs_enabled 1\n"); + sta::print(stream_, "set sta_preset_clear_arcs_enabled 1\n"); else - gzprintf(stream_, "set timing_enable_preset_clear_arcs true\n"); + sta::print(stream_, "set timing_enable_preset_clear_arcs true\n"); } } @@ -2325,9 +2325,9 @@ WriteSdc::writeVariables() const void WriteSdc::writeGetTimingArcsOfOjbects(const LibertyCell *cell) const { - gzprintf(stream_, "[%s -of_objects ", getTimingArcsCmd()); + sta::print(stream_, "[{} -of_objects ", getTimingArcsCmd()); writeGetLibCell(cell); - gzprintf(stream_, "]"); + sta::print(stream_, "]"); } void @@ -2340,15 +2340,15 @@ void WriteSdc::writeGetTimingArcs(Edge *edge, const char *filter) const { - gzprintf(stream_, "[%s -from ", getTimingArcsCmd()); + sta::print(stream_, "[{} -from ", getTimingArcsCmd()); Vertex *from_vertex = edge->from(graph_); writeGetPin(from_vertex->pin(), true); - gzprintf(stream_, " -to "); + sta::print(stream_, " -to "); Vertex *to_vertex = edge->to(graph_); writeGetPin(to_vertex->pin(), false); if (filter) - gzprintf(stream_, " -filter {%s}", filter); - gzprintf(stream_, "]"); + sta::print(stream_, " -filter {{{}}}", filter); + sta::print(stream_, "]"); } const char * @@ -2362,7 +2362,7 @@ WriteSdc::getTimingArcsCmd() const void WriteSdc::writeGetLibCell(const LibertyCell *cell) const { - gzprintf(stream_, "[get_lib_cells {%s/%s}]", + sta::print(stream_, "[get_lib_cells {{{}/{}}}]", cell->libertyLibrary()->name(), cell->name()); } @@ -2372,10 +2372,10 @@ WriteSdc::writeGetLibPin(const LibertyPort *port) const { LibertyCell *cell = port->libertyCell(); LibertyLibrary *lib = cell->libertyLibrary(); - gzprintf(stream_, "[get_lib_pins {%s/%s/%s}]", - lib->name(), - cell->name(), - port->name()); + sta::print(stream_, "[get_lib_pins {{{}/{}/{}}}]", + lib->name(), + cell->name(), + port->name()); } void @@ -2384,10 +2384,10 @@ WriteSdc::writeGetClocks(ClockSet *clks) const bool first = true; bool multiple = clks->size() > 1; if (multiple) - gzprintf(stream_, "[list "); + sta::print(stream_, "[list "); writeGetClocks(clks, multiple, first); if (multiple) - gzprintf(stream_, "]"); + sta::print(stream_, "]"); } void @@ -2398,7 +2398,7 @@ WriteSdc::writeGetClocks(ClockSet *clks, ClockSeq clks1 = sortByName(clks); for (const Clock *clk : clks1) { if (multiple && !first) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetClock(clk); first = false; } @@ -2407,14 +2407,14 @@ WriteSdc::writeGetClocks(ClockSet *clks, void WriteSdc::writeGetClock(const Clock *clk) const { - gzprintf(stream_, "[get_clocks {%s}]", - clk->name()); + sta::print(stream_, "[get_clocks {{{}}}]", + clk->name()); } void WriteSdc::writeGetPort(const Port *port) const { - gzprintf(stream_, "[get_ports {%s}]", sdc_network_->name(port)); + sta::print(stream_, "[get_ports {{{}}}]", sdc_network_->name(port)); } void @@ -2447,25 +2447,25 @@ WriteSdc::writeGetPins1(PinSeq *pins) const { bool multiple = pins->size() > 1; if (multiple) - gzprintf(stream_, "[list "); + sta::print(stream_, "[list "); bool first = true; for (const Pin *pin : *pins) { if (multiple && !first) - gzprintf(stream_, "\\\n "); + sta::print(stream_, "\\\n "); writeGetPin(pin); first = false; } if (multiple) - gzprintf(stream_, "]"); + sta::print(stream_, "]"); } void WriteSdc::writeGetPin(const Pin *pin) const { if (sdc_network_->instance(pin) == instance_) - gzprintf(stream_, "[get_ports {%s}]", sdc_network_->portName(pin)); + sta::print(stream_, "[get_ports {{{}}}]", sdc_network_->portName(pin)); else - gzprintf(stream_, "[get_pins {%s}]", pathName(pin)); + sta::print(stream_, "[get_pins {{{}}}]", pathName(pin)); } void @@ -2484,13 +2484,13 @@ WriteSdc::writeGetPin(const Pin *pin, void WriteSdc::writeGetNet(const Net *net) const { - gzprintf(stream_, "[get_nets {%s}]", pathName(net)); + sta::print(stream_, "[get_nets {{{}}}]", pathName(net)); } void WriteSdc::writeGetInstance(const Instance *inst) const { - gzprintf(stream_, "[get_cells {%s}]", pathName(inst)); + sta::print(stream_, "[get_cells {{{}}}]", pathName(inst)); } const char * @@ -2527,14 +2527,14 @@ void WriteSdc::writeCommentSection(const char *line) const { writeCommentSeparator(); - gzprintf(stream_, "# %s\n", line); + sta::print(stream_, "# {}\n", line); writeCommentSeparator(); } void WriteSdc::writeCommentSeparator() const { - gzprintf(stream_, "###############################################################################\n"); + sta::print(stream_, "###############################################################################\n"); } //////////////////////////////////////////////////////////////// @@ -2632,20 +2632,20 @@ WriteSdc::writeRiseFallMinMaxCmd(const char *sdc_cmd, const MinMaxAll *min_max, WriteSdcObject &write_object) const { - gzprintf(stream_, "%s%s%s ", - sdc_cmd, - transRiseFallFlag(rf), - minMaxFlag(min_max)); + sta::print(stream_, "{}{}{} ", + sdc_cmd, + transRiseFallFlag(rf), + minMaxFlag(min_max)); writeFloat(value / scale); - gzprintf(stream_, " "); + sta::print(stream_, " "); write_object.write(); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void WriteSdc::writeClockKey(const Clock *clk) const { - gzprintf(stream_, " -clock "); + sta::print(stream_, " -clock "); writeGetClock(clk); } @@ -2681,13 +2681,13 @@ WriteSdc::writeMinMaxFloatCmd(const char *sdc_cmd, const MinMaxAll *min_max, WriteSdcObject &write_object) const { - gzprintf(stream_, "%s%s ", - sdc_cmd, - minMaxFlag(min_max)); + sta::print(stream_, "{}{} ", + sdc_cmd, + minMaxFlag(min_max)); writeFloat(value / scale); - gzprintf(stream_, " "); + sta::print(stream_, " "); write_object.write(); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } void @@ -2718,12 +2718,12 @@ WriteSdc::writeMinMaxIntCmd(const char *sdc_cmd, const MinMaxAll *min_max, WriteSdcObject &write_object) const { - gzprintf(stream_, "%s%s ", - sdc_cmd, - minMaxFlag(min_max)); - gzprintf(stream_, "%d ", value); + sta::print(stream_, "{}{} ", + sdc_cmd, + minMaxFlag(min_max)); + sta::print(stream_, "{} ", value); write_object.write(); - gzprintf(stream_, "\n"); + sta::print(stream_, "\n"); } //////////////////////////////////////////////////////////////// @@ -2749,54 +2749,54 @@ WriteSdc::scaleResistance(float res) const void WriteSdc::writeFloat(float value) const { - gzprintf(stream_, "%.*f", digits_, value); + sta::print(stream_, "{}", sta::formatRuntime("{:.{}f}", value, digits_)); } void WriteSdc::writeTime(float time) const { - gzprintf(stream_, "%.*f", digits_, scaleTime(time)); + sta::print(stream_, "{}", sta::formatRuntime("{:.{}f}", scaleTime(time), digits_)); } void WriteSdc::writeCapacitance(float cap) const { - gzprintf(stream_, "%.*f", digits_, scaleCapacitance(cap)); + sta::print(stream_, "{}", sta::formatRuntime("{:.{}f}", scaleCapacitance(cap), digits_)); } void WriteSdc::writeResistance(float res) const { - gzprintf(stream_, "%.*f", digits_, scaleResistance(res)); + sta::print(stream_, "{}", sta::formatRuntime("{:.{}f}", scaleResistance(res), digits_)); } void WriteSdc::writeFloatSeq(FloatSeq *floats, float scale) const { - gzprintf(stream_, "{"); + sta::print(stream_, "{{"); bool first = true; for (float flt : *floats) { if (!first) - gzprintf(stream_, " "); + sta::print(stream_, " "); writeFloat(flt * scale); first = false; } - gzprintf(stream_, "}"); + sta::print(stream_, "}}"); } void WriteSdc::writeIntSeq(IntSeq *ints) const { - gzprintf(stream_, "{"); + sta::print(stream_, "{{"); bool first = true; for (int i : *ints) { if (!first) - gzprintf(stream_, " "); - gzprintf(stream_, "%d", i); + sta::print(stream_, " "); + sta::print(stream_, "{}", i); first = false; } - gzprintf(stream_, "}"); + sta::print(stream_, "}}"); } @@ -2846,9 +2846,9 @@ void WriteSdc::writeSetupHoldFlag(const MinMaxAll *min_max) const { if (min_max == MinMaxAll::min()) - gzprintf(stream_, " -hold"); + sta::print(stream_, " -hold"); else if (min_max == MinMaxAll::max()) - gzprintf(stream_, " -setup"); + sta::print(stream_, " -setup"); } static const char * @@ -2862,7 +2862,7 @@ WriteSdc::writeCmdComment(SdcCmdComment *cmd) const { const char *comment = cmd->comment(); if (comment) { - gzprintf(stream_, " -comment {%s}", comment); + sta::print(stream_, " -comment {{{}}}", comment); } } diff --git a/sdf/ReportAnnotation.cc b/sdf/ReportAnnotation.cc index 0e516e0e..8f667b71 100644 --- a/sdf/ReportAnnotation.cc +++ b/sdf/ReportAnnotation.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 "sdf/ReportAnnotation.hh" @@ -72,7 +72,8 @@ protected: count_input_net, count_output_net, }; - static const int count_index_max = static_cast(CountIndex::count_output_net) + 1; + static const int count_index_max = + static_cast(CountIndex::count_output_net) + 1; static int count_delay; void init(); @@ -81,7 +82,7 @@ protected: void reportDelayCounts(); void reportCheckCounts(); void reportArcs(); - void reportArcs(const char *header, + void reportArcs(const std::string &header, bool report_annotated, PinSet &pins); void reportArcs(Vertex *vertex, @@ -117,7 +118,6 @@ protected: PinSet annotated_pins_; }; - int ReportAnnotated::count_delay; void @@ -132,10 +132,9 @@ reportAnnotatedDelay(const Scene *scene, bool report_constant_arcs, StaState *sta) { - ReportAnnotated report(scene, report_cells, report_nets, - from_in_ports, to_out_ports, - max_lines, report_annotated, report_unannotated, - report_constant_arcs, sta); + ReportAnnotated report(scene, report_cells, report_nets, from_in_ports, + to_out_ports, max_lines, report_annotated, + report_unannotated, report_constant_arcs, sta); report.reportDelayAnnotation(); } @@ -176,24 +175,27 @@ ReportAnnotated::reportDelayAnnotation() void ReportAnnotated::reportDelayCounts() { - report_->reportLine(" Not "); - report_->reportLine("Delay type Total Annotated Annotated"); - report_->reportLine("----------------------------------------------------------------"); + report_->report( + " Not "); + report_->report( + "Delay type Total Annotated Annotated"); + report_->report( + "----------------------------------------------------------------"); int total = 0; int annotated_total = 0; reportCount("cell arcs", count_delay, total, annotated_total); - reportCount("internal net arcs", static_cast(CountIndex::count_internal_net), total, annotated_total); - reportCount("net arcs from primary inputs", static_cast(CountIndex::count_input_net), - total, annotated_total); - reportCount("net arcs to primary outputs", static_cast(CountIndex::count_output_net), + reportCount("internal net arcs", static_cast(CountIndex::count_internal_net), total, annotated_total); - report_->reportLine("----------------------------------------------------------------"); - report_->reportLine("%-28s %10u %10u %10u", - " ", - total, - annotated_total, - total - annotated_total); + reportCount("net arcs from primary inputs", + static_cast(CountIndex::count_input_net), total, annotated_total); + reportCount("net arcs to primary outputs", + static_cast(CountIndex::count_output_net), total, + annotated_total); + report_->report( + "----------------------------------------------------------------"); + report_->report("{:<28} {:10} {:10} {:10}", " ", total, annotated_total, + total - annotated_total); } //////////////////////////////////////////////////////////////// @@ -215,12 +217,10 @@ reportAnnotatedCheck(const Scene *scene, StaState *sta) { - ReportAnnotated report(scene, report_setup, report_hold, - report_recovery, report_removal, - report_nochange, report_width, - report_period, report_max_skew, - max_lines, report_annotated, report_unannotated, - report_constant_arcs, sta); + ReportAnnotated report(scene, report_setup, report_hold, report_recovery, + report_removal, report_nochange, report_width, + report_period, report_max_skew, max_lines, report_annotated, + report_unannotated, report_constant_arcs, sta); report.reportCheckAnnotation(); } @@ -269,9 +269,12 @@ ReportAnnotated::reportCheckAnnotation() void ReportAnnotated::reportCheckCounts() { - report_->reportLine(" Not "); - report_->reportLine("Check type Total Annotated Annotated"); - report_->reportLine("----------------------------------------------------------------"); + report_->report( + " Not "); + report_->report( + "Check type Total Annotated Annotated"); + report_->report( + "----------------------------------------------------------------"); int total = 0; int annotated_total = 0; @@ -284,12 +287,10 @@ ReportAnnotated::reportCheckCounts() reportCheckCount(TimingRole::period(), total, annotated_total); reportCheckCount(TimingRole::skew(), total, annotated_total); - report_->reportLine("----------------------------------------------------------------"); - report_->reportLine("%-28s %10u %10u %10u", - " ", - total, - annotated_total, - total - annotated_total); + report_->report( + "----------------------------------------------------------------"); + report_->report("{:<28} {:10} {:10} {:10}", " ", total, annotated_total, + total - annotated_total); } void @@ -299,8 +300,7 @@ ReportAnnotated::reportCheckCount(const TimingRole *role, { int index = role->index(); if (edge_count_[index] > 0) { - std::string title; - stringPrint(title, "cell %s arcs", role->to_string().c_str()); + std::string title = sta::format("cell {} arcs", role->to_string()); reportCount(title.c_str(), index, total, annotated_total); } } @@ -330,8 +330,7 @@ ReportAnnotated::findCounts() Pin *from_pin = from_vertex->pin(); LogicValue from_logic_value; bool from_logic_value_exists; - sdc->logicValue(from_pin, from_logic_value, - from_logic_value_exists); + sdc->logicValue(from_pin, from_logic_value, from_logic_value_exists); VertexOutEdgeIterator edge_iter(from_vertex, graph_); while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); @@ -341,8 +340,7 @@ ReportAnnotated::findCounts() int index = roleIndex(role, from_pin, to_pin); LogicValue to_logic_value; bool to_logic_value_exists; - sdc->logicValue(to_pin, to_logic_value, - to_logic_value_exists); + sdc->logicValue(to_pin, to_logic_value, to_logic_value_exists); edge_count_[index]++; @@ -374,7 +372,7 @@ ReportAnnotated::delayAnnotated(Edge *edge) for (const MinMax *min_max : MinMax::range()) { DcalcAPIndex ap_index = scene_->dcalcAnalysisPtIndex(min_max); if (!graph_->arcDelayAnnotated(edge, arc, ap_index)) - return false; + return false; } } return true; @@ -397,8 +395,7 @@ ReportAnnotated::roleIndex(const TimingRole *role, return count_delay; else { if (role->isTimingCheck() - && (role == TimingRole::latchSetup() - || role == TimingRole::latchHold())) + && (role == TimingRole::latchSetup() || role == TimingRole::latchHold())) role = role->genericRole(); return role->index(); } @@ -443,19 +440,13 @@ ReportAnnotated::reportCount(const char *title, if (report_role_[index]) { int count = edge_count_[index]; int annotated_count = edge_annotated_count_[index]; - report_->reportLine("%-28s %10u %10u %10u", - title, - count, - annotated_count, - count - annotated_count); + report_->report("{:<28} {:10} {:10} {:10}", title, count, annotated_count, + count - annotated_count); if (report_constant_arcs_) { int const_count = edge_constant_count_[index]; int const_annotated_count = edge_constant_annotated_count_[index]; - report_->reportLine("%-28s %10s %10u %10u", - "constant arcs", - "", - const_annotated_count, - const_count - const_annotated_count); + report_->report("{:<28} {:10} {:10} {:10}", "constant arcs", "", + const_annotated_count, const_count - const_annotated_count); } total += count; annotated_total += annotated_count; @@ -472,12 +463,12 @@ ReportAnnotated::reportArcs() } void -ReportAnnotated::reportArcs(const char *header, +ReportAnnotated::reportArcs(const std::string &header, bool report_annotated, PinSet &pins) { report_->reportBlankLine(); - report_->reportLineString(header); + report_->reportLine(header); PinSeq pins1 = sortByPathName(&pins, network_); int i = 0; for (const Pin *pin : pins1) { @@ -499,8 +490,7 @@ ReportAnnotated::reportArcs(Vertex *vertex, { const Pin *from_pin = vertex->pin(); VertexOutEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext() - && (max_lines_ == 0 || i < max_lines_)) { + while (edge_iter.hasNext() && (max_lines_ == 0 || i < max_lines_)) { Edge *edge = edge_iter.next(); const TimingRole *role = edge->role(); const Pin *to_pin = edge->to(graph_)->pin(); @@ -520,11 +510,8 @@ ReportAnnotated::reportArcs(Vertex *vertex, else role_name = "delay"; const std::string &cond = edge->timingArcSet()->sdfCond(); - report_->reportLine(" %-18s %s -> %s %s", - role_name, - network_->pathName(from_pin), - network_->pathName(to_pin), - cond.c_str()); + report_->report(" {:<18} {} -> {} {}", role_name, network_->pathName(from_pin), + network_->pathName(to_pin), cond); i++; } } @@ -539,8 +526,7 @@ ReportAnnotated::reportPeriodArcs(const Pin *pin, if (port) { DcalcAPIndex ap_index = 0; int period_index = TimingRole::period()->index(); - if (report_role_[period_index] - && (max_lines_ == 0 || i < max_lines_)) { + if (report_role_[period_index] && (max_lines_ == 0 || i < max_lines_)) { float value; bool exists, annotated; port->minPeriod(value, exists); @@ -548,9 +534,7 @@ ReportAnnotated::reportPeriodArcs(const Pin *pin, edge_count_[period_index]++; graph_->periodCheckAnnotation(pin, ap_index, value, annotated); if (annotated == report_annotated) { - report_->reportLine(" %-18s %s", - "period", - network_->pathName(pin)); + report_->report(" {:<18} {}", "period", network_->pathName(pin)); i++; } } @@ -558,4 +542,4 @@ ReportAnnotated::reportPeriodArcs(const Pin *pin, } } -} // namespace +} // namespace sta diff --git a/sdf/SdfParse.yy b/sdf/SdfParse.yy index 60e8b7ef..6c9c3efb 100644 --- a/sdf/SdfParse.yy +++ b/sdf/SdfParse.yy @@ -38,8 +38,7 @@ void sta::SdfParse::error(const location_type &loc, const std::string &msg) { - reader->report()->fileError(164,reader->filename().c_str(), - loc.begin.line,"%s",msg.c_str()); + reader->report()->fileError(170, reader->filename(), loc.begin.line,"{}",msg); } %} diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index 81818127..65a2bb8e 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.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 "sdf/SdfReader.hh" @@ -74,7 +74,7 @@ public: private: const Transition *tr_; const std::string *port_; - const std::string *cond_; // timing checks only + const std::string *cond_; // timing checks only }; bool @@ -88,11 +88,9 @@ readSdf(const char *filename, { int arc_min_index = scene->dcalcAnalysisPtIndex(MinMax::min()); int arc_max_index = scene->dcalcAnalysisPtIndex(MinMax::max()); - SdfReader reader(filename, path, - arc_min_index, arc_max_index, - scene->sdc()->analysisType(), - unescaped_dividers, incremental_only, - cond_use, sta); + SdfReader reader(filename, path, arc_min_index, arc_max_index, + scene->sdc()->analysisType(), unescaped_dividers, + incremental_only, cond_use, sta); bool success = reader.read(); return success; } @@ -123,7 +121,7 @@ SdfReader::SdfReader(const char *filename, cell_name_(nullptr), in_timing_check_(false), in_incremental_(false), - timescale_(1.0E-9F) // default units of ns + timescale_(1.0E-9F) // default units of ns { if (unescaped_dividers) network_ = makeSdcNetwork(network_); @@ -149,7 +147,7 @@ SdfReader::read() return success; } else - throw FileNotReadable(filename_.c_str()); + throw FileNotReadable(filename_); } void @@ -162,9 +160,7 @@ void SdfReader::setTimescale(float multiplier, const std::string *units) { - if (multiplier == 1.0 - || multiplier == 10.0 - || multiplier == 100.0) { + if (multiplier == 1.0 || multiplier == 10.0 || multiplier == 100.0) { if (*units == "us") timescale_ = multiplier * 1E-6F; else if (*units == "ns") @@ -172,10 +168,10 @@ SdfReader::setTimescale(float multiplier, else if (*units == "ps") timescale_ = multiplier * 1E-12F; else - sdfError(180, "TIMESCALE units not us, ns, or ps."); + error(180, "TIMESCALE units not us, ns, or ps."); } else - sdfError(181, "TIMESCALE multiplier not 1, 10, or 100."); + error(181, "TIMESCALE multiplier not 1, 10, or 100."); delete units; } @@ -198,23 +194,20 @@ SdfReader::interconnect(const std::string *from_pin_name, bool to_is_hier = network_->isHierarchical(to_pin); if (from_is_hier || to_is_hier) { if (from_is_hier) - sdfError(182, "pin %s is a hierarchical pin.", - from_pin_name->c_str()); + error(182, "pin {} is a hierarchical pin.", *from_pin_name); if (to_is_hier) - sdfError(183, "pin %s is a hierarchical pin.", - to_pin_name->c_str()); + error(183, "pin {} is a hierarchical pin.", *to_pin_name); } else - sdfWarn(184, "INTERCONNECT from %s to %s not found.", - from_pin_name->c_str(), - to_pin_name->c_str()); + warn(184, "INTERCONNECT from {} to {} not found.", + *from_pin_name, *to_pin_name); } } else { if (from_pin == nullptr) - sdfWarn(185, "pin %s not found.", from_pin_name->c_str()); + warn(185, "pin {} not found.", *from_pin_name); if (to_pin == nullptr) - sdfWarn(186, "pin %s not found.", to_pin_name->c_str()); + warn(186, "pin {} not found.", *to_pin_name); } } delete from_pin_name; @@ -229,10 +222,10 @@ SdfReader::port(const std::string *to_pin_name, // Ignore non-incremental annotations in incremental only mode. if (!(is_incremental_only_ && !in_incremental_)) { Pin *to_pin = (instance_) - ? network_->findPinRelative(instance_, to_pin_name->c_str()) - : network_->findPin(to_pin_name->c_str()); + ? network_->findPinRelative(instance_, to_pin_name->c_str()) + : network_->findPin(to_pin_name->c_str()); if (to_pin == nullptr) - sdfWarn(187, "pin %s not found.", to_pin_name->c_str()); + warn(187, "pin {} not found.", *to_pin_name); else { Vertex *vertex = graph_->pinLoadVertex(to_pin); VertexInEdgeIterator edge_iter(vertex, graph_); @@ -259,8 +252,7 @@ SdfReader::findWireEdge(Pin *from_pin, while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); const TimingRole *edge_role = edge->role(); - if (edge->from(graph_)->pin() == from_pin - && edge_role->sdfRole()->isWire()) + if (edge->from(graph_)->pin() == from_pin && edge_role->sdfRole()->isWire()) return edge; } } @@ -274,8 +266,7 @@ SdfReader::setEdgeDelays(Edge *edge, { // Rise/fall triples. size_t triple_count = triples->size(); - if (triple_count == 1 - || triple_count == 2) { + if (triple_count == 1 || triple_count == 2) { TimingArcSet *arc_set = edge->timingArcSet(); for (TimingArc *arc : arc_set->arcs()) { size_t triple_index; @@ -288,9 +279,9 @@ SdfReader::setEdgeDelays(Edge *edge, } } else if (triple_count == 0) - sdfError(188, "%s with no triples.", sdf_cmd); + error(188, "{} with no triples.", sdf_cmd); else - sdfError(189, "%s with more than 2 triples.", sdf_cmd); + error(189, "{} with more than 2 triples.", sdf_cmd); } void @@ -313,10 +304,8 @@ SdfReader::setInstance(const std::string *instance_name) Cell *inst_cell = network_->cell(instance_); const char *inst_cell_name = network_->name(inst_cell); if (cell_name_ && !stringEq(inst_cell_name, cell_name_->c_str())) - sdfWarn(190, "instance %s cell %s does not match enclosing cell %s.", - instance_name->c_str(), - inst_cell_name, - cell_name_->c_str()); + warn(190, "instance {} cell {} does not match enclosing cell {}.", + *instance_name, inst_cell_name, *cell_name_); } } } @@ -372,7 +361,7 @@ SdfReader::iopath(SdfPortSpec *from_edge, const std::string &lib_cond = arc_set->sdfCond(); const TimingRole *edge_role = arc_set->role(); bool cond_use_flag = cond_use_ && cond && lib_cond.empty() - && !(!is_incremental_only_ && in_incremental_); + && !(!is_incremental_only_ && in_incremental_); if (edge->from(graph_)->pin() == from_pin && edge_role->sdfRole() == TimingRole::sdfIopath() && (cond_use_flag @@ -402,10 +391,9 @@ SdfReader::iopath(SdfPortSpec *from_edge, } } if (!matched) - sdfWarn(191, "cell %s IOPATH %s -> %s not found.", - network_->cellName(instance_), - from_port_name->c_str(), - to_port_name->c_str()); + warn(191, "cell {} IOPATH {} -> {} not found.", + network_->cellName(instance_), *from_port_name, + *to_port_name); } } } @@ -422,9 +410,8 @@ SdfReader::findPort(const Cell *cell, { Port *port = network_->findPort(cell, port_name->c_str()); if (port == nullptr) - sdfWarn(194, "instance %s port %s not found.", - network_->pathName(instance_), - port_name->c_str()); + warn(194, "instance {} port {} not found.", network_->pathName(instance_), + *port_name); return port; } @@ -457,8 +444,7 @@ SdfReader::timingCheck1(const TimingRole *role, SdfTriple *triple) { // Ignore non-incremental annotations in incremental only mode. - if (!(is_incremental_only_ && !in_incremental_) - && instance_) { + if (!(is_incremental_only_ && !in_incremental_) && instance_) { Pin *data_pin = network_->findPin(instance_, data_port); Pin *clk_pin = network_->findPin(instance_, clk_port); if (data_pin && clk_pin) { @@ -468,36 +454,32 @@ SdfReader::timingCheck1(const TimingRole *role, float *value_max = values[triple_max_index_]; if (value_min && value_max) { switch (analysis_type_) { - case AnalysisType::single: - break; - case AnalysisType::bc_wc: - if (role->genericRole() == TimingRole::setup()) + case AnalysisType::single: + break; + case AnalysisType::bc_wc: + if (role->genericRole() == TimingRole::setup()) + *value_min = *value_max; + else + *value_max = *value_min; + break; + case AnalysisType::ocv: *value_min = *value_max; - else - *value_max = *value_min; - break; - case AnalysisType::ocv: - *value_min = *value_max; - break; + break; } } - bool matched = annotateCheckEdges(data_pin, data_edge, - clk_pin, clk_edge, role, + bool matched = annotateCheckEdges(data_pin, data_edge, clk_pin, clk_edge, role, triple, false); // Liberty setup/hold checks on preset/clear pins can be translated // into recovery/removal checks, so be flexible about matching. if (!matched) - matched = annotateCheckEdges(data_pin, data_edge, - clk_pin, clk_edge, role, + matched = annotateCheckEdges(data_pin, data_edge, clk_pin, clk_edge, role, triple, true); if (!matched // Only warn when non-null values are present. && triple->hasValue()) - sdfWarn(192, "cell %s %s -> %s %s check not found.", - network_->cellName(instance_), - network_->name(data_port), - network_->name(clk_port), - role->to_string().c_str()); + warn(192, "cell {} {} -> {} {} check not found.", + network_->cellName(instance_), network_->name(data_port), + network_->name(clk_port), role->to_string()); } } } @@ -526,11 +508,10 @@ SdfReader::annotateCheckEdges(Pin *data_pin, const TimingRole *edge_role = arc_set->role(); const std::string &lib_cond_start = arc_set->sdfCondStart(); const std::string &lib_cond_end = arc_set->sdfCondEnd(); - bool cond_matches = condMatch(cond_start, lib_cond_start) - && condMatch(cond_end, lib_cond_end); + bool cond_matches = + condMatch(cond_start, lib_cond_start) && condMatch(cond_end, lib_cond_end); if (((!match_generic && edge_role->sdfRole() == sdf_role) - || (match_generic - && edge_role->genericRole() == sdf_role->genericRole())) + || (match_generic && edge_role->genericRole() == sdf_role->genericRole())) && cond_matches) { TimingArcSet *arc_set = edge->timingArcSet(); for (TimingArc *arc : arc_set->arcs()) { @@ -553,8 +534,7 @@ SdfReader::timingCheckWidth(SdfPortSpec *edge, SdfTriple *triple) { // Ignore non-incremental annotations in incremental only mode. - if (!(is_incremental_only_ && !in_incremental_) - && instance_) { + if (!(is_incremental_only_ && !in_incremental_) && instance_) { const std::string *port_name = edge->port(); Cell *cell = network_->cell(instance_); Port *port = findPort(cell, port_name); @@ -622,8 +602,7 @@ SdfReader::timingCheckPeriod(SdfPortSpec *edge, SdfTriple *triple) { // Ignore non-incremental annotations in incremental only mode. - if (!(is_incremental_only_ && !in_incremental_) - && instance_) { + if (!(is_incremental_only_ && !in_incremental_) && instance_) { const std::string *port_name = edge->port(); Cell *cell = network_->cell(instance_); Port *port = findPort(cell, port_name); @@ -668,8 +647,7 @@ void SdfReader::device(SdfTripleSeq *triples) { // Ignore non-incremental annotations in incremental only mode. - if (!(is_incremental_only_ && !in_incremental_) - && instance_) { + if (!(is_incremental_only_ && !in_incremental_) && instance_) { InstancePinIterator *pin_iter = network_->pinIterator(instance_); while (pin_iter->hasNext()) { Pin *to_pin = pin_iter->next(); @@ -685,8 +663,7 @@ SdfReader::device(const std::string *to_port_name, SdfTripleSeq *triples) { // Ignore non-incremental annotations in incremental only mode. - if (!(is_incremental_only_ && !in_incremental_) - && instance_) { + if (!(is_incremental_only_ && !in_incremental_) && instance_) { Cell *cell = network_->cell(instance_); Port *to_port = findPort(cell, to_port_name); if (to_port) { @@ -780,8 +757,7 @@ SdfReader::setEdgeArcDelaysCondUse(Edge *edge, int arc_delay_index, const MinMax *min_max) { - if (value - && triple_index != null_index_) { + if (value && triple_index != null_index_) { ArcDelay delay(*value); if (!is_incremental_only_ && in_incremental_) delay = delaySum(graph_->arcDelay(edge, arc, arc_delay_index), *value, this); @@ -844,9 +820,7 @@ SdfReader::makeCondPortSpec(const std::string *cond_port) auto cond_end = cond_port1.find_last_not_of(" ", port_idx); if (cond_end != cond_port1.npos) { std::string *cond1 = new std::string(cond_port1.substr(0, cond_end + 1)); - SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(), - port1, - cond1); + SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(), port1, cond1); delete cond_port; return port_spec; } @@ -887,9 +861,12 @@ SdfReader::makeTriple(float *min, float *typ, float *max) { - if (min) *min *= timescale_; - if (typ) *typ *= timescale_; - if (max) *max *= timescale_; + if (min) + *min *= timescale_; + if (typ) + *typ *= timescale_; + if (max) + *max *= timescale_; return new SdfTriple(min, typ, max); } @@ -929,9 +906,7 @@ SdfReader::unescaped(const std::string *token) // Translate sdf divider to network divider. *unescaped += path_divider; } - else if (next_ch == '[' - || next_ch == ']' - || next_ch == escape_) { + else if (next_ch == '[' || next_ch == ']' || next_ch == escape_) { // Escaped bus bracket or escape. // Translate sdf escape to network escape. *unescaped += path_escape; @@ -946,9 +921,8 @@ SdfReader::unescaped(const std::string *token) // Just the normal noises. *unescaped += ch; } - debugPrint(debug_, "sdf_name", 1, "unescape %s -> %s", - token->c_str(), - unescaped->c_str()); + debugPrint(debug_, "sdf_name", 1, "unescape {} -> {}", *token, + *unescaped); delete token; return unescaped; } @@ -980,27 +954,13 @@ SdfReader::makeBusName(std::string *base_name, void SdfReader::notSupported(const char *feature) { - sdfError(193, "%s not supported.", feature); + error(193, "{} not supported.", feature); } -void -SdfReader::sdfWarn(int id, - const char *fmt, ...) +int +SdfReader::sdfLine() const { - va_list args; - va_start(args, fmt); - report_->vfileWarn(id, filename_.c_str(), scanner_->lineno(), fmt, args); - va_end(args); -} - -void -SdfReader::sdfError(int id, - const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - report_->vfileError(id, filename_.c_str(), scanner_->lineno(), fmt, args); - va_end(args); + return scanner_->lineno(); } Pin * @@ -1030,7 +990,7 @@ SdfReader::findInstance(const std::string *name) inst_name = *name; Instance *inst = network_->findInstance(inst_name.c_str()); if (inst == nullptr) - sdfWarn(195, "instance %s not found.", inst_name.c_str()); + warn(195, "instance {} not found.", inst_name); return inst; } @@ -1067,9 +1027,12 @@ SdfTriple::~SdfTriple() if (values_[0] == values_[1] && values_[0] == values_[2]) delete values_[0]; else { - if (values_[0]) delete values_[0]; - if (values_[1]) delete values_[1]; - if (values_[2]) delete values_[2]; + if (values_[0]) + delete values_[0]; + if (values_[1]) + delete values_[1]; + if (values_[2]) + delete values_[2]; } } @@ -1095,7 +1058,7 @@ SdfScanner::SdfScanner(std::istream *stream, void SdfScanner::error(const char *msg) { - report_->fileError(1869, filename_.c_str(), lineno(), "%s", msg); + report_->fileError(196, filename_.c_str(), lineno(), "{}", msg); } -} // namespace +} // namespace sta diff --git a/sdf/SdfReaderPvt.hh b/sdf/SdfReaderPvt.hh index 3b140a4e..4ae883ba 100644 --- a/sdf/SdfReaderPvt.hh +++ b/sdf/SdfReaderPvt.hh @@ -24,6 +24,7 @@ #pragma once +#include #include #include "TimingRole.hh" @@ -31,6 +32,7 @@ #include "LibertyClass.hh" #include "NetworkClass.hh" #include "GraphClass.hh" +#include "Report.hh" #include "SdcClass.hh" #include "StaState.hh" @@ -148,11 +150,23 @@ public: std::string *makeBusName(std::string *bus_name, int index); const std::string &filename() const { return filename_; } - void sdfWarn(int id, - const char *fmt, ...); - void sdfError(int id, - const char *fmt, - ...); + int sdfLine() const; + template + void warn(int id, + std::string_view fmt, + Args &&...args) + { + report_->fileWarn(id, filename_, sdfLine(), fmt, + std::forward(args)...); + } + template + void error(int id, + std::string_view fmt, + Args &&...args) + { + report_->fileError(id, filename_, sdfLine(), fmt, + std::forward(args)...); + } void notSupported(const char *feature); private: diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index db7af6b0..fa79139f 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -27,6 +27,7 @@ #include #include +#include "Format.hh" #include "Zlib.hh" #include "StaConfig.hh" // STA_VERSION #include "Fuzzy.hh" @@ -49,7 +50,6 @@ class SdfWriter : public StaState { public: SdfWriter(StaState *sta); - ~SdfWriter(); void write(const char *filename, const Scene *scene, char sdf_divider, @@ -118,7 +118,7 @@ private: char sdf_escape_; char network_escape_; - char *delay_format_; + int digits_; gzFile stream_; const Scene *scene_; @@ -145,16 +145,10 @@ writeSdf(const char *filename, SdfWriter::SdfWriter(StaState *sta) : StaState(sta), sdf_escape_('\\'), - network_escape_(network_->pathEscape()), - delay_format_(nullptr) + network_escape_(network_->pathEscape()) { } -SdfWriter::~SdfWriter() -{ - stringDelete(delay_format_); -} - void SdfWriter::write(const char *filename, const Scene *scene, @@ -167,8 +161,7 @@ SdfWriter::write(const char *filename, { sdf_divider_ = sdf_divider; include_typ_ = include_typ; - if (delay_format_ == nullptr) - delay_format_ = stringPrint("%%.%df", digits); + digits_ = digits; LibertyLibrary *default_lib = network_->defaultLibertyLibrary(); timescale_ = default_lib->units()->timeUnit()->scale(); @@ -195,25 +188,25 @@ SdfWriter::writeHeader(LibertyLibrary *default_lib, bool no_timestamp, bool no_version) { - gzprintf(stream_, "(DELAYFILE\n"); - gzprintf(stream_, " (SDFVERSION \"3.0\")\n"); - gzprintf(stream_, " (DESIGN \"%s\")\n", - network_->cellName(network_->topInstance())); - + sta::print(stream_, "(DELAYFILE\n"); + sta::print(stream_, " (SDFVERSION \"3.0\")\n"); + sta::print(stream_, " (DESIGN \"{}\")\n", + network_->cellName(network_->topInstance())); + if (!no_timestamp) { time_t now; time(&now); char *time_str = ctime(&now); // Remove trailing \n. time_str[strlen(time_str) - 1] = '\0'; - gzprintf(stream_, " (DATE \"%s\")\n", time_str); + sta::print(stream_, " (DATE \"{}\")\n", time_str); } - gzprintf(stream_, " (VENDOR \"Parallax\")\n"); - gzprintf(stream_, " (PROGRAM \"STA\")\n"); + sta::print(stream_, " (VENDOR \"Parallax\")\n"); + sta::print(stream_, " (PROGRAM \"STA\")\n"); if (!no_version) - gzprintf(stream_, " (VERSION \"%s\")\n", STA_VERSION); - gzprintf(stream_, " (DIVIDER %c)\n", sdf_divider_); + sta::print(stream_, " (VERSION \"{}\")\n", STA_VERSION); + sta::print(stream_, " (DIVIDER {:c})\n", sdf_divider_); LibertyLibrary *lib_min = default_lib; const LibertySeq &libs_min = scene_->libertyLibraries(MinMax::min()); @@ -227,15 +220,15 @@ SdfWriter::writeHeader(LibertyLibrary *default_lib, OperatingConditions *cond_min = lib_min->defaultOperatingConditions(); OperatingConditions *cond_max = lib_max->defaultOperatingConditions(); if (cond_min && cond_max) { - gzprintf(stream_, " (VOLTAGE %.3f::%.3f)\n", - cond_min->voltage(), - cond_max->voltage()); - gzprintf(stream_, " (PROCESS \"%.3f::%.3f\")\n", - cond_min->process(), - cond_max->process()); - gzprintf(stream_, " (TEMPERATURE %.3f::%.3f)\n", - cond_min->temperature(), - cond_max->temperature()); + sta::print(stream_, " (VOLTAGE {:.3f}::{:.3f})\n", + cond_min->voltage(), + cond_max->voltage()); + sta::print(stream_, " (PROCESS \"{:.3f}::{:.3f}\")\n", + cond_min->process(), + cond_max->process()); + sta::print(stream_, " (TEMPERATURE {:.3f}::{:.3f})\n", + cond_min->temperature(), + cond_max->temperature()); } const char *sdf_timescale = nullptr; @@ -258,24 +251,24 @@ SdfWriter::writeHeader(LibertyLibrary *default_lib, else if (fuzzyEqual(timescale_, 100e-12)) sdf_timescale = "100ps"; if (sdf_timescale) - gzprintf(stream_, " (TIMESCALE %s)\n", sdf_timescale); + sta::print(stream_, " (TIMESCALE {})\n", sdf_timescale); } void SdfWriter::writeTrailer() { - gzprintf(stream_, ")\n"); + sta::print(stream_, ")\n"); } void SdfWriter::writeInterconnects() { - gzprintf(stream_, " (CELL\n"); - gzprintf(stream_, " (CELLTYPE \"%s\")\n", - network_->cellName(network_->topInstance())); - gzprintf(stream_, " (INSTANCE)\n"); - gzprintf(stream_, " (DELAY\n"); - gzprintf(stream_, " (ABSOLUTE\n"); + sta::print(stream_, " (CELL\n"); + sta::print(stream_, " (CELLTYPE \"{}\")\n", + network_->cellName(network_->topInstance())); + sta::print(stream_, " (INSTANCE)\n"); + sta::print(stream_, " (DELAY\n"); + sta::print(stream_, " (ABSOLUTE\n"); writeInstInterconnects(network_->topInstance()); @@ -286,9 +279,9 @@ SdfWriter::writeInterconnects() } delete inst_iter; - gzprintf(stream_, " )\n"); - gzprintf(stream_, " )\n"); - gzprintf(stream_, " )\n"); + sta::print(stream_, " )\n"); + sta::print(stream_, " )\n"); + sta::print(stream_, " )\n"); } void @@ -315,11 +308,11 @@ SdfWriter::writeInterconnectFromPin(Pin *drvr_pin) Pin *load_pin = edge->to(graph_)->pin(); std::string drvr_pin_name = sdfPathName(drvr_pin); std::string load_pin_name = sdfPathName(load_pin); - gzprintf(stream_, " (INTERCONNECT %s %s ", - drvr_pin_name.c_str(), - load_pin_name.c_str()); + sta::print(stream_, " (INTERCONNECT {} {} ", + drvr_pin_name, + load_pin_name); writeArcDelays(edge); - gzprintf(stream_, ")\n"); + sta::print(stream_, ")\n"); } } } @@ -343,16 +336,16 @@ SdfWriter::writeInstances() void SdfWriter::writeInstHeader(const Instance *inst) { - gzprintf(stream_, " (CELL\n"); - gzprintf(stream_, " (CELLTYPE \"%s\")\n", network_->cellName(inst)); + sta::print(stream_, " (CELL\n"); + sta::print(stream_, " (CELLTYPE \"{}\")\n", network_->cellName(inst)); std::string inst_name = sdfPathName(inst); - gzprintf(stream_, " (INSTANCE %s)\n", inst_name.c_str()); + sta::print(stream_, " (INSTANCE {})\n", inst_name); } void SdfWriter::writeInstTrailer() { - gzprintf(stream_, " )\n"); + sta::print(stream_, " )\n"); } void @@ -387,18 +380,18 @@ SdfWriter::writeIopaths(const Instance *inst, } const std::string &sdf_cond = edge->timingArcSet()->sdfCond(); if (!sdf_cond.empty()) { - gzprintf(stream_, " (COND %s\n", sdf_cond.c_str()); - gzprintf(stream_, " "); + sta::print(stream_, " (COND {}\n", sdf_cond); + sta::print(stream_, " "); } std::string from_pin_name = sdfPortName(from_pin); std::string to_pin_name = sdfPortName(to_pin); - gzprintf(stream_, " (IOPATH %s %s ", - from_pin_name.c_str(), - to_pin_name.c_str()); + sta::print(stream_, " (IOPATH {} {} ", + from_pin_name, + to_pin_name); writeArcDelays(edge); if (!sdf_cond.empty()) - gzprintf(stream_, ")"); - gzprintf(stream_, ")\n"); + sta::print(stream_, ")"); + sta::print(stream_, ")\n"); } } } @@ -412,15 +405,15 @@ SdfWriter::writeIopaths(const Instance *inst, void SdfWriter::writeIopathHeader() { - gzprintf(stream_, " (DELAY\n"); - gzprintf(stream_, " (ABSOLUTE\n"); + sta::print(stream_, " (DELAY\n"); + sta::print(stream_, " (ABSOLUTE\n"); } void SdfWriter::writeIopathTrailer() { - gzprintf(stream_, " )\n"); - gzprintf(stream_, " )\n"); + sta::print(stream_, " )\n"); + sta::print(stream_, " )\n"); } void @@ -446,7 +439,7 @@ SdfWriter::writeArcDelays(Edge *edge) delays.value(RiseFall::fall(), MinMax::min())) && fuzzyEqual(delays.value(RiseFall::rise(), MinMax::max()), delays.value(RiseFall::fall(),MinMax::max())))) { - gzprintf(stream_, " "); + sta::print(stream_, " "); writeSdfTriple(delays, RiseFall::fall()); } } @@ -455,7 +448,7 @@ SdfWriter::writeArcDelays(Edge *edge) writeSdfTriple(delays, RiseFall::rise()); else if (delays.hasValue(RiseFall::fall(), MinMax::min())) { // Fall only. - gzprintf(stream_, "() "); + sta::print(stream_, "() "); writeSdfTriple(delays, RiseFall::fall()); } } @@ -473,23 +466,24 @@ void SdfWriter::writeSdfTriple(float min, float max) { - gzprintf(stream_, "("); + sta::print(stream_, "("); writeSdfDelay(min); if (include_typ_) { - gzprintf(stream_, ":"); + sta::print(stream_, ":"); writeSdfDelay((min + max) / 2.0); - gzprintf(stream_, ":"); + sta::print(stream_, ":"); } else - gzprintf(stream_, "::"); + sta::print(stream_, "::"); writeSdfDelay(max); - gzprintf(stream_, ")"); + sta::print(stream_, ")"); } void SdfWriter::writeSdfDelay(double delay) { - gzprintf(stream_, delay_format_, delay / timescale_); + std::string str = sta::formatRuntime("{:.{}f}", delay / timescale_, digits_); + sta::print(stream_, "{}", str); } void @@ -568,13 +562,13 @@ SdfWriter::ensureTimingCheckheaders(bool &check_header, void SdfWriter::writeTimingCheckHeader() { - gzprintf(stream_, " (TIMINGCHECK\n"); + sta::print(stream_, " (TIMINGCHECK\n"); } void SdfWriter::writeTimingCheckTrailer() { - gzprintf(stream_, " )\n"); + sta::print(stream_, " )\n"); } void @@ -663,40 +657,40 @@ SdfWriter::writeCheck(Edge *edge, const std::string &sdf_cond_start = arc_set->sdfCondStart(); const std::string &sdf_cond_end = arc_set->sdfCondEnd(); - gzprintf(stream_, " (%s ", sdf_check); + sta::print(stream_, " ({} ", sdf_check); if (!sdf_cond_start.empty()) - gzprintf(stream_, "(COND %s ", sdf_cond_start.c_str()); + sta::print(stream_, "(COND {} ", sdf_cond_start); std::string to_pin_name = sdfPortName(to_pin); if (use_data_edge) { - gzprintf(stream_, "(%s %s)", - sdfEdge(arc->toEdge()), - to_pin_name.c_str()); + sta::print(stream_, "({} {})", + sdfEdge(arc->toEdge()), + to_pin_name); } else - gzprintf(stream_, "%s", to_pin_name.c_str()); + sta::print(stream_, "{}", to_pin_name); if (!sdf_cond_start.empty()) - gzprintf(stream_, ")"); + sta::print(stream_, ")"); - gzprintf(stream_, " "); + sta::print(stream_, " "); if (!sdf_cond_end.empty()) - gzprintf(stream_, "(COND %s ", sdf_cond_end.c_str()); + sta::print(stream_, "(COND {} ", sdf_cond_end); std::string from_pin_name = sdfPortName(from_pin); if (use_clk_edge) - gzprintf(stream_, "(%s %s)", - sdfEdge(arc->fromEdge()), - from_pin_name.c_str()); + sta::print(stream_, "({} {})", + sdfEdge(arc->fromEdge()), + from_pin_name); else - gzprintf(stream_, "%s", from_pin_name.c_str()); + sta::print(stream_, "{}", from_pin_name); if (!sdf_cond_end.empty()) - gzprintf(stream_, ")"); + sta::print(stream_, ")"); - gzprintf(stream_, " "); + sta::print(stream_, " "); float min_delay = delayAsFloat(graph_->arcDelay(edge, arc, arc_delay_min_index_), MinMax::min(), this); @@ -704,7 +698,7 @@ SdfWriter::writeCheck(Edge *edge, MinMax::max(), this); writeSdfTriple(min_delay, max_delay); - gzprintf(stream_, ")\n"); + sta::print(stream_, ")\n"); } void @@ -714,11 +708,11 @@ SdfWriter::writeWidthCheck(const Pin *pin, float max_width) { std::string pin_name = sdfPortName(pin); - gzprintf(stream_, " (WIDTH (%s %s) ", - sdfEdge(hi_low->asTransition()), - pin_name.c_str()); + sta::print(stream_, " (WIDTH ({} {}) ", + sdfEdge(hi_low->asTransition()), + pin_name); writeSdfTriple(min_width, max_width); - gzprintf(stream_, ")\n"); + sta::print(stream_, ")\n"); } void @@ -726,9 +720,9 @@ SdfWriter::writePeriodCheck(const Pin *pin, float min_period) { std::string pin_name = sdfPortName(pin); - gzprintf(stream_, " (PERIOD %s ", pin_name.c_str()); + sta::print(stream_, " (PERIOD {} ", pin_name); writeSdfTriple(min_period, min_period); - gzprintf(stream_, ")\n"); + sta::print(stream_, ")\n"); } const char * diff --git a/search/Bfs.cc b/search/Bfs.cc index 9de9be6c..559cabb7 100644 --- a/search/Bfs.cc +++ b/search/Bfs.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 "Bfs.hh" @@ -37,10 +37,10 @@ namespace sta { BfsIterator::BfsIterator(BfsIndex bfs_index, - Level level_min, - Level level_max, - SearchPred *search_pred, - StaState *sta) : + Level level_min, + Level level_max, + SearchPred *search_pred, + StaState *sta) : StaState(sta), bfs_index_(bfs_index), level_min_(level_min), @@ -68,9 +68,7 @@ BfsIterator::ensureSize() } } -BfsIterator::~BfsIterator() -{ -} +BfsIterator::~BfsIterator() {} void BfsIterator::clear() @@ -80,7 +78,7 @@ BfsIterator::clear() VertexSeq &level_vertices = queue_[level]; for (Vertex *vertex : level_vertices) { if (vertex) - vertex->setBfsInQueue(bfs_index_, false); + vertex->setBfsInQueue(bfs_index_, false); } level_vertices.clear(); incrLevel(level); @@ -91,18 +89,18 @@ BfsIterator::clear() void BfsIterator::reportEntries() const { - for (Level level=first_level_; levelLessOrEqual(level, last_level_);incrLevel(level)){ + for (Level level = first_level_; levelLessOrEqual(level, last_level_); + incrLevel(level)) { const VertexSeq &level_vertices = queue_[level]; if (!level_vertices.empty()) { - report_->reportLine("Level %d", level); + report_->report("Level {}", level); for (Vertex *vertex : level_vertices) - report_->reportLine(" %s", - vertex ? vertex->to_string(this).c_str() : "NULL"); + report_->report(" {}", vertex ? vertex->to_string(this) : "NULL"); } } } -void +void BfsIterator::deleteEntries(Level level) { VertexSeq &level_vertices = queue_[level]; @@ -134,11 +132,11 @@ BfsIterator::enqueueAdjacentVertices(Vertex *vertex, int BfsIterator::visit(Level to_level, - VertexVisitor *visitor) + VertexVisitor *visitor) { int visit_count = 0; while (levelLessOrEqual(first_level_, last_level_) - && levelLessOrEqual(first_level_, to_level)) { + && levelLessOrEqual(first_level_, to_level)) { Level level = first_level_; VertexSeq &level_vertices = queue_[level]; incrLevel(first_level_); @@ -162,7 +160,7 @@ BfsIterator::visit(Level to_level, int BfsIterator::visitParallel(Level to_level, - VertexVisitor *visitor) + VertexVisitor *visitor) { size_t thread_count = thread_count_; int visit_count = 0; @@ -170,15 +168,15 @@ BfsIterator::visitParallel(Level to_level, if (thread_count == 1) visit_count = visit(to_level, visitor); else { - std::vector visitors; + std::vector visitors; for (int k = 0; k < thread_count_; k++) - visitors.push_back(visitor->copy()); + visitors.push_back(visitor->copy()); while (levelLessOrEqual(first_level_, last_level_) - && levelLessOrEqual(first_level_, to_level)) { - VertexSeq &level_vertices = queue_[first_level_]; + && levelLessOrEqual(first_level_, to_level)) { + VertexSeq &level_vertices = queue_[first_level_]; Level level = first_level_; - incrLevel(first_level_); - if (!level_vertices.empty()) { + incrLevel(first_level_); + if (!level_vertices.empty()) { size_t vertex_count = level_vertices.size(); if (vertex_count < thread_count) { for (Vertex *vertex : level_vertices) { @@ -196,7 +194,7 @@ BfsIterator::visitParallel(Level to_level, for (size_t k = 0; k < thread_count; k++) { // Last thread gets the left overs. size_t to = (k == thread_count - 1) ? vertex_count : from + chunk_size; - dispatch_queue_->dispatch( [=, this](int) { + dispatch_queue_->dispatch([=, this](int) { for (size_t i = from; i < to; i++) { Vertex *vertex = level_vertices[i]; if (vertex) { @@ -210,13 +208,13 @@ BfsIterator::visitParallel(Level to_level, } dispatch_queue_->finishTasks(); } - visitor->levelFinished(); - level_vertices.clear(); + visitor->levelFinished(); + level_vertices.clear(); visit_count += vertex_count; - } + } } for (VertexVisitor *visitor : visitors) - delete visitor; + delete visitor; } } return visit_count; @@ -233,7 +231,7 @@ BfsIterator::hasNext(Level to_level) { findNext(to_level); return levelLessOrEqual(first_level_, last_level_) - && !queue_[first_level_].empty(); + && !queue_[first_level_].empty(); } Vertex * @@ -250,16 +248,16 @@ void BfsIterator::findNext(Level to_level) { while (levelLessOrEqual(first_level_, last_level_) - && levelLessOrEqual(first_level_, to_level)) { + && levelLessOrEqual(first_level_, to_level)) { VertexSeq &level_vertices = queue_[first_level_]; // Skip null entries from deleted vertices. while (!level_vertices.empty()) { Vertex *vertex = level_vertices.back(); if (vertex == nullptr) - level_vertices.pop_back(); + level_vertices.pop_back(); else { checkLevel(vertex, first_level_); - return; + return; } } incrLevel(first_level_); @@ -269,8 +267,7 @@ BfsIterator::findNext(Level to_level) void BfsIterator::enqueue(Vertex *vertex) { - debugPrint(debug_, "bfs", 2, "enqueue %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "bfs", 2, "enqueue {}", vertex->to_string(this)); if (!vertex->bfsInQueue(bfs_index_)) { Level level = vertex->level(); LockGuard lock(queue_lock_); @@ -279,9 +276,9 @@ BfsIterator::enqueue(Vertex *vertex) queue_[level].push_back(vertex); if (levelLess(last_level_, level)) - last_level_ = level; + last_level_ = level; if (levelLess(level, first_level_)) - first_level_ = level; + first_level_ = level; } } } @@ -300,17 +297,15 @@ BfsIterator::checkInQueue(Vertex *vertex) if (static_cast(queue_.size()) > level) { for (Vertex *v : queue_[level]) { if (v == vertex) { - if (vertex->bfsInQueue(bfs_index_)) - return; - else - debugPrint(debug_, "bfs", 1, "extra %s", - vertex->to_string(this).c_str()); + if (vertex->bfsInQueue(bfs_index_)) + return; + else + debugPrint(debug_, "bfs", 1, "extra {}", vertex->to_string(this)); } } } if (vertex->bfsInQueue(bfs_index_)) - debugPrint(debug_, "brs", 1, "missing %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "brs", 1, "missing {}", vertex->to_string(this)); } void @@ -318,10 +313,8 @@ BfsIterator::checkLevel(Vertex *vertex, Level level) { if (vertex->level() != level) - report_->error(2300, "vertex %s level %d != bfs level %d", - vertex->to_string(this).c_str(), - vertex->level(), - level); + report_->error(2300, "vertex {} level {} != bfs level {}", + vertex->to_string(this), vertex->level(), level); } void @@ -336,14 +329,12 @@ BfsIterator::remove(Vertex *vertex) { // If the iterator has not been inited the queue will be empty. Level level = vertex->level(); - if (vertex->bfsInQueue(bfs_index_) - && static_cast(queue_.size()) > level) { - debugPrint(debug_, "bfs", 2, "remove %s", - vertex->to_string(this).c_str()); + if (vertex->bfsInQueue(bfs_index_) && static_cast(queue_.size()) > level) { + debugPrint(debug_, "bfs", 2, "remove {}", vertex->to_string(this)); for (Vertex *&v : queue_[level]) { if (v == vertex) { - v = nullptr; - vertex->setBfsInQueue(bfs_index_, false); + v = nullptr; + vertex->setBfsInQueue(bfs_index_, false); break; } } @@ -353,9 +344,13 @@ BfsIterator::remove(Vertex *vertex) //////////////////////////////////////////////////////////////// BfsFwdIterator::BfsFwdIterator(BfsIndex bfs_index, - SearchPred *search_pred, - StaState *sta) : - BfsIterator(bfs_index, 0, level_max, search_pred, sta) + SearchPred *search_pred, + StaState *sta) : + BfsIterator(bfs_index, + 0, + level_max, + search_pred, + sta) { } @@ -374,14 +369,14 @@ BfsFwdIterator::incrLevel(Level &level) const bool BfsFwdIterator::levelLessOrEqual(Level level1, - Level level2) const + Level level2) const { return level1 <= level2; } bool BfsFwdIterator::levelLess(Level level1, - Level level2) const + Level level2) const { return level1 < level2; } @@ -395,9 +390,8 @@ BfsFwdIterator::enqueueAdjacentVertices(Vertex *vertex, while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); Vertex *to_vertex = edge->to(graph_); - if (search_pred->searchThru(edge) - && search_pred->searchTo(to_vertex)) - enqueue(to_vertex); + if (search_pred->searchThru(edge) && search_pred->searchTo(to_vertex)) + enqueue(to_vertex); } } } @@ -422,9 +416,13 @@ BfsFwdIterator::enqueueAdjacentVertices(Vertex *vertex, //////////////////////////////////////////////////////////////// BfsBkwdIterator::BfsBkwdIterator(BfsIndex bfs_index, - SearchPred *search_pred, - StaState *sta) : - BfsIterator(bfs_index, level_max, 0, search_pred, sta) + SearchPred *search_pred, + StaState *sta) : + BfsIterator(bfs_index, + level_max, + 0, + search_pred, + sta) { } @@ -443,14 +441,14 @@ BfsBkwdIterator::incrLevel(Level &level) const bool BfsBkwdIterator::levelLessOrEqual(Level level1, - Level level2) const + Level level2) const { return level1 >= level2; } bool BfsBkwdIterator::levelLess(Level level1, - Level level2) const + Level level2) const { return level1 > level2; } @@ -464,9 +462,8 @@ BfsBkwdIterator::enqueueAdjacentVertices(Vertex *vertex, while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); Vertex *from_vertex = edge->from(graph_); - if (search_pred->searchFrom(from_vertex) - && search_pred->searchThru(edge)) - enqueue(from_vertex); + if (search_pred->searchFrom(from_vertex) && search_pred->searchThru(edge)) + enqueue(from_vertex); } } } @@ -488,4 +485,4 @@ BfsBkwdIterator::enqueueAdjacentVertices(Vertex *vertex, } } -} // namespace +} // namespace sta diff --git a/search/CheckMinPulseWidths.cc b/search/CheckMinPulseWidths.cc index 12c795ea..cad8319e 100644 --- a/search/CheckMinPulseWidths.cc +++ b/search/CheckMinPulseWidths.cc @@ -140,8 +140,8 @@ CheckMinPulseWidths::checkVertex(Vertex *vertex, Path *close_path = check.closePath(sta_); // Don't bother visiting if nobody is home. if (close_path) { - debugPrint(debug, "mpw", 2, "%s %s %s", - path_vertex->to_string(sta_).c_str(), + debugPrint(debug, "mpw", 2, "{} {} {}", + path_vertex->to_string(sta_), path->transition(sta_) == RiseFall::rise() ? "(high)" : "(low)", delayAsString(check.slack(sta_), sta_)); if (violators) { @@ -219,17 +219,17 @@ MinPulseWidthCheck::closePath(const StaState *sta) const open_tag->isSegmentStart(), open_tag->states(), false); - debugPrint(sta->debug(), "mpw", 3, " open %s", - open_tag->to_string(sta).c_str()); - debugPrint(sta->debug(), "mpw", 3, " close %s", - close_tag.to_string(sta).c_str()); + debugPrint(sta->debug(), "mpw", 3, " open {}", + open_tag->to_string(sta)); + debugPrint(sta->debug(), "mpw", 3, " close {}", + close_tag.to_string(sta)); VertexPathIterator close_iter(open_path_->vertex(sta), scene, close_min_max, close_rf, sta); while (close_iter.hasNext()) { Path *close_path = close_iter.next(); if (Tag::matchNoPathAp(close_path->tag(sta), &close_tag)) { - debugPrint(sta->debug(), "mpw", 3, " match %s", - close_path->tag(sta)->to_string(sta).c_str()); + debugPrint(sta->debug(), "mpw", 3, " match {}", + close_path->tag(sta)->to_string(sta)); return close_path; } } diff --git a/search/CheckTiming.cc b/search/CheckTiming.cc index de4ad8b4..9b83593f 100644 --- a/search/CheckTiming.cc +++ b/search/CheckTiming.cc @@ -123,8 +123,7 @@ CheckTiming::checkNoInputDelay() } } delete pin_iter; - pushPinErrors("Warning: There %is %d input port%s missing set_input_delay.", - no_arrival); + pushPinErrors("Warning: There {} {} input port{} missing set_input_delay.",no_arrival); } void @@ -132,7 +131,7 @@ CheckTiming::checkNoOutputDelay() { PinSet no_departure(network_); checkNoOutputDelay(no_departure); - pushPinErrors("Warning: There %is %d output port%s missing set_output_delay.", + pushPinErrors("Warning: There {} {} output port{} missing set_output_delay.", no_departure); } @@ -179,12 +178,24 @@ CheckTiming::checkRegClks(bool reg_multiple_clks, if (reg_multiple_clks && clks && clks->size() > 1) multiple_clk_pins.insert(pin); } - pushPinErrors("Warning: There %is %d unclocked register/latch pin%s.", + pushPinErrors("Warning: There {} {} unclocked register/latch pin{}.", no_clk_pins); - pushPinErrors("Warning: There %is %d register/latch pin%s with multiple clocks.", + pushPinErrors("Warning: There {} {} register/latch pin{} with multiple clocks.", multiple_clk_pins); } +static const char * +plurality(int n) +{ + return n == 1 ? "is" : "are"; +} + +static const char * +pluralSuffix(int n) +{ + return n == 1 ? "" : "s"; +} + void CheckTiming::checkLoops() { @@ -198,11 +209,11 @@ CheckTiming::checkLoops() loop_count++; } if (loop_count > 0) { - std::string error_msg; - errorMsgSubst("Warning: There %is %d combinational loop%s in the design.", - loop_count, error_msg); CheckError *error = new CheckError; - error->push_back(error_msg); + error->push_back(sta::format("Warning: There {} {} combinational loop{} in the design.", + plurality(loop_count), + loop_count, + pluralSuffix(loop_count))); for (GraphLoop *loop : loops) { if (loop->isCombinational()) { @@ -232,7 +243,7 @@ CheckTiming::checkUnconstrainedEndpoints() PinSet unconstrained_ends(network_); checkUnconstrainedOutputs(unconstrained_ends); checkUnconstrainedSetups(unconstrained_ends); - pushPinErrors("Warning: There %is %d unconstrained endpoint%s.", + pushPinErrors("Warning: There {} {} unconstrained endpoint{}.", unconstrained_ends); } @@ -338,27 +349,21 @@ CheckTiming::checkGeneratedClocks() gen_clk_errors.insert(clk); } } - pushClkErrors("Warning: There %is %d generated clock%s that %is not connected to a clock source.", + pushClkErrors("Warning: There {} {} generated clock{} not connected to a clock source.", gen_clk_errors); } // Report the "msg" error for each pin in "pins". -// -// Substitutions in msg are done as follows if the pin count is one -// or greater than one. -// %is - is/are -// %d - pin count -// %s - s/"" -// %a - a/"" void -CheckTiming::pushPinErrors(const char *msg, +CheckTiming::pushPinErrors(std::string_view msg, PinSet &pins) { if (!pins.empty()) { CheckError *error = new CheckError; - std::string error_msg; - errorMsgSubst(msg, pins.size(), error_msg); - error->push_back(error_msg); + error->push_back(sta::formatRuntime(msg, + plurality(pins.size()), + pins.size(), + pluralSuffix(pins.size()))); // Sort the error pins so the output is independent of the order // the the errors are discovered. PinSeq pins1 = sortByPathName(&pins, network_); @@ -375,9 +380,10 @@ CheckTiming::pushClkErrors(const char *msg, { if (!clks.empty()) { CheckError *error = new CheckError; - std::string error_msg; - errorMsgSubst(msg, clks.size(), error_msg); - error->push_back(error_msg); + error->push_back(sta::formatRuntime(msg, + plurality(clks.size()), + clks.size(), + pluralSuffix(clks.size()))); // Sort the error clks so the output is independent of the order // the the errors are discovered. ClockSeq clks1 = sortByName(&clks); @@ -388,47 +394,4 @@ CheckTiming::pushClkErrors(const char *msg, } } -// Copy msg making substitutions for singular/plurals. -void -CheckTiming::errorMsgSubst(const char *msg, - int obj_count, - std::string &error_msg) -{ - for (const char *s = msg; *s; s++) { - char ch = *s; - if (ch == '%') { - char flag = s[1]; - if (flag == 'i') { - if (obj_count > 1) - error_msg += "are"; - else - error_msg += "is"; - s += 2; - } - else if (flag == 'a') { - if (obj_count == 1) { - error_msg += 'a'; - s++; - } - else - // Skip space after %a. - s += 2; - } - else if (flag == 's') { - if (obj_count > 1) - error_msg += 's'; - s++; - } - else if (flag == 'd') { - error_msg += std::to_string(obj_count); - s++; - } - else - criticalError(245, "unknown print flag"); - } - else - error_msg += ch; - } -} - } // namespace diff --git a/search/CheckTiming.hh b/search/CheckTiming.hh index 9cdd4227..94f845b5 100644 --- a/search/CheckTiming.hh +++ b/search/CheckTiming.hh @@ -70,13 +70,10 @@ protected: bool hasClkedCheck(Vertex *vertex); bool hasMaxDelay(Pin *pin); void checkGeneratedClocks(); - void pushPinErrors(const char *msg, + void pushPinErrors(std::string_view msg, PinSet &pins); void pushClkErrors(const char *msg, ClockSet &clks); - void errorMsgSubst(const char *msg, - int count, - std::string &error_msg); CheckErrorSeq errors_; const Mode *mode_; diff --git a/search/ClkLatency.cc b/search/ClkLatency.cc index b7b4bac5..887c009e 100644 --- a/search/ClkLatency.cc +++ b/search/ClkLatency.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 "ClkLatency.hh" @@ -55,8 +55,7 @@ ClkLatency::findClkDelays(const Clock *clk, clks.push_back(clk); SceneSet scenes; scenes.insert(scene); - ClkDelayMap clk_delay_map = findClkDelays(clks, scenes, - include_internal_latency); + ClkDelayMap clk_delay_map = findClkDelays(clks, scenes, include_internal_latency); return clk_delay_map[clk]; } @@ -88,7 +87,7 @@ ClkLatency::reportClkLatency(const Clock *clk, int digits) { Unit *time_unit = units_->timeUnit(); - report_->reportLine("Clock %s", clk->name()); + report_->report("Clock {}", clk->name()); for (const RiseFall *src_rf : RiseFall::range()) { for (const RiseFall *end_rf : RiseFall::range()) { Path path_min; @@ -97,47 +96,41 @@ ClkLatency::reportClkLatency(const Clock *clk, float internal_latency_min; Delay latency_min; bool exists_min; - clk_delays.delay(src_rf, end_rf, MinMax::min(), insertion_min, - delay_min, internal_latency_min, latency_min, - path_min, exists_min); + clk_delays.delay(src_rf, end_rf, MinMax::min(), insertion_min, delay_min, + internal_latency_min, latency_min, path_min, exists_min); Path path_max; Delay insertion_max; Delay delay_max; float internal_latency_max; Delay latency_max; bool exists_max; - clk_delays.delay(src_rf, end_rf, MinMax::max(), insertion_max, - delay_max, internal_latency_max, latency_max, - path_max, exists_max); + clk_delays.delay(src_rf, end_rf, MinMax::max(), insertion_max, delay_max, + internal_latency_max, latency_max, path_max, exists_max); if (exists_min & exists_max) { - report_->reportLine("%s -> %s", - src_rf->name(), - end_rf->name()); - report_->reportLine(" min max"); - - report_->reportLine("%7s %7s source latency", - delayAsString(insertion_min, MinMax::min(), digits, this), - delayAsString(insertion_max, MinMax::max(), digits, this)); - report_->reportLine("%7s %7s network latency %s", - delayAsString(delay_min, MinMax::min(), digits, this), - "", - sdc_network_->pathName(path_min.pin(this))); - report_->reportLine("%7s %7s network latency %s", - "", - delayAsString(delay_max, MinMax::max(), digits, this), - sdc_network_->pathName(path_max.pin(this))); - if (internal_latency_min != 0.0 - || internal_latency_max != 0.0) - report_->reportLine("%7s %7s internal clock latency", - time_unit->asString(internal_latency_min, digits), - time_unit->asString(internal_latency_max, digits)); - report_->reportLine("---------------"); - report_->reportLine("%7s %7s latency", - delayAsString(latency_min, MinMax::min(), digits, this), - delayAsString(latency_max, MinMax::max(), digits, this)); + report_->report("{} -> {}", src_rf->name(), end_rf->name()); + report_->report(" min max"); + report_->report("{:>7} {:>7} source latency", + delayAsString(insertion_min, MinMax::min(), digits, this), + delayAsString(insertion_max, MinMax::max(), digits, this)); + report_->report("{:>7} {:>7} network latency {}", + delayAsString(delay_min, MinMax::min(), digits, this), + "", + sdc_network_->pathName(path_min.pin(this))); + report_->report("{:>7} {:>7} network latency {}", + "", + delayAsString(delay_max, MinMax::max(), digits, this), + sdc_network_->pathName(path_max.pin(this))); + if (internal_latency_min != 0.0 || internal_latency_max != 0.0) + report_->report("{:>7} {:>7} internal clock latency", + time_unit->asString(internal_latency_min, digits), + time_unit->asString(internal_latency_max, digits)); + report_->report("---------------"); + report_->report("{:>7} {:>7} latency", + delayAsString(latency_min, MinMax::min(), digits, this), + delayAsString(latency_max, MinMax::max(), digits, this)); Delay skew = delayDiff(latency_max, latency_min, this); - report_->reportLine(" %7s skew", - delayAsString(skew, MinMax::max(), digits, this)); + report_->report(" {:>7} skew", + delayAsString(skew, MinMax::max(), digits, this)); report_->reportBlankLine(); } } @@ -164,9 +157,7 @@ ClkLatency::findClkDelays(ConstClockSeq &clks, Path *path = path_iter.next(); const Scene *path_scene = path->scene(this); const Clock *path_clk = path->clock(this); - if (path_clk - && scenes.contains(path_scene) - && clk_set.contains(path_clk)) { + if (path_clk && scenes.contains(path_scene) && clk_set.contains(path_clk)) { auto delays_itr = clk_delay_map.find(path_clk); if (delays_itr != clk_delay_map.end()) { const ClockEdge *path_clk_edge = path->clkEdge(this); @@ -278,7 +269,6 @@ Delay ClkDelays::latency(Path *clk_path, StaState *sta) { - Delay insertion = insertionDelay(clk_path, sta); Delay delay1 = delay(clk_path, sta); float lib_clk_delay = clkTreeDelay(clk_path, sta); @@ -321,4 +311,4 @@ ClkDelays::clkTreeDelay(Path *clk_path, return port->clkTreeDelay(slew, rf, min_max); } -} // namespace +} // namespace sta diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index 56590fc4..8167d486 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.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 "ClkSkew.hh" -#include // abs +#include // abs #include #include #include @@ -78,12 +78,12 @@ ClkSkews::reportClkSkew(ConstClockSeq &clks, sort(sorted_clks, ClkNameLess()); for (const Clock *clk : sorted_clks) { - report_->reportLine("Clock %s", clk->name()); + report_->report("Clock {}", clk->name()); auto skew_itr = skews_.find(clk); if (skew_itr != skews_.end()) reportClkSkew(skew_itr->second[setup_hold->index()], digits); else - report_->reportLine("No launch/capture paths found."); + report_->report("No launch/capture paths found."); report_->reportBlankLine(); } } @@ -104,33 +104,33 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew, if (src_internal_clk_latency != 0.0) delayDecr(src_latency, src_internal_clk_latency, this); - report_->reportLine("%7s source latency %s %s", - delayAsString(src_latency, src_min_max, digits, this), - sdc_network_->pathName(src_path->pin(this)), - src_path->transition(this)->shortName()); + report_->report("{:>7} source latency {} {}", + delayAsString(src_latency, src_min_max, digits, this), + sdc_network_->pathName(src_path->pin(this)), + src_path->transition(this)->shortName()); if (src_internal_clk_latency != 0.0) - report_->reportLine("%7s source internal clock delay", - time_unit->asString(src_internal_clk_latency, digits)); + report_->report("{:>7} source internal clock delay", + time_unit->asString(src_internal_clk_latency, digits)); if (tgt_internal_clk_latency != 0.0) tgt_latency -= tgt_internal_clk_latency; - report_->reportLine("%7s target latency %s %s", - time_unit->asString(-tgt_latency, digits), - sdc_network_->pathName(tgt_path->pin(this)), - tgt_path->transition(this)->shortName()); + report_->report("{:>7} target latency {} {}", + time_unit->asString(-tgt_latency, digits), + sdc_network_->pathName(tgt_path->pin(this)), + tgt_path->transition(this)->shortName()); if (tgt_internal_clk_latency != 0.0) - report_->reportLine("%7s target internal clock delay", - time_unit->asString(-tgt_internal_clk_latency, digits)); + report_->report("{:>7} target internal clock delay", + time_unit->asString(-tgt_internal_clk_latency, digits)); if (uncertainty != 0.0) - report_->reportLine("%7s clock uncertainty", - time_unit->asString(uncertainty, digits)); - report_->reportLine("%7s CRPR", - delayAsString(delayDiff(0.0, clk_skew.crpr(this), this), - MinMax::max(), digits, this)); - report_->reportLine("--------------"); - report_->reportLine("%7s %s skew", - delayAsString(clk_skew.skew(), MinMax::max(), digits, this), - src_path->minMax(this) == MinMax::max() ? "setup" : "hold"); + report_->report("{:>7} clock uncertainty", + time_unit->asString(uncertainty, digits)); + report_->report("{:>7} CRPR", + delayAsString(delayDiff(0.0, clk_skew.crpr(this), this), + MinMax::max(), digits, this)); + report_->report("--------------"); + report_->report("{:>7} {} skew", + delayAsString(clk_skew.skew(), MinMax::max(), digits, this), + src_path->minMax(this) == MinMax::max() ? "setup" : "hold"); } static float @@ -174,11 +174,9 @@ void ClkSkews::findClkSkew(ConstClockSeq &clks, const SceneSeq &scenes, bool include_internal_latency) -{ - if (scenes == scenes_ - && include_internal_latency == include_internal_latency_ - && clks == clks_ - && !skews_.empty()) +{ + if (scenes == scenes_ && include_internal_latency == include_internal_latency_ + && clks == clks_ && !skews_.empty()) return; skews_.clear(); @@ -206,14 +204,14 @@ ClkSkews::findClkSkew(ConstClockSeq &clks, // Reduce skews from each register source. for (size_t i = 0; i < partial_skews.size(); i++) { - for (auto& [clk, partial_skew] : partial_skews[i]) { + for (auto &[clk, partial_skew] : partial_skews[i]) { auto itr = skews_.find(clk); if (itr == skews_.end()) { // Insert new entry using emplace with piecewise_construct // This will default-construct the array, then we copy the elements - auto result = skews_.emplace(std::piecewise_construct, - std::forward_as_tuple(clk), - std::make_tuple()); + auto result = + skews_.emplace(std::piecewise_construct, std::forward_as_tuple(clk), + std::make_tuple()); itr = result.first; // Copy array elements for (int setup_hold_idx : SetupHold::rangeIndex()) @@ -231,7 +229,8 @@ ClkSkews::findClkSkew(ConstClockSeq &clks, if (partial_skew_max > final_skew_max || (fuzzyEqual(partial_skew_max, final_skew_max) // Break ties based on source/target path names. - && ClkSkew::srcTgtPathNameLess(partial_skew_val, final_skew, this))) + && ClkSkew::srcTgtPathNameLess(partial_skew_val, final_skew, + this))) final_skew = partial_skew_val; } } @@ -269,9 +268,8 @@ ClkSkews::findClkSkewFrom(Vertex *src_vertex, if (edge->role()->genericRole() == TimingRole::regClkToQ()) { Vertex *q_vertex = edge->to(graph_); const RiseFall *rf = edge->timingArcSet()->isRisingFallingEdge(); - const RiseFallBoth *src_rf = rf - ? rf->asRiseFallBoth() - : RiseFallBoth::riseFall(); + const RiseFallBoth *src_rf = + rf ? rf->asRiseFallBoth() : RiseFallBoth::riseFall(); findClkSkewFrom(src_vertex, q_vertex, src_rf, skews); } } @@ -291,12 +289,11 @@ ClkSkews::findClkSkewFrom(Vertex *src_vertex, const TimingRole *role = edge->role(); if (role->genericRole() == TimingRole::setup() || role->genericRole() == TimingRole::hold()) { - Vertex *tgt_vertex = edge->from(graph_); - const RiseFall *tgt_rf1 = edge->timingArcSet()->isRisingFallingEdge(); - const RiseFallBoth *tgt_rf = tgt_rf1 - ? tgt_rf1->asRiseFallBoth() - : RiseFallBoth::riseFall(); - findClkSkew(src_vertex, src_rf, tgt_vertex, tgt_rf, skews); + Vertex *tgt_vertex = edge->from(graph_); + const RiseFall *tgt_rf1 = edge->timingArcSet()->isRisingFallingEdge(); + const RiseFallBoth *tgt_rf = + tgt_rf1 ? tgt_rf1->asRiseFallBoth() : RiseFallBoth::riseFall(); + findClkSkew(src_vertex, src_rf, tgt_vertex, tgt_rf, skews); } } } @@ -325,8 +322,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, while (tgt_iter.hasNext()) { Path *tgt_path = tgt_iter.next(); const Clock *tgt_clk = tgt_path->clock(this); - if (tgt_clk == src_clk - && tgt_path->isClock(this) + if (tgt_clk == src_clk && tgt_path->isClock(this) && tgt_rf->matches(tgt_path->transition(this)) && tgt_path->minMax(this) == tgt_min_max && tgt_path->scene(this) == src_scene) { @@ -334,7 +330,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, const SetupHold *setup_hold = src_path->minMax(this); ClkSkew &clk_skew = skews[src_clk][setup_hold->index()]; debugPrint(debug_, "clk_skew", 2, - "%s %s %s -> %s %s %s crpr = %s skew = %s", + "{} {} {} -> {} {} {} crpr = {} skew = {}", network_->pathName(src_path->pin(this)), src_path->transition(this)->shortName(), delayAsString(probe.srcLatency(this), src_min_max, this), @@ -356,14 +352,14 @@ VertexSet ClkSkews::findFanout(Vertex *from) { VertexSet endpoints = makeVertexSet(this); - std::unordered_set visited; + std::unordered_set visited; findFanout1(from, visited, endpoints); return endpoints; } void ClkSkews::findFanout1(Vertex *from, - std::unordered_set &visited, + std::unordered_set &visited, VertexSet &endpoints) { visited.insert(from); @@ -439,7 +435,8 @@ float ClkSkew::tgtLatency(const StaState *sta) { Arrival tgt_arrival = tgt_path_->arrival(); - return delayAsFloat(delaySum(delayDiff(tgt_arrival, tgt_path_->clkEdge(sta)->time(),sta), + return delayAsFloat(delaySum(delayDiff(tgt_arrival, + tgt_path_->clkEdge(sta)->time(),sta), clkTreeDelay(tgt_path_, sta), sta)); } @@ -477,8 +474,8 @@ float ClkSkew::uncertainty(const StaState *sta) { const TimingRole *check_role = (src_path_->minMax(sta) == SetupHold::max()) - ? TimingRole::setup() - : TimingRole::hold(); + ? TimingRole::setup() + : TimingRole::hold(); // Uncertainty decreases slack, but increases skew. return -PathEnd::checkTgtClkUncertainty(tgt_path_, tgt_path_->clkEdge(sta), check_role, sta); @@ -495,8 +492,7 @@ ClkSkew::srcTgtPathNameLess(ClkSkew &clk_skew1, const char *tgt_path1 = network->pathName(clk_skew1.tgtPath()->pin(sta)); const char *tgt_path2 = network->pathName(clk_skew2.tgtPath()->pin(sta)); return stringLess(src_path1, src_path2) - || (stringEqual(src_path1, src_path2) - && stringEqual(tgt_path1, tgt_path2)); + || (stringEqual(src_path1, src_path2) && stringEqual(tgt_path1, tgt_path2)); } //////////////////////////////////////////////////////////////// @@ -512,10 +508,9 @@ FanOutSrchPred::searchThru(Edge *edge, { const TimingRole *role = edge->role(); return SearchPred1::searchThru(edge, mode) - && (role == TimingRole::wire() - || role == TimingRole::combinational() - || role == TimingRole::tristateEnable() - || role == TimingRole::tristateDisable()); + && (role == TimingRole::wire() || role == TimingRole::combinational() + || role == TimingRole::tristateEnable() + || role == TimingRole::tristateDisable()); } -} // namespace +} // namespace sta diff --git a/search/Crpr.cc b/search/Crpr.cc index 21361ed2..3d1295bb 100644 --- a/search/Crpr.cc +++ b/search/Crpr.cc @@ -236,7 +236,7 @@ CheckCrpr::findCrpr(const Path *src_clk_path, && tgt_clk_path2 && !tgt_clk_path2->isNull() && (src_clk_path2->transition(this) == tgt_clk_path2->transition(this) || same_pin)) { - debugPrint(debug_, "crpr", 2, "crpr pin %s", + debugPrint(debug_, "crpr", 2, "crpr pin {}", network_->pathName(src_clk_path2->pin(this))); crpr = findCrpr1(src_clk_path2, tgt_clk_path2); crpr_pin = src_clk_path2->pin(this); @@ -289,12 +289,12 @@ CheckCrpr::findCrpr1(const Path *src_clk_path, // is the min of the source and target max-min delay. float src_delta = crprArrivalDiff(src_clk_path); float tgt_delta = crprArrivalDiff(tgt_clk_path); - debugPrint(debug_, "crpr", 2, " src delta %s", + debugPrint(debug_, "crpr", 2, " src delta {}", delayAsString(src_delta, this)); - debugPrint(debug_, "crpr", 2, " tgt delta %s", + debugPrint(debug_, "crpr", 2, " tgt delta {}", delayAsString(tgt_delta, this)); float common_delay = std::min(src_delta, tgt_delta); - debugPrint(debug_, "crpr", 2, " %s delta %s", + debugPrint(debug_, "crpr", 2, " {} delta {}", network_->pathName(src_clk_path->pin(this)), delayAsString(common_delay, this)); return common_delay; diff --git a/search/Genclks.cc b/search/Genclks.cc index ca81bb0a..3dee07b9 100644 --- a/search/Genclks.cc +++ b/search/Genclks.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 "Genclks.hh" @@ -85,10 +85,7 @@ GenclkInfo::GenclkInfo(Clock *gclk, { } -GenclkInfo::~GenclkInfo() -{ - delete src_filter_; -} +GenclkInfo::~GenclkInfo() { delete src_filter_; } void GenclkInfo::setFoundLatchFdbkEdges(bool found) @@ -202,7 +199,7 @@ Genclks::ensureInsertionDelays() // Generated clocks derived from a generated clock inherit its // insertion delay, so sort the clocks by source pin level. - sort(gclks , ClockPinMaxLevelLess(this)); + sort(gclks, ClockPinMaxLevelLess(this)); for (Clock *gclk : gclks) { if (gclk->masterClk()) { @@ -232,8 +229,7 @@ GenClkMasterSearchPred::GenClkMasterSearchPred(const StaState *sta) : bool GenClkMasterSearchPred::searchThruAllow(const TimingRole *role) const { - return (role->isWire() - || role == TimingRole::combinational() + return (role->isWire() || role == TimingRole::combinational() || role->regClkToQ()); } @@ -245,7 +241,7 @@ Genclks::checkMaster(Clock *gclk, { ensureMaster(gclk, sdc); if (gclk->masterClk() == nullptr) - report_->warn(1060, "no master clock found for generated clock %s.", + report_->warn(1060, "no master clock found for generated clock {}.", gclk->name()); } @@ -266,8 +262,7 @@ Genclks::ensureMaster(Clock *gclk, // Master source pin can actually be a clock source pin. if (master_clk != gclk) { gclk->setInferedMasterClk(master_clk); - debugPrint(debug_, "genclk", 2, " %s master clk %s", - gclk->name(), + debugPrint(debug_, "genclk", 2, " {} master clk {}", gclk->name(), master_clk->name()); found_master = true; master_clk_count++; @@ -291,8 +286,7 @@ Genclks::ensureMaster(Clock *gclk, // Master source pin can actually be a clock source pin. if (master_clk != gclk) { gclk->setInferedMasterClk(master_clk); - debugPrint(debug_, "genclk", 2, " %s master clk %s", - gclk->name(), + debugPrint(debug_, "genclk", 2, " {} master clk {}", gclk->name(), master_clk->name()); master_clk_count++; break; @@ -305,9 +299,8 @@ Genclks::ensureMaster(Clock *gclk, } if (master_clk_count > 1) report_->warn(1061, - "generated clock %s pin %s is in the fanout of multiple clocks.", - gclk->name(), - network_->pathName(src_pin)); + "generated clock {} pin {} is in the fanout of multiple clocks.", + gclk->name(), network_->pathName(src_pin)); } } @@ -346,8 +339,7 @@ GenClkFaninSrchPred::GenClkFaninSrchPred(Clock *gclk, bool GenClkFaninSrchPred::searchThruAllow(const TimingRole *role) const { - return (role == TimingRole::combinational() - || role == TimingRole::wire() + return (role == TimingRole::combinational() || role == TimingRole::wire() || !combinational_); } @@ -363,8 +355,8 @@ Genclks::findFanin(Clock *gclk, Vertex *vertex = iter.next(); if (!fanins.contains(vertex)) { fanins.insert(vertex); - debugPrint(debug_, "genclk", 2, "gen clk %s fanin %s", - gclk->name(), vertex->to_string(this).c_str()); + debugPrint(debug_, "genclk", 2, "gen clk {} fanin {}", gclk->name(), + vertex->to_string(this)); iter.enqueueAdjacentVertices(vertex, mode_); } } @@ -398,7 +390,7 @@ public: bool searchThru(Edge *edge, const Mode *mode) const override; bool searchTo(const Vertex *to_vertex, - const Mode *mode) const override; + const Mode *mode) const override; private: bool isNonGeneratedClkPin(const Pin *pin, @@ -423,12 +415,11 @@ GenClkInsertionSearchPred::searchThru(Edge *edge, { const TimingRole *role = edge->role(); EdgeSet &fdbk_edges = genclk_info_->fdbkEdges(); - return SearchPred0::searchThru(edge, mode) - && !role->isTimingCheck() - && (sta_->variables()->clkThruTristateEnabled() - || !(role == TimingRole::tristateEnable() - || role == TimingRole::tristateDisable())) - && !fdbk_edges.contains(edge); + return SearchPred0::searchThru(edge, mode) && !role->isTimingCheck() + && (sta_->variables()->clkThruTristateEnabled() + || !(role == TimingRole::tristateEnable() + || role == TimingRole::tristateDisable())) + && !fdbk_edges.contains(edge); } bool @@ -437,11 +428,11 @@ GenClkInsertionSearchPred::searchTo(const Vertex *to_vertex, { Pin *to_pin = to_vertex->pin(); return SearchPred0::searchTo(to_vertex, mode) - // Propagate through other generated clock roots but not regular - // clock roots. - && !(!gclk_->leafPins().contains(to_pin) - && isNonGeneratedClkPin(to_pin, mode->sdc())) - && genclk_info_->fanins().contains(const_cast(to_vertex)); + // Propagate through other generated clock roots but not regular + // clock roots. + && !(!gclk_->leafPins().contains(to_pin) + && isNonGeneratedClkPin(to_pin, mode->sdc())) + && genclk_info_->fanins().contains(const_cast(to_vertex)); } bool @@ -463,8 +454,7 @@ GenClkInsertionSearchPred::isNonGeneratedClkPin(const Pin *pin, void Genclks::findInsertionDelays(Clock *gclk) { - debugPrint(debug_, "genclk", 2, "find gen clk %s insertion", - gclk->name()); + debugPrint(debug_, "genclk", 2, "find gen clk {} insertion", gclk->name()); GenclkInfo *genclk_info = makeGenclkInfo(gclk); FilterPath *src_filter = genclk_info->srcFilter(); GenClkInsertionSearchPred srch_pred(gclk, genclk_info, this); @@ -492,7 +482,7 @@ Genclks::makeGenclkInfo(Clock *gclk) GenclkInfo * Genclks::genclkInfo(const Clock *gclk) const { - return findKey(genclk_info_map_, const_cast(gclk)); + return findKey(genclk_info_map_, const_cast(gclk)); } FilterPath * @@ -516,8 +506,7 @@ void Genclks::findLatchFdbkEdges(const Clock *clk) { GenclkInfo *genclk_info = genclkInfo(clk); - if (genclk_info - && !genclk_info->foundLatchFdbkEdges()) + if (genclk_info && !genclk_info->foundLatchFdbkEdges()) findLatchFdbkEdges(clk, genclk_info); } @@ -563,15 +552,15 @@ Genclks::findLatchFdbkEdges(Vertex *from_vertex, Edge *edge = edge_iter.next(); Vertex *to_vertex = edge->to(graph_); if (path_vertices.contains(to_vertex)) { - debugPrint(debug_, "genclk", 2, " found feedback edge %s", - edge->to_string(this).c_str()); + debugPrint(debug_, "genclk", 2, " found feedback edge {}", + edge->to_string(this)); fdbk_edges.insert(edge); } else if (srch_pred.searchThru(edge, mode_) && srch_pred.searchTo(to_vertex, mode_) && to_vertex->level() <= gclk_level) - findLatchFdbkEdges(to_vertex, gclk_level, srch_pred, - path_vertices, visited_vertices, fdbk_edges); + findLatchFdbkEdges(to_vertex, gclk_level, srch_pred, path_vertices, + visited_vertices, fdbk_edges); } path_vertices.erase(from_vertex); } @@ -584,11 +573,11 @@ Genclks::makeSrcFilter(Clock *gclk, ClockSet *from_clks = new ClockSet; from_clks->insert(gclk->masterClk()); const RiseFallBoth *rf = RiseFallBoth::riseFall(); - ExceptionFrom *from = sdc->makeExceptionFrom(nullptr,from_clks,nullptr,rf); + ExceptionFrom *from = sdc->makeExceptionFrom(nullptr, from_clks, nullptr, rf); PinSet *thru_pins = new PinSet(network_); thru_pins->insert(gclk->srcPin()); - ExceptionThru *thru = sdc->makeExceptionThru(thru_pins,nullptr,nullptr,rf); + ExceptionThru *thru = sdc->makeExceptionThru(thru_pins, nullptr, nullptr, rf); ExceptionThruSeq *thrus = new ExceptionThruSeq; thrus->push_back(thru); @@ -608,7 +597,7 @@ Genclks::seedSrcPins(Clock *gclk, for (const Pin *master_pin : master_clk->leafPins()) { Vertex *vertex = graph_->pinDrvrVertex(master_pin); if (vertex) { - debugPrint(debug_, "genclk", 2, " seed src pin %s", + debugPrint(debug_, "genclk", 2, " seed src pin {}", network_->pathName(master_pin)); TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); @@ -619,8 +608,8 @@ Genclks::seedSrcPins(Clock *gclk, for (const RiseFall *rf : RiseFall::range()) { Arrival insert = search_->clockInsertion(master_clk, master_pin, rf, min_max, early_late, mode_); - Tag *tag = makeTag(gclk, master_clk, master_pin, rf, - src_filter, insert, scene, min_max); + Tag *tag = makeTag(gclk, master_clk, master_pin, rf, src_filter, insert, + scene, min_max); tag_bldr.setArrival(tag, insert); } } @@ -648,13 +637,11 @@ Genclks::makeTag(const Clock *gclk, state = state->nextState(); ExceptionStateSet *states = new ExceptionStateSet(); states->insert(state); - const ClkInfo *clk_info = search_->findClkInfo(scene, - master_clk->edge(master_rf), - master_pin, true, nullptr, true, - nullptr, insert, 0.0, nullptr, - min_max, nullptr); - return search_->findTag(scene, master_rf, min_max, clk_info, - false, nullptr, false, states, true, nullptr); + const ClkInfo *clk_info = search_->findClkInfo( + scene, master_clk->edge(master_rf), master_pin, true, nullptr, true, nullptr, + insert, 0.0, nullptr, min_max, nullptr); + return search_->findTag(scene, master_rf, min_max, clk_info, false, nullptr, false, + states, true, nullptr); } class GenClkArrivalSearchPred : public EvalPred @@ -684,12 +671,10 @@ GenClkArrivalSearchPred::searchThru(Edge *edge, { const TimingRole *role = edge->role(); return EvalPred::searchThru(edge, mode) - && (role == TimingRole::combinational() - || role->isWire() - || !combinational_) - && (sta_->variables()->clkThruTristateEnabled() - || !(role == TimingRole::tristateEnable() - || role == TimingRole::tristateDisable())); + && (role == TimingRole::combinational() || role->isWire() || !combinational_) + && (sta_->variables()->clkThruTristateEnabled() + || !(role == TimingRole::tristateEnable() + || role == TimingRole::tristateDisable())); } // Override EvalPred::searchTo to search to generated clock pin. @@ -730,12 +715,14 @@ protected: GenclkSrcArrivalVisitor::GenclkSrcArrivalVisitor(Clock *gclk, BfsFwdIterator *insert_iter, GenclkInfo *genclk_info, - const Mode *mode): + const Mode *mode) : ArrivalVisitor(mode), gclk_(gclk), insert_iter_(insert_iter), genclk_info_(genclk_info), - srch_pred_(gclk_, genclk_info, mode), + srch_pred_(gclk_, + genclk_info, + mode), mode_(mode), sdc_(mode->sdc()), genclks_(mode->genclks()) @@ -749,11 +736,15 @@ GenclkSrcArrivalVisitor::GenclkSrcArrivalVisitor(Clock *gclk, bool always_to_endpoints, SearchPred *pred, const Mode *mode) : - ArrivalVisitor(always_to_endpoints, pred, mode), + ArrivalVisitor(always_to_endpoints, + pred, + mode), gclk_(gclk), insert_iter_(insert_iter), genclk_info_(genclk_info), - srch_pred_(gclk, genclk_info, mode), + srch_pred_(gclk, + genclk_info, + mode), mode_(mode), sdc_(mode->sdc()), genclks_(mode->genclks()) @@ -770,8 +761,8 @@ GenclkSrcArrivalVisitor::copy() const void GenclkSrcArrivalVisitor::visit(Vertex *vertex) { - debugPrint(debug_, "genclk", 2, "find gen clk insert arrival %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "genclk", 2, "find gen clk insert arrival {}", + vertex->to_string(this)); tag_bldr_->init(vertex); has_fanin_one_ = graph_->hasFaninOne(vertex); genclks_->copyGenClkSrcPaths(vertex, tag_bldr_); @@ -787,8 +778,7 @@ Genclks::findSrcArrivals(Clock *gclk, GenclkInfo *genclk_info) { GenClkArrivalSearchPred eval_pred(gclk, this); - GenclkSrcArrivalVisitor arrival_visitor(gclk, &insert_iter, - genclk_info, mode_); + GenclkSrcArrivalVisitor arrival_visitor(gclk, &insert_iter, genclk_info, mode_); arrival_visitor.init(true, false, &eval_pred); // This cannot restrict the search level because loops in the clock tree // can circle back to the generated clock src pin. @@ -803,7 +793,7 @@ Genclks::copyGenClkSrcPaths(Vertex *vertex, { auto itr = vertex_src_paths_map_.find(vertex); if (itr != vertex_src_paths_map_.end()) { - const std::vector &src_paths = itr->second; + const std::vector &src_paths = itr->second; for (const Path *path : src_paths) { Path src_path = *path; Path *prev_path = src_path.prevPath(); @@ -811,11 +801,11 @@ Genclks::copyGenClkSrcPaths(Vertex *vertex, Path *prev_vpath = Path::vertexPath(prev_path, this); src_path.setPrevPath(prev_vpath); } - debugPrint(debug_, "genclk", 3, "vertex %s insert genclk %s src path %s %ss", - src_path.vertex(this)->to_string(this).c_str(), + debugPrint(debug_, "genclk", 3, "vertex {} insert genclk {} src path {} {}s", + src_path.vertex(this)->to_string(this), src_path.tag(this)->genClkSrcPathClk()->name(), - src_path.tag(this)->minMax()->to_string().c_str(), - src_path.tag(this)->to_string(true, false, this).c_str()); + src_path.tag(this)->minMax()->to_string(), + src_path.tag(this)->to_string(true, false, this)); tag_bldr->insertPath(src_path); } } @@ -858,28 +848,21 @@ Genclks::recordSrcPaths(Clock *gclk) while (path_iter.hasNext()) { Path *path = path_iter.next(); const ClockEdge *src_clk_edge = path->clkEdge(this); - if (src_clk_edge - && matchesSrcFilter(path, gclk)) { + if (src_clk_edge && matchesSrcFilter(path, gclk)) { const EarlyLate *early_late = path->minMax(this); const RiseFall *src_clk_rf = src_clk_edge->transition(); const RiseFall *rf = path->transition(this); bool inverting_path = (rf != src_clk_rf); size_t path_index = srcPathIndex(rf, path->minMax(this)); Path &src_path = src_paths[path_index]; - if ((!divide_by_1 - || (inverting_path == invert)) - && (!has_edges - || src_clk_rf == gclk->masterClkEdgeTr(rf)) + if ((!divide_by_1 || (inverting_path == invert)) + && (!has_edges || src_clk_rf == gclk->masterClkEdgeTr(rf)) && (src_path.isNull() - || delayGreater(path->arrival(), - src_path.arrival(), - early_late, + || delayGreater(path->arrival(), src_path.arrival(), early_late, this))) { - debugPrint(debug_, "genclk", 2, " %s insertion %s %s %s", - network_->pathName(gclk_pin), - early_late->to_string().c_str(), - rf->shortName(), - delayAsString(path->arrival(), this)); + debugPrint(debug_, "genclk", 2, " {} insertion {} {} {}", + network_->pathName(gclk_pin), early_late->to_string(), + rf->shortName(), delayAsString(path->arrival(), this)); src_path = *path; } } @@ -905,19 +888,17 @@ Genclks::recordSrcPaths(Clock *gclk) } } // Don't warn if the master clock is ideal. - if (!found_src_paths - && gclk->masterClk() - && gclk->masterClk()->isPropagated()) - report_->warn(1062, "generated clock %s source pin %s missing paths from master clock %s.", - gclk->name(), - network_->pathName(gclk_pin), - gclk->masterClk()->name()); + if (!found_src_paths && gclk->masterClk() && gclk->masterClk()->isPropagated()) + report_->warn( + 1062, + "generated clock {} source pin {} missing paths from master clock {}.", + gclk->name(), network_->pathName(gclk_pin), gclk->masterClk()->name()); } deleteGenclkSrcPaths(gclk); } void -Genclks:: deleteGenclkSrcPaths(Clock *gclk) +Genclks::deleteGenclkSrcPaths(Clock *gclk) { GenclkInfo *genclk_info = genclkInfo(gclk); GenClkInsertionSearchPred srch_pred(gclk, genclk_info, mode_); @@ -938,13 +919,10 @@ Genclks::matchesSrcFilter(Path *path, { Tag *tag = path->tag(this); const ExceptionStateSet *states = tag->states(); - if (tag->isGenClkSrcPath() - && states) { + if (tag->isGenClkSrcPath() && states) { for (ExceptionState *state : *states) { ExceptionPath *except = state->exception(); - if (except->isFilter() - && state->nextThru() == nullptr - && except->to() + if (except->isFilter() && state->nextThru() == nullptr && except->to() && except->to()->matches(gclk)) return true; } @@ -958,8 +936,7 @@ Genclks::srcPath(const Path *clk_path) const const Pin *src_pin = clk_path->pin(this); const ClockEdge *clk_edge = clk_path->clkEdge(this); const EarlyLate *early_late = clk_path->minMax(this); - return srcPath(clk_edge->clock(), src_pin, - clk_edge->transition(), early_late); + return srcPath(clk_edge->clock(), src_pin, clk_edge->transition(), early_late); } const Path * @@ -967,8 +944,7 @@ Genclks::srcPath(const ClockEdge *clk_edge, const Pin *src_pin, const MinMax *min_max) const { - return srcPath(clk_edge->clock(), src_pin, - clk_edge->transition(), min_max); + return srcPath(clk_edge->clock(), src_pin, clk_edge->transition(), min_max); } const Path * @@ -1016,9 +992,7 @@ ClockPinPairLess::operator()(const ClockPinPair &pair1, int clk_index2 = clk2->index(); const Pin *pin1 = pair1.second; const Pin *pin2 = pair2.second; - return (clk_index1 < clk_index2 - || (clk_index1 == clk_index2 - && pin1 < pin2)); + return (clk_index1 < clk_index2 || (clk_index1 == clk_index2 && pin1 < pin2)); } class ClockPinPairHash @@ -1054,8 +1028,7 @@ ClockPinPairEqual::operator()(const ClockPinPair &pair1, const ClockPinPair &pair2) const { - return pair1.first == pair2.first - && pair1.second == pair2.second; + return pair1.first == pair2.first && pair1.second == pair2.second; } -} // namespace +} // namespace sta diff --git a/search/Latches.cc b/search/Latches.cc index 16bde088..c701e7fd 100644 --- a/search/Latches.cc +++ b/search/Latches.cc @@ -76,7 +76,7 @@ Latches::latchRequired(const Path *data_path, time_given_to_startpoint = 0.0; } else if (enable_path && disable_path) { - debugPrint(debug_, "latch", 1, "latch %s", + debugPrint(debug_, "latch", 1, "latch {}", sdc_network_->pathName(data_path->pin(this))); Delay open_latency, latency_diff, max_borrow; float nom_pulse_width, open_uncertainty; @@ -107,7 +107,7 @@ Latches::latchRequired(const Path *data_path, open_latency, this); enable_arrival = delaySum(enable_arrival, open_crpr, this); - debugPrint(debug_, "latch", 1, "data %s enable %s", + debugPrint(debug_, "latch", 1, "data {} enable {}", delayAsString(data_arrival, this), delayAsString(enable_arrival, this)); if (delayLessEqual(data_arrival, enable_arrival, this)) { @@ -155,7 +155,7 @@ Latches::latchRequired(const Path *data_path, adjusted_data_arrival = data_arrival; time_given_to_startpoint = 0.0; } - debugPrint(debug_, "latch", 2, "req %s borrow %s time_given %s adj_arrival %s", + debugPrint(debug_, "latch", 2, "req {} borrow {} time_given {} adj_arrival {}", delayAsString(required, this), delayAsString(borrow, this), delayAsString(time_given_to_startpoint, this), @@ -226,12 +226,12 @@ Latches::latchBorrowInfo(const Path *data_path, open_crpr = 0.0; crpr_diff = 0.0; } - debugPrint(debug_, "latch", 2, "nom_width %s open_lat %s lat_diff %s open_uncert %s", + debugPrint(debug_, "latch", 2, "nom_width {} open_lat {} lat_diff {} open_uncert {}", delayAsString(nom_pulse_width, this), delayAsString(open_latency, this), delayAsString(latency_diff, this), delayAsString(open_uncertainty, this)); - debugPrint(debug_, "latch", 2, "open_crpr %s crpr_diff %s open_uncert %s max_borrow %s", + debugPrint(debug_, "latch", 2, "open_crpr {} crpr_diff {} open_uncert {} max_borrow {}", delayAsString(open_crpr, this), delayAsString(crpr_diff, this), delayAsString(open_uncertainty, this), diff --git a/search/Levelize.cc b/search/Levelize.cc index dff1f199..5302be0a 100644 --- a/search/Levelize.cc +++ b/search/Levelize.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 "Levelize.hh" @@ -162,8 +162,7 @@ Levelize::findRoots() while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); if (isRoot(vertex)) { - debugPrint(debug_, "levelize", 2, "root %s%s", - vertex->to_string(this).c_str(), + debugPrint(debug_, "levelize", 2, "root {}{}", vertex->to_string(this), hasFanout(vertex) ? " fanout" : ""); roots_.insert(vertex); } @@ -174,9 +173,8 @@ Levelize::findRoots() if (hasFanout(root)) fanout_roots++; } - debugPrint(debug_, "levelize", 1, "Found %zu roots %zu with fanout", - roots_.size(), - fanout_roots); + debugPrint(debug_, "levelize", 1, "Found {} roots {} with fanout", + roots_.size(), fanout_roots); } } @@ -200,14 +198,11 @@ bool Levelize::searchThru(Edge *edge) { const TimingRole *role = edge->role(); - return !role->isTimingCheck() - && role != TimingRole::latchDtoQ() - && !edge->isDisabledLoop() - // Register/latch preset/clr edges are disabled by default. - && !(role == TimingRole::regSetClr() - && !variables_->presetClrArcsEnabled()) - && !(edge->isBidirectInstPath() - && !variables_->bidirectInstPathsEnabled()); + return !role->isTimingCheck() && role != TimingRole::latchDtoQ() + && !edge->isDisabledLoop() + // Register/latch preset/clr edges are disabled by default. + && !(role == TimingRole::regSetClr() && !variables_->presetClrArcsEnabled()) + && !(edge->isBidirectInstPath() && !variables_->bidirectInstPathsEnabled()); } bool @@ -271,7 +266,7 @@ Levelize::findBackEdges(EdgeSeq &path, EdgeSet back_edges; while (!stack.empty()) { VertexEdgeIterPair vertex_iter = stack.top(); - const auto& [vertex, edge_iter] = vertex_iter; + const auto &[vertex, edge_iter] = vertex_iter; if (edge_iter->hasNext()) { Edge *edge = edge_iter->next(); if (searchThru(edge)) { @@ -282,7 +277,7 @@ Levelize::findBackEdges(EdgeSeq &path, path.push_back(edge); stack.emplace(to_vertex, new VertexOutEdgeIterator(to_vertex, graph_)); } - else if (to_vertex->visited2()) { // on path + else if (to_vertex->visited2()) { // on path // Found a back edge (loop). recordLoop(edge, path); back_edges.insert(edge); @@ -327,7 +322,7 @@ Levelize::findCycleBackEdges() back_edge_count += back_edges.size(); } } - debugPrint(debug_, "levelize", 1, "Found %zu cycle back edges", back_edge_count); + debugPrint(debug_, "levelize", 1, "Found {} cycle back edges", back_edge_count); } // Find vertices in cycles that are were not accessible from roots. @@ -350,7 +345,7 @@ VertexSeq Levelize::findTopologicalOrder() { Stats stats(debug_, report_); - std::map in_degree; + std::map in_degree; VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { @@ -368,12 +363,13 @@ Levelize::findTopologicalOrder() const Pin *pin = vertex->pin(); if (graph_delay_calc_->bidirectDrvrSlewFromLoad(pin) && !vertex->isBidirectDriver()) { - Vertex *to_vertex = graph_->pinDrvrVertex(pin);; + Vertex *to_vertex = graph_->pinDrvrVertex(pin); + ; in_degree[to_vertex] += 1; } } - std::deque queue; + std::deque queue; for (Vertex *root : roots_) queue.push_back(root); @@ -412,14 +408,14 @@ Levelize::findTopologicalOrder() while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); if (in_degree[vertex] != 0) - debugPrint(debug_, "levelize", 2, "topological sort missing %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "levelize", 2, "topological sort missing {}", + vertex->to_string(this)); } } if (debug_->check("levelize", 3)) { - report_->reportLine("Topological sort"); + report_->report("Topological sort"); for (Vertex *vertex : topo_order) - report_->reportLine("%s", vertex->to_string(this).c_str()); + report_->report("{}", vertex->to_string(this)); } stats.report("Levelize topological sort"); return topo_order; @@ -429,9 +425,8 @@ void Levelize::recordLoop(Edge *edge, EdgeSeq &path) { - debugPrint(debug_, "levelize", 2, "Loop edge %s (%s)", - edge->to_string(this).c_str(), - edge->role()->to_string().c_str()); + debugPrint(debug_, "levelize", 2, "Loop edge {} ({})", + edge->to_string(this), edge->role()->to_string()); EdgeSeq *loop_edges = loopEdges(path, edge); GraphLoop *loop = new GraphLoop(loop_edges); loops_.push_back(loop); @@ -460,14 +455,12 @@ Levelize::loopEdges(EdgeSeq &path, if (from_pin == loop_pin) copy = true; if (copy) { - debugPrint(debug_, "loop", 2, " %s", - edge->to_string(this).c_str()); + debugPrint(debug_, "loop", 2, " {}", edge->to_string(this)); loop_edges->push_back(edge); loop_edges_.insert(edge); } } - debugPrint(debug_, "loop", 2, " %s", - closing_edge->to_string(this).c_str()); + debugPrint(debug_, "loop", 2, " {}", closing_edge->to_string(this)); loop_edges->push_back(closing_edge); loop_edges_.insert(closing_edge); return loop_edges; @@ -479,8 +472,8 @@ Levelize::reportPath(EdgeSeq &path) const bool first_edge = true; for (Edge *edge : path) { if (first_edge) - report_->reportLine(" %s", edge->from(graph_)->to_string(this).c_str()); - report_->reportLine(" %s", edge->to(graph_)->to_string(this).c_str()); + report_->report(" {}", edge->from(graph_)->to_string(this)); + report_->report(" {}", edge->to(graph_)->to_string(this)); first_edge = false; } } @@ -499,16 +492,16 @@ Levelize::assignLevels(VertexSeq &topo_sorted) Edge *edge = edge_iter.next(); Vertex *to_vertex = edge->to(graph_); if (searchThru(edge)) - setLevel(to_vertex, std::max(to_vertex->level(), - vertex->level() + level_space_)); + setLevel(to_vertex, + std::max(to_vertex->level(), vertex->level() + level_space_)); } // Levelize bidirect driver as if it was a fanout of the bidirect load. const Pin *pin = vertex->pin(); if (graph_delay_calc_->bidirectDrvrSlewFromLoad(pin) && !vertex->isBidirectDriver()) { Vertex *to_vertex = graph_->pinDrvrVertex(pin); - setLevel(to_vertex, std::max(to_vertex->level(), - vertex->level() + level_space_)); + setLevel(to_vertex, + std::max(to_vertex->level(), vertex->level() + level_space_)); } } } @@ -528,12 +521,9 @@ Levelize::ensureLatchLevels() Vertex *to = edge->to(graph_); if (from->level() == to->level()) { Level adjusted_level = from->level() + level_space_; - debugPrint(debug_, "levelize", 2, "latch %s %d (adjusted %d) -> %s %d", - from->to_string(this).c_str(), - from->level(), - adjusted_level, - to->to_string(this).c_str(), - to->level()); + debugPrint(debug_, "levelize", 2, "latch {} {} (adjusted {}) -> {} {}", + from->to_string(this), from->level(), adjusted_level, + to->to_string(this), to->level()); setLevel(from, adjusted_level); } } @@ -541,12 +531,11 @@ Levelize::ensureLatchLevels() } void -Levelize::setLevel(Vertex *vertex, +Levelize::setLevel(Vertex *vertex, Level level) { - debugPrint(debug_, "levelize", 3, "set level %s %d", - vertex->to_string(this).c_str(), - level); + debugPrint(debug_, "levelize", 3, "set level {} {}", + vertex->to_string(this), level); vertex->setLevel(level); max_level_ = std::max(level, max_level_); if (level >= Graph::vertex_level_max) @@ -576,8 +565,8 @@ void Levelize::relevelizeFrom(Vertex *vertex) { if (levelized_) { - debugPrint(debug_, "levelize", 1, "level invalid from %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "levelize", 1, "level invalid from {}", + vertex->to_string(this)); relevelize_from_.insert(vertex); levels_valid_ = false; } @@ -586,10 +575,9 @@ Levelize::relevelizeFrom(Vertex *vertex) void Levelize::deleteEdgeBefore(Edge *edge) { - if (levelized_ - && loop_edges_.contains(edge)) { - debugPrint(debug_, "levelize", 2, "delete loop edge %s", - edge->to_string(this).c_str()); + if (levelized_ && loop_edges_.contains(edge)) { + debugPrint(debug_, "levelize", 2, "delete loop edge {}", + edge->to_string(this)); disabled_loop_edges_.erase(edge); // Relevelize if a loop edge is removed. Incremental levelization // fails because the DFS path will be missing. @@ -610,9 +598,9 @@ void Levelize::relevelize() { for (Vertex *vertex : relevelize_from_) { - debugPrint(debug_, "levelize", 2, "relevelize from %s", - vertex->to_string(this).c_str()); - if (isRoot(vertex)) + debugPrint(debug_, "levelize", 2, "relevelize from {}", + vertex->to_string(this)); + if (isRoot(vertex)) roots_.insert(vertex); VertexSet path_vertices = makeVertexSet(this); EdgeSeq path; @@ -646,8 +634,8 @@ Levelize::visit(Vertex *vertex, // Back edges form feedback loops. recordLoop(edge, path); else if (to_vertex->level() <= level) - visit(to_vertex, edge, level+level_space, level_space, - path_vertices, path); + visit(to_vertex, edge, level + level_space, level_space, path_vertices, + path); } const TimingRole *role = edge->role(); @@ -668,8 +656,8 @@ Levelize::visit(Vertex *vertex, && !vertex->isBidirectDriver()) { Vertex *to_vertex = graph_->pinDrvrVertex(from_pin); if (to_vertex->level() <= level) - visit(to_vertex, nullptr, level+level_space, level_space, - path_vertices, path); + visit(to_vertex, nullptr, level + level_space, level_space, path_vertices, + path); } path_vertices.erase(vertex); if (from) @@ -683,12 +671,11 @@ Levelize::isDisabledLoop(Edge *edge) const } void -Levelize::setLevelIncr(Vertex *vertex, +Levelize::setLevelIncr(Vertex *vertex, Level level) { - debugPrint(debug_, "levelize", 2, "set level %s %d", - vertex->to_string(this).c_str(), - level); + debugPrint(debug_, "levelize", 2, "set level {} {}", + vertex->to_string(this), level); if (vertex->level() != level) { if (observer_) observer_->levelChangedBefore(vertex); @@ -715,11 +702,9 @@ Levelize::checkLevels() && from_level >= level // Loops with no entry edges are all level zero. && !(from_level == 0 && level == 0)) - report_->warn(617, "level check failed %s %d -> %s %d", - from_vertex->name(network_), - from_vertex->level(), - vertex->name(network_), - level); + report_->warn(617, "level check failed {} {} -> {} {}", + from_vertex->name(network_), from_vertex->level(), + vertex->name(network_), level); } } } @@ -731,18 +716,14 @@ GraphLoop::GraphLoop(EdgeSeq *edges) : { } -GraphLoop::~GraphLoop() -{ - delete edges_; -} +GraphLoop::~GraphLoop() { delete edges_; } bool GraphLoop::isCombinational() const { for (Edge *edge : *edges_) { const TimingRole *role = edge->role(); - if (!(role == TimingRole::wire() - || role == TimingRole::combinational() + if (!(role == TimingRole::wire() || role == TimingRole::combinational() || role == TimingRole::tristateEnable() || role == TimingRole::tristateDisable())) return false; @@ -758,10 +739,10 @@ GraphLoop::report(const StaState *sta) const bool first_edge = true; for (Edge *edge : *edges_) { if (first_edge) - report->reportLine(" %s", edge->from(graph)->to_string(sta).c_str()); - report->reportLine(" %s", edge->to(graph)->to_string(graph).c_str()); + report->report(" {}", edge->from(graph)->to_string(sta)); + report->report(" {}", edge->to(graph)->to_string(sta)); first_edge = false; } } -} // namespace +} // namespace sta diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 39f712fe..20ec6110 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.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 "MakeTimingModel.hh" @@ -75,7 +75,8 @@ MakeTimingModel::MakeTimingModel(const char *lib_name, scene_(scene), cell_(nullptr), min_max_(MinMax::max()), - lib_builder_(new LibertyBuilder(debug_, report_)), + lib_builder_(new LibertyBuilder(debug_, + report_)), tbl_template_index_(1), sdc_(scene->sdc()), sdc_backup_(nullptr), @@ -84,10 +85,7 @@ MakeTimingModel::MakeTimingModel(const char *lib_name, scenes_.insert(scene_); } -MakeTimingModel::~MakeTimingModel() -{ - delete lib_builder_; -} +MakeTimingModel::~MakeTimingModel() { delete lib_builder_; } LibertyLibrary * MakeTimingModel::makeTimingModel() @@ -107,7 +105,7 @@ MakeTimingModel::makeTimingModel() cell_->finish(false, report_, debug_); restoreSdc(); - + return library_; } @@ -193,9 +191,8 @@ MakeTimingModel::makePorts() int from_index = network_->fromIndex(port); int to_index = network_->toIndex(port); BusDcl *bus_dcl = library_->makeBusDcl(port_name, from_index, to_index); - LibertyPort *lib_port = lib_builder_->makeBusPort(cell_, port_name, - from_index, to_index, - bus_dcl); + LibertyPort *lib_port = + lib_builder_->makeBusPort(cell_, port_name, from_index, to_index, bus_dcl); lib_port->setDirection(network_->direction(port)); PortMemberIterator *member_iter = network_->memberIterator(port); while (member_iter->hasNext()) { @@ -223,8 +220,7 @@ MakeTimingModel::checkClock(Clock *clk) { for (const Pin *pin : clk->leafPins()) { if (!network_->isTopLevelPort(pin)) - report_->warn(1355, "clock %s pin %s is inside model block.", - clk->name(), + report_->warn(1355, "clock {} pin {} is inside model block.", clk->name(), network_->pathName(pin)); } } @@ -235,7 +231,7 @@ class MakeEndTimingArcs : public PathEndVisitor { public: MakeEndTimingArcs(Sta *sta); - MakeEndTimingArcs(const MakeEndTimingArcs&) = default; + MakeEndTimingArcs(const MakeEndTimingArcs &) = default; ~MakeEndTimingArcs() override {} PathEndVisitor *copy() const override; void visit(PathEnd *path_end) override; @@ -273,8 +269,7 @@ MakeEndTimingArcs::visit(PathEnd *path_end) const Sdc *sdc = src_path->sdc(sta_); const Clock *src_clk = src_path->clock(sta_); const ClockEdge *tgt_clk_edge = path_end->targetClkEdge(sta_); - if (src_clk == sdc->defaultArrivalClock() - && tgt_clk_edge) { + if (src_clk == sdc->defaultArrivalClock() && tgt_clk_edge) { Network *network = sta_->network(); Debug *debug = sta_->debug(); const MinMax *min_max = path_end->minMax(sta_); @@ -285,13 +280,10 @@ MakeEndTimingArcs::visit(PathEnd *path_end) ? delaySum(delayDiff(data_delay, clk_latency, sta_), check_margin, sta_) : delaySum(delayDiff(clk_latency, data_delay, sta_), check_margin, sta_); float delay1 = delayAsFloat(margin, MinMax::max(), sta_); - debugPrint(debug, "make_timing_model", 2, "%s -> %s clock %s %s %s %s", - input_rf_->shortName(), - network->pathName(src_path->pin(sta_)), - tgt_clk_edge->name(), - path_end->typeName(), - min_max->to_string().c_str(), - delayAsString(margin, sta_)); + debugPrint(debug, "make_timing_model", 2, "{} -> {} clock {} {} {} {}", + input_rf_->shortName(), network->pathName(src_path->pin(sta_)), + tgt_clk_edge->name(), path_end->typeName(), + min_max->to_string(), delayAsString(margin, sta_)); if (debug->check("make_timing_model", 3)) sta_->reportPathEnd(path_end); @@ -335,15 +327,14 @@ MakeTimingModel::findTimingFromInput(Port *input_port) OutputPinDelays output_delays; for (const RiseFall *input_rf : RiseFall::range()) { const RiseFallBoth *input_rf1 = input_rf->asRiseFallBoth(); - sta_->setInputDelay(input_pin, input_rf1, - sdc_->defaultArrivalClock(), - sdc_->defaultArrivalClockEdge()->transition(), - nullptr, false, false, MinMaxAll::all(), true, 0.0, sdc_); + sta_->setInputDelay(input_pin, input_rf1, sdc_->defaultArrivalClock(), + sdc_->defaultArrivalClockEdge()->transition(), nullptr, + false, false, MinMaxAll::all(), true, 0.0, sdc_); PinSet *from_pins = new PinSet(network_); from_pins->insert(input_pin); - ExceptionFrom *from = sta_->makeExceptionFrom(from_pins, nullptr, nullptr, - input_rf1, sdc_); + ExceptionFrom *from = + sta_->makeExceptionFrom(from_pins, nullptr, nullptr, input_rf1, sdc_); search_->findFilteredArrivals(from, nullptr, nullptr, false, false); end_visitor.setInputRf(input_rf); @@ -354,8 +345,7 @@ MakeTimingModel::findTimingFromInput(Port *input_port) findOutputDelays(input_rf, output_delays); search_->deleteFilteredArrivals(); - sta_->removeInputDelay(input_pin, input_rf1, - sdc_->defaultArrivalClock(), + sta_->removeInputDelay(input_pin, input_rf1, sdc_->defaultArrivalClock(), sdc_->defaultArrivalClockEdge()->transition(), MinMaxAll::all(), sdc_); } @@ -395,7 +385,7 @@ void MakeTimingModel::makeSetupHoldTimingArcs(const Pin *input_pin, const ClockEdgeDelays &clk_margins) { - for (const auto& [clk_edge, margins] : clk_margins) { + for (const auto &[clk_edge, margins] : clk_margins) { for (const MinMax *min_max : MinMax::range()) { bool setup = (min_max == MinMax::max()); TimingArcAttrsPtr attrs = nullptr; @@ -404,16 +394,14 @@ MakeTimingModel::makeSetupHoldTimingArcs(const Pin *input_pin, bool exists; margins.value(input_rf, min_max, margin, exists); if (exists) { - debugPrint(debug_, "make_timing_model", 2, "%s %s %s -> clock %s %s", - sta_->network()->pathName(input_pin), - input_rf->shortName(), - min_max == MinMax::max() ? "setup" : "hold", - clk_edge->name(), + debugPrint(debug_, "make_timing_model", 2, "{} {} {} -> clock {} {}", + sta_->network()->pathName(input_pin), input_rf->shortName(), + min_max == MinMax::max() ? "setup" : "hold", clk_edge->name(), delayAsString(margin, sta_)); - ScaleFactorType scale_type = setup - ? ScaleFactorType::setup - : ScaleFactorType::hold; - TimingModel *check_model = makeScalarCheckModel(margin, scale_type, input_rf); + ScaleFactorType scale_type = + setup ? ScaleFactorType::setup : ScaleFactorType::hold; + TimingModel *check_model = + makeScalarCheckModel(margin, scale_type, input_rf); if (attrs == nullptr) attrs = std::make_shared(); attrs->setModel(input_rf, check_model); @@ -425,12 +413,10 @@ MakeTimingModel::makeSetupHoldTimingArcs(const Pin *input_pin, LibertyPort *clk_port = modelPort(clk_pin); if (clk_port) { const RiseFall *clk_rf = clk_edge->transition(); - const TimingRole *role = setup - ? TimingRole::setup() - : TimingRole::hold(); - lib_builder_->makeFromTransitionArcs(cell_, clk_port, - input_port, nullptr, - clk_rf, role, attrs); + const TimingRole *role = + setup ? TimingRole::setup() : TimingRole::hold(); + lib_builder_->makeFromTransitionArcs(cell_, clk_port, input_port, + nullptr, clk_rf, role, attrs); } } } @@ -442,7 +428,7 @@ void MakeTimingModel::makeInputOutputTimingArcs(const Pin *input_pin, OutputPinDelays &output_pin_delays) { - for (const auto& [output_pin, output_delays] : output_pin_delays) { + for (const auto &[output_pin, output_delays] : output_pin_delays) { TimingArcAttrsPtr attrs = nullptr; for (const RiseFall *output_rf : RiseFall::range()) { const MinMax *min_max = MinMax::max(); @@ -450,11 +436,9 @@ MakeTimingModel::makeInputOutputTimingArcs(const Pin *input_pin, bool exists; output_delays.delays.value(output_rf, min_max, delay, exists); if (exists) { - debugPrint(debug_, "make_timing_model", 2, "%s -> %s %s delay %s", - network_->pathName(input_pin), - network_->pathName(output_pin), - output_rf->shortName(), - delayAsString(delay, sta_)); + debugPrint(debug_, "make_timing_model", 2, "{} -> {} {} delay {}", + network_->pathName(input_pin), network_->pathName(output_pin), + output_rf->shortName(), delayAsString(delay, sta_)); TimingModel *gate_model = makeGateModelTable(output_pin, delay, output_rf); if (attrs == nullptr) attrs = std::make_shared(); @@ -465,8 +449,8 @@ MakeTimingModel::makeInputOutputTimingArcs(const Pin *input_pin, LibertyPort *output_port = modelPort(output_pin); LibertyPort *input_port = modelPort(input_pin); attrs->setTimingSense(output_delays.timingSense()); - lib_builder_->makeCombinationalArcs(cell_, input_port, output_port, - true, true, attrs); + lib_builder_->makeCombinationalArcs(cell_, input_port, output_port, true, true, + attrs); } } } @@ -479,7 +463,7 @@ MakeTimingModel::findClkedOutputPaths() { InstancePinIterator *output_iter = network_->pinIterator(network_->topInstance()); while (output_iter->hasNext()) { - Pin *output_pin = output_iter->next(); + Pin *output_pin = output_iter->next(); if (network_->direction(output_pin)->isOutput()) { ClockEdgeDelays clk_delays; LibertyPort *output_port = modelPort(output_pin); @@ -493,11 +477,10 @@ MakeTimingModel::findClkedOutputPaths() const MinMax *min_max = path->minMax(sta_); Arrival delay = path->arrival(); RiseFallMinMax &delays = clk_delays[clk_edge]; - delays.mergeValue(output_rf, min_max, - delayAsFloat(delay, min_max, sta_)); + delays.mergeValue(output_rf, min_max, delayAsFloat(delay, min_max, sta_)); } } - for (const auto& [clk_edge, delays] : clk_delays) { + for (const auto &[clk_edge, delays] : clk_delays) { for (const Pin *clk_pin : clk_edge->clock()->pins()) { LibertyPort *clk_port = modelPort(clk_pin); if (clk_port) { @@ -505,16 +488,16 @@ MakeTimingModel::findClkedOutputPaths() TimingArcAttrsPtr attrs = nullptr; for (const RiseFall *output_rf : RiseFall::range()) { float delay = delays.value(output_rf, min_max_) - clk_edge->time(); - TimingModel *gate_model = makeGateModelTable(output_pin, delay, output_rf); + TimingModel *gate_model = + makeGateModelTable(output_pin, delay, output_rf); if (attrs == nullptr) attrs = std::make_shared(); attrs->setModel(output_rf, gate_model); } if (attrs) { - lib_builder_->makeFromTransitionArcs(cell_, clk_port, - output_port, nullptr, - clk_rf, TimingRole::regClkToQ(), - attrs); + lib_builder_->makeFromTransitionArcs(cell_, clk_port, output_port, + nullptr, clk_rf, + TimingRole::regClkToQ(), attrs); } } } @@ -545,8 +528,10 @@ MakeTimingModel::findClkTreeDelays() for (const Clock *clk : *clks) { ClkDelays delays = sta_->findClkDelays(clk, scene_, true); for (const MinMax *min_max : MinMax::range()) { - makeClkTreePaths(lib_port, min_max, TimingSense::positive_unate, delays); - makeClkTreePaths(lib_port, min_max, TimingSense::negative_unate, delays); + makeClkTreePaths(lib_port, min_max, TimingSense::positive_unate, + delays); + makeClkTreePaths(lib_port, min_max, TimingSense::negative_unate, + delays); } } } @@ -564,15 +549,14 @@ MakeTimingModel::makeClkTreePaths(LibertyPort *lib_port, { TimingArcAttrsPtr attrs = nullptr; for (const RiseFall *clk_rf : RiseFall::range()) { - const RiseFall *end_rf = (sense == TimingSense::positive_unate) - ? clk_rf - : clk_rf->opposite(); + const RiseFall *end_rf = + (sense == TimingSense::positive_unate) ? clk_rf : clk_rf->opposite(); Path clk_path; Delay insertion, delay, latency; float lib_clk_delay; bool exists; - delays.delay(clk_rf, end_rf, min_max, insertion, delay, - lib_clk_delay, latency, clk_path, exists); + delays.delay(clk_rf, end_rf, min_max, insertion, delay, lib_clk_delay, latency, + clk_path, exists); if (exists) { TimingModel *model = makeGateModelScalar(delay, end_rf); if (attrs == nullptr) @@ -583,8 +567,8 @@ MakeTimingModel::makeClkTreePaths(LibertyPort *lib_port, if (attrs) { attrs->setTimingSense(sense); const TimingRole *role = (min_max == MinMax::min()) - ? TimingRole::clockTreePathMin() - : TimingRole::clockTreePathMax(); + ? TimingRole::clockTreePathMin() + : TimingRole::clockTreePathMax(); lib_builder_->makeClockTreePathArcs(cell_, lib_port, role, attrs); } } @@ -669,12 +653,11 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin, const Pin *gate_in_pin = network_->findPin(drvr_inst, gate_in_port); if (gate_in_pin) { Vertex *gate_in_vertex = graph_->pinLoadVertex(gate_in_pin); - Slew in_slew = graph_->slew(gate_in_vertex, - drvr_arc->fromEdge()->asRiseFall(), - ap_index); + Slew in_slew = graph_->slew( + gate_in_vertex, drvr_arc->fromEdge()->asRiseFall(), ap_index); float in_slew1 = delayAsFloat(in_slew); - GateTableModel *drvr_gate_model = drvr_arc->gateTableModel(scene_, - min_max_); + GateTableModel *drvr_gate_model = + drvr_arc->gateTableModel(scene_, min_max_); if (drvr_gate_model) { float output_load_cap = graph_delay_calc_->loadCap(output_pin, scene_, @@ -704,15 +687,17 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin, } FloatSeq axis_values = drvr_axis_values; - TableAxisPtr load_axis = - std::make_shared(TableAxisVariable::total_output_net_capacitance, - std::move(axis_values)); + TableAxisPtr load_axis = std::make_shared( + TableAxisVariable::total_output_net_capacitance, + std::move(axis_values)); - TablePtr delay_table = std::make_shared(load_values, load_axis); - TablePtr slew_table = std::make_shared
(slew_values, load_axis); + TablePtr delay_table = + std::make_shared
(load_values, load_axis); + TablePtr slew_table = + std::make_shared
(slew_values, load_axis); - TableTemplate *model_template = ensureTableTemplate(drvr_template, - load_axis); + TableTemplate *model_template = + ensureTableTemplate(drvr_template, load_axis); TableModel *delay_model = new TableModel(delay_table, model_template, ScaleFactorType::cell, rf); TableModels *delay_models = new TableModels(delay_model); @@ -745,8 +730,8 @@ MakeTimingModel::ensureTableTemplate(const TableTemplate *drvr_template, std::string template_name = "template_"; template_name += std::to_string(tbl_template_index_++); - model_template = library_->makeTableTemplate(template_name, - TableTemplateType::delay); + model_template = + library_->makeTableTemplate(template_name, TableTemplateType::delay); model_template->setAxis1(load_axis); template_map_[drvr_template] = model_template; } @@ -757,13 +742,16 @@ const TableAxis * MakeTimingModel::loadCapacitanceAxis(const TableModel *table) { if (table->axis1() - && table->axis1()->variable() == TableAxisVariable::total_output_net_capacitance) + && table->axis1()->variable() + == TableAxisVariable::total_output_net_capacitance) return table->axis1(); else if (table->axis2() - && table->axis2()->variable() == TableAxisVariable::total_output_net_capacitance) + && table->axis2()->variable() + == TableAxisVariable::total_output_net_capacitance) return table->axis2(); else if (table->axis3() - && table->axis3()->variable() == TableAxisVariable::total_output_net_capacitance) + && table->axis3()->variable() + == TableAxisVariable::total_output_net_capacitance) return table->axis3(); else return nullptr; @@ -781,9 +769,9 @@ TimingSense OutputDelays::timingSense() const { if (rf_path_exists[RiseFall::riseIndex()][RiseFall::riseIndex()] - && rf_path_exists[RiseFall::fallIndex()][RiseFall::fallIndex()] - && !rf_path_exists[RiseFall::riseIndex()][RiseFall::fallIndex()] - && !rf_path_exists[RiseFall::fallIndex()][RiseFall::riseIndex()]) + && rf_path_exists[RiseFall::fallIndex()][RiseFall::fallIndex()] + && !rf_path_exists[RiseFall::riseIndex()][RiseFall::fallIndex()] + && !rf_path_exists[RiseFall::fallIndex()][RiseFall::riseIndex()]) return TimingSense::positive_unate; else if (rf_path_exists[RiseFall::riseIndex()][RiseFall::fallIndex()] && rf_path_exists[RiseFall::fallIndex()][RiseFall::riseIndex()] @@ -799,4 +787,4 @@ OutputDelays::timingSense() const return TimingSense::none; } -} // namespace +} // namespace sta diff --git a/search/Path.cc b/search/Path.cc index 38470f8e..c0bb35d1 100644 --- a/search/Path.cc +++ b/search/Path.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 "Path.hh" @@ -129,8 +129,7 @@ Path::init(Vertex *vertex, { const Graph *graph = sta->graph(); vertex_id_ = graph->id(vertex); - tag_index_ = tag_index_null, - prev_path_ = nullptr; + tag_index_ = tag_index_null, prev_path_ = nullptr; prev_arc_idx_ = 0; arrival_ = arrival; required_ = 0.0; @@ -144,8 +143,7 @@ Path::init(Vertex *vertex, { const Graph *graph = sta->graph(); vertex_id_ = graph->id(vertex); - tag_index_ = tag->index(), - prev_path_ = nullptr; + tag_index_ = tag->index(), prev_path_ = nullptr; prev_arc_idx_ = 0; arrival_ = 0.0; required_ = 0.0; @@ -160,8 +158,7 @@ Path::init(Vertex *vertex, { const Graph *graph = sta->graph(); vertex_id_ = graph->id(vertex); - tag_index_ = tag->index(), - prev_path_ = nullptr; + tag_index_ = tag->index(), prev_path_ = nullptr; prev_arc_idx_ = 0; arrival_ = arrival; required_ = 0.0; @@ -178,8 +175,7 @@ Path::init(Vertex *vertex, const StaState *sta) { const Graph *graph = sta->graph(); - tag_index_ = tag->index(), - prev_path_ = prev_path; + tag_index_ = tag->index(), prev_path_ = prev_path; if (prev_path) { prev_edge_id_ = graph->id(prev_edge); prev_arc_idx_ = prev_arc->index(); @@ -199,12 +195,12 @@ Path::to_string(const StaState *sta) const if (isNull()) return "null path"; else - return stringPrintTmp("%s %s %s/%s %d", - vertex(sta)->to_string(sta).c_str(), - transition(sta)->shortName(), - scene(sta)->name().c_str(), - minMax(sta)->to_string().c_str(), - tagIndex(sta)); + return sta::format("{} {} {}/{} {}", + vertex(sta)->to_string(sta), + transition(sta)->shortName(), + scene(sta)->name(), + minMax(sta)->to_string(), + tagIndex(sta)); } bool @@ -221,7 +217,7 @@ Path::vertex(const StaState *sta) const const Edge *edge = graph->edge(prev_edge_id_); return edge->to(graph); } - else + else return graph->vertex(vertex_id_); } @@ -404,7 +400,7 @@ Path::prevArc(const StaState *sta) const TimingArcSet *arc_set = edge->timingArcSet(); return arc_set->findTimingArc(prev_arc_idx_); } - else + else return nullptr; } @@ -415,7 +411,7 @@ Path::prevEdge(const StaState *sta) const const Graph *graph = sta->graph(); return graph->edge(prev_edge_id_); } - else + else return nullptr; } @@ -448,8 +444,7 @@ void Path::checkPrevPath(const StaState *sta) const { if (prev_path_ && prev_path_->isNull()) - sta->report()->reportLine("path %s prev path is null.", - to_string(sta).c_str()); + sta->report()->report("path {} prev path is null.", to_string(sta)); if (prev_path_ && !prev_path_->isNull()) { Graph *graph = sta->graph(); Edge *edge = prevEdge(sta); @@ -457,10 +452,9 @@ Path::checkPrevPath(const StaState *sta) const Vertex *prev_edge_vertex = edge->from(graph); if (prev_vertex != prev_edge_vertex) { Network *network = sta->network(); - sta->report()->reportLine("path %s prev path corrupted %s vs %s.", - to_string(sta).c_str(), - prev_vertex->name(network), - prev_edge_vertex->name(network)); + sta->report()->report("path {} prev path corrupted {} vs {}.", to_string(sta), + prev_vertex->name(network), + prev_edge_vertex->name(network)); } } } @@ -478,14 +472,14 @@ Path::tgtClkMinMax(const StaState *sta) const { const MinMax *min_max = minMax(sta); switch (mode(sta)->sdc()->analysisType()) { - case AnalysisType::single: - case AnalysisType::bc_wc: - return min_max; - case AnalysisType::ocv: - return min_max->opposite(); - default: - // suppress gcc warning - return min_max; + case AnalysisType::single: + case AnalysisType::bc_wc: + return min_max; + case AnalysisType::ocv: + return min_max->opposite(); + default: + // suppress gcc warning + return min_max; } } //////////////////////////////////////////////////////////////// @@ -579,8 +573,7 @@ Path::cmpClk(const Path *path1, else return 1; } - else if (clk_edge1 == nullptr - && clk_edge2 == nullptr) + else if (clk_edge1 == nullptr && clk_edge2 == nullptr) return 0; else if (clk_edge2) return -1; @@ -594,11 +587,10 @@ Path::equal(const Path *path1, const StaState *sta) { return (path1 == nullptr && path2 == nullptr) - || (path1 - && path2 - && path1->vertexId(sta) == path2->vertexId(sta) - // Tag equal implies transition and path ap equal. - && path1->tagIndex(sta) == path2->tagIndex(sta)); + || (path1 && path2 + && path1->vertexId(sta) == path2->vertexId(sta) + // Tag equal implies transition and path ap equal. + && path1->tagIndex(sta) == path2->tagIndex(sta)); } //////////////////////////////////////////////////////////////// @@ -779,12 +771,9 @@ VertexPathIterator::findNext() Path *path = &paths_[path_index_++]; if (filtered_) { const Tag *tag = path->tag(search_); - if ((scene_ == nullptr - || path->scene(search_) == scene_) - && (rf_ == nullptr - || tag->rfIndex() == rf_->index()) - && (min_max_ == nullptr - || path->minMax(search_) == min_max_)) { + if ((scene_ == nullptr || path->scene(search_) == scene_) + && (rf_ == nullptr || tag->rfIndex() == rf_->index()) + && (min_max_ == nullptr || path->minMax(search_) == min_max_)) { next_ = path; return; } @@ -797,9 +786,7 @@ VertexPathIterator::findNext() next_ = nullptr; } -VertexPathIterator::~VertexPathIterator() -{ -} +VertexPathIterator::~VertexPathIterator() {} bool VertexPathIterator::hasNext() @@ -815,4 +802,4 @@ VertexPathIterator::next() return path; } -} // namespace +} // namespace sta diff --git a/search/PathEnum.cc b/search/PathEnum.cc index c5e11778..437966a8 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.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 "PathEnum.hh" @@ -41,11 +41,11 @@ namespace sta { -// A diversion is an alternate path formed by changing the previous +// A diversion is an alternate path formed by changing the previous // path/arc of before_div to after_div/div_arc in path. // // div_arc -// after_div<--------+ +// after_div<--------+ // | // <--...--before_div<--...--path<---path_end // @@ -128,13 +128,14 @@ PathEnum::PathEnum(size_t group_path_count, void PathEnum::insert(PathEnd *path_end) { - debugPrint(debug_, "path_enum", 1, "insert %s", - path_end->path()->to_string(this).c_str()); - debugPrint(debug_, "path_enum", 2, "diversion %s %s %s", - path_end->path()->to_string(this).c_str(), + debugPrint(debug_, "path_enum", 1, "insert {}", + path_end->path()->to_string(this)); + debugPrint(debug_, "path_enum", 2, "diversion {} {} {}", + path_end->path()->to_string(this), cmp_slack_ ? "slack" : "delay", - delayAsString(cmp_slack_ ? path_end->slack(this) : - path_end->dataArrivalTime(this), this)); + delayAsString(cmp_slack_ ? path_end->slack(this) + : path_end->dataArrivalTime(this), + this)); Diversion *div = new Diversion(path_end, path_end->path()); div_queue_.push(div); div_count_++; @@ -154,13 +155,11 @@ PathEnum::~PathEnum() bool PathEnum::hasNext() { - if (unique_pins_ - && !inserts_pruned_) { + if (unique_pins_ && !inserts_pruned_) { pruneDiversionQueue(); inserts_pruned_ = true; } - if (next_ == nullptr - && !div_queue_.empty()) + if (next_ == nullptr && !div_queue_.empty()) findNext(); return next_ != nullptr; } @@ -186,11 +185,10 @@ PathEnum::findNext() Vertex *vertex = path_end->vertex(this); path_counts_[vertex]++; if (debug_->check("path_enum", 2)) { - report_->reportLine("path_enum: next path %zu %s delay %s slack %s", - path_counts_[vertex], - path->to_string(this).c_str(), - delayAsString(path_end->dataArrivalTime(this), this), - delayAsString(path_end->slack(this), this)); + report_->report("path_enum: next path {} {} delay {} slack {}", + path_counts_[vertex], path->to_string(this), + delayAsString(path_end->dataArrivalTime(this), this), + delayAsString(path_end->slack(this), this)); reportDiversionPath(div); } @@ -206,9 +204,8 @@ PathEnum::findNext() else { // We have endpoint_path_count paths for this endpoint, // so we are done with it. - debugPrint(debug_, "path_enum", 1, - "endpoint_path_count reached for %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "path_enum", 1, "endpoint_path_count reached for {}", + vertex->to_string(this)); deleteDiversionPathEnd(div); } } @@ -222,12 +219,10 @@ PathEnum::reportDiversionPath(Diversion *div) Path *p = path_end->path(); Path *after_div = div->divPath(); while (p) { - report_->reportLine("path_enum: %s %s%s", - p->to_string(this).c_str(), - delayAsString(p->arrival(), this), - Path::equal(p, after_div, this) ? " <-after diversion" : ""); - if (p != path - && network_->isLatchData(p->pin(this))) + report_->report("path_enum: {} {}{}", p->to_string(this), + delayAsString(p->arrival(), this), + Path::equal(p, after_div, this) ? " <-after diversion" : ""); + if (p != path && network_->isLatchData(p->pin(this))) break; p = p->prevPath(); } @@ -235,8 +230,8 @@ PathEnum::reportDiversionPath(Diversion *div) //////////////////////////////////////////////////////////////// -using VisitedFanins = std::set>; -using VertexEdge = std::pair; +using VisitedFanins = std::set>; +using VertexEdge = std::pair; class PathEnumFaninVisitor : public PathVisitor { @@ -251,19 +246,19 @@ public: Vertex *prev_vertex, TimingArc *prev_arc); bool visitFromToPath(const Pin *from_pin, - Vertex *from_vertex, - const RiseFall *from_rf, - Tag *from_tag, - Path *from_path, - const Arrival &from_arrival, - Edge *edge, - TimingArc *arc, - ArcDelay arc_delay, - Vertex *to_vertex, - const RiseFall *to_rf, - Tag *to_tag, - Arrival &to_arrival, - const MinMax *min_max) override; + Vertex *from_vertex, + const RiseFall *from_rf, + Tag *from_tag, + Path *from_path, + const Arrival &from_arrival, + Edge *edge, + TimingArc *arc, + ArcDelay arc_delay, + Vertex *to_vertex, + const RiseFall *to_rf, + Tag *to_tag, + Arrival &to_arrival, + const MinMax *min_max) override; private: void makeDivertedPathEnd(Path *after_div, @@ -299,7 +294,7 @@ private: Vertex *prev_vertex_; bool crpr_active_; VisitedFanins visited_fanins_; - std::map unique_edge_divs_; + std::map unique_edge_divs_; }; PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end, @@ -372,8 +367,7 @@ PathEnumFaninVisitor::visitEdge(const Pin *from_pin, Path *from_path = from_iter.next(); const Mode *mode = from_path->mode(this); const Sdc *sdc = mode->sdc(); - if (pred_->searchFrom(from_vertex, mode) - && pred_->searchThru(edge, mode) + if (pred_->searchFrom(from_vertex, mode) && pred_->searchThru(edge, mode) && pred_->searchTo(to_vertex, mode) // Fanin paths are broken by path delay internal pin startpoints. && !sdc->isPathDelayInternalFromBreak(to_pin)) { @@ -382,13 +376,13 @@ PathEnumFaninVisitor::visitEdge(const Pin *from_pin, arc_set->arcsFrom(from_rf, arc1, arc2); // Filter arcs by to edge. if (arc1 && arc1->toEdge()->asRiseFall()->index() == before_div_rf_index_) { - if (!visitArc(from_pin, from_vertex, from_rf, from_path, - edge, arc1, to_pin, to_vertex, min_max_, mode)) + if (!visitArc(from_pin, from_vertex, from_rf, from_path, edge, arc1, + to_pin, to_vertex, min_max_, mode)) return false; } if (arc2 && arc2->toEdge()->asRiseFall()->index() == before_div_rf_index_) { - if (!visitArc(from_pin, from_vertex, from_rf, from_path, - edge, arc2, to_pin, to_vertex, min_max_, mode)) + if (!visitArc(from_pin, from_vertex, from_rf, from_path, edge, arc2, + to_pin, to_vertex, min_max_, mode)) return false; } } @@ -415,23 +409,20 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, { // These paths fanin to before_div_ so we know to_vertex matches. if ((!unique_pins_ || from_vertex != prev_vertex_) - && (!unique_edges_ - || from_vertex != prev_vertex_ + && (!unique_edges_ || from_vertex != prev_vertex_ || from_rf != prev_arc_->fromEdge()->asRiseFall()) && arc != prev_arc_ && Tag::matchNoCrpr(to_tag, before_div_tag_) // Ignore paths that only differ by crpr from same vertex/edge. - && (!crpr_active_ - || !visited_fanins_.contains({from_vertex, arc}))) { - debugPrint(debug_, "path_enum", 3, "visit fanin %s -> %s %s %s", - from_path->to_string(this).c_str(), - to_vertex->to_string(this).c_str(), - to_rf->shortName(), - delayAsString(search_->deratedDelay(from_vertex, arc, edge, - false, from_path->minMax(this), - from_path->dcalcAnalysisPtIndex(this), - from_path->sdc(this)), - this)); + && (!crpr_active_ || !visited_fanins_.contains({from_vertex, arc}))) { + debugPrint(debug_, "path_enum", 3, "visit fanin {} -> {} {} {}", + from_path->to_string(this), + to_vertex->to_string(this), to_rf->shortName(), + delayAsString( + search_->deratedDelay( + from_vertex, arc, edge, false, from_path->minMax(this), + from_path->dcalcAnalysisPtIndex(this), from_path->sdc(this)), + this)); PathEnd *div_end; Path *after_div_copy; // Make the diverted path end to check slack with from_path crpr. @@ -448,21 +439,18 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, else { if (debug_->check("path_enum", 3)) { bool unique_pins = !(!unique_pins_ || from_vertex != prev_vertex_); - bool unique_edges = !(!unique_edges_ - || from_rf != prev_arc_->fromEdge()->asRiseFall()); + bool unique_edges = + !(!unique_edges_ || from_rf != prev_arc_->fromEdge()->asRiseFall()); bool same_arc = !(arc != prev_arc_); bool tag_march = !Tag::matchNoCrpr(to_tag, before_div_tag_); - bool crpr = !(!crpr_active_ - || visited_fanins_.find({from_vertex, arc}) - == visited_fanins_.end()); - debugPrint(debug_, "path_enum", 3, " pruned %s%s%s%s%s %s %s", + bool crpr = + !(!crpr_active_ + || visited_fanins_.find({from_vertex, arc}) == visited_fanins_.end()); + debugPrint(debug_, "path_enum", 3, " pruned {}{}{}{}{} {} {}", unique_pins ? "unique_pins " : "", - unique_edges ? "unique_edges " : "", - same_arc ? "same_arc " : "", - tag_march ? "tag_march " : "", - crpr ? "crpr " : "", - edge->to_string(this).c_str(), - arc->to_string().c_str()); + unique_edges ? "unique_edges " : "", same_arc ? "same_arc " : "", + tag_march ? "tag_march " : "", crpr ? "crpr " : "", + edge->to_string(this), arc->to_string()); } } return true; @@ -495,8 +483,8 @@ PathEnumFaninVisitor::makeDivertedPathEnd(Path *after_div, Path *&after_div_copy) { Path *div_path; - path_enum_->makeDivertedPath(path_end_->path(), before_div_, after_div, - div_edge, div_arc, div_path, after_div_copy); + path_enum_->makeDivertedPath(path_end_->path(), before_div_, after_div, div_edge, + div_arc, div_path, after_div_copy); div_end = path_end_->copy(); div_end->setPath(div_path); } @@ -505,7 +493,7 @@ void PathEnumFaninVisitor::reportDiversion(const Edge *div_edge, const TimingArc *div_arc, Path *after_div) -{ +{ if (debug_->check("path_enum", 3)) { Path *path = path_end_->path(); Arrival path_delay = path_enum_->cmp_slack_ @@ -517,16 +505,12 @@ PathEnumFaninVisitor::reportDiversion(const Edge *div_edge, div_arc), this); Path *div_prev = before_div_->prevPath(); - report_->reportLine("path_enum: diversion %s %s %s -> %s", - path->to_string(this).c_str(), - path_enum_->cmp_slack_ ? "slack" : "delay", - delayAsString(path_delay, this), - delayAsString(div_delay, this)); - report_->reportLine("path_enum: from %s -> %s", - div_prev->to_string(this).c_str(), - before_div_->to_string(this).c_str()); - report_->reportLine("path_enum: to %s", - after_div->to_string(this).c_str()); + report_->report("path_enum: diversion {} {} {} -> {}", path->to_string(this), + path_enum_->cmp_slack_ ? "slack" : "delay", + delayAsString(path_delay, this), delayAsString(div_delay, this)); + report_->report("path_enum: from {} -> {}", div_prev->to_string(this), + before_div_->to_string(this)); + report_->report("path_enum: to {}", after_div->to_string(this)); } } @@ -610,8 +594,8 @@ PathEnum::makeDiversions(PathEnd *path_end, Path *path = before; Path *prev_path = path->prevPath(); TimingArc *prev_arc = path->prevArc(this); - PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_, - unique_edges_, this); + PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_, unique_edges_, + this); while (prev_path) { // Fanin visitor does all the work. // While visiting the fanins the fanin_visitor finds the @@ -620,8 +604,7 @@ PathEnum::makeDiversions(PathEnd *path_end, // Do not enumerate beyond latch D to Q edges. // This breaks latch loop paths. const TimingRole *prev_role = prev_arc->role(); - if (prev_role == TimingRole::latchDtoQ() - || prev_role == TimingRole::regClkToQ()) + if (prev_role == TimingRole::latchDtoQ() || prev_role == TimingRole::regClkToQ()) break; path = prev_path; prev_path = path->prevPath(); @@ -649,14 +632,10 @@ PathEnum::makeDivertedPath(Path *path, Path *prev_copy = nullptr; while (p) { // prev_path made in next pass. - Path *copy = new Path(p->vertex(this), - p->tag(this), - p->arrival(), - // Replaced on next pass. - p->prevPath(), - p->prevEdge(this), - p->prevArc(this), - true, this); + Path *copy = + new Path(p->vertex(this), p->tag(this), p->arrival(), + // Replaced on next pass. + p->prevPath(), p->prevEdge(this), p->prevArc(this), true, this); search_->saveEnumPath(copy); if (prev_copy) prev_copy->setPrevPath(copy); @@ -666,8 +645,7 @@ PathEnum::makeDivertedPath(Path *path, after_div_copy = copy; if (first) div_path = copy; - else if (found_div - && network_->isLatchData(p->pin(this))) + else if (found_div && network_->isLatchData(p->pin(this))) break; if (p == before_div) { // Replaced on next pass. @@ -704,13 +682,11 @@ PathEnum::updatePathHeadDelays(PathSeq &paths, if (edge) { Arrival arrival; const MinMax *min_max = path->minMax(this); - if (i == path_idx_max - && edge->role()->isLatchDtoQ() + if (i == path_idx_max && edge->role()->isLatchDtoQ() && min_max == MinMax::max()) { ArcDelay arc_delay; Tag *q_tag; - latches_->latchOutArrival(after_div, arc, edge, - q_tag, arc_delay, arrival); + latches_->latchOutArrival(after_div, arc, edge, q_tag, arc_delay, arrival); path->setArrival(arrival); path->setTag(q_tag); prev_clk_info = q_tag->clkInfo(); @@ -731,19 +707,15 @@ PathEnum::updatePathHeadDelays(PathSeq &paths, && arc->role() != TimingRole::latchDtoQ()) { // When crpr is enabled the diverion may be from another crpr clk pin, // so update the tags to use the corresponding ClkInfo. - Tag *updated_tag = search_->findTag(path->scene(this), - path->transition(this), - path->minMax(this), - prev_clk_info, - tag->isClock(), - tag->inputDelay(), - tag->isSegmentStart(), - tag->states(), false, nullptr); + Tag *updated_tag = search_->findTag( + path->scene(this), path->transition(this), path->minMax(this), + prev_clk_info, tag->isClock(), tag->inputDelay(), + tag->isSegmentStart(), tag->states(), false, nullptr); path->setTag(updated_tag); } - debugPrint(debug_, "path_enum", 5, "update arrival %s %s %s -> %s", - path->vertex(this)->to_string(this).c_str(), - path->tag(this)->to_string(this).c_str(), + debugPrint(debug_, "path_enum", 5, "update arrival {} {} {} -> {}", + path->vertex(this)->to_string(this), + path->tag(this)->to_string(this), delayAsString(path->arrival(), this), delayAsString(arrival, this)); } @@ -752,4 +724,4 @@ PathEnum::updatePathHeadDelays(PathSeq &paths, } } -} // namespace +} // namespace sta diff --git a/search/PathGroup.cc b/search/PathGroup.cc index a60b6c42..e2ca7711 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -309,7 +309,7 @@ PathGroups::makeGroups(int group_path_count, const Sdc *sdc = mode_->sdc(); for (const auto& [name, group] : sdc->groupPaths()) { if (reportGroup(name, group_names)) { - PathGroup *group = PathGroup::makePathGroupSlack(name, + PathGroup *group = PathGroup::makePathGroupSlack(name.c_str(), group_path_count, endpoint_path_count, unique_pins, @@ -394,7 +394,7 @@ PathGroups::~PathGroups() } PathGroup * -PathGroups::findPathGroup(const char *name, +PathGroups::findPathGroup(const std::string &name, const MinMax *min_max) const { auto itr = named_map_[min_max->index()].find(name); @@ -416,7 +416,7 @@ PathGroups::findPathGroup(const Clock *clock, } bool -PathGroups::reportGroup(const char *group_name, +PathGroups::reportGroup(const std::string &group_name, StringSet &group_names) const { return group_names.empty() @@ -441,7 +441,7 @@ PathGroups::pathGroups(const PathEnd *path_end) const path_groups.push_back(path_delay_[mm_index]); } else { - const char *group_name = group_path->name(); + std::string group_name = group_path->name(); PathGroup *group = findPathGroup(group_name, min_max); if (group) path_groups.push_back(group); @@ -552,7 +552,7 @@ PathGroups::pushEnds(PathEndSeq &path_ends) for (const MinMax *min_max : MinMax::range()) { int mm_index = min_max->index(); for (std::string &group_name : pathGroupNames()) { - PathGroup *path_group = findPathGroup(group_name.c_str(), min_max); + PathGroup *path_group = findPathGroup(group_name, min_max); if (path_group) path_group->pushEnds(path_ends); } @@ -801,8 +801,8 @@ MakePathEndsAll::vertexEnd(Vertex *) // Only save the worst path end for each crpr tag. // PathEnum will peel the others. if (!unique_ends.contains(path_end)) { - debugPrint(debug, "path_group", 2, "insert %s %s %s %d", - path_end->vertex(sta_)->to_string(sta_).c_str(), + debugPrint(debug, "path_group", 2, "insert {} {} {} {}", + path_end->vertex(sta_)->to_string(sta_), path_end->typeName(), path_end->transition(sta_)->shortName(), path_end->path()->tag(sta_)->index()); @@ -816,8 +816,8 @@ MakePathEndsAll::vertexEnd(Vertex *) } } else - debugPrint(debug, "path_group", 3, "prune %s %s %s %d", - path_end->vertex(sta_)->to_string(sta_).c_str(), + debugPrint(debug, "path_group", 3, "prune {} {} {} {}", + path_end->vertex(sta_)->to_string(sta_), path_end->typeName(), path_end->transition(sta_)->shortName(), path_end->path()->tag(sta_)->index()); diff --git a/search/Property.cc b/search/Property.cc index dc37d4b3..35e6a096 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -27,6 +27,7 @@ #include #include +#include "Format.hh" #include "StringUtil.hh" #include "MinMax.hh" #include "Transition.hh" @@ -49,39 +50,26 @@ namespace sta { class PropertyUnknown : public Exception { public: - PropertyUnknown(const char *type, - const char *property); - PropertyUnknown(const char *type, - const std::string property); + PropertyUnknown(const std::string &type, + const std::string &property); virtual ~PropertyUnknown() {} virtual const char *what() const noexcept; private: - const char *type_; - const std::string property_; + std::string msg_; }; -PropertyUnknown::PropertyUnknown(const char *type, - const char *property) : +PropertyUnknown::PropertyUnknown(const std::string &type, + const std::string &property) : Exception(), - type_(type), - property_(property) -{ -} - -PropertyUnknown::PropertyUnknown(const char *type, - const std::string property) : - Exception(), - type_(type), - property_(property) + msg_(sta::format("{} objects do not have a {} property.", type, property)) { } const char * PropertyUnknown::what() const noexcept { - return stringPrint("%s objects do not have a %s property.", - type_, property_.c_str()); + return msg_.c_str(); } //////////////////////////////////////////////////////////////// @@ -89,29 +77,27 @@ PropertyUnknown::what() const noexcept class PropertyTypeWrong : public Exception { public: - PropertyTypeWrong(const char *accessor, - const char *type); + PropertyTypeWrong(const std::string &accessor, + const std::string &type); virtual ~PropertyTypeWrong() {} virtual const char *what() const noexcept; private: - const char *accessor_; - const char *type_; + std::string msg_; }; -PropertyTypeWrong::PropertyTypeWrong(const char *accessor, - const char *type) : +PropertyTypeWrong::PropertyTypeWrong(const std::string &accessor, + const std::string &type) : Exception(), - accessor_(accessor), - type_(type) + msg_(sta::format("property accessor {} is only valid for {} properties.", + accessor, type)) { } const char * PropertyTypeWrong::what() const noexcept { - return stringPrint("property accessor %s is only valid for %s properties.", - accessor_, type_); + return msg_.c_str(); } //////////////////////////////////////////////////////////////// @@ -1159,8 +1145,7 @@ Properties::getProperty(TimingArcSet *arc_set, const char *from = arc_set->from()->name(); const char *to = arc_set->to()->name(); const char *cell_name = arc_set->libertyCell()->name(); - std::string name; - stringPrint(name, "%s %s -> %s", cell_name, from, to); + std::string name = sta::format("{} {} -> {}", cell_name, from, to); return PropertyValue(name); } } diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 664af765..158b7919 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -28,6 +28,7 @@ #include "ReportPath.hh" #include "ContainerHelpers.hh" +#include "Format.hh" #include "Report.hh" #include "Error.hh" #include "StringUtil.hh" @@ -139,9 +140,7 @@ ReportPath::ReportPath(StaState *sta) : format_(ReportPathFormat::full), no_split_(false), start_end_pt_width_(80), - field_width_extra_(5), - plus_zero_(nullptr), - minus_zero_(nullptr) + field_width_extra_(5) { makeFields(); setDigits(2); @@ -160,9 +159,6 @@ ReportPath::~ReportPath() delete field_src_attr_; delete field_edge_; delete field_case_; - - stringDelete(plus_zero_); - stringDelete(minus_zero_); } void @@ -277,11 +273,8 @@ void ReportPath::setDigits(int digits) { digits_ = digits; - - stringDelete(plus_zero_); - stringDelete(minus_zero_); - minus_zero_ = stringPrint("-%.*f", digits_, 0.0); - plus_zero_ = stringPrint("%.*f", digits_, 0.0); + minus_zero_ = sta::formatRuntime("-{:.{}f}", 0.0, digits_); + plus_zero_ = sta::formatRuntime("{:.{}f}", 0.0, digits_); // Numeric field width expands with digits. int field_width = digits + field_width_extra_; @@ -348,7 +341,7 @@ ReportPath::reportPathEnds(const PathEndSeq *ends) const } else { if (format_ != ReportPathFormat::json) - report_->reportLine("No paths found."); + report_->report("No paths found."); } reportPathEndFooter(); } @@ -410,9 +403,7 @@ ReportPath::reportEndpointHeader(const PathEnd *end, const char *setup_hold = (end->minMax(this) == MinMax::min()) ? "min_delay/hold" : "max_delay/setup"; - report_->reportLine("%s group %s", - setup_hold, - group->name().c_str()); + report_->report("{} group {}", setup_hold, group->name()); reportBlankLine(); reportEndHeader(); } @@ -447,7 +438,7 @@ ReportPath::reportFull(const PathEndUnconstrained *end) const reportLine("data arrival time", end->dataArrivalTimeOffset(this), end->pathEarlyLate(this)); reportDashLine(); - report_->reportLine("(Path is unconstrained)"); + report_->report("(Path is unconstrained)"); } //////////////////////////////////////////////////////////////// @@ -482,8 +473,8 @@ ReportPath::reportFull(const PathEndCheck *end) const std::string ReportPath::checkRoleString(const PathEnd *end) const { - return stdstrPrint("library %s time", - end->checkRole(this)->to_string().c_str()); + return sta::format("library {} time", + end->checkRole(this)->to_string()); } void @@ -497,23 +488,23 @@ ReportPath::reportEndpoint(const PathEndCheck *end) const const TimingRole *check_generic_role = check_role->genericRole(); if (check_role == TimingRole::recovery() || check_role == TimingRole::removal()) { - auto reason = stdstrPrint("%s check against %s-edge clock %s", - check_role->to_string().c_str(), - rise_fall, - clk_name.c_str()); + std::string reason = sta::format("{} check against {}-edge clock {}", + check_role->to_string(), + rise_fall, + clk_name); reportEndpoint(inst_name, reason); } else if (check_generic_role == TimingRole::setup() || check_generic_role == TimingRole::hold()) { LibertyCell *cell = network_->libertyCell(inst); if (cell->isClockGate()) { - auto reason = stdstrPrint("%s clock gating-check end-point clocked by %s", - rise_fall, clk_name.c_str()); + std::string reason = sta::format("{} clock gating-check end-point clocked by {}", + rise_fall, clk_name); reportEndpoint(inst_name, reason); } else { const char *reg_desc = clkRegLatchDesc(end); - auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); + std::string reason = sta::format("{} clocked by {}", reg_desc, clk_name); reportEndpoint(inst_name, reason); } } @@ -600,7 +591,7 @@ ReportPath::reportEndpoint(const PathEndLatchCheck *end) const const char *inst_name = cmd_network_->pathName(inst); std::string clk_name = tgtClkName(end); const char *reg_desc = latchDesc(end); - auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); + std::string reason = sta::format("{} clocked by {}", reg_desc, clk_name); reportEndpoint(inst_name, reason); } @@ -625,7 +616,7 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end, end->latchBorrowInfo(this, nom_pulse_width, open_latency, latency_diff, open_uncertainty, open_crpr, crpr_diff, max_borrow, borrow_limit_exists); - report_->reportLine("Time Borrowing Information"); + report_->report("Time Borrowing Information"); reportDashLineTotal(); if (borrow_limit_exists) reportLineTotal("user max time borrow", max_borrow, early_late); @@ -634,13 +625,13 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end, Arrival tgt_clk_width = end->targetClkWidth(this); const Path *tgt_clk_path = end->targetClkPath(); if (tgt_clk_path->clkInfo(search_)->isPropagated()) { - auto width_msg = stdstrPrint("%s nominal pulse width", tgt_clk_name.c_str()); + std::string width_msg = sta::format("{} nominal pulse width", tgt_clk_name); reportLineTotal(width_msg.c_str(), nom_pulse_width, early_late); if (!delayZero(latency_diff, this)) reportLineTotalMinus("clock latency difference", latency_diff, early_late); } else { - auto width_msg = stdstrPrint("%s pulse width", tgt_clk_name.c_str()); + std::string width_msg = sta::format("{} pulse width", tgt_clk_name.c_str()); reportLineTotal(width_msg.c_str(), tgt_clk_width, early_late); } ArcDelay margin = end->margin(this); @@ -696,9 +687,9 @@ ReportPath::reportEndpoint(const PathEndPathDelay *end) const else { Instance *inst = network_->instance(end->vertex(this)->pin()); const char *inst_name = cmd_network_->pathName(inst); - std::string clk_name = tgtClkName(end); - const char *reg_desc = clkRegLatchDesc(end); - auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); + std::string reason = sta::format("{} clocked by {}", + clkRegLatchDesc(end), + tgtClkName(end)); reportEndpoint(inst_name, reason); } } @@ -826,8 +817,8 @@ ReportPath::reportEndpointOutputDelay(const PathEndClkConstrained *end) const if (network_->isTopLevelPort(pin)) { // Pin direction is "output" even for bidirects. if (tgt_clk) { - std::string clk_name = tgtClkName(end); - auto reason = stdstrPrint("output port clocked by %s", clk_name.c_str()); + std::string reason = sta::format("output port clocked by {}", + tgtClkName(end)); reportEndpoint(pin_name, reason); } else @@ -835,9 +826,8 @@ ReportPath::reportEndpointOutputDelay(const PathEndClkConstrained *end) const } else { if (tgt_clk) { - std::string clk_name = tgtClkName(end); - auto reason = stdstrPrint("internal path endpoint clocked by %s", - clk_name.c_str()); + std::string reason = sta::format("internal path endpoint clocked by {}", + tgtClkName(end)); reportEndpoint(pin_name, reason); } @@ -880,15 +870,14 @@ ReportPath::reportEndpoint(const PathEndGatedClock *end) const { Instance *inst = network_->instance(end->vertex(this)->pin()); const char *inst_name = cmd_network_->pathName(inst); - std::string clk_name = tgtClkName(end); const RiseFall *clk_end_rf = end->targetClkEndTrans(this); - const RiseFall *clk_rf = - (end->minMax(this) == MinMax::max()) ? clk_end_rf : clk_end_rf->opposite(); - const char *rise_fall = asRisingFalling(clk_rf); + const RiseFall *clk_rf = (end->minMax(this) == MinMax::max()) + ? clk_end_rf + : clk_end_rf->opposite(); // Note that target clock transition is ignored. - auto reason = stdstrPrint("%s clock gating-check end-point clocked by %s", - rise_fall, - clk_name.c_str()); + std::string reason = sta::format("{} clock gating-check end-point clocked by {}", + asRisingFalling(clk_rf), + tgtClkName(end)); reportEndpoint(inst_name, reason); } @@ -948,11 +937,9 @@ ReportPath::reportEndpoint(const PathEndDataCheck *end) const { Instance *inst = network_->instance(end->vertex(this)->pin()); const char *inst_name = cmd_network_->pathName(inst); - const char *tgt_clk_rf = asRisingFalling(end->dataClkPath()->transition(this)); - const char *tgt_clk_name = end->targetClk(this)->name(); - auto reason = stdstrPrint("%s edge-triggered data to data check clocked by %s", - tgt_clk_rf, - tgt_clk_name); + std::string reason = sta::format("{} edge-triggered data to data check clocked by {}", + asRisingFalling(end->dataClkPath()->transition(this)), + end->targetClk(this)->name()); reportEndpoint(inst_name, reason); } @@ -968,7 +955,7 @@ ReportPath::reportEndHeader() const reportField("Required", field_total_, line); line += ' '; reportField("Actual", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); // Line two. line.clear(); @@ -979,7 +966,7 @@ ReportPath::reportEndHeader() const reportField("Delay", field_total_, line); line += ' '; reportField("Slack", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(field_description_->width() + field_total_->width() * 3 + 3); } @@ -994,7 +981,7 @@ ReportPath::reportEndLine(const PathEnd *end) const reportSpaceFieldDelay(end->requiredTimeOffset(this), early_late, line); reportSpaceFieldDelay(end->dataArrivalTimeOffset(this), early_late, line); reportSpaceSlack(end, line); - report_->reportLineString(line); + report_->reportLine(line); } //////////////////////////////////////////////////////////////// @@ -1008,7 +995,7 @@ ReportPath::reportSummaryHeader() const reportDescription("Endpoint", line); line += ' '; reportField("Slack", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(field_description_->width() * 2 + field_total_->width() + 1); } @@ -1019,16 +1006,16 @@ ReportPath::reportSummaryLine(const PathEnd *end) const std::string line; PathExpanded expanded(end->path(), this); const EarlyLate *early_late = end->pathEarlyLate(this); - auto startpoint = pathStartpoint(end, expanded); + std::string startpoint = pathStartpoint(end, expanded); reportDescription(startpoint.c_str(), line); line += ' '; - auto endpoint = pathEndpoint(end); + std::string endpoint = pathEndpoint(end); reportDescription(endpoint.c_str(), line); if (end->isUnconstrained()) reportSpaceFieldDelay(end->dataArrivalTimeOffset(this), early_late, line); else reportSpaceFieldDelay(end->slack(this), EarlyLate::early(), line); - report_->reportLineString(line); + report_->reportLine(line); } std::string @@ -1040,12 +1027,12 @@ ReportPath::pathStartpoint(const PathEnd *end, const char *pin_name = cmd_network_->pathName(pin); if (network_->isTopLevelPort(pin)) { PortDirection *dir = network_->direction(pin); - return stdstrPrint("%s (%s)", pin_name, dir->name()); + return sta::format("{} ({})", pin_name, dir->name()); } else { Instance *inst = network_->instance(end->vertex(this)->pin()); const char *cell_name = cmd_network_->name(network_->cell(inst)); - return stdstrPrint("%s (%s)", pin_name, cell_name); + return sta::format("{} ({})", pin_name, cell_name); } } @@ -1056,12 +1043,12 @@ ReportPath::pathEndpoint(const PathEnd *end) const const char *pin_name = cmd_network_->pathName(pin); if (network_->isTopLevelPort(pin)) { PortDirection *dir = network_->direction(pin); - return stdstrPrint("%s (%s)", pin_name, dir->name()); + return sta::format("{} ({})", pin_name, dir->name()); } else { Instance *inst = network_->instance(end->vertex(this)->pin()); const char *cell_name = cmd_network_->name(network_->cell(inst)); - return stdstrPrint("%s (%s)", pin_name, cell_name); + return sta::format("{} ({})", pin_name, cell_name); } } @@ -1070,14 +1057,14 @@ ReportPath::pathEndpoint(const PathEnd *end) const void ReportPath::reportJsonHeader() const { - report_->reportLine("{\"checks\": ["); + report_->report("{{\"checks\": ["); } void ReportPath::reportJsonFooter() const { - report_->reportLine("]"); - report_->reportLine("}"); + report_->report("]"); + report_->report("}}"); } void @@ -1101,18 +1088,18 @@ ReportPath::reportJson(const PathEnd *end, PathExpanded expanded(end->path(), this); const Pin *startpoint = expanded.startPath()->vertex(this)->pin(); const Pin *endpoint = expanded.endPath()->vertex(this)->pin(); - stringAppend(result, " \"startpoint\": \"%s\",\n", + result += sta::format(" \"startpoint\": \"{}\",\n", sdc_network_->pathName(startpoint)); - stringAppend(result, " \"endpoint\": \"%s\",\n", + result += sta::format(" \"endpoint\": \"{}\",\n", sdc_network_->pathName(endpoint)); const ClockEdge *src_clk_edge = end->sourceClkEdge(this); const Path *src_clk_path = expanded.clkPath(); const Path *tgt_clk_path = end->targetClkPath(); if (src_clk_edge) { - stringAppend(result, " \"source_clock\": \"%s\",\n", + result += sta::format(" \"source_clock\": \"{}\",\n", src_clk_edge->clock()->name()); - stringAppend(result, " \"source_clock_edge\": \"%s\",\n", + result += sta::format(" \"source_clock_edge\": \"{}\",\n", src_clk_edge->transition()->name()); } if (src_clk_path) @@ -1121,41 +1108,41 @@ ReportPath::reportJson(const PathEnd *end, const ClockEdge *tgt_clk_edge = end->targetClkEdge(this); if (tgt_clk_edge) { - stringAppend(result, " \"target_clock\": \"%s\",\n", + result += sta::format(" \"target_clock\": \"{}\",\n", tgt_clk_edge->clock()->name()); - stringAppend(result, " \"target_clock_edge\": \"%s\",\n", + result += sta::format(" \"target_clock_edge\": \"{}\",\n", tgt_clk_edge->transition()->name()); } if (tgt_clk_path) reportJson(end->targetClkPath(), "target_clock_path", 2, true, result); if (end->checkRole(this)) { - stringAppend(result, " \"data_arrival_time\": %.3e,\n", + result += sta::format(" \"data_arrival_time\": {:.3e},\n", delayAsFloat(end->dataArrivalTimeOffset(this))); const MultiCyclePath *mcp = end->multiCyclePath(); if (mcp) - stringAppend(result, " \"multi_cycle_path\": %d,\n", + result += sta::format(" \"multi_cycle_path\": {},\n", mcp->pathMultiplier()); PathDelay *path_delay = end->pathDelay(); if (path_delay) - stringAppend(result, " \"path_delay\": %.3e,\n", + result += sta::format(" \"path_delay\": {:.3e},\n", path_delay->delay()); - stringAppend(result, " \"crpr\": %.3e,\n", + result += sta::format(" \"crpr\": {:.3e},\n", delayAsFloat(end->checkCrpr(this))); - stringAppend(result, " \"margin\": %.3e,\n", + result += sta::format(" \"margin\": {:.3e},\n", delayAsFloat(end->margin(this))); - stringAppend(result, " \"required_time\": %.3e,\n", + result += sta::format(" \"required_time\": {:.3e},\n", delayAsFloat(end->requiredTimeOffset(this))); - stringAppend(result, " \"slack\": %.3e\n", + result += sta::format(" \"slack\": {:.3e}\n", delayAsFloat(end->slack(this))); } result += "}"; if (!last) result += ","; - report_->reportLineString(result); + report_->reportLine(result); } void @@ -1165,7 +1152,7 @@ ReportPath::reportJson(const Path *path) const result += "{\n"; reportJson(path, "path", 0, false, result); result += "}\n"; - report_->reportLineString(result); + report_->reportLine(result); } void @@ -1186,7 +1173,7 @@ ReportPath::reportJson(const PathExpanded &expanded, bool trailing_comma, std::string &result) const { - stringAppend(result, "%*s\"%s\": [\n", indent, "", path_name); + result += sta::format("{:>{}}\"{}\": [\n", "", indent, path_name); for (size_t i = expanded.startIndex(); i < expanded.size(); i++) { const Path *path = expanded.path(i); const Pin *pin = path->vertex(this)->pin(); @@ -1197,69 +1184,69 @@ ReportPath::reportJson(const PathExpanded &expanded, const MinMax *min_max = path->minMax(this); bool is_driver = network_->isDriver(pin); - stringAppend(result, "%*s {\n", indent, ""); + result += sta::format("{:>{}} {{\n", "", indent); if (inst) { - stringAppend(result, "%*s \"instance\": \"%s\",\n", - indent, "", + result += sta::format("{:>{}} \"instance\": \"{}\",\n", + "", indent, sdc_network_->pathName(inst)); Cell *cell = network_->cell(inst); if (cell) - stringAppend(result, "%*s \"cell\": \"%s\",\n", - indent, "", + result += sta::format("{:>{}} \"cell\": \"{}\",\n", + "", indent, sdc_network_->name(cell)); - stringAppend(result, "%*s \"verilog_src\": \"%s\",\n", - indent, "", + result += sta::format("{:>{}} \"verilog_src\": \"{}\",\n", + "", indent, sdc_network_->getAttribute(inst, "src").c_str()); } - stringAppend(result, "%*s \"pin\": \"%s\",\n", - indent, "", + result += sta::format("{:>{}} \"pin\": \"{}\",\n", + "", indent, sdc_network_->pathName(pin)); if (net) { - stringAppend(result, "%*s \"net\": \"%s\",\n", - indent, "", + result += sta::format("{:>{}} \"net\": \"{}\",\n", + "", indent, sdc_network_->pathName(net)); } PinSeq pins_above; hierPinsAbove(pin, network_, pins_above); if (!pins_above.empty()) { - stringAppend(result, "%*s \"hier_pins\": [\n", indent, ""); + result += sta::format("{:>{}} \"hier_pins\": [\n", "", indent); for (const Pin *hpin : pins_above) { - stringAppend(result, "%*s \"%s\"%s\n", - indent, "", + result += sta::format("{:>{}} \"{}\"{}\n", + "", indent, sdc_network_->pathName(hpin), (hpin != pins_above.back()) ? "," : ""); } - stringAppend(result, "%*s ],\n", indent, ""); + result += sta::format("{:>{}} ],\n", "", indent); } double x, y; bool exists; network_->location(pin, x, y, exists); if (exists) { - stringAppend(result, "%*s \"x\": %.9f,\n", indent, "", x); - stringAppend(result, "%*s \"y\": %.9f,\n", indent, "", y); + result += sta::format("{:>{}} \"x\": {:.9f},\n", "", indent, x); + result += sta::format("{:>{}} \"y\": {:.9f},\n", "", indent, y); } - stringAppend(result, "%*s \"arrival\": %.3e,\n", - indent, "", + result += sta::format("{:>{}} \"arrival\": {:.3e},\n", + "", indent, delayAsFloat(path->arrival())); if (is_driver) - stringAppend(result, "%*s \"capacitance\": %.3e,\n", - indent, "", + result += sta::format("{:>{}} \"capacitance\": {:.3e},\n", + "", indent, graph_delay_calc_->loadCap(pin, rf, scene, min_max)); - stringAppend(result, "%*s \"slew\": %.3e\n", - indent, "", + result += sta::format("{:>{}} \"slew\": {:.3e}\n", + "", indent, delayAsFloat(path->slew(this))); - stringAppend(result, "%*s }%s\n", - indent, "", + result += sta::format("{:>{}} }}{}\n", + "", indent, (i < expanded.size() - 1) ? "," : ""); } - stringAppend(result, "%*s]%s\n", - indent, "", + result += sta::format("{:>{}}]{}\n", + "", indent, trailing_comma ? "," : ""); } @@ -1272,7 +1259,7 @@ ReportPath::reportSlackOnlyHeader() const reportDescription("Group", line); line += ' '; reportField("Slack", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(field_description_->width() + field_total_->width() + 1); } @@ -1287,7 +1274,7 @@ ReportPath::reportSlackOnly(const PathEnd *end) const reportSpaceFieldDelay(end->dataArrivalTimeOffset(this), early_late, line); else reportSpaceFieldDelay(end->slack(this), early_late, line); - report_->reportLineString(line); + report_->reportLine(line); } //////////////////////////////////////////////////////////////// @@ -1336,7 +1323,7 @@ ReportPath::reportMpwHeaderShort() const reportField("Required", field_total_, line); line += ' '; reportField("Actual", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); line.clear(); reportDescription("Pin", line); @@ -1346,7 +1333,7 @@ ReportPath::reportMpwHeaderShort() const reportField("Width", field_total_, line); line += ' '; reportField("Slack", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(field_description_->width() + field_total_->width() * 3 + 3); } @@ -1355,14 +1342,14 @@ void ReportPath::reportShort(const MinPulseWidthCheck &check) const { std::string line; - const char *pin_name = cmd_network_->pathName(check.pin(this)); - const char *hi_low = mpwCheckHiLow(check); - auto what = stdstrPrint("%s (%s)", pin_name, hi_low); + std::string what = sta::format("{} ({})", + cmd_network_->pathName(check.pin(this)), + mpwCheckHiLow(check)); reportDescription(what.c_str(), line); reportSpaceFieldTime(check.minWidth(this), line); reportSpaceFieldDelay(check.width(this), EarlyLate::late(), line); reportSpaceSlack(check.slack(this), line); - report_->reportLineString(line); + report_->reportLine(line); } void @@ -1372,19 +1359,19 @@ ReportPath::reportVerbose(const MinPulseWidthCheck &check) const const char *pin_name = cmd_network_->pathName(check.pin(this)); line += "Pin: "; line += pin_name; - report_->reportLineString(line); + report_->reportLine(line); - report_->reportLine("Check: sequential_clock_pulse_width"); + report_->report("Check: sequential_clock_pulse_width"); reportBlankLine(); reportPathHeader(); const EarlyLate *open_el = EarlyLate::late(); const ClockEdge *open_clk_edge = check.openClkEdge(this); const Clock *open_clk = open_clk_edge->clock(); - const char *open_clk_name = open_clk->name(); - const char *open_rise_fall = asRiseFall(open_clk_edge->transition()); float open_clk_time = open_clk_edge->time(); - auto open_clk_msg = stdstrPrint("clock %s (%s edge)", open_clk_name, open_rise_fall); + std::string open_clk_msg = sta::format("clock {} ({} edge)", + open_clk->name(), + asRiseFall(open_clk_edge->transition())); reportLine(open_clk_msg.c_str(), open_clk_time, open_clk_time, open_el); Arrival open_arrival = check.openArrival(this); @@ -1398,11 +1385,11 @@ ReportPath::reportVerbose(const MinPulseWidthCheck &check) const const EarlyLate *close_el = EarlyLate::late(); const ClockEdge *close_clk_edge = check.closeClkEdge(this); const Clock *close_clk = close_clk_edge->clock(); - const char *close_clk_name = close_clk->name(); - const char *close_rise_fall = asRiseFall(close_clk_edge->transition()); float close_offset = check.closeOffset(this); float close_clk_time = close_clk_edge->time() + close_offset; - auto close_clk_msg = stdstrPrint("clock %s (%s edge)", close_clk_name, close_rise_fall); + std::string close_clk_msg = sta::format("clock {} ({} edge)", + close_clk->name(), + asRiseFall(close_clk_edge->transition())); reportLine(close_clk_msg.c_str(), close_clk_time, close_clk_time, close_el); Arrival close_arrival = delaySum(check.closeArrival(this), close_offset, this); @@ -1419,8 +1406,8 @@ ReportPath::reportVerbose(const MinPulseWidthCheck &check) const reportDashLine(); float min_width = check.minWidth(this); - const char *hi_low = mpwCheckHiLow(check); - auto rpw_msg = stdstrPrint("required pulse width (%s)", hi_low); + std::string rpw_msg = sta::format("required pulse width ({})", + mpwCheckHiLow(check)); reportLine(rpw_msg.c_str(), min_width, EarlyLate::early()); reportLine("actual pulse width", check.width(this), EarlyLate::early()); reportDashLine(); @@ -1484,7 +1471,7 @@ ReportPath::reportPeriodHeaderShort() const reportField("Min", field_total_, line); line += ' '; reportField("", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); line.clear(); reportDescription("Pin", line); @@ -1494,7 +1481,7 @@ ReportPath::reportPeriodHeaderShort() const reportField("Period", field_total_, line); line += ' '; reportField("Slack", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(field_description_->width() + field_total_->width() * 3 + 3); } @@ -1508,7 +1495,7 @@ ReportPath::reportShort(const MinPeriodCheck &check) const reportSpaceFieldDelay(check.period(), EarlyLate::early(), line); reportSpaceFieldDelay(check.minPeriod(this), EarlyLate::early(), line); reportSpaceSlack(check.slack(this), line); - report_->reportLineString(line); + report_->reportLine(line); } void @@ -1518,7 +1505,7 @@ ReportPath::reportVerbose(const MinPeriodCheck &check) const const char *pin_name = cmd_network_->pathName(check.pin()); line += "Pin: "; line += pin_name; - report_->reportLineString(line); + report_->reportLine(line); reportLine("period", check.period(), EarlyLate::early()); reportLine("min period", -check.minPeriod(this), EarlyLate::early()); @@ -1558,7 +1545,7 @@ ReportPath::reportMaxSkewHeaderShort() const reportField("Actual", field_total_, line); line += ' '; reportField("", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); line.clear(); reportDescription("Pin", line); @@ -1568,7 +1555,7 @@ ReportPath::reportMaxSkewHeaderShort() const reportField("Skew", field_total_, line); line += ' '; reportField("Slack", field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(field_description_->width() + field_total_->width() * 3 + 3); } @@ -1578,36 +1565,33 @@ ReportPath::reportShort(const MaxSkewCheck &check) const { std::string line; Pin *clk_pin = check.clkPin(this); - const char *clk_pin_name = network_->pathName(clk_pin); TimingArc *check_arc = check.checkArc(); - auto what = stdstrPrint("%s (%s->%s)", - clk_pin_name, - check_arc->fromEdge()->to_string().c_str(), - check_arc->toEdge()->to_string().c_str()); + std::string what = sta::format("{} ({}->{})", + network_->pathName(clk_pin), + check_arc->fromEdge()->to_string(), + check_arc->toEdge()->to_string()); reportDescription(what.c_str(), line); const EarlyLate *early_late = EarlyLate::early(); reportSpaceFieldDelay(check.maxSkew(this), early_late, line); reportSpaceFieldDelay(check.skew(this), early_late, line); reportSpaceSlack(check.slack(this), line); - report_->reportLineString(line); + report_->reportLine(line); } void ReportPath::reportVerbose(const MaxSkewCheck &check) const { std::string line; - const char *clk_pin_name = cmd_network_->pathName(check.clkPin(this)); line += "Constrained Pin: "; - line += clk_pin_name; - report_->reportLineString(line); + line += cmd_network_->pathName(check.clkPin(this)); + report_->reportLine(line); - const char *ref_pin_name = cmd_network_->pathName(check.refPin(this)); line = "Reference Pin: "; - line += ref_pin_name; - report_->reportLineString(line); + line += cmd_network_->pathName(check.refPin(this)); + report_->reportLine(line); line = "Check: max_skew"; - report_->reportLineString(line); + report_->reportLine(line); reportBlankLine(); reportPathHeader(); @@ -1680,7 +1664,7 @@ ReportPath::reportLimitShortHeader(const ReportField *field) const reportField(field->title(), field, line); line += ' '; reportField("Slack", field, line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(field_description_->width() + field->width() * 3 + 3); } @@ -1704,7 +1688,7 @@ ReportPath::reportLimitShort(const ReportField *field, line += (slack >= 0.0) ? " (MET)" : " (VIOLATED)"; - report_->reportLineString(line); + report_->reportLine(line); } void @@ -1731,19 +1715,19 @@ ReportPath::reportLimitVerbose(const ReportField *field, line += scene->name(); line += ")"; } - report_->reportLineString(line); + report_->reportLine(line); line = min_max->to_string(); line += ' '; line += field->name(); line += ' '; reportField(limit, field, line); - report_->reportLineString(line); + report_->reportLine(line); line = field->name(); line += " "; reportField(value, field, line); - report_->reportLineString(line); + report_->reportLine(line); int name_width = strlen(field->name()) + 5; reportDashLine(name_width + field->width()); @@ -1755,7 +1739,7 @@ ReportPath::reportLimitVerbose(const ReportField *field, line += (slack >= 0.0) ? " (MET)" : " (VIOLATED)"; - report_->reportLineString(line); + report_->reportLine(line); } //////////////////////////////////////////////////////////////// @@ -1775,7 +1759,7 @@ ReportPath::reportStartpoint(const PathEnd *end, const char *pin_name = cmd_network_->pathName(pin); if (pathFromClkPin(path, pin)) { const char *clk_name = clk->name(); - auto reason = stdstrPrint("clock source '%s'", clk_name); + std::string reason = sta::format("clock source '{}'", clk_name); reportStartpoint(pin_name, reason); } else if (network_->isTopLevelPort(pin)) { @@ -1783,7 +1767,7 @@ ReportPath::reportStartpoint(const PathEnd *end, && clk != sdc->defaultArrivalClock()) { const char *clk_name = clk->name(); // Pin direction is "input" even for bidirects. - auto reason = stdstrPrint("input port clocked by %s", clk_name); + std::string reason = sta::format("input port clocked by {}", clk_name); reportStartpoint(pin_name, reason); } else @@ -1799,7 +1783,7 @@ ReportPath::reportStartpoint(const PathEnd *end, && clk_rf != clk_path->transition(this); std::string clk_name = clkName(clk, clk_inverted); const char *reg_desc = edgeRegLatchDesc(prev_edge, prev_arc); - auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); + std::string reason = sta::format("{} clocked by {}", reg_desc, clk_name); reportStartpoint(inst_name, reason); } else { @@ -1811,8 +1795,8 @@ ReportPath::reportStartpoint(const PathEnd *end, if (clk_edge) { Clock *clk = clk_edge->clock(); if (clk != sdc->defaultArrivalClock()) { - const char *clk_name = clk->name(); - auto reason = stdstrPrint("internal path startpoint clocked by %s", clk_name); + std::string reason = sta::format("internal path startpoint clocked by {}", + clk->name()); reportStartpoint(pin_name, reason); } else @@ -1912,7 +1896,7 @@ ReportPath::reportStartEndPoint(const char *pt, line = key; line += ": "; line += pt; - report_->reportLineString(line); + report_->reportLine(line); line.clear(); for (unsigned i = 0; i < strlen(key); i++) @@ -1921,7 +1905,7 @@ ReportPath::reportStartEndPoint(const char *pt, line += " ("; line += reason; line += ")"; - report_->reportLineString(line); + report_->reportLine(line); } else { line = key; @@ -1930,7 +1914,7 @@ ReportPath::reportStartEndPoint(const char *pt, line += " ("; line += reason; line += ")"; - report_->reportLineString(line); + report_->reportLine(line); } } @@ -1941,22 +1925,22 @@ ReportPath::reportGroup(const PathEnd *end) const line = "Path Group: "; PathGroup *group = end->pathGroup(); line += group ? group->name() : "(none)"; - report_->reportLineString(line); + report_->reportLine(line); line = "Path Type: "; line += end->minMax(this)->to_string(); - report_->reportLineString(line); + report_->reportLine(line); if (modes_.size() > 1) { line = "Mode: "; line += end->path()->mode(this)->name(); - report_->reportLineString(line); + report_->reportLine(line); } if (multiScene()) { line = "Corner: "; line += end->path()->scene(this)->name(); - report_->reportLineString(line); + report_->reportLine(line); } } @@ -1965,7 +1949,7 @@ ReportPath::reportGroup(const PathEnd *end) const std::string ReportPath::checkRoleReason(const PathEnd *end) const { - return stdstrPrint("%s time", end->checkRole(this)->to_string().c_str()); + return sta::format("{} time", end->checkRole(this)->to_string()); } std::string @@ -2348,7 +2332,7 @@ ReportPath::reportClkLine(const Clock *clk, const MinMax *min_max) const { const char *rise_fall = asRiseFall(clk_rf); - auto clk_msg = stdstrPrint("clock %s (%s edge)", clk_name, rise_fall); + std::string clk_msg = sta::format("clock {} ({} edge)", clk_name, rise_fall); if (clk->isPropagated()) reportLine(clk_msg.c_str(), delayDiff(clk_time, prev_time, this), @@ -2621,7 +2605,7 @@ ReportPath::reportPath(const Path *path) const case ReportPathFormat::endpoint: case ReportPathFormat::summary: case ReportPathFormat::slack_only: - report_->reportLine("Format not supported."); + report_->report("Format not supported."); break; } } @@ -3003,7 +2987,7 @@ ReportPath::descriptionField(const Pin *pin) const Instance *inst = network_->instance(pin); name2 = network_->cellName(inst); } - return stdstrPrint("%s (%s)", pin_name, name2); + return sta::format("{} ({})", pin_name, name2); } std::string @@ -3011,14 +2995,14 @@ ReportPath::descriptionNet(const Pin *pin) const { if (network_->isTopLevelPort(pin)) { const char *pin_name = cmd_network_->pathName(pin); - return stdstrPrint("%s (net)", pin_name); + return sta::format("{} (net)", pin_name); } else { Net *net = network_->net(pin); if (net) { Net *highest_net = network_->highestNetAbove(net); const char *net_name = cmd_network_->pathName(highest_net); - return stdstrPrint("%s (net)", net_name); + return sta::format("{} (net)", net_name); } else return "(unconnected)"; @@ -3141,7 +3125,7 @@ ReportPath::reportPathHeader() const } } trimRight(line); - report_->reportLineString(line); + report_->reportLine(line); reportDashLine(); } @@ -3247,9 +3231,9 @@ ReportPath::reportLine(const char *what, if (fanout == field_blank_) reportFieldBlank(field, line); else - line += stdstrPrint("%*d", - field_fanout_->width(), - static_cast(fanout)); + line += sta::format("{:{}}", + static_cast(fanout), + field_fanout_->width()); } else if (field == field_capacitance_) reportField(cap, field, line); @@ -3289,7 +3273,7 @@ ReportPath::reportLine(const char *what, // Trim trailing spaces and report the line. std::string line_stdstr = line; trimRight(line_stdstr); - report_->reportLineString(line_stdstr.c_str()); + report_->reportLine(line_stdstr); } //////////////////////////////////////////////////////////////// @@ -3325,7 +3309,7 @@ ReportPath::reportLineTotal1(const char *what, reportFieldDelayMinus(incr, early_late, field_total_, line); else reportFieldDelay(incr, early_late, field_total_, line); - report_->reportLineString(line); + report_->reportLine(line); } void @@ -3372,11 +3356,11 @@ ReportPath::reportFieldTime(float value, if (delayAsFloat(value) == field_blank_) reportFieldBlank(field, line); else { - const char *str = units_->timeUnit()->asString(value, digits_); - if (stringEq(str, minus_zero_)) + std::string str = units_->timeUnit()->asString(value, digits_); + if (str == minus_zero_) // Filter "-0.00" fields. str = plus_zero_; - reportField(str, field, line); + reportField(str.c_str(), field, line); } } @@ -3402,11 +3386,11 @@ ReportPath::reportTotalDelay(const Delay &value, const EarlyLate *early_late, std::string &line) const { - const char *str = delayAsString(value, early_late, digits_, this); - if (stringEq(str, minus_zero_)) + std::string str = delayAsString(value, early_late, digits_, this); + if (str == minus_zero_) // Filter "-0.00" fields. str = plus_zero_; - reportField(str, field_total_, line); + reportField(str.c_str(), field_total_, line); } // Total time always with leading minus sign. @@ -3420,12 +3404,12 @@ ReportPath::reportFieldDelayMinus(const Delay &value, reportFieldBlank(field, line); else { // Opposite min/max for negative value. - const char *str = delayAsString(delayDiff(delay_zero, value, this), + std::string str = delayAsString(delayDiff(delay_zero, value, this), early_late->opposite(), digits_, this); - if (stringEq(str, plus_zero_)) + if (str == plus_zero_) // Force leading minus sign. str = minus_zero_; - reportField(str, field, line); + reportField(str.c_str(), field, line); } } @@ -3438,11 +3422,11 @@ ReportPath::reportFieldDelay(const Delay &value, if (value.mean() == field_blank_) reportFieldBlank(field, line); else { - const char *str = delayAsString(value, early_late, digits_, this); - if (stringEq(str, minus_zero_)) + std::string str = delayAsString(value, early_late, digits_, this); + if (str == minus_zero_) // Filter "-0.00" fields. str = plus_zero_; - reportField(str, field, line); + reportField(str.c_str(), field, line); } } @@ -3456,13 +3440,12 @@ ReportPath::reportField(float value, else { Unit *unit = field->unit(); if (unit) { - const char *value_str = unit->asString(value, digits_); - reportField(value_str, field, line); + std::string value_str = unit->asString(value, digits_); + reportField(value_str.c_str(), field, line); } else { // fanout - std::string value_str; - stringPrint(value_str, "%.0f", value); + std::string value_str = sta::format("{:.0f}", value); reportField(value_str.c_str(), field, line); } } @@ -3499,7 +3482,7 @@ ReportPath::reportDashLine() const } } line += "------"; - report_->reportLineString(line); + report_->reportLine(line); } void @@ -3508,7 +3491,7 @@ ReportPath::reportDashLine(int line_width) const std::string line; for (int i = 0; i < line_width; i++) line += '-'; - report_->reportLineString(line); + report_->reportLine(line); } void diff --git a/search/ReportPath.hh b/search/ReportPath.hh index cad81c74..cec91ba7 100644 --- a/search/ReportPath.hh +++ b/search/ReportPath.hh @@ -491,11 +491,13 @@ protected: ReportField *field_src_attr_; ReportField *field_edge_; ReportField *field_case_; - static constexpr float field_blank_ = -1; - int field_width_extra_; - const char *plus_zero_; - const char *minus_zero_; + std::string plus_zero_; + std::string minus_zero_; + + int field_width_extra_; + static constexpr float field_blank_ = -1; + static const float field_skip_; }; class ReportField diff --git a/search/Search.cc b/search/Search.cc index eeafaace..ae6bbfbf 100644 --- a/search/Search.cc +++ b/search/Search.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 "Search.hh" @@ -28,7 +28,7 @@ #include "ContainerHelpers.hh" #include "Mutex.hh" -#include "Report.hh" +#include "Report.hh" #include "Debug.hh" #include "Stats.hh" #include "Fuzzy.hh" @@ -89,11 +89,9 @@ EvalPred::searchThru(Edge *edge, { const TimingRole *role = edge->role(); return SearchPred0::searchThru(edge, mode) - && (sta_->variables()->dynamicLoopBreaking() - || !edge->isDisabledLoop()) - && (search_thru_latches_ - || role->isLatchDtoQ() - || sta_->latches()->latchDtoQState(edge, mode) == LatchEnableState::open); + && (sta_->variables()->dynamicLoopBreaking() || !edge->isDisabledLoop()) + && (search_thru_latches_ || role->isLatchDtoQ() + || sta_->latches()->latchDtoQState(edge, mode) == LatchEnableState::open); } bool @@ -103,10 +101,9 @@ EvalPred::searchTo(const Vertex *to_vertex, const Pin *to_pin = to_vertex->pin(); const Sdc *sdc = mode->sdc(); return SearchPred0::searchTo(to_vertex, mode) - && !(sdc->isLeafPinClock(to_pin) - && !sdc->isPathDelayInternalTo(to_pin)) - // Fanin paths are broken by path delay internal pin startpoints. - && !sdc->isPathDelayInternalFromBreak(to_pin); + && !(sdc->isLeafPinClock(to_pin) && !sdc->isPathDelayInternalTo(to_pin)) + // Fanin paths are broken by path delay internal pin startpoints. + && !sdc->isPathDelayInternalFromBreak(to_pin); } //////////////////////////////////////////////////////////////// @@ -130,8 +127,7 @@ bool SearchThru::searchThru(Edge *edge, const Mode *mode) const { - return EvalPred::searchThru(edge, mode) - && !edge->role()->isLatchDtoQ(); + return EvalPred::searchThru(edge, mode) && !edge->role()->isLatchDtoQ(); } //////////////////////////////////////////////////////////////// @@ -159,7 +155,6 @@ protected: TagGroupBldr *tag_bldr_; const StaState *sta_; - }; SearchAdj::SearchAdj(TagGroupBldr *tag_bldr, @@ -184,30 +179,25 @@ SearchAdj::searchThru(Edge *edge, const TimingRole *role = edge->role(); const Variables *variables = sta_->variables(); return !role->isTimingCheck() - && !role->isLatchDtoQ() - // Register/latch preset/clr edges are disabled by default. - && !(role == TimingRole::regSetClr() - && !variables->presetClrArcsEnabled()) - && !(edge->isBidirectInstPath() - && !variables->bidirectInstPathsEnabled()) - && (!edge->isDisabledLoop() - || (variables->dynamicLoopBreaking() - && hasPendingLoopPaths(edge))); + && !role->isLatchDtoQ() + // Register/latch preset/clr edges are disabled by default. + && !(role == TimingRole::regSetClr() && !variables->presetClrArcsEnabled()) + && !(edge->isBidirectInstPath() && !variables->bidirectInstPathsEnabled()) + && (!edge->isDisabledLoop() + || (variables->dynamicLoopBreaking() && hasPendingLoopPaths(edge))); } bool SearchAdj::loopEnabled(Edge *edge) const { return !edge->isDisabledLoop() - || (sta_->variables()->dynamicLoopBreaking() - && hasPendingLoopPaths(edge)); + || (sta_->variables()->dynamicLoopBreaking() && hasPendingLoopPaths(edge)); } bool SearchAdj::hasPendingLoopPaths(Edge *edge) const { - if (tag_bldr_ - && tag_bldr_->hasLoopTag()) { + if (tag_bldr_ && tag_bldr_->hasLoopTag()) { const Graph *graph = sta_->graph(); Search *search = sta_->search(); Vertex *from_vertex = edge->from(graph); @@ -218,8 +208,7 @@ SearchAdj::hasPendingLoopPaths(Edge *edge) const // does not matter. Tag *to_tag = search->thruTag(from_tag, edge, RiseFall::rise(), nullptr); if (to_tag - && (prev_tag_group == nullptr - || !prev_tag_group->hasTag(from_tag))) + && (prev_tag_group == nullptr || !prev_tag_group->hasTag(from_tag))) return true; } } @@ -243,19 +232,24 @@ Search::Search(StaState *sta) : crpr_approx_missing_requireds_(true), search_thru_(new SearchThru(this)), - search_adj_(new SearchAdj(nullptr, this)), + search_adj_(new SearchAdj(nullptr, + this)), eval_pred_(new EvalPred(this)), - + arrivals_exist_(false), arrivals_seeded_(false), invalid_arrivals_(makeVertexSet(this)), - arrival_iter_(new BfsFwdIterator(BfsIndex::arrival, nullptr, this)), + arrival_iter_(new BfsFwdIterator(BfsIndex::arrival, + nullptr, + this)), arrival_visitor_(new ArrivalVisitor(this)), requireds_exist_(false), requireds_seeded_(false), invalid_requireds_(makeVertexSet(this)), - required_iter_(new BfsBkwdIterator(BfsIndex::required, search_adj_, this)), + required_iter_(new BfsBkwdIterator(BfsIndex::required, + search_adj_, + this)), tns_exists_(false), invalid_tns_(makeVertexSet(this)), @@ -263,12 +257,14 @@ Search::Search(StaState *sta) : clk_info_set_(new ClkInfoSet(ClkInfoLess(this))), tag_capacity_(128), - tags_(new Tag*[tag_capacity_]), - tag_set_(new TagSet(tag_capacity_, TagHash(this), TagEqual(this))), + tags_(new Tag *[tag_capacity_]), + tag_set_(new TagSet(tag_capacity_, + TagHash(this), + TagEqual(this))), tag_next_(0), tag_group_capacity_(tag_capacity_), - tag_groups_(new TagGroup*[tag_group_capacity_]), + tag_groups_(new TagGroup *[tag_group_capacity_]), tag_group_set_(new TagGroupSet(tag_group_capacity_)), tag_group_next_(0), @@ -310,8 +306,8 @@ Search::~Search() deleteTags(); delete tag_set_; delete clk_info_set_; - delete [] tags_; - delete [] tag_groups_; + delete[] tags_; + delete[] tag_groups_; delete tag_group_set_; delete search_thru_; delete search_adj_; @@ -476,8 +472,8 @@ Search::deletePathsIncr(Vertex *vertex) void Search::deletePaths(Vertex *vertex) { - debugPrint(debug_, "search", 4, "delete paths %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 4, "delete paths {}", + vertex->to_string(this)); TagGroup *tag_group = tagGroup(vertex); if (tag_group) { vertex->deletePaths(); @@ -521,15 +517,10 @@ Search::findPathEnds(ExceptionFrom *from, const ModeSeq modes = Scene::modesSorted(scenes); PathEndSeq path_ends; for (Mode *mode : modes) { - PathGroups *path_groups = mode->makePathGroups(group_path_count, - endpoint_path_count, - unique_pins, unique_edges, - slack_min, slack_max, - group_names, - setup, hold, - recovery, removal, - clk_gating_setup, clk_gating_hold, - unconstrained_paths_); + PathGroups *path_groups = mode->makePathGroups( + group_path_count, endpoint_path_count, unique_pins, unique_edges, slack_min, + slack_max, group_names, setup, hold, recovery, removal, clk_gating_setup, + clk_gating_hold, unconstrained_paths_); SceneSeq mode_scenes; for (Scene *scene : scenes) { if (scene->mode() == mode) @@ -555,10 +546,7 @@ Search::findFilteredArrivals(ExceptionFrom *from, filter_from_ = from; filter_thrus_ = thrus; filter_to_ = to; - if ((from - && (from->pins() - || from->instances())) - || thrus) { + if ((from && (from->pins() || from->instances())) || thrus) { for (const Mode *mode : modes_) { Sdc *sdc = mode->sdc(); sdc->makeFilter(from ? from->clone(network_) : nullptr, @@ -583,9 +571,7 @@ Search::deleteFilteredArrivals() { if (have_filter_) { ExceptionThruSeq *thrus = filter_thrus_; - if ((filter_from_ - && (filter_from_->pins() - || filter_from_->instances())) + if ((filter_from_ && (filter_from_->pins() || filter_from_->instances())) || thrus) { for (Vertex *vertex : filtered_arrivals_) { deletePathsIncr(vertex); @@ -598,14 +584,13 @@ Search::deleteFilteredArrivals() while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); TagGroup *tag_group = tagGroup(vertex); - if (tag_group - && tag_group->hasFilterTag()) + if (tag_group && tag_group->hasFilterTag()) filtered_arrivals_.erase(vertex); } if (!filtered_arrivals_.empty()) { - report_->reportLine("Filtered verticies mismatch"); + report_->report("Filtered verticies mismatch"); for (Vertex *vertex : filtered_arrivals_) - report_->reportLine(" %s", vertex->to_string(this).c_str()); + report_->report(" {}", vertex->to_string(this)); } } filtered_arrivals_.clear(); @@ -623,8 +608,7 @@ Search::deleteFilterTagGroups() { for (TagGroupIndex i = 0; i < tag_group_next_; i++) { TagGroup *group = tag_groups_[i]; - if (group - && group->hasFilterTag()) + if (group && group->hasFilterTag()) deleteTagGroup(group); } } @@ -643,9 +627,7 @@ Search::deleteFilterTags() { for (TagIndex i = 0; i < tag_next_; i++) { Tag *tag = tags_[i]; - if (tag - && (tag->isFilter() - || tag->clkInfo()->crprPathRefsFilter())) { + if (tag && (tag->isFilter() || tag->clkInfo()->crprPathRefsFilter())) { tags_[i] = nullptr; tag_set_->erase(tag); delete tag; @@ -656,7 +638,7 @@ Search::deleteFilterTags() void Search::deleteFilterClkInfos() { - for (auto itr = clk_info_set_->cbegin(); itr != clk_info_set_->cend(); ) { + for (auto itr = clk_info_set_->cbegin(); itr != clk_info_set_->cend();) { const ClkInfo *clk_info = *itr; if (clk_info->crprPathRefsFilter()) { itr = clk_info_set_->erase(itr); @@ -680,13 +662,14 @@ Search::findFilteredArrivals(bool thru_latches) // Iterate until data arrivals at all latches stop changing. postpone_latch_outputs_ = true; enqueuePendingClkFanouts(); - for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs()) ; pass++) { + for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs()); + pass++) { if (thru_latches) enqueuePendingLatchOutputs(); - debugPrint(debug_, "search", 1, "find arrivals pass %d", pass); + debugPrint(debug_, "search", 1, "find arrivals pass {}", pass); int arrival_count = arrival_iter_->visitParallel(max_level, arrival_visitor_); deleteTagsPrev(); - debugPrint(debug_, "search", 1, "found %d arrivals", arrival_count); + debugPrint(debug_, "search", 1, "found {} arrivals", arrival_count); postpone_latch_outputs_ = false; } arrivals_exist_ = true; @@ -696,12 +679,12 @@ Search::findFilteredArrivals(bool thru_latches) void Search::deleteTagsPrev() { - for (Tag** tags: tags_prev_) - delete [] tags; + for (Tag **tags : tags_prev_) + delete[] tags; tags_prev_.clear(); - for (TagGroup** tag_groups: tag_groups_prev_) - delete [] tag_groups; + for (TagGroup **tag_groups : tag_groups_prev_) + delete[] tag_groups; tag_groups_prev_.clear(); } @@ -824,8 +807,7 @@ Search::deleteEdgeBefore(Edge *edge) bool Search::arrivalsValid() { - return arrivals_exist_ - && invalid_arrivals_.empty(); + return arrivals_exist_ && invalid_arrivals_.empty(); } void @@ -872,8 +854,8 @@ void Search::arrivalInvalid(Vertex *vertex) { if (arrivals_exist_) { - debugPrint(debug_, "search", 2, "arrival invalid %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "arrival invalid {}", + vertex->to_string(this)); if (!arrival_iter_->inQueue(vertex)) { // Lock for StaDelayCalcObserver called by delay calc threads. LockGuard lock(invalid_arrivals_lock_); @@ -951,8 +933,8 @@ void Search::requiredInvalid(Vertex *vertex) { if (requireds_exist_) { - debugPrint(debug_, "search", 2, "required invalid %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "required invalid {}", + vertex->to_string(this)); if (!required_iter_->inQueue(vertex)) { // Lock for StaDelayCalcObserver called by delay calc threads. LockGuard lock(invalid_arrivals_lock_); @@ -1020,9 +1002,10 @@ Search::findAllArrivals(bool thru_latches, arrival_visitor_->init(false, clks_only, eval_pred_); // Iterate until data arrivals at all latches stop changing. postpone_latch_outputs_ = true; - for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs()); pass++) { + for (int pass = 1; pass == 1 || (thru_latches && havePendingLatchOutputs()); + pass++) { enqueuePendingLatchOutputs(); - debugPrint(debug_, "search", 1, "find arrivals pass %d", pass); + debugPrint(debug_, "search", 1, "find arrivals pass {}", pass); findArrivals1(levelize_->maxLevel()); if (pass > 2) postpone_latch_outputs_ = false; @@ -1045,8 +1028,8 @@ void Search::enqueuePendingLatchOutputs() { for (Vertex *latch_vertex : pending_latch_outputs_) { - debugPrint(debug_, "search", 2, "enqueue latch output %s", - latch_vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "enqueue latch output {}", + latch_vertex->to_string(this)); arrival_iter_->enqueue(latch_vertex); } clearPendingLatchOutputs(); @@ -1056,8 +1039,8 @@ void Search::enqueuePendingClkFanouts() { for (Vertex *vertex : pending_clk_endpoints_) { - debugPrint(debug_, "search", 2, "enqueue clk fanout %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "enqueue clk fanout {}", + vertex->to_string(this)); arrival_iter_->enqueueAdjacentVertices(vertex, search_adj_); } pending_clk_endpoints_.clear(); @@ -1086,7 +1069,7 @@ Search::findArrivals(Level level) void Search::findArrivals1(Level level) { - debugPrint(debug_, "search", 1, "find arrivals to level %d", level); + debugPrint(debug_, "search", 1, "find arrivals to level {}", level); findArrivalsSeed(); Stats stats(debug_, report_); int arrival_count = arrival_iter_->visitParallel(level, arrival_visitor_); @@ -1095,7 +1078,7 @@ Search::findArrivals1(Level level) deleteUnusedTagGroups(); stats.report("Find arrivals"); arrivals_exist_ = true; - debugPrint(debug_, "search", 1, "found %d arrivals", arrival_count); + debugPrint(debug_, "search", 1, "found {} arrivals", arrival_count); } void @@ -1119,7 +1102,9 @@ Search::findArrivalsSeed() //////////////////////////////////////////////////////////////// ArrivalVisitor::ArrivalVisitor(const StaState *sta) : - PathVisitor(nullptr, false, sta) + PathVisitor(nullptr, + false, + sta) { init0(); init(true, false, nullptr); @@ -1129,7 +1114,9 @@ ArrivalVisitor::ArrivalVisitor(const StaState *sta) : ArrivalVisitor::ArrivalVisitor(bool always_to_endpoints, SearchPred *pred, const StaState *sta) : - PathVisitor(pred, true, sta) + PathVisitor(pred, + true, + sta) { init0(); init(always_to_endpoints, false, pred); @@ -1154,7 +1141,6 @@ ArrivalVisitor::init(bool always_to_endpoints, crpr_active_ = variables_->crprEnabled(); } - VertexVisitor * ArrivalVisitor::copy() const { @@ -1184,21 +1170,19 @@ ArrivalVisitor::setAlwaysToEndpoints(bool to_endpoints) void ArrivalVisitor::visit(Vertex *vertex) { - debugPrint(debug_, "search", 2, "find arrivals %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "find arrivals {}", + vertex->to_string(this)); Pin *pin = vertex->pin(); tag_bldr_->init(vertex); has_fanin_one_ = graph_->hasFaninOne(vertex); - if (crpr_active_ - && !has_fanin_one_) + if (crpr_active_ && !has_fanin_one_) tag_bldr_no_crpr_->init(vertex); visitFaninPaths(vertex); if (crpr_active_ && search_->crprPathPruningEnabled() // No crpr for ideal clocks. - && tag_bldr_->hasPropagatedClk() - && !has_fanin_one_) + && tag_bldr_->hasPropagatedClk() && !has_fanin_one_) pruneCrprArrivals(); // Insert paths that originate here. @@ -1209,14 +1193,11 @@ ArrivalVisitor::visit(Vertex *vertex) // If vertex is a latch data input arrival that changed from the // previous eval pass enqueue the latch outputs to be re-evaled on the // next pass. - if (arrivals_changed - && network_->isLatchData(pin)) + if (arrivals_changed && network_->isLatchData(pin)) search_->enqueueLatchDataOutputs(vertex); - if ((always_to_endpoints_ - || arrivals_changed)) { - if (clks_only_ - && vertex->isRegClk()) { + if ((always_to_endpoints_ || arrivals_changed)) { + if (clks_only_ && vertex->isRegClk()) { debugPrint(debug_, "search", 3, "postponing clk fanout"); search_->postponeClkFanouts(vertex); } @@ -1244,22 +1225,18 @@ ArrivalVisitor::seedArrivals(Vertex *vertex) if (search_->isInputArrivalSrchStart(vertex)) search_->seedInputArrival(pin, vertex, mode, tag_bldr_); // Do not apply input delay to bidir load vertices. - if (!(network_->direction(pin)->isBidirect() - && !vertex->isBidirectDriver()) - && !network_->isTopLevelPort(pin) - && sdc->hasInputDelay(pin)) + if (!(network_->direction(pin)->isBidirect() && !vertex->isBidirectDriver()) + && !network_->isTopLevelPort(pin) && sdc->hasInputDelay(pin)) search_->seedInputSegmentArrival(pin, vertex, mode, tag_bldr_); - if (sdc->isPathDelayInternalFrom(pin) - && !sdc->isLeafPinClock(pin)) + if (sdc->isPathDelayInternalFrom(pin) && !sdc->isLeafPinClock(pin)) // set_min/max_delay -from internal pin. search_->makeUnclkedPaths(vertex, false, true, tag_bldr_, mode); if (search_->isSrchRoot(vertex, mode)) { bool is_reg_clk = vertex->isRegClk(); if (is_reg_clk // Internal roots isolated by disabled pins are seeded with no clock. - || (search_->unconstrainedPaths() - && !network_->isTopLevelPort(pin))) { - debugPrint(debug_, "search", 2, "arrival seed unclked root %s", + || (search_->unconstrainedPaths() && !network_->isTopLevelPort(pin))) { + debugPrint(debug_, "search", 2, "arrival seed unclked root {}", network_->pathName(pin)); search_->makeUnclkedPaths(vertex, is_reg_clk, false, tag_bldr_, mode); } @@ -1270,7 +1247,7 @@ ArrivalVisitor::seedArrivals(Vertex *vertex) // These paths are required to report path delays from unclocked registers // For example, "set_max_delay -to" from an unclocked source register. if (vertex->isRegClk() && !is_clk) { - debugPrint(debug_, "search", 2, "arrival seed unclked reg clk %s", + debugPrint(debug_, "search", 2, "arrival seed unclked reg clk {}", network_->pathName(pin)); search_->makeUnclkedPaths(vertex, true, false, tag_bldr_, mode); } @@ -1286,8 +1263,7 @@ ArrivalVisitor::constrainedRequiredsInvalid(Vertex *vertex, bool is_clk) { Pin *pin = vertex->pin(); - if (network_->isLoad(pin) - && search_->requiredsExist()) { + if (network_->isLoad(pin) && search_->requiredsExist()) { if (is_clk && network_->isCheckClk(pin)) { VertexOutEdgeIterator edge_iter(vertex, graph_); while (edge_iter.hasNext()) { @@ -1326,8 +1302,7 @@ Search::arrivalsChanged(Vertex *vertex, Path *paths1 = vertex->paths(); if (paths1) { TagGroup *tag_group = tagGroup(vertex); - if (tag_group == nullptr - || tag_group->pathCount() != tag_bldr->pathCount()) + if (tag_group == nullptr || tag_group->pathCount() != tag_bldr->pathCount()) return true; for (auto const [tag1, path_index1] : *tag_group->pathIndexMap()) { Path *path1 = &paths1[path_index1]; @@ -1362,16 +1337,12 @@ ArrivalVisitor::visitFromToPath(const Pin * /* from_pin */, Arrival &to_arrival, const MinMax *min_max) { - debugPrint(debug_, "search", 3, " %s", - from_vertex->to_string(this).c_str()); - debugPrint(debug_, "search", 3, " %s -> %s %s", - from_rf->shortName(), - to_rf->shortName(), - min_max->to_string().c_str()); - debugPrint(debug_, "search", 3, " from tag: %s", - from_tag->to_string(this).c_str()); - debugPrint(debug_, "search", 3, " to tag : %s", - to_tag->to_string(this).c_str()); + debugPrint(debug_, "search", 3, " {}", from_vertex->to_string(this)); + debugPrint(debug_, "search", 3, " {} -> {} {}", from_rf->shortName(), + to_rf->shortName(), min_max->to_string()); + debugPrint(debug_, "search", 3, " from tag: {}", + from_tag->to_string(this)); + debugPrint(debug_, "search", 3, " to tag : {}", to_tag->to_string(this)); const ClkInfo *to_clk_info = to_tag->clkInfo(); bool to_is_clk = to_tag->isClock(); Path *match; @@ -1379,16 +1350,13 @@ ArrivalVisitor::visitFromToPath(const Pin * /* from_pin */, tag_bldr_->tagMatchPath(to_tag, match, path_index); if (match == nullptr || delayGreater(to_arrival, match->arrival(), min_max, this)) { - debugPrint(debug_, "search", 3, " %s + %s = %s %s %s", - delayAsString(from_arrival, this), - delayAsString(arc_delay, this), - delayAsString(to_arrival, this), - min_max == MinMax::max() ? ">" : "<", + debugPrint(debug_, "search", 3, " {} + {} = {} {} {}", + delayAsString(from_arrival, this), delayAsString(arc_delay, this), + delayAsString(to_arrival, this), min_max == MinMax::max() ? ">" : "<", match ? delayAsString(match->arrival(), this) : "MIA"); - tag_bldr_->setMatchPath(match, path_index, to_tag, to_arrival, from_path, edge, arc); - if (crpr_active_ - && !has_fanin_one_ - && to_clk_info->hasCrprClkPin() + tag_bldr_->setMatchPath(match, path_index, to_tag, to_arrival, from_path, edge, + arc); + if (crpr_active_ && !has_fanin_one_ && to_clk_info->hasCrprClkPin() && !to_is_clk) { tag_bldr_no_crpr_->tagMatchPath(to_tag, match, path_index); if (match == nullptr @@ -1406,13 +1374,12 @@ ArrivalVisitor::pruneCrprArrivals() { CheckCrpr *crpr = search_->checkCrpr(); PathIndexMap &path_index_map = tag_bldr_->pathIndexMap(); - for (auto path_itr = path_index_map.cbegin(); path_itr != path_index_map.cend(); ) { + for (auto path_itr = path_index_map.cbegin(); path_itr != path_index_map.cend();) { Tag *tag = path_itr->first; size_t path_index = path_itr->second; const ClkInfo *clk_info = tag->clkInfo(); bool deleted_tag = false; - if (!tag->isClock() - && clk_info->hasCrprClkPin()) { + if (!tag->isClock() && clk_info->hasCrprClkPin()) { const MinMax *min_max = tag->minMax(); Path *path_no_crpr = tag_bldr_no_crpr_->tagMatchPath(tag); if (path_no_crpr) { @@ -1422,7 +1389,7 @@ ArrivalVisitor::pruneCrprArrivals() Arrival max_arrival_max_crpr = (min_max == MinMax::max()) ? delayDiff(max_arrival, max_crpr, this) : delaySum(max_arrival, max_crpr, this); - debugPrint(debug_, "search", 4, " cmp %s %s - %s = %s", + debugPrint(debug_, "search", 4, " cmp {} {} - {} = {}", tag->to_string(this).c_str(), delayAsString(max_arrival, this), delayAsString(max_crpr, this), @@ -1432,9 +1399,9 @@ ArrivalVisitor::pruneCrprArrivals() // does not match the path min/max. if (delayGreater(max_arrival_max_crpr, arrival, min_max, this) && clk_info_no_crpr->crprClkPath(this)->minMax(this) - == clk_info->crprClkPath(this)->minMax(this)) { - debugPrint(debug_, "search", 3, " pruned %s", - tag->to_string(this).c_str()); + == clk_info->crprClkPath(this)->minMax(this)) { + debugPrint(debug_, "search", 3, " pruned {}", + tag->to_string(this)); path_itr = path_index_map.erase(path_itr); deleted_tag = true; } @@ -1547,24 +1514,21 @@ Search::seedClkArrivals(const Pin *pin, ClockSet *clks = sdc->findLeafPinClocks(pin); if (clks) { for (const Clock *clk : *clks) { - debugPrint(debug_, "search", 2, "arrival seed clk %s/%s pin %s", - mode->name().c_str(), - clk->name(), - network_->pathName(pin)); + debugPrint(debug_, "search", 2, "arrival seed clk {}/{} pin {}", + mode->name(), clk->name(), network_->pathName(pin)); for (Scene *scene : mode->scenes()) { for (const MinMax *min_max : MinMax::range()) { for (const RiseFall *rf : RiseFall::range()) { const ClockEdge *clk_edge = clk->edge(rf); const EarlyLate *early_late = min_max; - if (clk->isGenerated() - && clk->masterClk() == nullptr) - seedClkDataArrival(pin, rf, clk, clk_edge, min_max, - 0.0, scene, tag_bldr); + if (clk->isGenerated() && clk->masterClk() == nullptr) + seedClkDataArrival(pin, rf, clk, clk_edge, min_max, 0.0, scene, + tag_bldr); else { - Arrival insertion = clockInsertion(clk, pin, rf, min_max, - early_late, mode); - seedClkArrival(pin, rf, clk, clk_edge, min_max, - insertion, scene, tag_bldr); + Arrival insertion = + clockInsertion(clk, pin, rf, min_max, early_late, mode); + seedClkArrival(pin, rf, clk, clk_edge, min_max, insertion, scene, + tag_bldr); } } } @@ -1588,12 +1552,10 @@ Search::seedClkArrival(const Pin *pin, float latency = 0.0; bool latency_exists; // Check for clk pin latency. - sdc->clockLatency(clk, pin, rf, min_max, - latency, latency_exists); + sdc->clockLatency(clk, pin, rf, min_max, latency, latency_exists); if (!latency_exists) { // Check for clk latency (lower priority). - sdc->clockLatency(clk, rf, min_max, - latency, latency_exists); + sdc->clockLatency(clk, rf, min_max, latency, latency_exists); if (latency_exists) { // Propagated pin overrides latency on clk. if (sdc->isPropagatedClock(pin)) { @@ -1603,8 +1565,7 @@ Search::seedClkArrival(const Pin *pin, } } else - is_propagated = sdc->isPropagatedClock(pin) - || clk->isPropagated(); + is_propagated = sdc->isPropagatedClock(pin) || clk->isPropagated(); } const ClockUncertainties *uncertainties = sdc->clockUncertainties(pin); @@ -1613,9 +1574,8 @@ Search::seedClkArrival(const Pin *pin, // Propagate liberty "pulse_clock" transition to transitive fanout. LibertyPort *port = network_->libertyPort(pin); const RiseFall *pulse_clk_sense = (port ? port->pulseClkSense() : nullptr); - const ClkInfo *clk_info = findClkInfo(scene, clk_edge, pin, is_propagated, - nullptr, false, - pulse_clk_sense, insertion, latency, + const ClkInfo *clk_info = findClkInfo(scene, clk_edge, pin, is_propagated, nullptr, + false, pulse_clk_sense, insertion, latency, uncertainties, min_max, nullptr); // Only false_paths -from apply to clock tree pins. ExceptionStateSet *states = nullptr; @@ -1635,7 +1595,7 @@ Search::seedClkDataArrival(const Pin *pin, Arrival insertion, Scene *scene, TagGroupBldr *tag_bldr) -{ +{ Tag *tag = clkDataTag(pin, clk, rf, clk_edge, insertion, min_max, scene); if (tag) { // Data arrivals include insertion delay. @@ -1656,12 +1616,11 @@ Search::clkDataTag(const Pin *pin, Sdc *sdc = scene->sdc(); ExceptionStateSet *states = nullptr; if (sdc->exceptionFromStates(pin, rf, clk, rf, min_max, states)) { - bool is_propagated = (clk->isPropagated() - || sdc->isPropagatedClock(pin)); - const ClkInfo *clk_info = findClkInfo(scene, clk_edge, pin, is_propagated, - insertion, min_max); - return findTag(scene, rf, min_max, clk_info, false, nullptr, false, - states, true, nullptr); + bool is_propagated = (clk->isPropagated() || sdc->isPropagatedClock(pin)); + const ClkInfo *clk_info = + findClkInfo(scene, clk_edge, pin, is_propagated, insertion, min_max); + return findTag(scene, rf, min_max, clk_info, false, nullptr, false, states, true, + nullptr); } else return nullptr; @@ -1748,8 +1707,7 @@ Search::isInputArrivalSrchStart(Vertex *vertex) PortDirection *dir = network_->direction(pin); bool is_top_level_port = network_->isTopLevelPort(pin); return (is_top_level_port - && (dir->isInput() - || (dir->isBidirect() && vertex->isBidirectDriver()))) ; + && (dir->isInput() || (dir->isBidirect() && vertex->isBidirectDriver()))); } void @@ -1792,10 +1750,9 @@ Search::seedInputArrival1(const Pin *pin, // Input arrival wrt a clock source pin is the clock insertion // delay (source latency), but arrivals wrt other clocks // propagate. - if (pin_clks == nullptr - || !pin_clks->contains(input_clk)) - seedInputDelayArrival(pin, vertex, input_delay, is_segment_start, - mode, tag_bldr); + if (pin_clks == nullptr || !pin_clks->contains(input_clk)) + seedInputDelayArrival(pin, vertex, input_delay, is_segment_start, mode, + tag_bldr); } } } @@ -1809,17 +1766,14 @@ Search::seedInputDelayArrival(const Pin *pin, TagGroupBldr *tag_bldr) { debugPrint(debug_, "search", 2, - input_delay - ? "arrival seed input arrival %s" - : "arrival seed input %s", + input_delay ? "arrival seed input arrival {}" : "arrival seed input {}", vertex->to_string(this).c_str()); const ClockEdge *clk_edge = nullptr; const Pin *ref_pin = nullptr; const Sdc *sdc = mode->sdc(); if (input_delay) { clk_edge = input_delay->clkEdge(); - if (clk_edge == nullptr - && variables_->useDefaultArrivalClock()) + if (clk_edge == nullptr && variables_->useDefaultArrivalClock()) clk_edge = sdc->defaultArrivalClockEdge(); ref_pin = input_delay->refPin(); } @@ -1835,12 +1789,10 @@ Search::seedInputDelayArrival(const Pin *pin, while (ref_path_iter.hasNext()) { Path *ref_path = ref_path_iter.next(); if (ref_path->isClock(this) - && (clk == nullptr - || ref_path->clock(this) == clk)) { + && (clk == nullptr || ref_path->clock(this) == clk)) { float ref_arrival, ref_insertion, ref_latency; - inputDelayRefPinArrival(ref_path, ref_path->clkEdge(this), min_max, - sdc, ref_arrival, ref_insertion, - ref_latency); + inputDelayRefPinArrival(ref_path, ref_path->clkEdge(this), min_max, sdc, + ref_arrival, ref_insertion, ref_latency); seedInputDelayArrival(pin, input_delay, ref_path->clkEdge(this), ref_arrival, ref_insertion, ref_latency, is_segment_start, min_max, scene, tag_bldr); @@ -1852,12 +1804,12 @@ Search::seedInputDelayArrival(const Pin *pin, else { for (const MinMax *min_max : MinMax::range()) { float clk_arrival, clk_insertion, clk_latency; - inputDelayClkArrival(input_delay, clk_edge, min_max, mode, - clk_arrival, clk_insertion, clk_latency); + inputDelayClkArrival(input_delay, clk_edge, min_max, mode, clk_arrival, + clk_insertion, clk_latency); for (Scene *scene : mode->scenes()) { - seedInputDelayArrival(pin, input_delay, clk_edge, - clk_arrival, clk_insertion, clk_latency, - is_segment_start, min_max, scene, tag_bldr); + seedInputDelayArrival(pin, input_delay, clk_edge, clk_arrival, clk_insertion, + clk_latency, is_segment_start, min_max, scene, + tag_bldr); } } } @@ -1911,15 +1863,13 @@ Search::seedInputDelayArrival(const Pin *pin, bool exists; input_delay->delays()->value(rf, min_max, delay, exists); if (exists) - seedInputDelayArrival(pin, rf, clk_arrival + delay, - input_delay, clk_edge, - clk_insertion, clk_latency, is_segment_start, - min_max, scene, tag_bldr); + seedInputDelayArrival(pin, rf, clk_arrival + delay, input_delay, clk_edge, + clk_insertion, clk_latency, is_segment_start, min_max, + scene, tag_bldr); } else - seedInputDelayArrival(pin, rf, 0.0, nullptr, clk_edge, - clk_insertion, clk_latency, is_segment_start, - min_max, scene, tag_bldr); + seedInputDelayArrival(pin, rf, 0.0, nullptr, clk_edge, clk_insertion, + clk_latency, is_segment_start, min_max, scene, tag_bldr); } } @@ -1961,13 +1911,11 @@ Search::inputDelayClkArrival(InputDelay *input_delay, const RiseFall *clk_rf = clk_edge->transition(); if (!input_delay->sourceLatencyIncluded()) { const EarlyLate *early_late = min_max; - clk_insertion = delayAsFloat(clockInsertion(clk, clk->defaultPin(), - clk_rf, min_max, - early_late, mode)); + clk_insertion = delayAsFloat( + clockInsertion(clk, clk->defaultPin(), clk_rf, min_max, early_late, mode)); clk_arrival += clk_insertion; } - if (!clk->isPropagated() - && !input_delay->networkLatencyIncluded()) { + if (!clk->isPropagated() && !input_delay->networkLatencyIncluded()) { clk_latency = mode->sdc()->clockLatency(clk, clk_rf, min_max); clk_arrival += clk_latency; } @@ -2001,21 +1949,19 @@ Search::inputDelayTag(const Pin *pin, Sdc *sdc = scene->sdc(); ExceptionStateSet *states = nullptr; Tag *tag = nullptr; - if (sdc->exceptionFromStates(pin,rf,clk,clk_rf,min_max,states)) { - const ClkInfo *clk_info = findClkInfo(scene, clk_edge, clk_pin, - is_propagated, nullptr, - false, nullptr, clk_insertion, clk_latency, - clk_uncertainties, min_max, nullptr); - tag = findTag(scene, rf, min_max, clk_info, false, - input_delay, is_segment_start, states, true, nullptr); + if (sdc->exceptionFromStates(pin, rf, clk, clk_rf, min_max, states)) { + const ClkInfo *clk_info = + findClkInfo(scene, clk_edge, clk_pin, is_propagated, nullptr, false, nullptr, + clk_insertion, clk_latency, clk_uncertainties, min_max, nullptr); + tag = findTag(scene, rf, min_max, clk_info, false, input_delay, is_segment_start, + states, true, nullptr); } if (tag) { const ClkInfo *clk_info = tag->clkInfo(); // Check for state changes on existing tag exceptions (pending -thru pins). - tag = mutateTag(tag, pin, rf, false, clk_info, - pin, rf, false, false, is_segment_start, clk_info, - input_delay, nullptr); + tag = mutateTag(tag, pin, rf, false, clk_info, pin, rf, false, false, + is_segment_start, clk_info, input_delay, nullptr); } return tag; } @@ -2026,7 +1972,7 @@ PathVisitor::PathVisitor(const StaState *sta) : StaState(sta), pred_(sta->search()->evalPred()), - tag_cache_( nullptr) + tag_cache_(nullptr) { } @@ -2036,16 +1982,14 @@ PathVisitor::PathVisitor(SearchPred *pred, StaState(sta), pred_(pred), - tag_cache_(make_tag_cache - ? new TagSet(128, TagSet::hasher(sta), TagSet::key_equal(sta)) - : nullptr) + tag_cache_(make_tag_cache ? new TagSet(128, + TagSet::hasher(sta), + TagSet::key_equal(sta)) + : nullptr) { } -PathVisitor::~PathVisitor() -{ - delete tag_cache_; -} +PathVisitor::~PathVisitor() { delete tag_cache_; } void PathVisitor::visitFaninPaths(Vertex *to_vertex) @@ -2070,8 +2014,7 @@ PathVisitor::visitFanoutPaths(Vertex *from_vertex) Edge *edge = edge_iter.next(); Vertex *to_vertex = edge->to(graph_); const Pin *to_pin = to_vertex->pin(); - debugPrint(debug_, "search", 3, " %s", - to_vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 3, " {}", to_vertex->to_string(this)); if (!visitEdge(from_pin, from_vertex, edge, to_pin, to_vertex)) break; } @@ -2093,19 +2036,18 @@ PathVisitor::visitEdge(const Pin *from_pin, Path *from_path = from_iter.next(); const Mode *mode = from_path->mode(this); if (mode == prev_mode - || (pred_->searchFrom(from_vertex, mode) - && pred_->searchThru(edge, mode) + || (pred_->searchFrom(from_vertex, mode) && pred_->searchThru(edge, mode) && pred_->searchTo(to_vertex, mode))) { - prev_mode = mode; + prev_mode = mode; const MinMax *min_max = from_path->minMax(this); const RiseFall *from_rf = from_path->transition(this); TimingArc *arc1, *arc2; arc_set->arcsFrom(from_rf, arc1, arc2); - if (!visitArc(from_pin, from_vertex, from_rf, from_path, - edge, arc1, to_pin, to_vertex, min_max, mode)) + if (!visitArc(from_pin, from_vertex, from_rf, from_path, edge, arc1, to_pin, + to_vertex, min_max, mode)) return false; - if (!visitArc(from_pin, from_vertex, from_rf, from_path, - edge, arc2, to_pin, to_vertex, min_max, mode)) + if (!visitArc(from_pin, from_vertex, from_rf, from_path, edge, arc2, to_pin, + to_vertex, min_max, mode)) return false; } } @@ -2128,8 +2070,8 @@ PathVisitor::visitArc(const Pin *from_pin, if (arc) { const RiseFall *to_rf = arc->toEdge()->asRiseFall(); if (searchThru(from_vertex, from_rf, edge, to_vertex, to_rf, mode)) - return visitFromPath(from_pin, from_vertex, from_rf, from_path, - edge, arc, to_pin, to_vertex, to_rf, min_max); + return visitFromPath(from_pin, from_vertex, from_rf, from_path, edge, arc, + to_pin, to_vertex, to_rf, min_max); } return true; } @@ -2160,7 +2102,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, DcalcAPIndex dcalc_ap = from_path->dcalcAnalysisPtIndex(this); Arrival to_arrival; if (from_clk_info->isGenClkSrcPath()) { - if (!sdc->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf) + if (!sdc->clkStopPropagation(clk, from_pin, from_rf, to_pin, to_rf) && (variables_->clkThruTristateEnabled() || !(role == TimingRole::tristateEnable() || role == TimingRole::tristateDisable()))) { @@ -2169,18 +2111,16 @@ PathVisitor::visitFromPath(const Pin *from_pin, Genclks *genclks = mode->genclks(); VertexSet *fanins = genclks->fanins(gclk); // Note: encountering a latch d->q edge means find the - // latch feedback edges, but they are referenced for + // latch feedback edges, but they are referenced for // other edges in the gen clk fanout. if (role == TimingRole::latchDtoQ()) genclks->findLatchFdbkEdges(gclk); EdgeSet &fdbk_edges = genclks->latchFdbkEdges(gclk); - if ((role == TimingRole::combinational() - || role == TimingRole::wire() + if ((role == TimingRole::combinational() || role == TimingRole::wire() || !gclk->combinational()) - && fanins->contains(to_vertex) - && !fdbk_edges.contains(edge)) { - arc_delay = search_->deratedDelay(from_vertex, arc, edge, - true, min_max, dcalc_ap, sdc); + && fanins->contains(to_vertex) && !fdbk_edges.contains(edge)) { + arc_delay = search_->deratedDelay(from_vertex, arc, edge, true, min_max, + dcalc_ap, sdc); DcalcAPIndex dcalc_ap = scene->dcalcAnalysisPtIndex(min_max->opposite()); Delay arc_delay_opp = search_->deratedDelay(from_vertex, arc, edge, true, min_max, @@ -2197,10 +2137,9 @@ PathVisitor::visitFromPath(const Pin *from_pin, } } else if (role->genericRole() == TimingRole::regClkToQ()) { - if (clk == nullptr - || !sdc->clkStopPropagation(from_pin, clk)) { - arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, - min_max, dcalc_ap, sdc); + if (clk == nullptr || !sdc->clkStopPropagation(from_pin, clk)) { + arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, min_max, + dcalc_ap, sdc); // Remove clock network delay for macros created with propagated // clocks when used in a context with ideal clocks. @@ -2217,8 +2156,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, // Propagate from unclocked reg/latch clk pins, which have no // clk but are distinguished with a segment_start flag. - if ((clk_edge == nullptr - && from_tag->isSegmentStart()) + if ((clk_edge == nullptr && from_tag->isSegmentStart()) // Do not propagate paths from input ports with default // input arrival clk thru CLK->Q edges. || (clk != sdc->defaultArrivalClock() @@ -2229,11 +2167,9 @@ PathVisitor::visitFromPath(const Pin *from_pin, const ClkInfo *to_clk_info = from_clk_info; if (from_clk_info->crprClkPath(this) == nullptr || network_->direction(to_pin)->isInternal()) - to_clk_info = search_->clkInfoWithCrprClkPath(from_clk_info, - from_path); - to_tag = search_->fromRegClkTag(from_pin, from_rf, clk, clk_rf, - to_clk_info, to_pin, to_rf, min_max, - from_tag->scene()); + to_clk_info = search_->clkInfoWithCrprClkPath(from_clk_info, from_path); + to_tag = search_->fromRegClkTag(from_pin, from_rf, clk, clk_rf, to_clk_info, + to_pin, to_rf, min_max, from_tag->scene()); if (to_tag) to_tag = search_->thruTag(to_tag, edge, to_rf, tag_cache_); from_arrival = search_->clkPathArrival(from_path, from_clk_info, @@ -2245,8 +2181,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, } } else if (edge->role() == TimingRole::latchDtoQ()) { - if (min_max == MinMax::max() - && clk) { + if (min_max == MinMax::max() && clk) { bool postponed = false; if (search_->postponeLatchOutputs()) { const Path *from_clk_path = from_clk_info->crprClkPath(this); @@ -2258,21 +2193,19 @@ PathVisitor::visitFromPath(const Pin *from_pin, // Crpr clk path on latch data input is required to find Q // arrival. If the data clk path level is >= Q level the // crpr clk path prev_path pointers are not complete. - debugPrint(debug_, "search", 3, "postponed latch eval %d %s -> %s %d", - d_clk_level, - d_clk_vertex->to_string(this).c_str(), - edge->to_string(this).c_str(), - q_level); + debugPrint(debug_, "search", 3, "postponed latch eval {} {} -> {} {}", + d_clk_level, d_clk_vertex->to_string(this), + edge->to_string(this), q_level); postponed = true; search_->enqueueLatchOutput(to_vertex); } } } if (!postponed) { - arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, - min_max, dcalc_ap, sdc); - latches_->latchOutArrival(from_path, arc, edge, to_tag, - arc_delay, to_arrival); + arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, min_max, + dcalc_ap, sdc); + latches_->latchOutArrival(from_path, arc, edge, to_tag, arc_delay, + to_arrival); if (to_tag) to_tag = search_->thruTag(to_tag, edge, to_rf, tag_cache_); } @@ -2288,22 +2221,18 @@ PathVisitor::visitFromPath(const Pin *from_pin, && sdc->clkDisabledByHpinThru(clk, from_pin, to_pin)) // Generated clock source pins have arrivals for the source clock. // Do not propagate them past the generated clock source pin. - && !(clks - && !clks->contains(const_cast(from_tag->clock())))) { + && !(clks && !clks->contains(const_cast(from_tag->clock())))) { // Propagate arrival as non-clock at the end of the clock tree. bool to_propagates_clk = - !sdc->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf) - && (variables_->clkThruTristateEnabled() - || !(role == TimingRole::tristateEnable() - || role == TimingRole::tristateDisable())); - arc_delay = search_->deratedDelay(from_vertex, arc, edge, - to_propagates_clk, min_max, - dcalc_ap, sdc); - DcalcAPIndex dcalc_ap_opp = - scene->dcalcAnalysisPtIndex(min_max->opposite()); - Delay arc_delay_opp = search_->deratedDelay(from_vertex, arc, edge, - to_propagates_clk, - min_max, dcalc_ap_opp, sdc); + !sdc->clkStopPropagation(clk, from_pin, from_rf, to_pin, to_rf) + && (variables_->clkThruTristateEnabled() + || !(role == TimingRole::tristateEnable() + || role == TimingRole::tristateDisable())); + arc_delay = search_->deratedDelay(from_vertex, arc, edge, to_propagates_clk, + min_max, dcalc_ap, sdc); + DcalcAPIndex dcalc_ap_opp = scene->dcalcAnalysisPtIndex(min_max->opposite()); + Delay arc_delay_opp = search_->deratedDelay( + from_vertex, arc, edge, to_propagates_clk, min_max, dcalc_ap_opp, sdc); bool arc_delay_min_max_eq = fuzzyEqual(delayAsFloat(arc_delay), delayAsFloat(arc_delay_opp)); to_tag = search_->thruClkTag(from_path, from_vertex, from_tag, @@ -2325,11 +2254,9 @@ PathVisitor::visitFromPath(const Pin *from_pin, } } if (to_tag) - return visitFromToPath(from_pin, from_vertex, from_rf, - from_tag, from_path, from_arrival, - edge, arc, arc_delay, - to_vertex, to_rf, to_tag, to_arrival, - min_max); + return visitFromToPath(from_pin, from_vertex, from_rf, from_tag, from_path, + from_arrival, edge, arc, arc_delay, to_vertex, to_rf, + to_tag, to_arrival, min_max); else return true; } @@ -2350,9 +2277,7 @@ Search::clkPathArrival(const Path *clk_path, const MinMax *min_max) const { const Scene *scene = clk_path->scene(this); - if (clk_path->vertex(this)->isRegClk() - && clk_path->isClock(this) - && clk_edge + if (clk_path->vertex(this)->isRegClk() && clk_path->isClock(this) && clk_edge && !clk_info->isPropagated()) { // Ideal clock, apply ideal insertion delay and latency. const EarlyLate *early_late = min_max; @@ -2425,10 +2350,10 @@ Search::fromUnclkedInputTag(const Pin *pin, ExceptionStateSet *states = nullptr; if (sdc->exceptionFromStates(pin, rf, nullptr, nullptr, min_max, states) && (!require_exception || states)) { - const ClkInfo *clk_info = findClkInfo(scene, nullptr, nullptr, false, - 0.0, min_max); - return findTag(scene, rf, min_max, clk_info, false, nullptr, - is_segment_start, states, true, nullptr); + const ClkInfo *clk_info = + findClkInfo(scene, nullptr, nullptr, false, 0.0, min_max); + return findTag(scene, rf, min_max, clk_info, false, nullptr, is_segment_start, + states, true, nullptr); } return nullptr; } @@ -2446,12 +2371,11 @@ Search::fromRegClkTag(const Pin *from_pin, { Sdc *sdc = scene->sdc(); ExceptionStateSet *states = nullptr; - if (sdc->exceptionFromStates(from_pin, from_rf, clk, clk_rf, - min_max, states)) { + if (sdc->exceptionFromStates(from_pin, from_rf, clk, clk_rf, min_max, states)) { // Hack for filter -from reg/Q. sdc->filterRegQStates(to_pin, to_rf, min_max, states); - return findTag(scene, to_rf, min_max, clk_info, false, nullptr, - false, states, true, nullptr); + return findTag(scene, to_rf, min_max, clk_info, false, nullptr, false, states, + true, nullptr); } else return nullptr; @@ -2464,18 +2388,12 @@ Search::clkInfoWithCrprClkPath(const ClkInfo *from_clk_info, { Scene *scene = from_clk_info->scene(); if (crprActive(scene->mode())) - return findClkInfo(scene, - from_clk_info->clkEdge(), - from_clk_info->clkSrc(), - from_clk_info->isPropagated(), - from_clk_info->genClkSrc(), + return findClkInfo(scene, from_clk_info->clkEdge(), from_clk_info->clkSrc(), + from_clk_info->isPropagated(), from_clk_info->genClkSrc(), from_clk_info->isGenClkSrcPath(), - from_clk_info->pulseClkSense(), - from_clk_info->insertion(), - from_clk_info->latency(), - from_clk_info->uncertainties(), - from_clk_info->minMax(), - from_path); + from_clk_info->pulseClkSense(), from_clk_info->insertion(), + from_clk_info->latency(), from_clk_info->uncertainties(), + from_clk_info->minMax(), from_path); else return from_clk_info; } @@ -2494,8 +2412,8 @@ Search::thruTag(Tag *from_tag, const RiseFall *from_rf = from_tag->transition(); const ClkInfo *from_clk_info = from_tag->clkInfo(); bool to_is_reg_clk = to_vertex->isRegClk(); - Tag *to_tag = mutateTag(from_tag, from_pin, from_rf, false, from_clk_info, - to_pin, to_rf, false, to_is_reg_clk, false, + Tag *to_tag = mutateTag(from_tag, from_pin, from_rf, false, from_clk_info, to_pin, + to_rf, false, to_is_reg_clk, false, // input delay is not propagated. from_clk_info, nullptr, tag_cache); return to_tag; @@ -2521,15 +2439,12 @@ Search::thruClkTag(Path *from_path, bool from_is_clk = from_tag->isClock(); bool to_is_reg_clk = to_vertex->isRegClk(); const TimingRole *role = edge->role(); - bool to_is_clk = (from_is_clk - && to_propagates_clk - && (role->isWire() - || role == TimingRole::combinational())); - const ClkInfo *to_clk_info = thruClkInfo(from_path, from_vertex, - from_clk_info, from_is_clk, - edge, to_vertex, to_pin, to_is_clk, - arc_delay_min_max_eq, min_max, scene); - Tag *to_tag = mutateTag(from_tag,from_pin,from_rf,from_is_clk,from_clk_info, + bool to_is_clk = (from_is_clk && to_propagates_clk + && (role->isWire() || role == TimingRole::combinational())); + const ClkInfo *to_clk_info = thruClkInfo( + from_path, from_vertex, from_clk_info, from_is_clk, edge, to_vertex, to_pin, + to_is_clk, arc_delay_min_max_eq, min_max, scene); + Tag *to_tag = mutateTag(from_tag, from_pin, from_rf, from_is_clk, from_clk_info, to_pin, to_rf, to_is_clk, to_is_reg_clk, false, to_clk_info, nullptr, nullptr); return to_tag; @@ -2557,8 +2472,7 @@ Search::thruClkInfo(Path *from_path, bool from_clk_prop = from_clk_info->isPropagated(); bool to_clk_prop = from_clk_prop; - if (!from_clk_prop - && sdc->isPropagatedClock(to_pin)) { + if (!from_clk_prop && sdc->isPropagatedClock(to_pin)) { to_clk_prop = true; changed = true; } @@ -2567,9 +2481,7 @@ Search::thruClkInfo(Path *from_path, // so that generated clock crpr info can be (later) safely set on // the clkinfo. const Pin *gen_clk_src = nullptr; - if (from_clk_info->isGenClkSrcPath() - && crprActive(mode) - && sdc->isClock(to_pin)) { + if (from_clk_info->isGenClkSrcPath() && crprActive(mode) && sdc->isClock(to_pin)) { // Don't care that it could be a regular clock root. gen_clk_src = to_pin; changed = true; @@ -2579,9 +2491,7 @@ Search::thruClkInfo(Path *from_path, if (crprActive(mode) // Update crpr clk path for combinational paths leaving the clock // network (ie, tristate en->out) and buffer driving reg clk. - && ((from_is_clk - && !to_is_clk - && !from_vertex->isRegClk()) + && ((from_is_clk && !to_is_clk && !from_vertex->isRegClk()) || (to_vertex->isRegClk() // If the wire delay to the reg clk pin is zero, // leave the crpr_clk_path null to indicate that @@ -2599,8 +2509,8 @@ Search::thruClkInfo(Path *from_path, to_pulse_sense = port->pulseClkSense(); changed = true; } - else if (from_pulse_sense && - edge->timingArcSet()->sense() == TimingSense::negative_unate) { + else if (from_pulse_sense + && edge->timingArcSet()->sense() == TimingSense::negative_unate) { to_pulse_sense = from_pulse_sense->opposite(); changed = true; } @@ -2610,8 +2520,7 @@ Search::thruClkInfo(Path *from_path, float to_latency = from_clk_info->latency(); float latency; bool exists; - sdc->clockLatency(from_clk, to_pin, clk_rf, min_max, - latency, exists); + sdc->clockLatency(from_clk, to_pin, clk_rf, min_max, latency, exists); if (exists) { // Latency on pin has precedence over fanin or hierarchical // pin latency. @@ -2621,8 +2530,7 @@ Search::thruClkInfo(Path *from_path, } else { // Check for hierarchical pin latency thru edge. - sdc->clockLatency(edge, clk_rf, min_max, - latency, exists); + sdc->clockLatency(edge, clk_rf, min_max, latency, exists); if (exists) { to_latency = latency; to_clk_prop = false; @@ -2638,11 +2546,10 @@ Search::thruClkInfo(Path *from_path, } if (changed) - to_clk_info = findClkInfo(scene, from_clk_edge, from_clk_info->clkSrc(), - to_clk_prop, gen_clk_src, - from_clk_info->isGenClkSrcPath(), - to_pulse_sense, to_insertion, to_latency, - to_uncertainties, min_max, to_crpr_clk_path); + to_clk_info = findClkInfo( + scene, from_clk_edge, from_clk_info->clkSrc(), to_clk_prop, gen_clk_src, + from_clk_info->isGenClkSrcPath(), to_pulse_sense, to_insertion, to_latency, + to_uncertainties, min_max, to_crpr_clk_path); return to_clk_info; } @@ -2680,7 +2587,7 @@ Search::mutateTag(Tag *from_tag, for (ExceptionState *state : *from_states) { ExceptionPath *exception = state->exception(); // One edge may traverse multiple hierarchical thru pins. - while (state->matchesNextThru(from_pin,to_pin,to_rf,min_max,network_)) { + while (state->matchesNextThru(from_pin, to_pin, to_rf, min_max, network_)) { // Found a -thru that we've been waiting for. state = state->nextState(); state_change = true; @@ -2692,20 +2599,16 @@ Search::mutateTag(Tag *from_tag, // Don't propagate a completed false path -thru unless it is a // clock. Clocks carry the completed false path to disable // downstream paths that use the clock as data. - if ((state->isComplete() - && exception->isFalse() - && !from_is_clk) + if ((state->isComplete() && exception->isFalse() && !from_is_clk) // to_pin/edge completes a loop path. - || (exception->isLoop() - && state->isComplete())) + || (exception->isLoop() && state->isComplete())) return nullptr; // Kill path delay tags past the -to pin. if ((exception->isPathDelay() && sdc->isCompleteTo(state, to_pin, to_rf, min_max)) // Kill loop tags at register clock pins. - || (exception->isLoop() - && to_is_reg_clk)) { + || (exception->isLoop() && to_is_reg_clk)) { state_change = true; break; } @@ -2721,19 +2624,16 @@ Search::mutateTag(Tag *from_tag, for (auto state : *from_states) { ExceptionPath *exception = state->exception(); // One edge may traverse multiple hierarchical thru pins. - while (state->matchesNextThru(from_pin,to_pin,to_rf,min_max,network_)) + while (state->matchesNextThru(from_pin, to_pin, to_rf, min_max, network_)) // Found a -thru that we've been waiting for. state = state->nextState(); // Don't propagate a completed false path -thru unless it is a // clock. Clocks carry the completed false path to disable // downstream paths that use the clock as data. - if ((state->isComplete() - && exception->isFalse() - && !from_is_clk) + if ((state->isComplete() && exception->isFalse() && !from_is_clk) // to_pin/edge completes a loop path. - || (exception->isLoop() - && state->isComplete())) { + || (exception->isLoop() && state->isComplete())) { delete new_states; return nullptr; } @@ -2742,8 +2642,7 @@ Search::mutateTag(Tag *from_tag, if (!((exception->isPathDelay() && sdc->isCompleteTo(state, from_pin, from_rf, min_max)) // Kill loop tags at register clock pins. - || (to_is_reg_clk - && exception->isLoop()))) + || (to_is_reg_clk && exception->isLoop()))) new_states->insert(state); } } @@ -2754,20 +2653,18 @@ Search::mutateTag(Tag *from_tag, if (new_states) return findTag(scene, to_rf, min_max, to_clk_info, to_is_clk, - from_tag->inputDelay(), to_is_segment_start, - new_states, true, tag_cache); + from_tag->inputDelay(), to_is_segment_start, new_states, true, + tag_cache); else { // No state change. - if (to_clk_info == from_clk_info - && to_is_clk == from_is_clk + if (to_clk_info == from_clk_info && to_is_clk == from_is_clk && from_tag->isSegmentStart() == to_is_segment_start && from_tag->inputDelay() == to_input_delay) { return tags_[tagsTableRfIndex(from_tag->index(), to_rf)]; } else - return findTag(scene, to_rf, min_max, to_clk_info, to_is_clk, - to_input_delay, to_is_segment_start, - from_states, false, tag_cache); + return findTag(scene, to_rf, min_max, to_clk_info, to_is_clk, to_input_delay, + to_is_segment_start, from_states, false, tag_cache); } } @@ -2793,9 +2690,8 @@ Search::findTagGroup(TagGroupBldr *tag_bldr) // can use Search::tagGroup(TagGroupIndex) without returning gubbish. if (tag_group_next_ == tag_group_capacity_) { TagGroupIndex tag_capacity = tag_group_capacity_ * 2; - TagGroup **tag_groups = new TagGroup*[tag_capacity]; - memcpy(tag_groups, tag_groups_, - tag_group_capacity_ * sizeof(TagGroup*)); + TagGroup **tag_groups = new TagGroup *[tag_capacity]; + memcpy(tag_groups, tag_groups_, tag_group_capacity_ * sizeof(TagGroup *)); tag_groups_prev_.push_back(tag_groups_); tag_groups_ = tag_groups; tag_group_capacity_ = tag_capacity; @@ -2865,7 +2761,6 @@ private: const StaState *sta_; }; - ReportPathLess::ReportPathLess(const StaState *sta) : sta_(sta) { @@ -2882,12 +2777,12 @@ void Search::reportArrivals(Vertex *vertex, bool report_tag_index) const { - report_->reportLine("Vertex %s", vertex->to_string(this).c_str()); + report_->report("Vertex {}", vertex->to_string(this)); TagGroup *tag_group = tagGroup(vertex); if (tag_group) { if (report_tag_index) - report_->reportLine("Group %u", tag_group->index()); - std::vector paths; + report_->report("Group {}", tag_group->index()); + std::vector paths; VertexPathIterator path_iter(vertex, this); while (path_iter.hasNext()) { const Path *path = path_iter.next(); @@ -2897,7 +2792,7 @@ Search::reportArrivals(Vertex *vertex, for (const Path *path : paths) { const Tag *tag = path->tag(this); const RiseFall *rf = tag->transition(); - const char *req = delayAsString(path->required(), this); + std::string req = delayAsString(path->required(), this); bool report_prev = false; std::string prev_str; if (report_prev) { @@ -2919,17 +2814,14 @@ Search::reportArrivals(Vertex *vertex, else prev_str += "NULL"; } - report_->reportLine(" %s %s %s / %s %s%s", - rf->shortName(), - path->minMax(this)->to_string().c_str(), - delayAsString(path->arrival(), this), - req, - tag->to_string(report_tag_index, false, this).c_str(), - prev_str.c_str()); + report_->report(" {} {} {} / {} {}{}", rf->shortName(), + path->minMax(this)->to_string(), + delayAsString(path->arrival(), this), req, + tag->to_string(report_tag_index, false, this), prev_str); } } else - report_->reportLine(" no arrivals"); + report_->report(" no arrivals"); } TagGroup * @@ -2960,10 +2852,8 @@ Search::reportTagGroups() const for (TagGroupIndex i = 0; i < tag_group_next_; i++) { TagGroup *tag_group = tag_groups_[i]; if (tag_group) { - report_->reportLine("Group %4u hash = %4lu (%4lu)", - i, - tag_group->hash(), - tag_group->hash() % tag_group_set_->bucket_count()); + report_->report("Group {:4} hash = {:4} ({:4})", i, tag_group->hash(), + tag_group->hash() % tag_group_set_->bucket_count()); tag_group->reportArrivalMap(this); } } @@ -2972,9 +2862,8 @@ Search::reportTagGroups() const if (tag_group_set_->bucket_size(i) > long_hash) long_hash = i; } - report_->reportLine("Longest hash bucket length %zu hash=%zu", - tag_group_set_->bucket_size(long_hash), - long_hash); + report_->report("Longest hash bucket length {} hash={}", + tag_group_set_->bucket_size(long_hash), long_hash); } void @@ -2996,7 +2885,7 @@ Search::reportPathCountHistogram() const for (size_t path_count = 0; path_count < vertex_counts.size(); path_count++) { int vertex_count = vertex_counts[path_count]; if (vertex_count > 0) - report_->reportLine("%6lu %6d",path_count, vertex_count); + report_->report("{:6} {:6}", path_count, vertex_count); } } @@ -3026,8 +2915,8 @@ Search::findTag(Scene *scene, bool own_states, TagSet *tag_cache) { - Tag probe(scene, 0, rf, min_max, clk_info, is_clk, - input_delay, is_segment_start, states, false); + Tag probe(scene, 0, rf, min_max, clk_info, is_clk, input_delay, is_segment_start, + states, false); if (tag_cache) { Tag *tag = findKey(tag_cache, &probe); if (tag) @@ -3040,8 +2929,8 @@ Search::findTag(Scene *scene, // Make rise/fall versions of the tag to avoid tag_set lookups when the // only change is the rise/fall edge. for (const RiseFall *rf1 : RiseFall::range()) { - ExceptionStateSet *new_states = !own_states && states - ? new ExceptionStateSet(*states) : states; + ExceptionStateSet *new_states = + !own_states && states ? new ExceptionStateSet(*states) : states; TagIndex tag_index = tag_next_++; Tag *tag1 = new Tag(scene, tag_index, rf1, min_max, clk_info, is_clk, input_delay, is_segment_start, new_states, true); @@ -3064,8 +2953,8 @@ Search::findTag(Scene *scene, // can use Search::tag(TagIndex) without returning gubbish. if (tag_next_ == tag_capacity_) { TagIndex tag_capacity = tag_capacity_ * 2; - Tag **tags = new Tag*[tag_capacity]; - memcpy(tags, tags_, tag_capacity_ * sizeof(Tag*)); + Tag **tags = new Tag *[tag_capacity]; + memcpy(tags, tags_, tag_capacity_ * sizeof(Tag *)); tags_prev_.push_back(tags_); tags_ = tags; tag_capacity_ = tag_capacity; @@ -3083,29 +2972,28 @@ Search::reportTags() const for (TagIndex i = 0; i < tag_next_; i++) { Tag *tag = tags_[i]; if (tag) - report_->reportLine("%s", tag->to_string(this).c_str()) ; + report_->report("{}", tag->to_string(this)); } size_t long_hash = 0; for (size_t i = 0; i < tag_set_->bucket_count(); i++) { if (tag_set_->bucket_size(i) > long_hash) long_hash = i; } - report_->reportLine("Longest hash bucket length %zu hash=%zu", - tag_set_->bucket_size(long_hash), - long_hash); + report_->report("Longest hash bucket length {} hash={}", + tag_set_->bucket_size(long_hash), long_hash); } void Search::reportClkInfos() const { - std::vector clk_infos; + std::vector clk_infos; // set -> vector for sorting. for (const ClkInfo *clk_info : *clk_info_set_) clk_infos.push_back(clk_info); sort(clk_infos, ClkInfoLess(this)); for (const ClkInfo *clk_info : clk_infos) - report_->reportLine("%s", clk_info->to_string(this).c_str()); - report_->reportLine("%zu clk infos", clk_info_set_->size()); + report_->report("{}", clk_info->to_string(this)); + report_->report("{} clk infos", clk_info_set_->size()); } const ClkInfo * @@ -3123,16 +3011,14 @@ Search::findClkInfo(Scene *scene, Path *crpr_clk_path) { const ClkInfo probe(scene, clk_edge, clk_src, is_propagated, gen_clk_src, - gen_clk_src_path, pulse_clk_sense, - insertion, latency, uncertainties, min_max, - crpr_clk_path, this); + gen_clk_src_path, pulse_clk_sense, insertion, latency, + uncertainties, min_max, crpr_clk_path, this); LockGuard lock(clk_info_lock_); const ClkInfo *clk_info = findKey(clk_info_set_, &probe); if (clk_info == nullptr) { - clk_info = new ClkInfo(scene, clk_edge, clk_src, - is_propagated, gen_clk_src, gen_clk_src_path, - pulse_clk_sense, insertion, latency, uncertainties, - min_max, crpr_clk_path, this); + clk_info = new ClkInfo(scene, clk_edge, clk_src, is_propagated, gen_clk_src, + gen_clk_src_path, pulse_clk_sense, insertion, latency, + uncertainties, min_max, crpr_clk_path, this); clk_info_set_->insert(clk_info); } return clk_info; @@ -3146,9 +3032,8 @@ Search::findClkInfo(Scene *scene, Arrival insertion, const MinMax *min_max) { - return findClkInfo(scene, clk_edge, clk_src, is_propagated, - nullptr, false, nullptr, - insertion, 0.0, nullptr, min_max, nullptr); + return findClkInfo(scene, clk_edge, clk_src, is_propagated, nullptr, false, + nullptr, insertion, 0.0, nullptr, min_max, nullptr); } int @@ -3179,8 +3064,7 @@ Search::timingDerate(const Vertex *from_vertex, const Sdc *sdc, const MinMax *min_max) { - PathClkOrData derate_clk_data = - is_clk ? PathClkOrData::clk : PathClkOrData::data; + PathClkOrData derate_clk_data = is_clk ? PathClkOrData::clk : PathClkOrData::data; const TimingRole *role = edge->role(); const Pin *pin = from_vertex->pin(); if (role->isWire()) { @@ -3195,11 +3079,10 @@ Search::timingDerate(const Vertex *from_vertex, rf = arc->toEdge()->asRiseFall(); } else { - derate_type = TimingDerateCellType::cell_delay; - rf = arc->fromEdge()->asRiseFall(); + derate_type = TimingDerateCellType::cell_delay; + rf = arc->fromEdge()->asRiseFall(); } - return sdc->timingDerateInstance(pin, derate_type, derate_clk_data, - rf, min_max); + return sdc->timingDerateInstance(pin, derate_type, derate_clk_data, rf, min_max); } } @@ -3219,7 +3102,7 @@ Search::clockDomains(const Vertex *vertex, // Return value. ClockSet &clks) const { - VertexPathIterator path_iter(const_cast(vertex), this); + VertexPathIterator path_iter(const_cast(vertex), this); while (path_iter.hasNext()) { Path *path = path_iter.next(); const Clock *clk = path->clock(this); @@ -3273,11 +3156,10 @@ Search::clocks(const Vertex *vertex, // Return value. ClockSet &clks) const { - VertexPathIterator path_iter(const_cast(vertex), this); + VertexPathIterator path_iter(const_cast(vertex), this); while (path_iter.hasNext()) { Path *path = path_iter.next(); - if (path->isClock(this) - && path->mode(this) == mode) + if (path->isClock(this) && path->mode(this) == mode) clks.insert(const_cast(path->clock(this))); } } @@ -3294,7 +3176,7 @@ void Search::findRequireds(Level level) { Stats stats(debug_, report_); - debugPrint(debug_, "search", 1, "find requireds to level %d", level); + debugPrint(debug_, "search", 1, "find requireds to level {}", level); RequiredVisitor req_visitor(this); if (!requireds_seeded_) seedRequireds(); @@ -3302,7 +3184,7 @@ Search::findRequireds(Level level) int required_count = required_iter_->visitParallel(level, &req_visitor); deleteTagsPrev(); requireds_exist_ = true; - debugPrint(debug_, "search", 1, "found %d requireds", required_count); + debugPrint(debug_, "search", 1, "found {} requireds", required_count); stats.report("Find requireds"); } @@ -3324,8 +3206,8 @@ Search::endpoints() while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); if (isEndpoint(vertex)) { - debugPrint(debug_, "endpoint", 2, "insert %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "endpoint", 2, "insert {}", + vertex->to_string(this)); endpoints_.insert(vertex); } } @@ -3334,15 +3216,13 @@ Search::endpoints() if (!invalid_endpoints_.empty()) { for (Vertex *vertex : invalid_endpoints_) { if (isEndpoint(vertex)) { - debugPrint(debug_, "endpoint", 2, "insert %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "endpoint", 2, "insert {}", + vertex->to_string(this)); endpoints_.insert(vertex); } else { - if (debug_->check("endpoint", 2) - && endpoints_.contains(vertex)) - report_->reportLine("endpoint: remove %s", - vertex->to_string(this).c_str()); + if (debug_->check("endpoint", 2) && endpoints_.contains(vertex)) + report_->report("endpoint: remove {}", vertex->to_string(this)); endpoints_.erase(vertex); } } @@ -3354,8 +3234,7 @@ Search::endpoints() void Search::endpointInvalid(Vertex *vertex) { - debugPrint(debug_, "endpoint", 2, "invalid %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "endpoint", 2, "invalid {}", vertex->to_string(this)); invalid_endpoints_.insert(vertex); } @@ -3395,16 +3274,13 @@ Search::isEndpoint(Vertex *vertex, const Pin *pin = vertex->pin(); const Sdc *sdc = mode->sdc(); return hasFanin(vertex, pred, graph_, mode) - && ((vertex->hasChecks() - && hasEnabledChecks(vertex, mode)) - || sdc->isConstrainedEnd(pin) - || !hasFanout(vertex, pred, graph_, mode) - || sdc->isPathDelayInternalTo(pin) - // Unconstrained paths at register clk pins. - || (unconstrained_paths_ - && vertex->isRegClk()) - || (variables_->gatedClkChecksEnabled() - && gated_clk_->isGatedClkEnable(vertex, mode))); + && ((vertex->hasChecks() && hasEnabledChecks(vertex, mode)) + || sdc->isConstrainedEnd(pin) || !hasFanout(vertex, pred, graph_, mode) + || sdc->isPathDelayInternalTo(pin) + // Unconstrained paths at register clk pins. + || (unconstrained_paths_ && vertex->isRegClk()) + || (variables_->gatedClkChecksEnabled() + && gated_clk_->isGatedClkEnable(vertex, mode))); } bool @@ -3497,8 +3373,8 @@ FindEndRequiredVisitor::visit(PathEnd *path_end) void Search::seedRequired(Vertex *vertex) { - debugPrint(debug_, "search", 2, "required seed %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "required seed {}", + vertex->to_string(this)); RequiredCmp required_cmp; FindEndRequiredVisitor seeder(&required_cmp, this); required_cmp.requiredsInit(vertex, this); @@ -3572,7 +3448,7 @@ RequiredCmp::requiredsSave(Vertex *vertex, const Required req = requireds_[path_index]; const Required &prev_req = path->required(); bool changed = !delayEqual(prev_req, req, sta); - debugPrint(debug, "search", 3, "required %s save %s -> %s%s", + debugPrint(debug, "search", 3, "required {} save {} -> {}{}", path->to_string(sta).c_str(), delayAsString(prev_req, sta), delayAsString(req, sta), @@ -3600,7 +3476,9 @@ RequiredVisitor::RequiredVisitor(const StaState *sta) : RequiredVisitor::RequiredVisitor(bool make_tag_cache, const StaState *sta) : - PathVisitor(sta->search()->evalPred(), make_tag_cache, sta), + PathVisitor(sta->search()->evalPred(), + make_tag_cache, + sta), required_cmp_(new RequiredCmp), visit_path_ends_(new VisitPathEnds(sta)) { @@ -3621,8 +3499,8 @@ RequiredVisitor::copy() const void RequiredVisitor::visit(Vertex *vertex) { - debugPrint(debug_, "search", 2, "find required %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "find required {}", + vertex->to_string(this)); required_cmp_->requiredsInit(vertex, this); // Back propagate requireds from fanout. visitFanoutPaths(vertex); @@ -3656,13 +3534,10 @@ RequiredVisitor::visitFromToPath(const Pin *, { // Don't propagate required times through latch D->Q edges. if (!edge->role()->isLatchDtoQ()) { - debugPrint(debug_, "search", 3, " %s -> %s %s", - from_rf->shortName(), - to_rf->shortName(), - min_max->to_string().c_str()); - debugPrint(debug_, "search", 3, " from tag %2u: %s", - from_tag->index(), - from_tag->to_string(this).c_str()); + debugPrint(debug_, "search", 3, " {} -> {} {}", from_rf->shortName(), + to_rf->shortName(), min_max->to_string()); + debugPrint(debug_, "search", 3, " from tag {:2}: {}", from_tag->index(), + from_tag->to_string(this)); size_t path_index = from_path->pathIndex(this); const MinMax *req_min = min_max->opposite(); TagGroup *to_tag_group = search_->tagGroup(to_vertex); @@ -3672,10 +3547,10 @@ RequiredVisitor::visitFromToPath(const Pin *, Path &to_path = to_vertex->paths()[to_path_index]; const Required &to_required = to_path.required(); Required from_required = delayDiff(to_required, arc_delay, this); - debugPrint(debug_, "search", 3, " to tag %2u: %s", + debugPrint(debug_, "search", 3, " to tag {:2}: {}", to_tag->index(), to_tag->to_string(this).c_str()); - debugPrint(debug_, "search", 3, " %s - %s = %s %s %s", + debugPrint(debug_, "search", 3, " {} - {} = {} {} {}", delayAsString(to_required, this), delayAsString(arc_delay, this), delayAsString(from_required, this), @@ -3696,16 +3571,15 @@ RequiredVisitor::visitFromToPath(const Pin *, if (Tag::matchNoCrpr(to_path_tag, to_tag)) { Required to_required = to_path->required(); Required from_required = delayDiff(to_required, arc_delay, this); - debugPrint(debug_, "search", 3, " to tag %2u: %s", + debugPrint(debug_, "search", 3, " to tag {:2}: {}", to_path_tag->index(), to_path_tag->to_string(this).c_str()); - debugPrint(debug_, "search", 3, " %s - %s = %s %s %s", + debugPrint(debug_, "search", 3, " {} - {} = {} {} {}", delayAsString(to_required, this), delayAsString(arc_delay, this), delayAsString(from_required, this), min_max == MinMax::max() ? "<" : ">", - delayAsString(required_cmp_->required(path_index), - this)); + delayAsString(required_cmp_->required(path_index), this)); required_cmp_->requiredSet(path_index, from_required, req_min, this); break; } @@ -3744,9 +3618,7 @@ bool Search::matchesFilter(Path *path, const ClockEdge *to_clk_edge) { - if (!have_filter_ - && filter_from_ == nullptr - && filter_to_ == nullptr) + if (!have_filter_ && filter_from_ == nullptr && filter_to_ == nullptr) return true; else if (have_filter_) { // -from pins|inst @@ -3755,29 +3627,25 @@ Search::matchesFilter(Path *path, ExceptionStateSet *states = path->tag(this)->states(); if (states) { for (auto state : *states) { - if (state->exception()->isFilter() - && state->nextThru() == nullptr + if (state->exception()->isFilter() && state->nextThru() == nullptr && matchesFilterTo(path, to_clk_edge)) return true; } } return false; } - else if (filter_from_ - && filter_from_->pins() == nullptr - && filter_from_->instances() == nullptr - && filter_from_->clks()) { + else if (filter_from_ && filter_from_->pins() == nullptr + && filter_from_->instances() == nullptr && filter_from_->clks()) { // -from clks const ClockEdge *path_clk_edge = path->clkEdge(this); const Clock *path_clk = path_clk_edge ? path_clk_edge->clock() : nullptr; const RiseFall *path_clk_rf = - path_clk_edge ? path_clk_edge->transition() : nullptr; - return filter_from_->clks()->contains(const_cast(path_clk)) - && filter_from_->transition()->matches(path_clk_rf) - && matchesFilterTo(path, to_clk_edge); + path_clk_edge ? path_clk_edge->transition() : nullptr; + return filter_from_->clks()->contains(const_cast(path_clk)) + && filter_from_->transition()->matches(path_clk_rf) + && matchesFilterTo(path, to_clk_edge); } - else if (filter_from_ == nullptr - && filter_to_) + else if (filter_from_ == nullptr && filter_to_) // -to return matchesFilterTo(path, to_clk_edge); else { @@ -3819,12 +3687,10 @@ Search::exceptionTo(ExceptionPathType type, for (auto state : *states) { ExceptionPath *exception = state->exception(); int priority = exception->priority(min_max); - if ((type == ExceptionPathType::any - || exception->type() == type) + if ((type == ExceptionPathType::any || exception->type() == type) && sdc->isCompleteTo(state, pin, rf, clk_edge, min_max, match_min_max_exactly, require_to_pin) - && (hi_priority_exception == nullptr - || priority > hi_priority + && (hi_priority_exception == nullptr || priority > hi_priority || (priority == hi_priority && exception->tighterThan(hi_priority_exception)))) { hi_priority = priority; @@ -3833,8 +3699,7 @@ Search::exceptionTo(ExceptionPathType type, } } // Check for -to exceptions originating at the end pin or target clock. - sdc->exceptionTo(type, pin, rf, clk_edge, min_max, - match_min_max_exactly, + sdc->exceptionTo(type, pin, rf, clk_edge, min_max, match_min_max_exactly, hi_priority_exception, hi_priority); return hi_priority_exception; } @@ -3858,8 +3723,8 @@ Search::groupPathsTo(const PathEnd *path_end) const for (auto state : *states) { ExceptionPath *exception = state->exception(); if (exception->isGroupPath() - && sdc->exceptionMatchesTo(exception, pin, rf, clk_edge, min_max, - false, false)) + && sdc->exceptionMatchesTo(exception, pin, rf, clk_edge, min_max, false, + false)) group_paths.push_back(exception); } } @@ -3909,10 +3774,8 @@ Search::tnsPreamble() void Search::tnsInvalid(Vertex *vertex) { - if ((tns_exists_ || worst_slacks_) - && isEndpoint(vertex)) { - debugPrint(debug_, "tns", 2, "tns invalid %s", - vertex->to_string(this).c_str()); + if ((tns_exists_ || worst_slacks_) && isEndpoint(vertex)) { + debugPrint(debug_, "tns", 2, "tns invalid {}", vertex->to_string(this)); LockGuard lock(tns_lock_); invalid_tns_.insert(vertex); } @@ -3925,8 +3788,7 @@ Search::updateInvalidTns() for (Vertex *vertex : invalid_tns_) { // Network edits can change endpointedness since tnsInvalid was called. if (isEndpoint(vertex)) { - debugPrint(debug_, "tns", 2, "update tns %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "tns", 2, "update tns {}", vertex->to_string(this)); SlackSeq slacks(path_count); wnsSlacks(vertex, slacks); @@ -3974,7 +3836,7 @@ Search::tnsIncr(Vertex *vertex, PathAPIndex path_ap_index) { if (delayLess(slack, 0.0, this)) { - debugPrint(debug_, "tns", 3, "tns+ %s %s", + debugPrint(debug_, "tns", 3, "tns+ {} {}", delayAsString(slack, this), vertex->to_string(this).c_str()); delayIncr(tns_[path_ap_index], slack, this); @@ -3993,7 +3855,7 @@ Search::tnsDecr(Vertex *vertex, findKeyValue(tns_slacks_[path_ap_index], vertex, slack, found); if (found && delayLess(slack, 0.0, this)) { - debugPrint(debug_, "tns", 3, "tns- %s %s", + debugPrint(debug_, "tns", 3, "tns- {} {}", delayAsString(slack, this), vertex->to_string(this).c_str()); delayDecr(tns_[path_ap_index], slack, this); @@ -4005,8 +3867,7 @@ Search::tnsDecr(Vertex *vertex, void Search::tnsNotifyBefore(Vertex *vertex) { - if (tns_exists_ - && isEndpoint(vertex)) { + if (tns_exists_ && isEndpoint(vertex)) { size_t path_count = scenePathCount(); for (size_t i = 0; i < path_count; i++) { tnsDecr(vertex, i); @@ -4053,10 +3914,10 @@ Search::wnsTnsPreamble() findAllArrivals(); // Required times are only needed at endpoints. if (requireds_seeded_) { - for (auto itr = invalid_requireds_.begin(); itr != invalid_requireds_.end(); ) { + for (auto itr = invalid_requireds_.begin(); itr != invalid_requireds_.end();) { Vertex *vertex = *itr; - debugPrint(debug_, "search", 2, "tns update required %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "tns update required {}", + vertex->to_string(this)); if (isEndpoint(vertex)) { seedRequired(vertex); // If the endpoint has fanout it's required time @@ -4164,4 +4025,4 @@ Search::wnsSlack(Vertex *vertex, return slacks[path_ap_index]; } -} // namespace +} // namespace sta diff --git a/search/Search.i b/search/Search.i index f83399b5..e6716ae1 100644 --- a/search/Search.i +++ b/search/Search.i @@ -241,7 +241,7 @@ endpoint_slack(const Pin *pin, return sta->units()->timeUnit()->staToUser(delayAsFloat(slack, min_max, sta)); } else { - sta->report()->error(1577, "%s is not a known path group name.", + sta->report()->error(1577, "{} is not a known path group name.", path_group_name); return INF; } @@ -322,7 +322,7 @@ report_loops() Report *report = sta->report(); for (GraphLoop *loop : sta->graphLoops()) { loop->report(sta); - report->reportLineString(""); + report->reportLine(""); } } @@ -436,7 +436,7 @@ set_report_path_field_properties(const char *field_name, if (field) field->setProperties(title, width, left_justify); else - sta->report()->warn(1575, "unknown report path field %s", field_name); + sta->report()->warn(1575, "unknown report path field {}", field_name); } void diff --git a/search/Sim.cc b/search/Sim.cc index 31e7ca8e..bf459097 100644 --- a/search/Sim.cc +++ b/search/Sim.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 "Sim.hh" @@ -68,10 +68,7 @@ Sim::Sim(StaState *sta) : { } -Sim::~Sim() -{ - delete observer_; -} +Sim::~Sim() { delete observer_; } void Sim::copyState(const StaState *sta) @@ -92,9 +89,8 @@ Sim::functionSense(const FuncExpr *expr, const Pin *input_pin, const Instance *inst) { - debugPrint(debug_, "sim", 4, "find sense pin %s %s", - network_->pathName(input_pin), - expr->to_string().c_str()); + debugPrint(debug_, "sim", 4, "find sense pin {} {}", network_->pathName(input_pin), + expr->to_string()); bool increasing, decreasing; { LockGuard lock(bdd_lock_); @@ -103,10 +99,10 @@ Sim::functionSense(const FuncExpr *expr, LibertyPort *input_port = network_->libertyPort(input_pin); DdNode *input_node = bdd_.ensureNode(input_port); unsigned int input_index = Cudd_NodeReadIndex(input_node); - increasing = (Cudd_Increasing(cudd_mgr, bdd, input_index) - == Cudd_ReadOne(cudd_mgr)); - decreasing = (Cudd_Decreasing(cudd_mgr, bdd, input_index) - == Cudd_ReadOne(cudd_mgr)); + increasing = + (Cudd_Increasing(cudd_mgr, bdd, input_index) == Cudd_ReadOne(cudd_mgr)); + decreasing = + (Cudd_Decreasing(cudd_mgr, bdd, input_index) == Cudd_ReadOne(cudd_mgr)); Cudd_RecursiveDeref(cudd_mgr, bdd); bdd_.clearVarMap(); } @@ -119,7 +115,7 @@ Sim::functionSense(const FuncExpr *expr, sense = TimingSense::negative_unate; else sense = TimingSense::non_unate; - debugPrint(debug_, "sim", 4, " %s", to_string(sense)); + debugPrint(debug_, "sim", 4, " {}", to_string(sense)); return sense; } @@ -159,16 +155,17 @@ Sim::funcBddSim(const FuncExpr *expr, LogicValue value = simValue(pin); int var_index = Cudd_NodeReadIndex(port_node); switch (value) { - case LogicValue::zero: - bdd = Cudd_bddCompose(cudd_mgr, bdd, Cudd_ReadLogicZero(cudd_mgr), var_index); - Cudd_Ref(bdd); - break; - case LogicValue::one: - bdd = Cudd_bddCompose(cudd_mgr, bdd, Cudd_ReadOne(cudd_mgr), var_index); - Cudd_Ref(bdd); - break; - default: - break; + case LogicValue::zero: + bdd = Cudd_bddCompose(cudd_mgr, bdd, Cudd_ReadLogicZero(cudd_mgr), + var_index); + Cudd_Ref(bdd); + break; + case LogicValue::one: + bdd = Cudd_bddCompose(cudd_mgr, bdd, Cudd_ReadOne(cudd_mgr), var_index); + Cudd_Ref(bdd); + break; + default: + break; } } } @@ -243,16 +240,14 @@ bool Sim::isConstant(const Vertex *vertex) const { LogicValue value = simValue(vertex); - return value == LogicValue::zero - || value == LogicValue::one; + return value == LogicValue::zero || value == LogicValue::one; } bool Sim::isConstant(const Pin *pin) const { LogicValue value = simValue(pin); - return value == LogicValue::zero - || value == LogicValue::one; + return value == LogicValue::zero || value == LogicValue::one; } TimingSense @@ -283,8 +278,7 @@ Sim::setSimTimingSense(Edge *edge, bool Sim::isDisabledCond(const Edge *edge) const { - return edge->hasDisabledCond() - && edge_disabled_cond_set_.contains(edge); + return edge->hasDisabledCond() && edge_disabled_cond_set_.contains(edge); } //////////////////////////////////////////////////////////////// @@ -356,13 +350,12 @@ Sim::propagateFromInvalidDrvrsToLoads() { for (const Pin *drvr_pin : invalid_drvr_pins_) { LogicValue value = const_func_pins_.contains(drvr_pin) - ? pinConstFuncValue(drvr_pin) - : simValue(drvr_pin); - PinConnectedPinIterator *load_iter=network_->connectedPinIterator(drvr_pin); + ? pinConstFuncValue(drvr_pin) + : simValue(drvr_pin); + PinConnectedPinIterator *load_iter = network_->connectedPinIterator(drvr_pin); while (load_iter->hasNext()) { const Pin *load_pin = load_iter->next(); - if (load_pin != drvr_pin - && network_->isLoad(load_pin)) + if (load_pin != drvr_pin && network_->isLoad(load_pin)) setPinValue(load_pin, value); } delete load_iter; @@ -413,8 +406,7 @@ Sim::recordConstPinFunc(const Pin *pin) if (expr // Tristate outputs do not force the output to be constant. && port->tristateEnable() == nullptr - && (expr->op() == FuncExpr::Op::zero - || expr->op() == FuncExpr::Op::one)) + && (expr->op() == FuncExpr::Op::zero || expr->op() == FuncExpr::Op::one)) const_func_pins_.insert(pin); } } @@ -507,17 +499,15 @@ void Sim::setConstraintConstPins(const LogicValueMap &value_map) { for (const auto [pin, value] : value_map) { - debugPrint(debug_, "sim", 2, "case pin %s = %c", - network_->pathName(pin), + debugPrint(debug_, "sim", 2, "case pin {} = {}", network_->pathName(pin), logicValueString(value)); if (network_->isHierarchical(pin)) { // Set the logic value on pins inside the instance of a hierarchical pin. bool pin_is_output = network_->direction(pin)->isAnyOutput(); - PinConnectedPinIterator *pin_iter=network_->connectedPinIterator(pin); + PinConnectedPinIterator *pin_iter = network_->connectedPinIterator(pin); while (pin_iter->hasNext()) { const Pin *pin1 = pin_iter->next(); - if (network_->isLeaf(pin1) - && network_->direction(pin1)->isAnyInput() + if (network_->isLeaf(pin1) && network_->direction(pin1)->isAnyInput() && ((pin_is_output && !network_->isInside(pin1, pin)) || (!pin_is_output && network_->isInside(pin1, pin)))) setPinValue(pin1, value); @@ -537,8 +527,7 @@ Sim::setConstFuncPins() for (const Pin *pin : const_func_pins_) { LogicValue value = pinConstFuncValue(pin); setPinValue(pin, value); - debugPrint(debug_, "sim", 2, "func pin %s = %c", - network_->pathName(pin), + debugPrint(debug_, "sim", 2, "func pin {} = {}", network_->pathName(pin), logicValueString(value)); } } @@ -565,9 +554,8 @@ Sim::enqueueConstantPinInputs() LogicValue value; const Pin *pin; const_iter->next(pin, value); - debugPrint(debug_, "sim", 2, "network constant pin %s = %c", - network_->pathName(pin), - logicValueString(value)); + debugPrint(debug_, "sim", 2, "network constant pin {} = {}", + network_->pathName(pin), logicValueString(value)); setPinValue(pin, value); } delete const_iter; @@ -587,7 +575,7 @@ Sim::removePropagatedValue(const Pin *pin) if (!exists) { sdc->logicValue(pin, constraint_value, exists); if (!exists) { - debugPrint(debug_, "sim", 2, "pin %s remove prop constant", + debugPrint(debug_, "sim", 2, "pin {} remove prop constant", network_->pathName(pin)); setSimValue(pin, LogicValue::unknown); } @@ -604,17 +592,16 @@ Sim::setPinValue(const Pin *pin, sdc->caseLogicValue(pin, constraint_value, exists); if (!exists) sdc->logicValue(pin, constraint_value, exists); - if (exists - && value != constraint_value) { + if (exists && value != constraint_value) { if (value != LogicValue::unknown) - report_->warn(1521, "propagated logic value %c differs from constraint value of %c on pin %s.", - logicValueString(value), - logicValueString(constraint_value), - sdc_network_->pathName(pin)); + report_->warn( + 1521, + "propagated logic value {} differs from constraint value of {} on pin {}.", + logicValueString(value), logicValueString(constraint_value), + sdc_network_->pathName(pin)); } else { - debugPrint(debug_, "sim", 3, "pin %s = %c", - network_->pathName(pin), + debugPrint(debug_, "sim", 3, "pin {} = {}", network_->pathName(pin), logicValueString(value)); bool value_changed = false; value_changed |= value != simValue(pin); @@ -623,19 +610,16 @@ Sim::setPinValue(const Pin *pin, Instance *inst = network_->instance(pin); instances_to_annotate_.insert(inst); - if (network_->isLeaf(inst) - && network_->direction(pin)->isAnyInput()) { - if (eval_queue_.empty() - || (eval_queue_.back() != inst)) + if (network_->isLeaf(inst) && network_->direction(pin)->isAnyInput()) { + if (eval_queue_.empty() || (eval_queue_.back() != inst)) eval_queue_.push(inst); } else if (network_->isDriver(pin)) { // Enqueue instances with input pins connected to net. - PinConnectedPinIterator *pin_iter=network_->connectedPinIterator(pin); + PinConnectedPinIterator *pin_iter = network_->connectedPinIterator(pin); while (pin_iter->hasNext()) { const Pin *pin1 = pin_iter->next(); - if (pin1 != pin - && network_->isLoad(pin1)) + if (pin1 != pin && network_->isLoad(pin1)) setPinValue(pin1, value); } delete pin_iter; @@ -648,7 +632,7 @@ void Sim::evalInstance(const Instance *inst, bool thru_sequentials) { - debugPrint(debug_, "sim", 2, "eval %s", network_->pathName(inst)); + debugPrint(debug_, "sim", 2, "eval {}", network_->pathName(inst)); InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); @@ -664,39 +648,32 @@ Sim::evalInstance(const Instance *inst, if (tri_en_expr) { if (evalExpr(tri_en_expr, inst) == LogicValue::one) { value = evalExpr(expr, inst); - debugPrint(debug_, "sim", 2, " %s tri_en=1 %s = %c", - port->name(), - expr->to_string().c_str(), - logicValueString(value)); + debugPrint(debug_, "sim", 2, " {} tri_en=1 {} = {}", port->name(), + expr->to_string(), logicValueString(value)); } } else { LibertyPort *expr_port = expr->port(); - Sequential *sequential = (thru_sequentials && expr_port) - ? cell->outputPortSequential(expr_port) - : nullptr; + Sequential *sequential = (thru_sequentials && expr_port) + ? cell->outputPortSequential(expr_port) + : nullptr; if (sequential) { value = evalExpr(sequential->data(), inst); if (expr_port == sequential->outputInv()) value = logicNot(value); - debugPrint(debug_, "sim", 2, " %s seq %s = %c", - port->name(), - expr->to_string().c_str(), - logicValueString(value)); + debugPrint(debug_, "sim", 2, " {} seq {} = {}", port->name(), + expr->to_string(), logicValueString(value)); } else { value = evalExpr(expr, inst); - debugPrint(debug_, "sim", 2, " %s %s = %c", - port->name(), - expr->to_string().c_str(), - logicValueString(value)); + debugPrint(debug_, "sim", 2, " {} {} = {}", port->name(), + expr->to_string(), logicValueString(value)); } } } else if (port->isClockGateOut()) { value = clockGateOutValue(inst); - debugPrint(debug_, "sim", 2, " %s gated_clk = %c", - port->name(), + debugPrint(debug_, "sim", 2, " {} gated_clk = {}", port->name(), logicValueString(value)); } if (value != simValue(pin)) @@ -714,11 +691,9 @@ Sim::clockGateOutValue(const Instance *inst) LibertyCellPortIterator port_iter(cell); while (port_iter.hasNext()) { LibertyPort *port = port_iter.next(); - if (port->isClockGateClock() - || port->isClockGateEnable()) { + if (port->isClockGateClock() || port->isClockGateEnable()) { Pin *gclk_pin = network_->findPin(inst, port); - if (gclk_pin - && simValue(gclk_pin) == LogicValue::zero) + if (gclk_pin && simValue(gclk_pin) == LogicValue::zero) return LogicValue::zero; } } @@ -932,15 +907,15 @@ Sim::isDisabledMode(Edge *edge, void Sim::findDisabledEdges() { - for (const Instance *inst : instances_to_annotate_) - findDisabledEdges(inst); - instances_to_annotate_.clear(); + for (const Instance *inst : instances_to_annotate_) + findDisabledEdges(inst); + instances_to_annotate_.clear(); } void Sim::findDisabledEdges(const Instance *inst) { - debugPrint(debug_, "sim", 4, "annotate %s", network_->pathName(inst)); + debugPrint(debug_, "sim", 4, "annotate {}", network_->pathName(inst)); InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); @@ -974,9 +949,9 @@ Sim::findDisabledEdges(const Instance *inst, if (sense != TimingSense::none) // Disable conditional timing edges based on constant pins. is_disabled_cond = isDisabledCond(edge, inst, from_pin, pin) - // Disable mode conditional timing - // edges based on constant pins. - || isDisabledMode(edge,inst); + // Disable mode conditional timing + // edges based on constant pins. + || isDisabledMode(edge, inst); bool disables_changed = false; if (sense != simTimingSense(edge)) { @@ -997,4 +972,4 @@ Sim::findDisabledEdges(const Instance *inst, observer_->faninEdgesChangeAfter(vertex->pin()); } -} // namespace +} // namespace sta diff --git a/search/Sta.cc b/search/Sta.cc index d5d58bbb..355ef3f0 100644 --- a/search/Sta.cc +++ b/search/Sta.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 "Sta.hh" @@ -29,6 +29,7 @@ #include #include "Machine.hh" +#include "Format.hh" #include "ContainerHelpers.hh" #include "DispatchQueue.hh" #include "ReportTcl.hh" @@ -95,13 +96,13 @@ namespace sta { static bool libertyPortCapsEqual(const LibertyPort *port1, - const LibertyPort *port2); + const LibertyPort *port2); static bool hasDisabledArcs(Edge *edge, const Mode *mode); static InstanceSet pinInstances(PinSet &pins, - const Network *network); + const Network *network); //////////////////////////////////////////////////////////////// // @@ -201,7 +202,8 @@ StaSimObserver::fanoutEdgesChangeAfter(const Pin *pin) class StaLevelizeObserver : public LevelizeObserver { public: - StaLevelizeObserver(Search *search, GraphDelayCalc *graph_delay_calc); + StaLevelizeObserver(Search *search, + GraphDelayCalc *graph_delay_calc); void levelsChangedBefore() override; void levelChangedBefore(Vertex *vertex) override; @@ -583,8 +585,7 @@ Sta::setCmdMode(const std::string &mode_name) { if (!mode_name.empty()) { if (!mode_name_map_.contains(mode_name)) { - if (modes_.size() == 1 - && modes_[0]->name() == "default") { + if (modes_.size() == 1 && modes_[0]->name() == "default") { // No need for default mode if one is defined. delete modes_[0]; mode_name_map_.clear(); @@ -596,8 +597,7 @@ Sta::setCmdMode(const std::string &mode_name) mode->sim()->setMode(mode); mode->sim()->setObserver(new StaSimObserver(this)); - if (scenes_.size() == 1 - && scenes_[0]->name() == "default") + if (scenes_.size() == 1 && scenes_[0]->name() == "default") scenes_[0]->setMode(mode); updateComponentsState(); } @@ -665,12 +665,12 @@ Sta::setCmdNamespace1(CmdNamespace namespc) { cmd_namespace_ = namespc; switch (cmd_namespace_) { - case CmdNamespace::sta: - cmd_network_ = network_; - break; - case CmdNamespace::sdc: - cmd_network_ = sdc_network_; - break; + case CmdNamespace::sta: + cmd_network_ = network_; + break; + case CmdNamespace::sdc: + cmd_network_ = sdc_network_; + break; } } @@ -694,12 +694,11 @@ Sta::setCurrentInstance(Instance *inst) LibertyLibrary * Sta::readLiberty(const char *filename, Scene *scene, - const MinMaxAll *min_max, - bool infer_latches) + const MinMaxAll *min_max, + bool infer_latches) { Stats stats(debug_, report_); - LibertyLibrary *library = readLibertyFile(filename, scene, min_max, - infer_latches); + LibertyLibrary *library = readLibertyFile(filename, scene, min_max, infer_latches); if (library // The default library is the first library read. // This corresponds to a link_path of '*'. @@ -715,11 +714,10 @@ Sta::readLiberty(const char *filename, LibertyLibrary * Sta::readLibertyFile(const char *filename, Scene *scene, - const MinMaxAll *min_max, - bool infer_latches) + const MinMaxAll *min_max, + bool infer_latches) { - LibertyLibrary *liberty = sta::readLibertyFile(filename, infer_latches, - network_); + LibertyLibrary *liberty = sta::readLibertyFile(filename, infer_latches, network_); if (liberty) { // Don't map liberty cells if they are redefined by reading another // library with the same cell names. @@ -736,7 +734,7 @@ Sta::readLibertyFile(const char *filename, LibertyLibrary * Sta::readLibertyFile(const char *filename, - bool infer_latches) + bool infer_latches) { return sta::readLibertyFile(filename, infer_latches, network_); } @@ -744,11 +742,11 @@ Sta::readLibertyFile(const char *filename, void Sta::readLibertyAfter(LibertyLibrary *liberty, Scene *scene, - const MinMax *min_max) + const MinMax *min_max) { scene->addLiberty(liberty, min_max); - LibertyLibrary::makeSceneMap(liberty, scene->libertyIndex(min_max), - network_, report_); + LibertyLibrary::makeSceneMap(liberty, scene->libertyIndex(min_max), network_, + report_); } bool @@ -780,9 +778,7 @@ Sta::linkDesign(const char *top_cell_name, { clear(); Stats stats(debug_, report_); - bool status = network_->linkNetwork(top_cell_name, - make_black_boxes, - report_); + bool status = network_->linkNetwork(top_cell_name, make_black_boxes, report_); stats.report("Link"); return status; } @@ -791,7 +787,7 @@ Sta::linkDesign(const char *top_cell_name, void Sta::setDebugLevel(const char *what, - int level) + int level) { debug_->setLevel(what, level); } @@ -837,9 +833,9 @@ Sta::pvt(Instance *inst, void Sta::setPvt(Instance *inst, - const MinMaxAll *min_max, - float process, - float voltage, + const MinMaxAll *min_max, + float process, + float voltage, float temperature, Sdc *sdc) { @@ -849,7 +845,7 @@ Sta::setPvt(Instance *inst, void Sta::setPvt(const Instance *inst, - const MinMaxAll *min_max, + const MinMaxAll *min_max, const Pvt &pvt, Sdc *sdc) { @@ -876,9 +872,9 @@ Sta::setVoltage(const Net *net, void Sta::setTimingDerate(TimingDerateType type, - PathClkOrData clk_data, - const RiseFallBoth *rf, - const EarlyLate *early_late, + PathClkOrData clk_data, + const RiseFallBoth *rf, + const EarlyLate *early_late, float derate, Sdc *sdc) { @@ -890,9 +886,9 @@ Sta::setTimingDerate(TimingDerateType type, void Sta::setTimingDerate(const Net *net, - PathClkOrData clk_data, - const RiseFallBoth *rf, - const EarlyLate *early_late, + PathClkOrData clk_data, + const RiseFallBoth *rf, + const EarlyLate *early_late, float derate, Sdc *sdc) { @@ -904,10 +900,10 @@ Sta::setTimingDerate(const Net *net, void Sta::setTimingDerate(const Instance *inst, - TimingDerateCellType type, - PathClkOrData clk_data, - const RiseFallBoth *rf, - const EarlyLate *early_late, + TimingDerateCellType type, + PathClkOrData clk_data, + const RiseFallBoth *rf, + const EarlyLate *early_late, float derate, Sdc *sdc) { @@ -919,10 +915,10 @@ Sta::setTimingDerate(const Instance *inst, void Sta::setTimingDerate(const LibertyCell *cell, - TimingDerateCellType type, - PathClkOrData clk_data, - const RiseFallBoth *rf, - const EarlyLate *early_late, + TimingDerateCellType type, + PathClkOrData clk_data, + const RiseFallBoth *rf, + const EarlyLate *early_late, float derate, Sdc *sdc) { @@ -943,8 +939,8 @@ Sta::unsetTimingDerate(Sdc *sdc) void Sta::setInputSlew(const Port *port, - const RiseFallBoth *rf, - const MinMaxAll *min_max, + const RiseFallBoth *rf, + const MinMaxAll *min_max, float slew, Sdc *sdc) { @@ -954,24 +950,24 @@ Sta::setInputSlew(const Port *port, void Sta::setDriveCell(const LibertyLibrary *library, - const LibertyCell *cell, - const Port *port, - const LibertyPort *from_port, - float *from_slews, - const LibertyPort *to_port, - const RiseFallBoth *rf, + const LibertyCell *cell, + const Port *port, + const LibertyPort *from_port, + float *from_slews, + const LibertyPort *to_port, + const RiseFallBoth *rf, const MinMaxAll *min_max, Sdc *sdc) { - sdc->setDriveCell(library, cell, port, from_port, from_slews, to_port, - rf, min_max); + sdc->setDriveCell(library, cell, port, from_port, from_slews, to_port, rf, + min_max); delaysInvalidFrom(port); } void Sta::setDriveResistance(const Port *port, - const RiseFallBoth *rf, - const MinMaxAll *min_max, + const RiseFallBoth *rf, + const MinMaxAll *min_max, float res, Sdc *sdc) { @@ -1016,7 +1012,7 @@ Sta::setMinPulseWidth(const RiseFallBoth *rf, void Sta::setMinPulseWidth(const Pin *pin, - const RiseFallBoth *rf, + const RiseFallBoth *rf, float min_width, Sdc *sdc) { @@ -1025,7 +1021,7 @@ Sta::setMinPulseWidth(const Pin *pin, void Sta::setMinPulseWidth(const Instance *inst, - const RiseFallBoth *rf, + const RiseFallBoth *rf, float min_width, Sdc *sdc) { @@ -1034,7 +1030,7 @@ Sta::setMinPulseWidth(const Instance *inst, void Sta::setMinPulseWidth(const Clock *clk, - const RiseFallBoth *rf, + const RiseFallBoth *rf, float min_width, Sdc *sdc) { @@ -1069,9 +1065,9 @@ Sta::setWireloadSelection(WireloadSelection *selection, void Sta::setSlewLimit(Clock *clk, - const RiseFallBoth *rf, - const PathClkOrData clk_data, - const MinMax *min_max, + const RiseFallBoth *rf, + const PathClkOrData clk_data, + const MinMax *min_max, float slew, Sdc *sdc) { @@ -1080,7 +1076,7 @@ Sta::setSlewLimit(Clock *clk, void Sta::setSlewLimit(Port *port, - const MinMax *min_max, + const MinMax *min_max, float slew, Sdc *sdc) { @@ -1089,7 +1085,7 @@ Sta::setSlewLimit(Port *port, void Sta::setSlewLimit(Cell *cell, - const MinMax *min_max, + const MinMax *min_max, float slew, Sdc *sdc) { @@ -1098,7 +1094,7 @@ Sta::setSlewLimit(Cell *cell, void Sta::setCapacitanceLimit(Cell *cell, - const MinMax *min_max, + const MinMax *min_max, float cap, Sdc *sdc) { @@ -1107,7 +1103,7 @@ Sta::setCapacitanceLimit(Cell *cell, void Sta::setCapacitanceLimit(Port *port, - const MinMax *min_max, + const MinMax *min_max, float cap, Sdc *sdc) { @@ -1116,7 +1112,7 @@ Sta::setCapacitanceLimit(Port *port, void Sta::setCapacitanceLimit(Pin *pin, - const MinMax *min_max, + const MinMax *min_max, float cap, Sdc *sdc) { @@ -1125,7 +1121,7 @@ Sta::setCapacitanceLimit(Pin *pin, void Sta::setFanoutLimit(Cell *cell, - const MinMax *min_max, + const MinMax *min_max, float fanout, Sdc *sdc) { @@ -1134,7 +1130,7 @@ Sta::setFanoutLimit(Cell *cell, void Sta::setFanoutLimit(Port *port, - const MinMax *min_max, + const MinMax *min_max, float fanout, Sdc *sdc) { @@ -1150,10 +1146,10 @@ Sta::setMaxArea(float area, void Sta::makeClock(const char *name, - PinSet *pins, - bool add_to_pins, - float period, - FloatSeq *waveform, + PinSet *pins, + bool add_to_pins, + float period, + FloatSeq *waveform, char *comment, const Mode *mode) { @@ -1166,25 +1162,23 @@ Sta::makeClock(const char *name, void Sta::makeGeneratedClock(const char *name, - PinSet *pins, - bool add_to_pins, - Pin *src_pin, - Clock *master_clk, - int divide_by, - int multiply_by, - float duty_cycle, - bool invert, - bool combinational, - IntSeq *edges, - FloatSeq *edge_shifts, + PinSet *pins, + bool add_to_pins, + Pin *src_pin, + Clock *master_clk, + int divide_by, + int multiply_by, + float duty_cycle, + bool invert, + bool combinational, + IntSeq *edges, + FloatSeq *edge_shifts, char *comment, const Mode *mode) { - mode->sdc()->makeGeneratedClock(name, pins, add_to_pins, - src_pin, master_clk, - divide_by, multiply_by, duty_cycle, - invert, combinational, - edges, edge_shifts, comment); + mode->sdc()->makeGeneratedClock(name, pins, add_to_pins, src_pin, master_clk, + divide_by, multiply_by, duty_cycle, invert, + combinational, edges, edge_shifts, comment); update_genclks_ = true; search_->arrivalsInvalid(); power_->activitiesInvalid(); @@ -1245,8 +1239,8 @@ Sta::removePropagatedClock(Pin *pin, void Sta::setClockSlew(Clock *clk, - const RiseFallBoth *rf, - const MinMaxAll *min_max, + const RiseFallBoth *rf, + const MinMaxAll *min_max, float slew, Sdc *sdc) { @@ -1272,9 +1266,9 @@ Sta::clockSlewChanged(Clock *clk) void Sta::setClockLatency(Clock *clk, - Pin *pin, - const RiseFallBoth *rf, - const MinMaxAll *min_max, + Pin *pin, + const RiseFallBoth *rf, + const MinMaxAll *min_max, float delay, Sdc *sdc) { @@ -1293,10 +1287,10 @@ Sta::removeClockLatency(const Clock *clk, void Sta::setClockInsertion(const Clock *clk, - const Pin *pin, - const RiseFallBoth *rf, - const MinMaxAll *min_max, - const EarlyLateAll *early_late, + const Pin *pin, + const RiseFallBoth *rf, + const MinMaxAll *min_max, + const EarlyLateAll *early_late, float delay, Sdc *sdc) { @@ -1315,8 +1309,8 @@ Sta::removeClockInsertion(const Clock *clk, void Sta::setClockUncertainty(Clock *clk, - const SetupHoldAll *setup_hold, - float uncertainty) + const SetupHoldAll *setup_hold, + float uncertainty) { clk->setUncertainty(setup_hold, uncertainty); search_->arrivalsInvalid(); @@ -1324,7 +1318,7 @@ Sta::setClockUncertainty(Clock *clk, void Sta::removeClockUncertainty(Clock *clk, - const SetupHoldAll *setup_hold) + const SetupHoldAll *setup_hold) { clk->removeUncertainty(setup_hold); search_->arrivalsInvalid(); @@ -1332,7 +1326,7 @@ Sta::removeClockUncertainty(Clock *clk, void Sta::setClockUncertainty(Pin *pin, - const SetupHoldAll *setup_hold, + const SetupHoldAll *setup_hold, float uncertainty, Sdc *sdc) { @@ -1351,23 +1345,23 @@ Sta::removeClockUncertainty(Pin *pin, void Sta::setClockUncertainty(Clock *from_clk, - const RiseFallBoth *from_rf, - Clock *to_clk, - const RiseFallBoth *to_rf, - const SetupHoldAll *setup_hold, + const RiseFallBoth *from_rf, + Clock *to_clk, + const RiseFallBoth *to_rf, + const SetupHoldAll *setup_hold, float uncertainty, Sdc *sdc) { - sdc->setClockUncertainty(from_clk, from_rf, to_clk, to_rf, - setup_hold, uncertainty); + sdc->setClockUncertainty(from_clk, from_rf, to_clk, to_rf, setup_hold, + uncertainty); search_->arrivalsInvalid(); } void Sta::removeClockUncertainty(Clock *from_clk, - const RiseFallBoth *from_rf, - Clock *to_clk, - const RiseFallBoth *to_rf, + const RiseFallBoth *from_rf, + Clock *to_clk, + const RiseFallBoth *to_rf, const SetupHoldAll *setup_hold, Sdc *sdc) { @@ -1376,26 +1370,31 @@ Sta::removeClockUncertainty(Clock *from_clk, } ClockGroups * -Sta::makeClockGroups(const char *name, - bool logically_exclusive, - bool physically_exclusive, - bool asynchronous, - bool allow_paths, +Sta::makeClockGroups(const std::string &name, + bool logically_exclusive, + bool physically_exclusive, + bool asynchronous, + bool allow_paths, const char *comment, Sdc *sdc) { - ClockGroups *groups = sdc->makeClockGroups(name, - logically_exclusive, - physically_exclusive, - asynchronous, - allow_paths, - comment); + ClockGroups *groups = sdc->makeClockGroups(name, logically_exclusive, + physically_exclusive, + asynchronous, allow_paths, + comment); search_->requiredsInvalid(); return groups; } void -Sta::removeClockGroupsLogicallyExclusive(const char *name, +Sta::removeClockGroupsLogicallyExclusive(Sdc *sdc) +{ + sdc->removeClockGroupsLogicallyExclusive(); + search_->requiredsInvalid(); +} + +void +Sta::removeClockGroupsLogicallyExclusive(const std::string &name, Sdc *sdc) { sdc->removeClockGroupsLogicallyExclusive(name); @@ -1403,7 +1402,14 @@ Sta::removeClockGroupsLogicallyExclusive(const char *name, } void -Sta::removeClockGroupsPhysicallyExclusive(const char *name, +Sta::removeClockGroupsPhysicallyExclusive(Sdc *sdc) +{ + sdc->removeClockGroupsPhysicallyExclusive(); + search_->requiredsInvalid(); +} + +void +Sta::removeClockGroupsPhysicallyExclusive(const std::string &name, Sdc *sdc) { sdc->removeClockGroupsPhysicallyExclusive(name); @@ -1411,7 +1417,14 @@ Sta::removeClockGroupsPhysicallyExclusive(const char *name, } void -Sta::removeClockGroupsAsynchronous(const char *name, +Sta::removeClockGroupsAsynchronous(Sdc *sdc) +{ + sdc->removeClockGroupsAsynchronous(); + search_->requiredsInvalid(); +} + +void +Sta::removeClockGroupsAsynchronous(const std::string &name, Sdc *sdc) { sdc->removeClockGroupsAsynchronous(name); @@ -1428,7 +1441,7 @@ Sta::makeClockGroup(ClockGroups *clk_groups, void Sta::setClockSense(PinSet *pins, - ClockSet *clks, + ClockSet *clks, ClockSense sense, Sdc *sdc) { @@ -1440,7 +1453,7 @@ Sta::setClockSense(PinSet *pins, void Sta::setClockGatingCheck(const RiseFallBoth *rf, - const SetupHold *setup_hold, + const SetupHold *setup_hold, float margin, Sdc *sdc) { @@ -1450,8 +1463,8 @@ Sta::setClockGatingCheck(const RiseFallBoth *rf, void Sta::setClockGatingCheck(Clock *clk, - const RiseFallBoth *rf, - const SetupHold *setup_hold, + const RiseFallBoth *rf, + const SetupHold *setup_hold, float margin, Sdc *sdc) { @@ -1461,48 +1474,48 @@ Sta::setClockGatingCheck(Clock *clk, void Sta::setClockGatingCheck(Instance *inst, - const RiseFallBoth *rf, - const SetupHold *setup_hold, - float margin, + const RiseFallBoth *rf, + const SetupHold *setup_hold, + float margin, LogicValue active_value, Sdc *sdc) { - sdc->setClockGatingCheck(inst, rf, setup_hold, margin,active_value); + sdc->setClockGatingCheck(inst, rf, setup_hold, margin, active_value); search_->arrivalsInvalid(); } void Sta::setClockGatingCheck(Pin *pin, - const RiseFallBoth *rf, - const SetupHold *setup_hold, - float margin, + const RiseFallBoth *rf, + const SetupHold *setup_hold, + float margin, LogicValue active_value, Sdc *sdc) { - sdc->setClockGatingCheck(pin, rf, setup_hold, margin,active_value); + sdc->setClockGatingCheck(pin, rf, setup_hold, margin, active_value); search_->arrivalsInvalid(); } void Sta::setDataCheck(Pin *from, - const RiseFallBoth *from_rf, - Pin *to, - const RiseFallBoth *to_rf, - Clock *clk, - const SetupHoldAll *setup_hold, + const RiseFallBoth *from_rf, + Pin *to, + const RiseFallBoth *to_rf, + Clock *clk, + const SetupHoldAll *setup_hold, float margin, Sdc *sdc) { - sdc->setDataCheck(from, from_rf, to, to_rf, clk, setup_hold,margin); + sdc->setDataCheck(from, from_rf, to, to_rf, clk, setup_hold, margin); search_->requiredInvalid(to); } void Sta::removeDataCheck(Pin *from, - const RiseFallBoth *from_rf, - Pin *to, - const RiseFallBoth *to_rf, - Clock *clk, + const RiseFallBoth *from_rf, + Pin *to, + const RiseFallBoth *to_rf, + Clock *clk, const SetupHoldAll *setup_hold, Sdc *sdc) { @@ -1533,7 +1546,7 @@ Sta::removeDisable(Pin *pin, void Sta::disable(Instance *inst, - LibertyPort *from, + LibertyPort *from, LibertyPort *to, Sdc *sdc) { @@ -1559,7 +1572,7 @@ Sta::disable(Instance *inst, void Sta::removeDisable(Instance *inst, - LibertyPort *from, + LibertyPort *from, LibertyPort *to, Sdc *sdc) { @@ -1585,7 +1598,7 @@ Sta::removeDisable(Instance *inst, void Sta::disable(LibertyCell *cell, - LibertyPort *from, + LibertyPort *from, LibertyPort *to, Sdc *sdc) { @@ -1595,7 +1608,7 @@ Sta::disable(LibertyCell *cell, void Sta::removeDisable(LibertyCell *cell, - LibertyPort *from, + LibertyPort *from, LibertyPort *to, Sdc *sdc) { @@ -1687,18 +1700,15 @@ Sta::disabledEdges(const Mode *mode) VertexOutEdgeIterator edge_iter(vertex, graph_); while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); - if (isDisabledConstant(edge, mode) - || isDisabledCondDefault(edge) - || isDisabledConstraint(edge, sdc) - || edge->isDisabledLoop() - || isDisabledPresetClr(edge)) - disabled_edges.push_back(edge); + if (isDisabledConstant(edge, mode) || isDisabledCondDefault(edge) + || isDisabledConstraint(edge, sdc) || edge->isDisabledLoop() + || isDisabledPresetClr(edge)) + disabled_edges.push_back(edge); } } return disabled_edges; } - EdgeSeq Sta::disabledEdgesSorted(const Mode *mode) { @@ -1713,9 +1723,8 @@ Sta::isDisabledConstraint(Edge *edge, { Pin *from_pin = edge->from(graph_)->pin(); Pin *to_pin = edge->to(graph_)->pin(); - return sdc->isDisabledConstraint(from_pin) - || sdc->isDisabledConstraint(to_pin) - || sdc->isDisabledConstraint(edge); + return sdc->isDisabledConstraint(from_pin) || sdc->isDisabledConstraint(to_pin) + || sdc->isDisabledConstraint(edge); } bool @@ -1739,12 +1748,10 @@ Sta::isDisabledConstant(Edge *edge, Vertex *to_vertex = edge->to(graph_); Pin *to_pin = to_vertex->pin(); const Instance *inst = network_->instance(from_pin); - return sim->isConstant(from_vertex) - || sim->isConstant(to_vertex) - || (!role->isWire() - && (sim->isDisabledCond(edge, inst, from_pin, to_pin) - || sim->isDisabledMode(edge, inst) - || hasDisabledArcs(edge, mode))); + return sim->isConstant(from_vertex) || sim->isConstant(to_vertex) + || (!role->isWire() + && (sim->isDisabledCond(edge, inst, from_pin, to_pin) + || sim->isDisabledMode(edge, inst) || hasDisabledArcs(edge, mode))); } static bool @@ -1786,8 +1793,7 @@ Sta::disabledConstantPins(Edge *edge, const Instance *inst = network_->instance(to_pin); bool is_disabled; FuncExpr *disable_cond; - sim->isDisabledCond(edge, inst, from_pin, to_pin, - is_disabled, disable_cond); + sim->isDisabledCond(edge, inst, from_pin, to_pin, is_disabled, disable_cond); if (is_disabled) exprConstantPins(disable_cond, inst, mode, pins); sim->isDisabledMode(edge, inst, is_disabled, disable_cond); @@ -1796,9 +1802,8 @@ Sta::disabledConstantPins(Edge *edge, if (hasDisabledArcs(edge, mode)) { LibertyPort *to_port = network_->libertyPort(to_pin); if (to_port) { - FuncExpr *func = to_port->function(); - if (func - && sim->functionSense(inst, from_pin, to_pin) != edge->sense()) + FuncExpr *func = to_port->function(); + if (func && sim->functionSense(inst, from_pin, to_pin) != edge->sense()) exprConstantPins(func, inst, mode, pins); } } @@ -1829,7 +1834,7 @@ Sta::exprConstantPins(FuncExpr *expr, if (pin) { LogicValue value = mode->sim()->simValue(pin); if (value != LogicValue::unknown) - pins.insert(pin); + pins.insert(pin); } } } @@ -1837,15 +1842,14 @@ Sta::exprConstantPins(FuncExpr *expr, bool Sta::isDisabledBidirectInstPath(Edge *edge) const { - return !variables_->bidirectInstPathsEnabled() - && edge->isBidirectInstPath(); + return !variables_->bidirectInstPathsEnabled() && edge->isBidirectInstPath(); } bool Sta::isDisabledPresetClr(Edge *edge) const { return !variables_->presetClrArcsEnabled() - && edge->role() == TimingRole::regSetClr(); + && edge->role() == TimingRole::regSetClr(); } void @@ -1930,29 +1934,28 @@ Sta::removeCaseAnalysis(Pin *pin, void Sta::setInputDelay(const Pin *pin, - const RiseFallBoth *rf, - const Clock *clk, - const RiseFall *clk_rf, - const Pin *ref_pin, - bool source_latency_included, - bool network_latency_included, - const MinMaxAll *min_max, - bool add, + const RiseFallBoth *rf, + const Clock *clk, + const RiseFall *clk_rf, + const Pin *ref_pin, + bool source_latency_included, + bool network_latency_included, + const MinMaxAll *min_max, + bool add, float delay, Sdc *sdc) { - sdc->setInputDelay(pin, rf, clk, clk_rf, ref_pin, - source_latency_included, network_latency_included, - min_max, add, delay); + sdc->setInputDelay(pin, rf, clk, clk_rf, ref_pin, source_latency_included, + network_latency_included, min_max, add, delay); search_->arrivalInvalid(pin); } -void +void Sta::removeInputDelay(const Pin *pin, - const RiseFallBoth *rf, - const Clock *clk, - const RiseFall *clk_rf, + const RiseFallBoth *rf, + const Clock *clk, + const RiseFall *clk_rf, const MinMaxAll *min_max, Sdc *sdc) { @@ -1962,28 +1965,27 @@ Sta::removeInputDelay(const Pin *pin, void Sta::setOutputDelay(const Pin *pin, - const RiseFallBoth *rf, - const Clock *clk, - const RiseFall *clk_rf, - const Pin *ref_pin, - bool source_latency_included, - bool network_latency_included, - const MinMaxAll *min_max, - bool add, + const RiseFallBoth *rf, + const Clock *clk, + const RiseFall *clk_rf, + const Pin *ref_pin, + bool source_latency_included, + bool network_latency_included, + const MinMaxAll *min_max, + bool add, float delay, Sdc *sdc) { - sdc->setOutputDelay(pin, rf, clk, clk_rf, ref_pin, - source_latency_included,network_latency_included, - min_max, add, delay); + sdc->setOutputDelay(pin, rf, clk, clk_rf, ref_pin, source_latency_included, + network_latency_included, min_max, add, delay); search_->requiredInvalid(pin); } -void +void Sta::removeOutputDelay(const Pin *pin, - const RiseFallBoth *rf, - const Clock *clk, - const RiseFall *clk_rf, + const RiseFallBoth *rf, + const Clock *clk, + const RiseFall *clk_rf, const MinMaxAll *min_max, Sdc *sdc) { @@ -1993,9 +1995,9 @@ Sta::removeOutputDelay(const Pin *pin, void Sta::makeFalsePath(ExceptionFrom *from, - ExceptionThruSeq *thrus, - ExceptionTo *to, - const MinMaxAll *min_max, + ExceptionThruSeq *thrus, + ExceptionTo *to, + const MinMaxAll *min_max, const char *comment, Sdc *sdc) { @@ -2005,42 +2007,40 @@ Sta::makeFalsePath(ExceptionFrom *from, void Sta::makeMulticyclePath(ExceptionFrom *from, - ExceptionThruSeq *thrus, - ExceptionTo *to, - const MinMaxAll *min_max, - bool use_end_clk, - int path_multiplier, + ExceptionThruSeq *thrus, + ExceptionTo *to, + const MinMaxAll *min_max, + bool use_end_clk, + int path_multiplier, const char *comment, Sdc *sdc) { - sdc->makeMulticyclePath(from, thrus, to, min_max, - use_end_clk, path_multiplier, - comment); + sdc->makeMulticyclePath(from, thrus, to, min_max, use_end_clk, path_multiplier, + comment); search_->arrivalsInvalid(); } void Sta::makePathDelay(ExceptionFrom *from, - ExceptionThruSeq *thrus, - ExceptionTo *to, - const MinMax *min_max, - bool ignore_clk_latency, + ExceptionThruSeq *thrus, + ExceptionTo *to, + const MinMax *min_max, + bool ignore_clk_latency, bool break_path, - float delay, + float delay, const char *comment, Sdc *sdc) { - sdc->makePathDelay(from, thrus, to, min_max, - ignore_clk_latency, break_path, - delay, comment); + sdc->makePathDelay(from, thrus, to, min_max, ignore_clk_latency, break_path, delay, + comment); search_->endpointsInvalid(); search_->arrivalsInvalid(); } void Sta::resetPath(ExceptionFrom *from, - ExceptionThruSeq *thrus, - ExceptionTo *to, + ExceptionThruSeq *thrus, + ExceptionTo *to, const MinMaxAll *min_max, Sdc *sdc) { @@ -2049,11 +2049,11 @@ Sta::resetPath(ExceptionFrom *from, } void -Sta::makeGroupPath(const char *name, - bool is_default, - ExceptionFrom *from, - ExceptionThruSeq *thrus, - ExceptionTo *to, +Sta::makeGroupPath(const std::string &name, + bool is_default, + ExceptionFrom *from, + ExceptionThruSeq *thrus, + ExceptionTo *to, const char *comment, Sdc *sdc) { @@ -2072,12 +2072,11 @@ bool Sta::isPathGroupName(const char *group_name, const Sdc *sdc) const { - return sdc->findClock(group_name) - || sdc->isGroupPathName(group_name) - || stringEq(group_name, PathGroups::asyncPathGroupName()) - || stringEq(group_name, PathGroups::pathDelayGroupName()) - || stringEq(group_name, PathGroups::gatedClkGroupName()) - || stringEq(group_name, PathGroups::unconstrainedGroupName()); + return sdc->findClock(group_name) || sdc->isGroupPathName(group_name) + || stringEq(group_name, PathGroups::asyncPathGroupName()) + || stringEq(group_name, PathGroups::pathDelayGroupName()) + || stringEq(group_name, PathGroups::gatedClkGroupName()) + || stringEq(group_name, PathGroups::unconstrainedGroupName()); } StringSeq @@ -2099,8 +2098,8 @@ Sta::pathGroupNames(const Sdc *sdc) const ExceptionFrom * Sta::makeExceptionFrom(PinSet *from_pins, - ClockSet *from_clks, - InstanceSet *from_insts, + ClockSet *from_clks, + InstanceSet *from_insts, const RiseFallBoth *from_rf, const Sdc *sdc) { @@ -2109,7 +2108,7 @@ Sta::makeExceptionFrom(PinSet *from_pins, void Sta::checkExceptionFromPins(ExceptionFrom *from, - const char *file, + const char *file, int line, const Sdc *sdc) const { @@ -2118,16 +2117,16 @@ Sta::checkExceptionFromPins(ExceptionFrom *from, if (pins) { for (const Pin *pin : *pins) { if (!sdc->isExceptionStartpoint(pin)) { - if (line) - report_->fileWarn(1554, file, line, "'%s' is not a valid start point.", - cmd_network_->pathName(pin)); - else - report_->warn(1550, "'%s' is not a valid start point.", - cmd_network_->pathName(pin)); + if (line) + report_->fileWarn(1554, file, line, "'{}' is not a valid start point.", + cmd_network_->pathName(pin)); + else + report_->warn(1550, "'{}' is not a valid start point.", + cmd_network_->pathName(pin)); + } } } } - } } void @@ -2138,8 +2137,8 @@ Sta::deleteExceptionFrom(ExceptionFrom *from) ExceptionThru * Sta::makeExceptionThru(PinSet *pins, - NetSet *nets, - InstanceSet *insts, + NetSet *nets, + InstanceSet *insts, const RiseFallBoth *rf, const Sdc *sdc) { @@ -2154,9 +2153,9 @@ Sta::deleteExceptionThru(ExceptionThru *thru) ExceptionTo * Sta::makeExceptionTo(PinSet *to_pins, - ClockSet *to_clks, - InstanceSet *to_insts, - const RiseFallBoth *rf, + ClockSet *to_clks, + InstanceSet *to_insts, + const RiseFallBoth *rf, const RiseFallBoth *end_rf, const Sdc *sdc) { @@ -2171,7 +2170,7 @@ Sta::deleteExceptionTo(ExceptionTo *to) void Sta::checkExceptionToPins(ExceptionTo *to, - const char *file, + const char *file, int line, const Sdc *sdc) const { @@ -2180,30 +2179,30 @@ Sta::checkExceptionToPins(ExceptionTo *to, if (pins) { for (const Pin *pin : *pins) { if (!sdc->isExceptionEndpoint(pin)) { - if (line) - report_->fileWarn(1551, file, line, "'%s' is not a valid endpoint.", - cmd_network_->pathName(pin)); - else - report_->warn(1552, "'%s' is not a valid endpoint.", - cmd_network_->pathName(pin)); + if (line) + report_->fileWarn(1551, file, line, "'{}' is not a valid endpoint.", + cmd_network_->pathName(pin)); + else + report_->warn(1552, "'{}' is not a valid endpoint.", + cmd_network_->pathName(pin)); + } } } } - } } void Sta::writeSdc(const Sdc *sdc, const char *filename, - bool leaf, - bool native, - int digits, + bool leaf, + bool native, + int digits, bool gzip, - bool no_timestamp) + bool no_timestamp) { ensureLibLinked(); - sta::writeSdc(sdc, network_->topInstance(), filename, "write_sdc", - leaf, native, digits, gzip, no_timestamp); + sta::writeSdc(sdc, network_->topInstance(), filename, "write_sdc", leaf, native, + digits, gzip, no_timestamp); } //////////////////////////////////////////////////////////////// @@ -2211,12 +2210,12 @@ Sta::writeSdc(const Sdc *sdc, CheckErrorSeq & Sta::checkTiming(const Mode *mode, bool no_input_delay, - bool no_output_delay, - bool reg_multiple_clks, - bool reg_no_clks, - bool unconstrained_endpoints, - bool loops, - bool generated_clks) + bool no_output_delay, + bool reg_multiple_clks, + bool reg_no_clks, + bool unconstrained_endpoints, + bool loops, + bool generated_clks) { if (unconstrained_endpoints) { // Only need non-clock arrivals to find unconstrained_endpoints. @@ -2230,9 +2229,8 @@ Sta::checkTiming(const Mode *mode, mode->clkNetwork()->ensureClkNetwork(); } return check_timing_->check(mode, no_input_delay, no_output_delay, - reg_multiple_clks, reg_no_clks, - unconstrained_endpoints, - loops, generated_clks); + reg_multiple_clks, reg_no_clks, + unconstrained_endpoints, loops, generated_clks); } //////////////////////////////////////////////////////////////// @@ -2261,8 +2259,7 @@ void Sta::setCrprMode(CrprMode mode) { // Pessimism is only relevant for on_chip_variation analysis. - if (variables_->crprEnabled() - && variables_->crprMode() != mode) + if (variables_->crprEnabled() && variables_->crprMode() != mode) search_->arrivalsInvalid(); variables_->setCrprMode(mode); } @@ -2378,7 +2375,7 @@ bool Sta::recoveryRemovalChecksEnabled() const { return variables_->recoveryRemovalChecksEnabled(); -} +} void Sta::setRecoveryRemovalChecksEnabled(bool enabled) @@ -2529,10 +2526,9 @@ Sta::makeScene(const std::string &name, parasitics_min = findParasitics(spef_min_file); parasitics_max = findParasitics(spef_max_file); if (parasitics_min == nullptr) - report_->error(1558, "Spef file %s not found.", spef_min_file.c_str()); - if (parasitics_max == nullptr - && spef_max_file != spef_min_file) - report_->error(1559, "Spef file %s not found.", spef_max_file.c_str()); + report_->error(1558, "Spef file {} not found.", spef_min_file); + if (parasitics_max == nullptr && spef_max_file != spef_min_file) + report_->error(1559, "Spef file {} not found.", spef_max_file); } mode->sdc()->makeSceneBefore(); @@ -2544,7 +2540,7 @@ Sta::makeScene(const std::string &name, cmd_scene_ = scene; } else - report_->error(1572, "mode %s not found.", mode_name.c_str()); + report_->error(1572, "mode {} not found.", mode_name); } Scene * @@ -2576,12 +2572,11 @@ Sta::makeScene(const std::string &name, Parasitics *parasitics_min, Parasitics *parasitics_max) { - if (scenes_.size() == 1 - && findScene("default")) + if (scenes_.size() == 1 && findScene("default")) deleteScenes(); - Scene *scene = new Scene(name, scenes_.size(), mode, - parasitics_min, parasitics_max); + Scene *scene = + new Scene(name, scenes_.size(), mode, parasitics_min, parasitics_max); scene_name_map_[name] = scene; scenes_.push_back(scene); mode->addScene(scene); @@ -2628,18 +2623,17 @@ Sta::updateSceneLiberty(Scene *scene, { StringSet warned_files; for (const MinMax *min_max : MinMax::range()) { - const StringSeq &liberty_files = min_max == MinMax::min() - ? liberty_min_files - : liberty_max_files; + const StringSeq &liberty_files = + min_max == MinMax::min() ? liberty_min_files : liberty_max_files; for (const std::string &lib_file : liberty_files) { LibertyLibrary *lib = network_->findLiberty(lib_file.c_str()); - if (lib == nullptr) + if (lib == nullptr) lib = network_->findLibertyFilename(lib_file.c_str()); if (lib) - LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), - network_, report_); + LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), network_, + report_); else if (!warned_files.contains(lib_file)) { - report_->warn(1555, "liberty name/filename %s not found.", lib_file.c_str()); + report_->warn(1555, "liberty name/filename {} not found.", lib_file); warned_files.insert(lib_file); } } @@ -2654,8 +2648,8 @@ Sta::updateLibertyScenes() while (iter->hasNext()) { LibertyLibrary *lib = iter->next(); for (const MinMax *min_max : MinMax::range()) { - LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), - network_, report_); + LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), network_, + report_); } } } @@ -2691,36 +2685,33 @@ Sta::makeSceneSeq(Scene *scene) const // PathEnds are owned by Search PathGroups and deleted on next call. PathEndSeq Sta::findPathEnds(ExceptionFrom *from, - ExceptionThruSeq *thrus, - ExceptionTo *to, - bool unconstrained, + ExceptionThruSeq *thrus, + ExceptionTo *to, + bool unconstrained, const SceneSeq &scenes, - const MinMaxAll *min_max, - int group_path_count, - int endpoint_path_count, - bool unique_pins, - bool unique_edges, - float slack_min, - float slack_max, - bool sort_by_slack, + const MinMaxAll *min_max, + int group_path_count, + int endpoint_path_count, + bool unique_pins, + bool unique_edges, + float slack_min, + float slack_max, + bool sort_by_slack, StringSeq &group_names, - bool setup, - bool hold, - bool recovery, - bool removal, - bool clk_gating_setup, - bool clk_gating_hold) + bool setup, + bool hold, + bool recovery, + bool removal, + bool clk_gating_setup, + bool clk_gating_hold) { searchPreamble(); clk_skews_->clear(); - return search_->findPathEnds(from, thrus, to, unconstrained, - scenes, min_max, group_path_count, - endpoint_path_count, - unique_pins, unique_edges, slack_min, slack_max, - sort_by_slack, group_names, - setup, hold, - recovery, removal, - clk_gating_setup, clk_gating_hold); + return search_->findPathEnds(from, thrus, to, unconstrained, scenes, min_max, + group_path_count, endpoint_path_count, unique_pins, + unique_edges, slack_min, slack_max, sort_by_slack, + group_names, setup, hold, recovery, removal, + clk_gating_setup, clk_gating_hold); } //////////////////////////////////////////////////////////////// @@ -2824,23 +2815,21 @@ Sta::updateTiming(bool full) void Sta::reportClkSkew(ConstClockSeq &clks, const SceneSeq &scenes, - const SetupHold *setup_hold, + const SetupHold *setup_hold, bool include_internal_latency, - int digits) + int digits) { clkSkewPreamble(); - clk_skews_->reportClkSkew(clks, scenes, setup_hold, - include_internal_latency, digits); + clk_skews_->reportClkSkew(clks, scenes, setup_hold, include_internal_latency, + digits); } Delay Sta::findWorstClkSkew(const SetupHold *setup_hold, bool include_internal_latency) { - clkSkewPreamble(); - return clk_skews_->findWorstClkSkew(scenes_, setup_hold, - include_internal_latency); + return clk_skews_->findWorstClkSkew(scenes_, setup_hold, include_internal_latency); } void @@ -2944,15 +2933,15 @@ Sta::findRequireds() Path * Sta::vertexWorstArrivalPath(Vertex *vertex, - const MinMax *min_max) + const MinMax *min_max) { return vertexWorstArrivalPath(vertex, nullptr, min_max); } Path * Sta::vertexWorstArrivalPath(Vertex *vertex, - const RiseFall *rf, - const MinMax *min_max) + const RiseFall *rf, + const MinMax *min_max) { Path *worst_path = nullptr; Arrival worst_arrival = min_max->initValue(); @@ -2961,7 +2950,7 @@ Sta::vertexWorstArrivalPath(Vertex *vertex, Path *path = path_iter.next(); Arrival arrival = path->arrival(); if (!path->tag(this)->isGenClkSrcPath() - && delayGreater(arrival, worst_arrival, min_max, this)) { + && delayGreater(arrival, worst_arrival, min_max, this)) { worst_arrival = arrival; worst_path = path; } @@ -2989,7 +2978,7 @@ Sta::vertexWorstRequiredPath(Vertex *vertex, Path *path = path_iter.next(); const Required path_req = path->required(); if (!path->tag(this)->isGenClkSrcPath() - && delayGreater(path_req, worst_req, req_min_max, this)) { + && delayGreater(path_req, worst_req, req_min_max, this)) { worst_req = path_req; worst_path = path; } @@ -2999,8 +2988,8 @@ Sta::vertexWorstRequiredPath(Vertex *vertex, Path * Sta::vertexWorstSlackPath(Vertex *vertex, - const RiseFall *rf, - const MinMax *min_max) + const RiseFall *rf, + const MinMax *min_max) { Path *worst_path = nullptr; Slack min_slack = MinMax::min()->initValue(); @@ -3008,8 +2997,7 @@ Sta::vertexWorstSlackPath(Vertex *vertex, while (path_iter.hasNext()) { Path *path = path_iter.next(); Slack slack = path->slack(this); - if (!path->tag(this)->isGenClkSrcPath() - && delayLess(slack, min_slack, this)) { + if (!path->tag(this)->isGenClkSrcPath() && delayLess(slack, min_slack, this)) { min_slack = slack; worst_path = path; } @@ -3019,7 +3007,7 @@ Sta::vertexWorstSlackPath(Vertex *vertex, Path * Sta::vertexWorstSlackPath(Vertex *vertex, - const MinMax *min_max) + const MinMax *min_max) { return vertexWorstSlackPath(vertex, nullptr, min_max); @@ -3028,7 +3016,7 @@ Sta::vertexWorstSlackPath(Vertex *vertex, Arrival Sta::arrival(const Pin *pin, const RiseFallBoth *rf, - const MinMax *min_max) + const MinMax *min_max) { Vertex *vertex, *bidirect_vertex; graph_->pinVertices(pin, vertex, bidirect_vertex); @@ -3047,7 +3035,7 @@ Arrival Sta::arrival(Vertex *vertex, const RiseFallBoth *rf, const SceneSeq &scenes, - const MinMax *min_max) + const MinMax *min_max) { searchPreamble(); search_->findArrivals(vertex->level()); @@ -3061,9 +3049,8 @@ Sta::arrival(Vertex *vertex, if (!clk_info->isGenClkSrcPath() && (rf == RiseFallBoth::riseFall() || path->transition(this)->asRiseFallBoth() == rf) - && path->minMax(this) == min_max - && scenes_set.contains(path->scene(this)) - && delayGreater(path->arrival(), arrival, min_max, this)) + && path->minMax(this) == min_max && scenes_set.contains(path->scene(this)) + && delayGreater(path->arrival(), arrival, min_max, this)) arrival = path_arrival; } return arrival; @@ -3073,7 +3060,7 @@ Required Sta::required(Vertex *vertex, const RiseFallBoth *rf, const SceneSeq &scenes, - const MinMax *min_max) + const MinMax *min_max) { findRequired(vertex); const SceneSet scenes_set = Scene::sceneSet(scenes); @@ -3085,9 +3072,8 @@ Sta::required(Vertex *vertex, const Required path_required = path->required(); if ((rf == RiseFallBoth::riseFall() || path->transition(this)->asRiseFallBoth() == rf) - && path->minMax(this) == min_max - && scenes_set.contains(path->scene(this)) - && delayGreater(path_required, required, req_min_max, this)) + && path->minMax(this) == min_max && scenes_set.contains(path->scene(this)) + && delayGreater(path_required, required, req_min_max, this)) required = path_required; } return required; @@ -3144,8 +3130,8 @@ Sta::slack(Vertex *vertex, Slack Sta::slack(Vertex *vertex, - const RiseFall *rf, - const MinMax *min_max) + const RiseFall *rf, + const MinMax *min_max) { return slack(vertex, rf->asRiseFallBoth(), scenes_, min_max); } @@ -3166,8 +3152,7 @@ Sta::slack(Vertex *vertex, Slack path_slack = path->slack(this); if ((rf == RiseFallBoth::riseFall() || path->transition(this)->asRiseFallBoth() == rf) - && path->minMax(this) == min_max - && scenes_set.contains(path->scene(this)) + && path->minMax(this) == min_max && scenes_set.contains(path->scene(this)) && delayLess(path_slack, slack, this)) slack = path_slack; } @@ -3237,9 +3222,9 @@ EndpointPathEndVisitor::visit(PathEnd *path_end) StringSeq group_names = PathGroups::pathGroupNames(path_end, sta_); for (std::string &group_name : group_names) { if (group_name == path_group_name_) { - Slack end_slack = path_end->slack(sta_); - if (delayLess(end_slack, slack_, sta_)) - slack_ = end_slack; + Slack end_slack = path_end->slack(sta_); + if (delayLess(end_slack, slack_, sta_)) + slack_ = end_slack; } } } @@ -3355,25 +3340,21 @@ Sta::reportDelaysWrtClks(Vertex *vertex, int digits, PathDelayFunc get_path_delay) { - RiseFallMinMaxDelay delays = findDelaysWrtClks(vertex, clk_edge, scene, - get_path_delay); + RiseFallMinMaxDelay delays = + findDelaysWrtClks(vertex, clk_edge, scene, get_path_delay); if (!delays.empty()) { std::string clk_name; - if (clk_edge) { - clk_name = " ("; - clk_name += clk_edge->name(); - clk_name += ')'; - } - report_->reportLine("%s r %s:%s f %s:%s", - clk_name.c_str(), - formatDelay(RiseFall::rise(), MinMax::min(), - delays, report_variance, digits).c_str(), - formatDelay(RiseFall::rise(), MinMax::max(), - delays, report_variance, digits).c_str(), - formatDelay(RiseFall::fall(), MinMax::min(), - delays, report_variance, digits).c_str(), - formatDelay(RiseFall::fall(), MinMax::max(), - delays, report_variance, digits).c_str()); + if (clk_edge) + clk_name = sta::format("({})", clk_edge->name()); + report_->report("{} r {}:{} f {}:{}", clk_name, + formatDelay(RiseFall::rise(), MinMax::min(), + delays, report_variance, digits).c_str(), + formatDelay(RiseFall::rise(), MinMax::max(), + delays, report_variance, digits).c_str(), + formatDelay(RiseFall::fall(), MinMax::min(), + delays, report_variance, digits).c_str(), + formatDelay(RiseFall::fall(), MinMax::max(), + delays, report_variance, digits).c_str()); } } @@ -3460,10 +3441,8 @@ MinPeriodEndVisitor::visit(PathEnd *path_end) const ClockEdge *src_edge = path_end->sourceClkEdge(sta_); const ClockEdge *tgt_edge = path_end->targetClkEdge(sta_); PathEnd::Type end_type = path_end->type(); - if ((end_type == PathEnd::Type::check - || end_type == PathEnd::Type::output_delay) - && path->minMax(sta_) == MinMax::max() - && src_edge->clock() == clk_ + if ((end_type == PathEnd::Type::check || end_type == PathEnd::Type::output_delay) + && path->minMax(sta_) == MinMax::max() && src_edge->clock() == clk_ && tgt_edge->clock() == clk_ // Only consider rise/rise and fall/fall paths. && src_edge->transition() == tgt_edge->transition() @@ -3527,7 +3506,7 @@ Sta::totalNegativeSlack(const MinMax *min_max) Slack Sta::totalNegativeSlack(const Scene *scene, - const MinMax *min_max) + const MinMax *min_max) { searchPreamble(); return search_->totalNegativeSlack(scene, min_max); @@ -3545,9 +3524,9 @@ Sta::worstSlack(const MinMax *min_max) void Sta::worstSlack(const MinMax *min_max, - // Return values. - Slack &worst_slack, - Vertex *&worst_vertex) + // Return values. + Slack &worst_slack, + Vertex *&worst_vertex) { searchPreamble(); search_->worstSlack(min_max, worst_slack, worst_vertex); @@ -3555,10 +3534,10 @@ Sta::worstSlack(const MinMax *min_max, void Sta::worstSlack(const Scene *scene, - const MinMax *min_max, - // Return values. - Slack &worst_slack, - Vertex *&worst_vertex) + const MinMax *min_max, + // Return values. + Slack &worst_slack, + Vertex *&worst_vertex) { searchPreamble(); return search_->worstSlack(scene, min_max, worst_slack, worst_vertex); @@ -3624,7 +3603,7 @@ Sta::setIncrementalDelayTolerance(float tol) const ArcDelay Sta::arcDelay(Edge *edge, - TimingArc *arc, + TimingArc *arc, DcalcAPIndex ap_index) { findDelays(edge->to(graph_)); @@ -3633,7 +3612,7 @@ Sta::arcDelay(Edge *edge, bool Sta::arcDelayAnnotated(Edge *edge, - TimingArc *arc, + TimingArc *arc, const Scene *scene, const MinMax *min_max) { @@ -3643,10 +3622,10 @@ Sta::arcDelayAnnotated(Edge *edge, void Sta::setArcDelayAnnotated(Edge *edge, - TimingArc *arc, + TimingArc *arc, const Scene *scene, const MinMax *min_max, - bool annotated) + bool annotated) { DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max); graph_->setArcDelayAnnotated(edge, arc, ap_index, annotated); @@ -3661,7 +3640,7 @@ Slew Sta::slew(Vertex *vertex, const RiseFallBoth *rf, const SceneSeq &scenes, - const MinMax *min_max) + const MinMax *min_max) { findDelays(vertex); Slew mm_slew = min_max->initValue(); @@ -3736,22 +3715,22 @@ Sta::updateGeneratedClks() for (Mode *mode : modes_) { Genclks *genclks = mode->genclks(); Sdc *sdc = mode->sdc(); - bool gen_clk_changed = true; - while (gen_clk_changed) { - gen_clk_changed = false; + bool gen_clk_changed = true; + while (gen_clk_changed) { + gen_clk_changed = false; for (Clock *clk : sdc->clocks()) { - if (clk->isGenerated() && !clk->waveformValid()) { + if (clk->isGenerated() && !clk->waveformValid()) { genclks->ensureMaster(clk, sdc); - Clock *master_clk = clk->masterClk(); - if (master_clk && master_clk->waveformValid()) { - clk->generate(master_clk); - gen_clk_changed = true; - } - } + Clock *master_clk = clk->masterClk(); + if (master_clk && master_clk->waveformValid()) { + clk->generate(master_clk); + gen_clk_changed = true; + } + } + } } } } - } update_genclks_ = false; } @@ -3787,7 +3766,7 @@ Sta::maxPathCountVertex() const } int -Sta::vertexPathCount(Vertex *vertex) const +Sta::vertexPathCount(Vertex *vertex) const { TagGroup *tag_group = search_->tagGroup(vertex); if (tag_group) @@ -3828,10 +3807,10 @@ Sta::clkInfoCount() const void Sta::setArcDelay(Edge *edge, - TimingArc *arc, + TimingArc *arc, const Scene *scene, - const MinMaxAll *min_max, - ArcDelay delay) + const MinMaxAll *min_max, + ArcDelay delay) { ensureGraph(); for (const MinMax *mm : min_max->range()) { @@ -3851,9 +3830,9 @@ Sta::setArcDelay(Edge *edge, void Sta::setAnnotatedSlew(Vertex *vertex, const Scene *scene, - const MinMaxAll *min_max, - const RiseFallBoth *rf, - float slew) + const MinMaxAll *min_max, + const RiseFallBoth *rf, + float slew) { ensureGraph(); for (const MinMax *mm : min_max->range()) { @@ -3870,16 +3849,16 @@ Sta::setAnnotatedSlew(Vertex *vertex, void Sta::writeSdf(const char *filename, const Scene *scene, - char divider, - bool include_typ, + char divider, + bool include_typ, int digits, - bool gzip, - bool no_timestamp, - bool no_version) + bool gzip, + bool no_timestamp, + bool no_version) { findDelays(); - sta::writeSdf(filename, scene, divider, include_typ, digits, gzip, - no_timestamp, no_version, this); + sta::writeSdf(filename, scene, divider, include_typ, digits, gzip, no_timestamp, + no_version, this); } void @@ -3925,8 +3904,8 @@ Sta::clearLogicConstants() void Sta::setPortExtPinCap(const Port *port, - const RiseFallBoth *rf, - const MinMaxAll *min_max, + const RiseFallBoth *rf, + const MinMaxAll *min_max, float cap, Sdc *sdc) { @@ -3955,10 +3934,8 @@ Sta::portExtCaps(const Port *port, float pin_cap1, wire_cap1; int fanout1; bool pin_exists1, wire_exists1, fanout_exists1; - sdc->portExtCap(port, rf, min_max, - pin_cap1, pin_exists1, - wire_cap1, wire_exists1, - fanout1, fanout_exists1); + sdc->portExtCap(port, rf, min_max, pin_cap1, pin_exists1, wire_cap1, + wire_exists1, fanout1, fanout_exists1); if (pin_exists1) { pin_cap = min_max->minMax(pin_cap, pin_cap1); pin_exists = true; @@ -3982,8 +3959,8 @@ Sta::portExtCaps(const Port *port, void Sta::setPortExtWireCap(const Port *port, - const RiseFallBoth *rf, - const MinMaxAll *min_max, + const RiseFallBoth *rf, + const MinMaxAll *min_max, float cap, Sdc *sdc) { @@ -4003,7 +3980,7 @@ Sta::removeNetLoadCaps(Sdc *sdc) const void Sta::setPortExtFanout(const Port *port, - int fanout, + int fanout, const MinMaxAll *min_max, Sdc *sdc) { @@ -4014,8 +3991,8 @@ Sta::setPortExtFanout(const Port *port, void Sta::setNetWireCap(const Net *net, - bool subtract_pin_cap, - const MinMaxAll *min_max, + bool subtract_pin_cap, + const MinMaxAll *min_max, float cap, Sdc *sdc) { @@ -4026,22 +4003,21 @@ Sta::setNetWireCap(const Net *net, void Sta::connectedCap(const Pin *drvr_pin, - const RiseFall *rf, + const RiseFall *rf, const Scene *scene, - const MinMax *min_max, - float &pin_cap, - float &wire_cap) const + const MinMax *min_max, + float &pin_cap, + float &wire_cap) const { - graph_delay_calc_->loadCap(drvr_pin, rf, scene, min_max, - pin_cap, wire_cap); + graph_delay_calc_->loadCap(drvr_pin, rf, scene, min_max, pin_cap, wire_cap); } void Sta::connectedCap(const Net *net, Scene *scene, - const MinMax *min_max, - float &pin_cap, - float &wire_cap) const + const MinMax *min_max, + float &pin_cap, + float &wire_cap) const { const Pin *drvr_pin = findNetParasiticDrvrPin(net); if (drvr_pin) { @@ -4073,7 +4049,8 @@ Sta::capacitance(const LibertyPort *port, OperatingConditions *op_cond = operatingConditions(min_max, sdc); const LibertyPort *scene_port = port->scenePort(scene, min_max); for (const RiseFall *rf : RiseFall::range()) - cap = min_max->minMax(cap, scene_port->capacitance(rf, min_max, op_cond, op_cond)); + cap = min_max->minMax(cap, + scene_port->capacitance(rf, min_max, op_cond, op_cond)); } return cap; } @@ -4100,7 +4077,7 @@ Sta::findNetParasiticDrvrPin(const Net *net) const void Sta::setResistance(const Net *net, - const MinMaxAll *min_max, + const MinMaxAll *min_max, float res, Sdc *sdc) { @@ -4113,7 +4090,7 @@ bool Sta::readSpef(const std::string &name, const std::string &filename, Instance *instance, - Scene *scene, // -scene deprecated 11/20/2025 + Scene *scene, // -scene deprecated 11/20/2025 const MinMaxAll *min_max, bool pin_cap_included, bool keep_coupling_caps, @@ -4125,8 +4102,7 @@ Sta::readSpef(const std::string &name, // Use -name to distinguish rel 2.7 args for compatibility. if (name.empty()) { std::string spef_name = "default"; - if (scene - || min_max != MinMaxAll::minMax()) { + if (scene || min_max != MinMaxAll::minMax()) { if (scene) spef_name = scene->name(); if (min_max != MinMaxAll::minMax()) { @@ -4151,10 +4127,9 @@ Sta::readSpef(const std::string &name, parasitics = makeConcreteParasitics(name, filename); } - bool success = readSpefFile(filename.c_str(), instance, - pin_cap_included, keep_coupling_caps, - coupling_cap_factor, reduce, - scene, min_max, parasitics, this); + bool success = + readSpefFile(filename.c_str(), instance, pin_cap_included, keep_coupling_caps, + coupling_cap_factor, reduce, scene, min_max, parasitics, this); delaysInvalid(); return success; } @@ -4175,22 +4150,21 @@ Sta::reportParasiticAnnotation(const std::string &spef_name, if (!spef_name.empty()) { parasitics = findParasitics(spef_name); if (parasitics == nullptr) - report_->error(1560, "spef %s not found.", spef_name.c_str()); + report_->error(1560, "spef {} not found.", spef_name); } else parasitics = cmd_scene_->parasitics(MinMax::max()); - sta::reportParasiticAnnotation(parasitics, report_unannotated, - cmd_scene_, this); + sta::reportParasiticAnnotation(parasitics, report_unannotated, cmd_scene_, this); } void Sta::findPiElmore(Pin *drvr_pin, - const RiseFall *rf, - const MinMax *min_max, - float &c2, - float &rpi, - float &c1, - bool &exists) const + const RiseFall *rf, + const MinMax *min_max, + float &c2, + float &rpi, + float &c1, + bool &exists) const { Scene *scene = cmd_scene_; const Parasitics *parasitics = scene->parasitics(min_max); @@ -4205,11 +4179,11 @@ Sta::findPiElmore(Pin *drvr_pin, void Sta::makePiElmore(Pin *drvr_pin, - const RiseFall *rf, - const MinMaxAll *min_max, - float c2, - float rpi, - float c1) + const RiseFall *rf, + const MinMaxAll *min_max, + float c2, + float rpi, + float c1) { const Scene *scene = cmd_scene_; for (const MinMax *mm : min_max->range()) { @@ -4221,11 +4195,11 @@ Sta::makePiElmore(Pin *drvr_pin, void Sta::findElmore(Pin *drvr_pin, - Pin *load_pin, - const RiseFall *rf, - const MinMax *min_max, - float &elmore, - bool &exists) const + Pin *load_pin, + const RiseFall *rf, + const MinMax *min_max, + float &elmore, + bool &exists) const { Scene *scene = cmd_scene_; const Parasitics *parasitics = scene->parasitics(min_max); @@ -4238,10 +4212,10 @@ Sta::findElmore(Pin *drvr_pin, void Sta::setElmore(Pin *drvr_pin, - Pin *load_pin, - const RiseFall *rf, - const MinMaxAll *min_max, - float elmore) + Pin *load_pin, + const RiseFall *rf, + const MinMaxAll *min_max, + float elmore) { const Scene *scene = cmd_scene_; for (const MinMax *mm : min_max->range()) { @@ -4308,13 +4282,13 @@ Sta::makeParasiticNetwork(const Net *net, NetworkEdit * Sta::networkCmdEdit() { - return dynamic_cast(cmd_network_); + return dynamic_cast(cmd_network_); } Instance * Sta::makeInstance(const char *name, - LibertyCell *cell, - Instance *parent) + LibertyCell *cell, + Instance *parent) { NetworkEdit *network = networkCmdEdit(); Instance *inst = network->makeInstance(cell, name, parent); @@ -4333,7 +4307,7 @@ Sta::deleteInstance(Instance *inst) void Sta::replaceCell(Instance *inst, - LibertyCell *to_lib_cell) + LibertyCell *to_lib_cell) { Cell *to_cell = network_->cell(to_lib_cell); replaceCell(inst, to_cell, to_lib_cell); @@ -4341,7 +4315,7 @@ Sta::replaceCell(Instance *inst, void Sta::replaceCell(Instance *inst, - Cell *to_cell) + Cell *to_cell) { LibertyCell *to_lib_cell = network_->libertyCell(to_cell); replaceCell(inst, to_cell, to_lib_cell); @@ -4349,8 +4323,8 @@ Sta::replaceCell(Instance *inst, void Sta::replaceCell(Instance *inst, - Cell *to_cell, - LibertyCell *to_lib_cell) + Cell *to_cell, + LibertyCell *to_lib_cell) { NetworkEdit *network = networkCmdEdit(); LibertyCell *from_lib_cell = network->libertyCell(inst); @@ -4370,7 +4344,7 @@ Sta::replaceCell(Instance *inst, Net * Sta::makeNet(const char *name, - Instance *parent) + Instance *parent) { NetworkEdit *network = networkCmdEdit(); Net *net = network->makeNet(name, parent); @@ -4388,8 +4362,8 @@ Sta::deleteNet(Net *net) void Sta::connectPin(Instance *inst, - Port *port, - Net *net) + Port *port, + Net *net) { NetworkEdit *network = networkCmdEdit(); Pin *pin = network->connect(inst, port, net); @@ -4398,8 +4372,8 @@ Sta::connectPin(Instance *inst, void Sta::connectPin(Instance *inst, - LibertyPort *port, - Net *net) + LibertyPort *port, + Net *net) { NetworkEdit *network = networkCmdEdit(); Pin *pin = network->connect(inst, port, net); @@ -4419,7 +4393,7 @@ Sta::makePortPin(const char *port_name, PortDirection *dir) { ensureLinked(); - NetworkReader *network = dynamic_cast(network_); + NetworkReader *network = dynamic_cast(network_); Instance *top_inst = network->topInstance(); Cell *top_cell = network->cell(top_inst); Port *port = network->makePort(top_cell, port_name); @@ -4427,7 +4401,7 @@ Sta::makePortPin(const char *port_name, Pin *pin = network->makePin(top_inst, port, nullptr); makePortPinAfter(pin); } - + //////////////////////////////////////////////////////////////// // // Network edit before/after methods. @@ -4437,7 +4411,7 @@ Sta::makePortPin(const char *port_name, void Sta::makeInstanceAfter(const Instance *inst) { - debugPrint(debug_, "network_edit", 1, "make instance %s", + debugPrint(debug_, "network_edit", 1, "make instance {}", sdc_network_->pathName(inst)); if (graph_) { LibertyCell *lib_cell = network_->libertyCell(inst); @@ -4450,7 +4424,6 @@ Sta::makeInstanceAfter(const Instance *inst) if (pin) { Vertex *vertex, *bidir_drvr_vertex; graph_->makePinVertices(pin, vertex, bidir_drvr_vertex); - } } graph_->makeInstanceEdges(inst); @@ -4470,7 +4443,7 @@ Sta::makePortPinAfter(Pin *pin) void Sta::replaceEquivCellBefore(const Instance *inst, - const LibertyCell *to_cell) + const LibertyCell *to_cell) { if (graph_) { InstancePinIterator *pin_iter = network_->pinIterator(inst); @@ -4494,15 +4467,16 @@ Sta::replaceEquivCellBefore(const Instance *inst, if (to_set) edge->setTimingArcSet(to_set); else - report_->critical(1556, "corresponding timing arc set not found in equiv cells"); + report_->critical( + 1556, "corresponding timing arc set not found in equiv cells"); } } } else { // Force delay calculation on output pins. Vertex *vertex = graph_->pinDrvrVertex(pin); - if (vertex) - graph_delay_calc_->delayInvalid(vertex); + if (vertex) + graph_delay_calc_->delayInvalid(vertex); } } } @@ -4530,16 +4504,15 @@ Sta::replaceEquivCellAfter(const Instance *inst) void Sta::replaceCellPinInvalidate(const LibertyPort *from_port, - Vertex *vertex, - const LibertyCell *to_cell) + Vertex *vertex, + const LibertyCell *to_cell) { LibertyPort *to_port = to_cell->findLibertyPort(from_port->name()); if (to_port == nullptr || (!libertyPortCapsEqual(to_port, from_port) // If this is an ideal clock pin, do not invalidate // arrivals and delay calc on the clock pin driver. - && !(to_port->isClock() - && idealClockMode()))) + && !(to_port->isClock() && idealClockMode()))) // Input port capacitance changed, so invalidate delay // calculation from input driver. delaysInvalidFromFanin(vertex); @@ -4553,30 +4526,30 @@ Sta::idealClockMode() for (Mode *mode : modes_) { Sdc *sdc = mode->sdc(); for (Clock *clk : sdc->clocks()) { - if (clk->isPropagated()) - return false; - } + if (clk->isPropagated()) + return false; + } } return true; } static bool libertyPortCapsEqual(const LibertyPort *port1, - const LibertyPort *port2) + const LibertyPort *port2) { return port1->capacitance(RiseFall::rise(), MinMax::min()) - == port2->capacitance(RiseFall::rise(), MinMax::min()) - && port1->capacitance(RiseFall::rise(), MinMax::max()) - == port2->capacitance(RiseFall::rise(), MinMax::max()) - && port1->capacitance(RiseFall::fall(), MinMax::min()) - == port2->capacitance(RiseFall::fall(), MinMax::min()) - && port1->capacitance(RiseFall::fall(), MinMax::max()) - == port2->capacitance(RiseFall::fall(), MinMax::max()); + == port2->capacitance(RiseFall::rise(), MinMax::min()) + && port1->capacitance(RiseFall::rise(), MinMax::max()) + == port2->capacitance(RiseFall::rise(), MinMax::max()) + && port1->capacitance(RiseFall::fall(), MinMax::min()) + == port2->capacitance(RiseFall::fall(), MinMax::min()) + && port1->capacitance(RiseFall::fall(), MinMax::max()) + == port2->capacitance(RiseFall::fall(), MinMax::max()); } void Sta::replaceCellBefore(const Instance *inst, - const LibertyCell *to_cell) + const LibertyCell *to_cell) { if (graph_) { // Delete all graph edges between instance pins. @@ -4585,16 +4558,16 @@ Sta::replaceCellBefore(const Instance *inst, Pin *pin = pin_iter->next(); LibertyPort *port = network_->libertyPort(pin); if (port->direction()->isAnyInput()) { - Vertex *vertex = graph_->pinLoadVertex(pin); - replaceCellPinInvalidate(port, vertex, to_cell); + Vertex *vertex = graph_->pinLoadVertex(pin); + replaceCellPinInvalidate(port, vertex, to_cell); - VertexOutEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - Vertex *to_vertex = edge->to(graph_); - if (network_->instance(to_vertex->pin()) == inst) - deleteEdge(edge); - } + VertexOutEdgeIterator edge_iter(vertex, graph_); + while (edge_iter.hasNext()) { + Edge *edge = edge_iter.next(); + Vertex *to_vertex = edge->to(graph_); + if (network_->instance(to_vertex->pin()) == inst) + deleteEdge(edge); + } } } delete pin_iter; @@ -4623,7 +4596,7 @@ Sta::replaceCellAfter(const Instance *inst) void Sta::connectPinAfter(const Pin *pin) { - debugPrint(debug_, "network_edit", 1, "connect %s to %s", + debugPrint(debug_, "network_edit", 1, "connect {} to {}", sdc_network_->pathName(pin), sdc_network_->pathName(network_->net(pin))); if (graph_) { @@ -4631,11 +4604,11 @@ Sta::connectPinAfter(const Pin *pin) graph_->makeWireEdgesThruPin(pin); EdgesThruHierPinIterator edge_iter(pin, network_, graph_); while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->role()->isWire()) { - connectDrvrPinAfter(edge->from(graph_)); - connectLoadPinAfter(edge->to(graph_)); - } + Edge *edge = edge_iter.next(); + if (edge->role()->isWire()) { + connectDrvrPinAfter(edge->from(graph_)); + connectLoadPinAfter(edge->to(graph_)); + } } } else { @@ -4724,7 +4697,7 @@ Sta::connectLoadPinAfter(Vertex *vertex) void Sta::disconnectPinBefore(const Pin *pin) { - debugPrint(debug_, "network_edit", 1, "disconnect %s from %s", + debugPrint(debug_, "network_edit", 1, "disconnect {} from {}", sdc_network_->pathName(pin), sdc_network_->pathName(network_->net(pin))); @@ -4742,37 +4715,37 @@ Sta::disconnectPinBefore(const Pin *pin) Vertex *vertex = graph_->pinDrvrVertex(pin); // Delete wire edges from pin. if (vertex) { - VertexOutEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->role()->isWire()) - deleteEdge(edge); - } + VertexOutEdgeIterator edge_iter(vertex, graph_); + while (edge_iter.hasNext()) { + Edge *edge = edge_iter.next(); + if (edge->role()->isWire()) + deleteEdge(edge); + } } } if (network_->isLoad(pin)) { // Delete wire edges to pin. Vertex *vertex = graph_->pinLoadVertex(pin); if (vertex) { - VertexInEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->role()->isWire()) - deleteEdge(edge); - } + VertexInEdgeIterator edge_iter(vertex, graph_); + while (edge_iter.hasNext()) { + Edge *edge = edge_iter.next(); + if (edge->role()->isWire()) + deleteEdge(edge); + } } } if (is_hierarchical) { // Delete wire edges thru pin. EdgesThruHierPinIterator edge_iter(pin, network_, graph_); while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->role()->isWire()) { - deleteEdge(edge); + Edge *edge = edge_iter.next(); + if (edge->role()->isWire()) { + deleteEdge(edge); const Pin *from_pin = edge->from(graph_)->pin(); for (Mode *mode : modes_) mode->clkNetwork()->disconnectPinBefore(from_pin); - } + } } } clk_skews_->clear(); @@ -4783,7 +4756,7 @@ Sta::disconnectPinBefore(const Pin *pin) void Sta::deleteEdge(Edge *edge) { - debugPrint(debug_, "network_edit", 2, "delete edge %s -> %s", + debugPrint(debug_, "network_edit", 2, "delete edge {} -> {}", edge->from(graph_)->name(sdc_network_), edge->to(graph_)->name(sdc_network_)); Vertex *to = edge->to(graph_); @@ -4801,24 +4774,24 @@ Sta::deleteEdge(Edge *edge) void Sta::deleteNetBefore(const Net *net) { - debugPrint(debug_, "network_edit", 1, "delete net %s", + debugPrint(debug_, "network_edit", 1, "delete net {}", sdc_network_->pathName(net)); if (graph_) { NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net); while (pin_iter->hasNext()) { const Pin *pin = pin_iter->next(); if (!network_->isHierarchical(pin)) { - disconnectPinBefore(pin); - // Delete wire edges on net pins. - Vertex *vertex = graph_->pinDrvrVertex(pin); - if (vertex) { - VertexOutEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->role()->isWire()) - deleteEdge(edge); - } - } + disconnectPinBefore(pin); + // Delete wire edges on net pins. + Vertex *vertex = graph_->pinDrvrVertex(pin); + if (vertex) { + VertexOutEdgeIterator edge_iter(vertex, graph_); + while (edge_iter.hasNext()) { + Edge *edge = edge_iter.next(); + if (edge->role()->isWire()) + deleteEdge(edge); + } + } } } delete pin_iter; @@ -4832,7 +4805,7 @@ Sta::deleteNetBefore(const Net *net) void Sta::deleteInstanceBefore(const Instance *inst) { - debugPrint(debug_, "network_edit", 1, "delete instance %s", + debugPrint(debug_, "network_edit", 1, "delete instance {}", sdc_network_->pathName(inst)); if (network_->isLeaf(inst)) { deleteInstancePinsBefore(inst); @@ -4875,8 +4848,8 @@ void Sta::deletePinBefore(const Pin *pin) { if (graph_) { - debugPrint(debug_, "network_edit", 1, "delete pin %s", - sdc_network_->pathName(pin)); + debugPrint(debug_, "network_edit", 1, "delete pin {}", + sdc_network_->pathName(pin)); if (network_->isLoad(pin)) { Vertex *vertex = graph_->pinLoadVertex(pin); if (vertex) { @@ -4894,7 +4867,7 @@ Sta::deletePinBefore(const Pin *pin) } levelize_->deleteEdgeBefore(edge); } - // Deletes edges to/from vertex also. + // Deletes edges to/from vertex also. graph_->deleteVertex(vertex); } } @@ -4917,7 +4890,7 @@ Sta::deletePinBefore(const Pin *pin) } levelize_->deleteEdgeBefore(edge); } - // Deletes edges to/from vertex also. + // Deletes edges to/from vertex also. graph_->deleteVertex(vertex); } } @@ -5018,12 +4991,12 @@ Sta::delaysInvalidFromFanin(const Net *net) while (pin_iter->hasNext()) { const Pin *pin = pin_iter->next(); if (!network_->isHierarchical(pin)) { - Vertex *vertex, *bidirect_drvr_vertex; - graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); - if (vertex) - delaysInvalidFrom(vertex); - if (bidirect_drvr_vertex) - delaysInvalidFrom(bidirect_drvr_vertex); + Vertex *vertex, *bidirect_drvr_vertex; + graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); + if (vertex) + delaysInvalidFrom(vertex); + if (bidirect_drvr_vertex) + delaysInvalidFrom(bidirect_drvr_vertex); } } delete pin_iter; @@ -5065,62 +5038,57 @@ Sta::clockDomains(const Pin *pin, InstanceSet Sta::findRegisterInstances(ClockSet *clks, - const RiseFallBoth *clk_rf, - bool edge_triggered, + const RiseFallBoth *clk_rf, + bool edge_triggered, bool latches, const Mode *mode) { findRegisterPreamble(mode); - return findRegInstances(clks, clk_rf, edge_triggered, latches, - mode, this); + return findRegInstances(clks, clk_rf, edge_triggered, latches, mode, this); } PinSet Sta::findRegisterDataPins(ClockSet *clks, - const RiseFallBoth *clk_rf, - bool edge_triggered, + const RiseFallBoth *clk_rf, + bool edge_triggered, bool latches, const Mode *mode) { findRegisterPreamble(mode); - return findRegDataPins(clks, clk_rf, edge_triggered, latches, - mode, this); + return findRegDataPins(clks, clk_rf, edge_triggered, latches, mode, this); } PinSet Sta::findRegisterClkPins(ClockSet *clks, - const RiseFallBoth *clk_rf, - bool edge_triggered, + const RiseFallBoth *clk_rf, + bool edge_triggered, bool latches, const Mode *mode) { findRegisterPreamble(mode); - return findRegClkPins(clks, clk_rf, edge_triggered, latches, - mode, this); + return findRegClkPins(clks, clk_rf, edge_triggered, latches, mode, this); } PinSet Sta::findRegisterAsyncPins(ClockSet *clks, - const RiseFallBoth *clk_rf, - bool edge_triggered, + const RiseFallBoth *clk_rf, + bool edge_triggered, bool latches, const Mode *mode) { findRegisterPreamble(mode); - return findRegAsyncPins(clks, clk_rf, edge_triggered, latches, - mode, this); + return findRegAsyncPins(clks, clk_rf, edge_triggered, latches, mode, this); } PinSet Sta::findRegisterOutputPins(ClockSet *clks, - const RiseFallBoth *clk_rf, - bool edge_triggered, + const RiseFallBoth *clk_rf, + bool edge_triggered, bool latches, const Mode *mode) { findRegisterPreamble(mode); - return findRegOutputPins(clks, clk_rf, edge_triggered, latches, - mode, this); + return findRegOutputPins(clks, clk_rf, edge_triggered, latches, mode, this); } void @@ -5137,8 +5105,8 @@ class FanInOutSrchPred : public SearchPred { public: FanInOutSrchPred(bool thru_disabled, - bool thru_constants, - const StaState *sta); + bool thru_constants, + const StaState *sta); bool searchFrom(const Vertex *from_vertex, const Mode *mode) const override; bool searchThru(Edge *edge, @@ -5156,8 +5124,8 @@ protected: }; FanInOutSrchPred::FanInOutSrchPred(bool thru_disabled, - bool thru_constants, - const StaState *sta) : + bool thru_constants, + const StaState *sta) : SearchPred(sta), thru_disabled_(thru_disabled), thru_constants_(thru_constants), @@ -5171,10 +5139,8 @@ FanInOutSrchPred::searchFrom(const Vertex *from_vertex, { const Pin *from_pin = from_vertex->pin(); const Sdc *sdc = mode->sdc(); - return (thru_disabled_ - || !sdc->isDisabledConstraint(from_pin)) - && (thru_constants_ - || !mode->sim()->isConstant(from_vertex)); + return (thru_disabled_ || !sdc->isDisabledConstraint(from_pin)) + && (thru_constants_ || !mode->sim()->isConstant(from_vertex)); } bool @@ -5184,22 +5150,19 @@ FanInOutSrchPred::searchThru(Edge *edge, const Sdc *sdc = mode->sdc(); const Sim *sim = mode->sim(); return searchThruRole(edge) - && (thru_disabled_ - || !(sdc->isDisabledConstraint(edge) - || sim->isDisabledCond(edge) - || sta_->isDisabledCondDefault(edge))) - && (thru_constants_ - || sim->simTimingSense(edge) != TimingSense::none); + && (thru_disabled_ + || !(sdc->isDisabledConstraint(edge) || sim->isDisabledCond(edge) + || sta_->isDisabledCondDefault(edge))) + && (thru_constants_ || sim->simTimingSense(edge) != TimingSense::none); } bool FanInOutSrchPred::searchThruRole(Edge *edge) const { const TimingRole *role = edge->role(); - return role == TimingRole::wire() - || role == TimingRole::combinational() - || role == TimingRole::tristateEnable() - || role == TimingRole::tristateDisable(); + return role == TimingRole::wire() || role == TimingRole::combinational() + || role == TimingRole::tristateEnable() + || role == TimingRole::tristateDisable(); } bool @@ -5220,27 +5183,27 @@ FanInOutSrchPred::searchTo(const Vertex *to_vertex, { const Pin *to_pin = to_vertex->pin(); const Sdc *sdc = mode->sdc(); - return (thru_disabled_ - || !sdc->isDisabledConstraint(to_pin)) - && (thru_constants_ - || !mode->sim()->isConstant(to_vertex)); + return (thru_disabled_ || !sdc->isDisabledConstraint(to_pin)) + && (thru_constants_ || !mode->sim()->isConstant(to_vertex)); } class FaninSrchPred : public FanInOutSrchPred { public: FaninSrchPred(bool thru_disabled, - bool thru_constants, - const StaState *sta); + bool thru_constants, + const StaState *sta); protected: bool searchThruRole(Edge *edge) const override; }; FaninSrchPred::FaninSrchPred(bool thru_disabled, - bool thru_constants, - const StaState *sta) : - FanInOutSrchPred(thru_disabled, thru_constants, sta) + bool thru_constants, + const StaState *sta) : + FanInOutSrchPred(thru_disabled, + thru_constants, + sta) { } @@ -5248,21 +5211,19 @@ bool FaninSrchPred::searchThruRole(Edge *edge) const { const TimingRole *role = edge->role(); - return role == TimingRole::wire() - || role == TimingRole::combinational() - || role == TimingRole::tristateEnable() - || role == TimingRole::tristateDisable() - || role == TimingRole::regClkToQ() - || role == TimingRole::latchEnToQ(); + return role == TimingRole::wire() || role == TimingRole::combinational() + || role == TimingRole::tristateEnable() + || role == TimingRole::tristateDisable() || role == TimingRole::regClkToQ() + || role == TimingRole::latchEnToQ(); } PinSet Sta::findFaninPins(PinSeq *to, - bool flat, - bool startpoints_only, - int inst_levels, - int pin_levels, - bool thru_disabled, + bool flat, + bool startpoints_only, + int inst_levels, + int pin_levels, + bool thru_disabled, bool thru_constants, const Mode *mode) { @@ -5275,15 +5236,15 @@ Sta::findFaninPins(PinSeq *to, if (network_->isHierarchical(pin)) { EdgesThruHierPinIterator edge_iter(pin, network_, graph_); while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - findFaninPins(edge->from(graph_), flat, startpoints_only, - inst_levels, pin_levels, fanin, pred, mode); + Edge *edge = edge_iter.next(); + findFaninPins(edge->from(graph_), flat, startpoints_only, inst_levels, + pin_levels, fanin, pred, mode); } } else { Vertex *vertex = graph_->pinLoadVertex(pin); - findFaninPins(vertex, flat, startpoints_only, - inst_levels, pin_levels, fanin, pred, mode); + findFaninPins(vertex, flat, startpoints_only, inst_levels, pin_levels, fanin, + pred, mode); } } return fanin; @@ -5291,21 +5252,19 @@ Sta::findFaninPins(PinSeq *to, void Sta::findFaninPins(Vertex *vertex, - bool flat, - bool startpoints_only, - int inst_levels, - int pin_levels, - PinSet &fanin, + bool flat, + bool startpoints_only, + int inst_levels, + int pin_levels, + PinSet &fanin, SearchPred &pred, const Mode *mode) { VertexSet visited = makeVertexSet(this); - findFaninPins(vertex, flat, inst_levels, - pin_levels, visited, &pred, 0, 0, mode); + findFaninPins(vertex, flat, inst_levels, pin_levels, visited, &pred, 0, 0, mode); for (Vertex *visited_vertex : visited) { Pin *visited_pin = visited_vertex->pin(); - if (!startpoints_only - || network_->isRegClkPin(visited_pin) + if (!startpoints_only || network_->isRegClkPin(visited_pin) || !hasFanin(visited_vertex, &pred, graph_, mode)) fanin.insert(visited_pin); } @@ -5313,40 +5272,32 @@ Sta::findFaninPins(Vertex *vertex, void Sta::findFaninPins(Vertex *to, - bool flat, - int inst_levels, - int pin_levels, - VertexSet &visited, - SearchPred *pred, - int inst_level, + bool flat, + int inst_levels, + int pin_levels, + VertexSet &visited, + SearchPred *pred, + int inst_level, int pin_level, const Mode *mode) { - debugPrint(debug_, "fanin", 1, "%s", - to->to_string(this).c_str()); + debugPrint(debug_, "fanin", 1, "{}", to->to_string(this)); if (!visited.contains(to)) { visited.insert(to); Pin *to_pin = to->pin(); bool is_reg_clk_pin = network_->isRegClkPin(to_pin); - if (!is_reg_clk_pin - && (inst_levels <= 0 - || inst_level < inst_levels) - && (pin_levels <= 0 - || pin_level < pin_levels) - && pred->searchTo(to, mode)) { + if (!is_reg_clk_pin && (inst_levels <= 0 || inst_level < inst_levels) + && (pin_levels <= 0 || pin_level < pin_levels) && pred->searchTo(to, mode)) { VertexInEdgeIterator edge_iter(to, graph_); while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - Vertex *from_vertex = edge->from(graph_); - if (pred->searchThru(edge, mode) - && (flat - || !crossesHierarchy(edge)) + Edge *edge = edge_iter.next(); + Vertex *from_vertex = edge->from(graph_); + if (pred->searchThru(edge, mode) && (flat || !crossesHierarchy(edge)) && pred->searchFrom(from_vertex, mode)) { - findFaninPins(from_vertex, flat, inst_levels, - pin_levels, visited, pred, - edge->role()->isWire() ? inst_level : inst_level+1, - pin_level+1, mode); - } + findFaninPins(from_vertex, flat, inst_levels, pin_levels, visited, pred, + edge->role()->isWire() ? inst_level : inst_level + 1, + pin_level + 1, mode); + } } } } @@ -5354,26 +5305,26 @@ Sta::findFaninPins(Vertex *to, InstanceSet Sta::findFaninInstances(PinSeq *to, - bool flat, - bool startpoints_only, - int inst_levels, - int pin_levels, - bool thru_disabled, + bool flat, + bool startpoints_only, + int inst_levels, + int pin_levels, + bool thru_disabled, bool thru_constants, const Mode *mode) { - PinSet pins = findFaninPins(to, flat, startpoints_only, inst_levels, - pin_levels, thru_disabled, thru_constants, mode); + PinSet pins = findFaninPins(to, flat, startpoints_only, inst_levels, pin_levels, + thru_disabled, thru_constants, mode); return pinInstances(pins, network_); } PinSet Sta::findFanoutPins(PinSeq *from, - bool flat, - bool endpoints_only, - int inst_levels, - int pin_levels, - bool thru_disabled, + bool flat, + bool endpoints_only, + int inst_levels, + int pin_levels, + bool thru_disabled, bool thru_constants, const Mode *mode) { @@ -5386,15 +5337,15 @@ Sta::findFanoutPins(PinSeq *from, if (network_->isHierarchical(pin)) { EdgesThruHierPinIterator edge_iter(pin, network_, graph_); while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - findFanoutPins(edge->to(graph_), flat, endpoints_only, - inst_levels, pin_levels, fanout, pred, mode); + Edge *edge = edge_iter.next(); + findFanoutPins(edge->to(graph_), flat, endpoints_only, inst_levels, + pin_levels, fanout, pred, mode); } } else { Vertex *vertex = graph_->pinDrvrVertex(pin); - findFanoutPins(vertex, flat, endpoints_only, - inst_levels, pin_levels, fanout, pred, mode); + findFanoutPins(vertex, flat, endpoints_only, inst_levels, pin_levels, fanout, + pred, mode); } } return fanout; @@ -5402,21 +5353,19 @@ Sta::findFanoutPins(PinSeq *from, void Sta::findFanoutPins(Vertex *vertex, - bool flat, - bool endpoints_only, - int inst_levels, - int pin_levels, - PinSet &fanout, + bool flat, + bool endpoints_only, + int inst_levels, + int pin_levels, + PinSet &fanout, SearchPred &pred, const Mode *mode) { VertexSet visited = makeVertexSet(this); - findFanoutPins(vertex, flat, inst_levels, - pin_levels, visited, &pred, 0, 0, mode); + findFanoutPins(vertex, flat, inst_levels, pin_levels, visited, &pred, 0, 0, mode); for (Vertex *visited_vertex : visited) { Pin *visited_pin = visited_vertex->pin(); - if (!endpoints_only - || search_->isEndpoint(visited_vertex, &pred, mode)) + if (!endpoints_only || search_->isEndpoint(visited_vertex, &pred, mode)) fanout.insert(visited_pin); } } @@ -5424,38 +5373,32 @@ Sta::findFanoutPins(Vertex *vertex, // DFS to support level limits. void Sta::findFanoutPins(Vertex *from, - bool flat, - int inst_levels, - int pin_levels, - VertexSet &visited, - SearchPred *pred, - int inst_level, + bool flat, + int inst_levels, + int pin_levels, + VertexSet &visited, + SearchPred *pred, + int inst_level, int pin_level, const Mode *mode) { - debugPrint(debug_, "fanout", 1, "%s", - from->to_string(this).c_str()); + debugPrint(debug_, "fanout", 1, "{}", from->to_string(this)); if (!visited.contains(from)) { visited.insert(from); if (!search_->isEndpoint(from, pred, mode) - && (inst_levels <= 0 - || inst_level < inst_levels) - && (pin_levels <= 0 - || pin_level < pin_levels) + && (inst_levels <= 0 || inst_level < inst_levels) + && (pin_levels <= 0 || pin_level < pin_levels) && pred->searchFrom(from, mode)) { VertexOutEdgeIterator edge_iter(from, graph_); while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - Vertex *to_vertex = edge->to(graph_); - if (pred->searchThru(edge, mode) - && (flat - || !crossesHierarchy(edge)) + Edge *edge = edge_iter.next(); + Vertex *to_vertex = edge->to(graph_); + if (pred->searchThru(edge, mode) && (flat || !crossesHierarchy(edge)) && pred->searchTo(to_vertex, mode)) { - findFanoutPins(to_vertex, flat, inst_levels, - pin_levels, visited, pred, - edge->role()->isWire() ? inst_level : inst_level+1, - pin_level+1, mode); - } + findFanoutPins(to_vertex, flat, inst_levels, pin_levels, visited, pred, + edge->role()->isWire() ? inst_level : inst_level + 1, + pin_level + 1, mode); + } } } } @@ -5463,22 +5406,22 @@ Sta::findFanoutPins(Vertex *from, InstanceSet Sta::findFanoutInstances(PinSeq *from, - bool flat, - bool endpoints_only, - int inst_levels, - int pin_levels, - bool thru_disabled, + bool flat, + bool endpoints_only, + int inst_levels, + int pin_levels, + bool thru_disabled, bool thru_constants, const Mode *mode) { - PinSet pins = findFanoutPins(from, flat, endpoints_only, inst_levels, - pin_levels, thru_disabled, thru_constants, mode); + PinSet pins = findFanoutPins(from, flat, endpoints_only, inst_levels, pin_levels, + thru_disabled, thru_constants, mode); return pinInstances(pins, network_); } static InstanceSet pinInstances(PinSet &pins, - const Network *network) + const Network *network) { InstanceSet insts(network); for (const Pin *pin : pins) @@ -5498,11 +5441,11 @@ Sta::crossesHierarchy(Edge *edge) const // Treat input/output port pins as "inside". if (network_->isTopInstance(from_inst)) from_parent = from_inst; - else + else from_parent = network_->parent(from_inst); if (network_->isTopInstance(to_inst)) to_parent = to_inst; - else + else to_parent = network_->parent(to_inst); return from_parent != to_parent; } @@ -5521,8 +5464,8 @@ instMaxSlew(const Instance *inst, Pin *pin = pin_iter->next(); if (network->isDriver(pin)) { Vertex *vertex = graph->pinDrvrVertex(pin); - Slew slew = sta->slew(vertex, RiseFallBoth::riseFall(), - sta->scenes(), MinMax::max()); + Slew slew = + sta->slew(vertex, RiseFallBoth::riseFall(), sta->scenes(), MinMax::max()); if (delayGreater(slew, max_slew, sta)) max_slew = slew; } @@ -5536,11 +5479,8 @@ Sta::slowDrivers(int count) { findDelays(); InstanceSeq insts = network_->leafInstances(); - sort(insts, [this] (const Instance *inst1, - const Instance *inst2) { - return delayGreater(instMaxSlew(inst1, this), - instMaxSlew(inst2, this), - this); + sort(insts, [this](const Instance *inst1, const Instance *inst2) { + return delayGreater(instMaxSlew(inst1, this), instMaxSlew(inst2, this), this); }); insts.resize(count); return insts; @@ -5557,10 +5497,11 @@ Sta::reportSlewChecks(const Net *net, const MinMax *min_max) { checkSlewsPreamble(); - SlewCheckSeq &checks = check_slews_->check(net, max_count, violators, scenes, min_max); + SlewCheckSeq &checks = + check_slews_->check(net, max_count, violators, scenes, min_max); if (!checks.empty()) { - report_->reportLine("%s slew", min_max->to_string().c_str()); - report_->reportLine(""); + report_->report("{} slew", min_max->to_string()); + report_->report(""); if (!verbose) report_path_->reportLimitShortHeader(report_path_->fieldSlew()); @@ -5576,7 +5517,7 @@ Sta::reportSlewChecks(const Net *net, delayAsFloat(check.slew(), min_max, this), check.limit(), check.slack()); } - report_->reportLine(""); + report_->report(""); } } @@ -5589,7 +5530,7 @@ Sta::checkSlewsPreamble() if (mode->sdc()->haveClkSlewLimits()) have_clk_slew_limits = true; mode->clkNetwork()->ensureClkNetwork(); - } + } if (have_clk_slew_limits) // Arrivals are needed to know pin clock domains. updateTiming(false); @@ -5602,17 +5543,17 @@ Sta::checkSlewsPreamble() void Sta::checkSlew(const Pin *pin, const SceneSeq &scenes, - const MinMax *min_max, - bool check_clks, - // Return values. - Slew &slew, - float &limit, + const MinMax *min_max, + bool check_clks, + // Return values. + Slew &slew, + float &limit, float &slack, const RiseFall *&rf, const Scene *&scene) { - check_slews_->check(pin, scenes, min_max, check_clks, - slew, limit, slack, rf, scene); + check_slews_->check(pin, scenes, min_max, check_clks, slew, limit, slack, rf, + scene); } size_t @@ -5623,14 +5564,15 @@ Sta::maxSlewViolationCount() } void -Sta::maxSlewCheck(// Return values. - const Pin *&pin, - Slew &slew, - float &slack, - float &limit) +Sta::maxSlewCheck( // Return values. + const Pin *&pin, + Slew &slew, + float &slack, + float &limit) { checkSlewsPreamble(); - SlewCheckSeq &checks = check_slews_->check(nullptr, 1, false, scenes_, MinMax::max()); + SlewCheckSeq &checks = + check_slews_->check(nullptr, 1, false, scenes_, MinMax::max()); if (!checks.empty()) { SlewCheck &check = checks[0]; pin = check.pin(); @@ -5639,9 +5581,9 @@ Sta::maxSlewCheck(// Return values. limit = check.limit(); } else { - pin = nullptr; - slew = 0.0; - slack = INF; + pin = nullptr; + slew = 0.0; + slack = INF; } } @@ -5655,8 +5597,7 @@ Sta::findSlewLimit(const LibertyPort *port, { if (check_slews_ == nullptr) makeCheckSlews(); - check_slews_->findLimit(port, scene, min_max, - limit, exists); + check_slews_->findLimit(port, scene, min_max, limit, exists); } ////////////////////////////////////////////////////////////////' @@ -5664,34 +5605,32 @@ Sta::findSlewLimit(const LibertyPort *port, void Sta::reportFanoutChecks(const Net *net, size_t max_count, - bool violators, + bool violators, bool verbose, const SceneSeq &scenes, - const MinMax *min_max) + const MinMax *min_max) { checkFanoutPreamble(); - const ModeSeq modes = Scene::modesSorted(scenes); - FanoutCheckSeq &checks = check_fanouts_->check(net, max_count, violators, - modes, min_max); + const ModeSeq modes = Scene::modesSorted(scenes); + FanoutCheckSeq &checks = + check_fanouts_->check(net, max_count, violators, modes, min_max); if (!checks.empty()) { - report_->reportLine("%s fanout", min_max->to_string().c_str()); - report_->reportLine(""); + report_->report("{} fanout", min_max->to_string()); + report_->report(""); if (!verbose) - report_path_->reportLimitShortHeader(report_path_->fieldFanout()); + report_path_->reportLimitShortHeader(report_path_->fieldFanout()); for (const FanoutCheck &check : checks) { if (verbose) - report_path_->reportLimitVerbose(report_path_->fieldFanout(), - check.pin(), nullptr, check.fanout(), - check.limit(), check.slack(), nullptr, - min_max); + report_path_->reportLimitVerbose(report_path_->fieldFanout(), check.pin(), + nullptr, check.fanout(), check.limit(), + check.slack(), nullptr, min_max); else - report_path_->reportLimitShort(report_path_->fieldFanout(), - check.pin(), check.fanout(), - check.limit(), check.slack()); + report_path_->reportLimitShort(report_path_->fieldFanout(), check.pin(), + check.fanout(), check.limit(), check.slack()); } - report_->reportLine(""); + report_->report(""); } } @@ -5718,11 +5657,11 @@ Sta::fanoutViolationCount(const MinMax *min_max, void Sta::checkFanout(const Pin *pin, const Mode *mode, - const MinMax *min_max, - // Return values. - float &fanout, - float &limit, - float &slack) + const MinMax *min_max, + // Return values. + float &fanout, + float &limit, + float &slack) { FanoutCheck check = check_fanouts_->check(pin, mode, min_max); pin = check.pin(); @@ -5734,15 +5673,15 @@ Sta::checkFanout(const Pin *pin, void Sta::maxFanoutMinSlackPin(const ModeSeq &modes, // Return values. - const Pin *&pin, - float &fanout, + const Pin *&pin, + float &fanout, float &limit, - float &slack, + float &slack, const Mode *&mode) { checkFanoutPreamble(); - FanoutCheckSeq &checks = check_fanouts_->check(nullptr, 1, false, - modes, MinMax::max()); + FanoutCheckSeq &checks = + check_fanouts_->check(nullptr, 1, false, modes, MinMax::max()); if (!checks.empty()) { FanoutCheck &check = checks[0]; pin = check.pin(); @@ -5752,9 +5691,9 @@ Sta::maxFanoutMinSlackPin(const ModeSeq &modes, mode = check.mode(); } else { - pin = nullptr; - fanout = 0; - limit = INF; + pin = nullptr; + fanout = 0; + limit = INF; slack = INF; mode = nullptr; } @@ -5765,32 +5704,31 @@ Sta::maxFanoutMinSlackPin(const ModeSeq &modes, void Sta::reportCapacitanceChecks(const Net *net, size_t max_count, - bool violators, + bool violators, bool verbose, const SceneSeq &scenes, - const MinMax *min_max) + const MinMax *min_max) { checkCapacitancesPreamble(scenes); - CapacitanceCheckSeq &checks = check_capacitances_->check(net, max_count, - violators, - scenes, min_max); + CapacitanceCheckSeq &checks = + check_capacitances_->check(net, max_count, violators, scenes, min_max); if (!checks.empty()) { - report_->reportLine("%s capacitance", min_max->to_string().c_str()); - report_->reportLine(""); + report_->report("{} capacitance", min_max->to_string()); + report_->report(""); if (!verbose) - report_path_->reportLimitShortHeader(report_path_->fieldCapacitance()); + report_path_->reportLimitShortHeader(report_path_->fieldCapacitance()); for (CapacitanceCheck &check : checks) { if (verbose) - report_path_->reportLimitVerbose(report_path_->fieldCapacitance(), - check.pin(), check.rf(), check.capacitance(), - check.limit(), check.slack(), check.scene(), - min_max); + report_path_->reportLimitVerbose(report_path_->fieldCapacitance(), + check.pin(), check.rf(), + check.capacitance(), check.limit(), + check.slack(), check.scene(), min_max); else - report_path_->reportLimitShort(report_path_->fieldCapacitance(), - check.pin(), check.capacitance(), - check.limit(), check.slack()); - report_->reportLine(""); + report_path_->reportLimitShort(report_path_->fieldCapacitance(), check.pin(), + check.capacitance(), check.limit(), + check.slack()); + report_->report(""); } } } @@ -5810,10 +5748,10 @@ Sta::checkCapacitancesPreamble(const SceneSeq &scenes) void Sta::checkCapacitance(const Pin *pin, const SceneSeq &scenes, - const MinMax *min_max, - // Return values. - float &capacitance, - float &limit, + const MinMax *min_max, + // Return values. + float &capacitance, + float &limit, float &slack, const RiseFall *&rf, const Scene *&scene) @@ -5831,21 +5769,19 @@ size_t Sta::maxCapacitanceViolationCount() { checkCapacitancesPreamble(scenes_); - return check_capacitances_->check(nullptr, 1, true, scenes_, - MinMax::max()).size(); + return check_capacitances_->check(nullptr, 1, true, scenes_, MinMax::max()).size(); } void -Sta::maxCapacitanceCheck(// Return values. - const Pin *&pin, - float &capacitance, - float &slack, - float &limit) +Sta::maxCapacitanceCheck( // Return values. + const Pin *&pin, + float &capacitance, + float &slack, + float &limit) { checkCapacitancesPreamble(scenes_); - CapacitanceCheckSeq &checks = check_capacitances_->check(nullptr, 1, false, - scenes_, - MinMax::max()); + CapacitanceCheckSeq &checks = + check_capacitances_->check(nullptr, 1, false, scenes_, MinMax::max()); pin = nullptr; capacitance = 0.0; slack = INF; @@ -5872,7 +5808,7 @@ Sta::reportMinPulseWidthChecks(const Net *net, if (check_min_pulse_widths_ == nullptr) makeCheckMinPulseWidths(); MinPulseWidthCheckSeq &checks = - check_min_pulse_widths_->check(net, max_count, violators, scenes); + check_min_pulse_widths_->check(net, max_count, violators, scenes); report_path_->reportMpwChecks(checks, verbose); } @@ -5889,8 +5825,8 @@ Sta::reportMinPeriodChecks(const Net *net, ensureClkArrivals(); if (check_min_periods_ == nullptr) makeCheckMinPeriods(); - MinPeriodCheckSeq &checks = check_min_periods_->check(net, max_count, - violators, scenes); + MinPeriodCheckSeq &checks = + check_min_periods_->check(net, max_count, violators, scenes); report_path_->reportChecks(checks, verbose); } @@ -5904,7 +5840,8 @@ Sta::reportMaxSkewChecks(const Net *net, const SceneSeq &scenes) { maxSkewPreamble(); - MaxSkewCheckSeq &checks = check_max_skews_->check(net, max_count, violators, scenes); + MaxSkewCheckSeq &checks = + check_max_skews_->check(net, max_count, violators, scenes); report_path_->reportChecks(checks, verbose); } @@ -5920,7 +5857,7 @@ Sta::maxSkewPreamble() void Sta::makeEquivCells(LibertyLibrarySeq *equiv_libs, - LibertyLibrarySeq *map_libs) + LibertyLibrarySeq *map_libs) { delete equiv_cells_; equiv_cells_ = new EquivCells(equiv_libs, map_libs); @@ -5945,8 +5882,8 @@ Sta::writeTimingModel(const char *lib_name, { ensureLibLinked(); ensureGraph(); - LibertyLibrary *library = makeTimingModel(lib_name, cell_name, filename, - scene, this); + LibertyLibrary *library = + makeTimingModel(lib_name, cell_name, filename, scene, this); writeLiberty(library, filename, this); } @@ -6012,13 +5949,13 @@ Sta::powerPreamble(const Scene *scene) void Sta::power(const Scene *scene, - // Return values. - PowerResult &total, - PowerResult &sequential, - PowerResult &combinational, - PowerResult &clock, - PowerResult ¯o, - PowerResult &pad) + // Return values. + PowerResult &total, + PowerResult &sequential, + PowerResult &combinational, + PowerResult &clock, + PowerResult ¯o, + PowerResult &pad) { powerPreamble(scene); power_->power(scene, total, sequential, combinational, clock, macro, pad); @@ -6053,9 +5990,8 @@ Sta::writePathSpice(const Path *path, CircuitSim ckt_sim) { ensureLibLinked(); - sta::writePathSpice(path, spice_filename, subckt_filename, - lib_subckt_filename, model_filename, - power_name, gnd_name, ckt_sim, this); + sta::writePathSpice(path, spice_filename, subckt_filename, lib_subckt_filename, + model_filename, power_name, gnd_name, ckt_sim, this); } //////////////////////////////////////////////////////////////// @@ -6113,4 +6049,4 @@ Sta::clkPinsInvalid(const Mode *mode) mode->clkNetwork()->clkPinsInvalid(); } -} // namespace +} // namespace sta diff --git a/search/Tag.cc b/search/Tag.cc index a242be9c..9e5113e4 100644 --- a/search/Tag.cc +++ b/search/Tag.cc @@ -160,10 +160,10 @@ Tag::to_string(bool report_index, for (ExceptionState *state : *states_) { ExceptionPath *exception = state->exception(); result += " "; - result += exception->asString(network); + result += exception->to_string(network); if (state->nextThru()) { result += " (next thru "; - result += state->nextThru()->asString(network); + result += state->nextThru()->to_string(network); result += ")"; } else { diff --git a/search/TagGroup.cc b/search/TagGroup.cc index 67d0d5eb..85fc29a5 100644 --- a/search/TagGroup.cc +++ b/search/TagGroup.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 "TagGroup.hh" @@ -43,7 +43,8 @@ TagGroup::TagGroup(TagGroupIndex index, bool has_loop_tag, const StaState *sta) : path_index_map_(path_index_map), - hash_(hash(path_index_map, sta)), + hash_(hash(path_index_map, + sta)), ref_count_(0), index_(index), has_clk_tag_(has_clk_tag), @@ -57,7 +58,8 @@ TagGroup::TagGroup(TagGroupIndex index, TagGroup::TagGroup(TagGroupBldr *tag_bldr, const StaState *sta) : path_index_map_(&tag_bldr->pathIndexMap()), - hash_(hash(path_index_map_, sta)), + hash_(hash(path_index_map_, + sta)), ref_count_(0), own_path_map_(false) { @@ -121,7 +123,7 @@ void TagGroup::report(const StaState *sta) const { Report *report = sta->report(); - report->reportLine("Group %u hash = %zu", index_, hash_); + report->report("Group {} hash = {}", index_, hash_); pathIndexMapReport(path_index_map_, sta); } @@ -137,9 +139,7 @@ pathIndexMapReport(const PathIndexMap *path_index_map, { Report *report = sta->report(); for (auto const [tag, path_index] : *path_index_map) - report->reportLine(" %2zu %s", - path_index, - tag->to_string(sta).c_str()); + report->report(" {:2} {}", path_index, tag->to_string(sta)); report->reportBlankLine(); } @@ -147,10 +147,10 @@ pathIndexMapReport(const PathIndexMap *path_index_map, TagGroupBldr::TagGroupBldr(bool match_crpr_clk_pin, const StaState *sta) : - default_path_count_(sta->scenes().size() - * RiseFall::index_count + default_path_count_(sta->scenes().size() * RiseFall::index_count * MinMax::index_count), - path_index_map_(TagMatchLess(match_crpr_clk_pin, sta)), + path_index_map_(TagMatchLess(match_crpr_clk_pin, + sta)), paths_(default_path_count_), has_clk_tag_(false), has_genclk_src_tag_(false), @@ -213,7 +213,7 @@ TagGroupBldr::tagMatchPath(Tag *tag, } } -Arrival +Arrival TagGroupBldr::arrival(size_t path_index) const { return paths_[path_index].arrival(); @@ -247,8 +247,8 @@ TagGroupBldr::setMatchPath(Path *match, path_index_map_.erase(tag_match); path_index_map_[tag] = path_index; } - paths_[path_index].init(vertex_, tag, arrival, prev_path, - prev_edge, prev_arc, sta_); + paths_[path_index].init(vertex_, tag, arrival, prev_path, prev_edge, prev_arc, + sta_); } else insertPath(tag, arrival, prev_path, prev_edge, prev_arc); @@ -264,15 +264,13 @@ TagGroupBldr::insertPath(Tag *tag, { size_t path_index = paths_.size(); path_index_map_[tag] = path_index; - paths_.emplace_back(vertex_, tag, arrival, prev_path, - prev_edge, prev_arc, sta_); + paths_.emplace_back(vertex_, tag, arrival, prev_path, prev_edge, prev_arc, sta_); if (tag->isClock()) has_clk_tag_ = true; if (tag->isGenClkSrcPath()) has_genclk_src_tag_ = true; - if (tag->isFilter() - || tag->clkInfo()->crprPathRefsFilter()) + if (tag->isFilter() || tag->clkInfo()->crprPathRefsFilter()) has_filter_tag_ = true; if (tag->isLoop()) has_loop_tag_ = true; @@ -283,18 +281,16 @@ TagGroupBldr::insertPath(Tag *tag, void TagGroupBldr::insertPath(const Path &path) { - insertPath(path.tag(sta_), path.arrival(), path.prevPath(), - path.prevEdge(sta_), path.prevArc(sta_)); + insertPath(path.tag(sta_), path.arrival(), path.prevPath(), path.prevEdge(sta_), + path.prevArc(sta_)); } TagGroup * TagGroupBldr::makeTagGroup(TagGroupIndex index, const StaState *sta) { - return new TagGroup(index, makePathIndexMap(sta), - has_clk_tag_, has_genclk_src_tag_, has_filter_tag_, - has_loop_tag_, sta); - + return new TagGroup(index, makePathIndexMap(sta), has_clk_tag_, + has_genclk_src_tag_, has_filter_tag_, has_loop_tag_, sta); } PathIndexMap * @@ -352,9 +348,9 @@ TagGroupEqual::operator()(const TagGroup *tag_group1, const TagGroup *tag_group2) const { return tag_group1 == tag_group2 - || (tag_group1->hash() == tag_group2->hash() - && pathIndexMapEqual(tag_group1->pathIndexMap(), - tag_group2->pathIndexMap())); + || (tag_group1->hash() == tag_group2->hash() + && pathIndexMapEqual(tag_group1->pathIndexMap(), + tag_group2->pathIndexMap())); } -} // namespace +} // namespace sta diff --git a/search/VisitPathEnds.cc b/search/VisitPathEnds.cc index 0c414c86..4a668d9b 100644 --- a/search/VisitPathEnds.cc +++ b/search/VisitPathEnds.cc @@ -67,8 +67,8 @@ VisitPathEnds::visitPathEnds(Vertex *vertex, // Ignore slack on bidirect driver vertex. The load vertex gets the slack. if (!vertex->isBidirectDriver()) { const Pin *pin = vertex->pin(); - debugPrint(debug_, "search", 2, "find end slack %s", - vertex->to_string(this).c_str()); + debugPrint(debug_, "search", 2, "find end slack {}", + vertex->to_string(this)); visitor->vertexBegin(vertex); bool is_constrained = false; visitClkedPathEnds(pin, vertex, scenes, min_max, filtered, visitor, diff --git a/search/WorstSlack.cc b/search/WorstSlack.cc index 8a19ca57..a58efb64 100644 --- a/search/WorstSlack.cc +++ b/search/WorstSlack.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 "WorstSlack.hh" @@ -37,7 +37,8 @@ namespace sta { WorstSlacks::WorstSlacks(StaState *sta) : - worst_slacks_(sta->scenePathCount(), sta), + worst_slacks_(sta->scenePathCount(), + sta), sta_(sta) { } @@ -54,8 +55,8 @@ WorstSlacks::worstSlack(const MinMax *min_max, PathAPIndex path_ap_index = scene->pathIndex(min_max); Slack worst_slack1; Vertex *worst_vertex1; - worst_slacks_[path_ap_index].worstSlack(path_ap_index, - worst_slack1, worst_vertex1); + worst_slacks_[path_ap_index].worstSlack(path_ap_index, worst_slack1, + worst_vertex1); if (delayLess(worst_slack1, worst_slack, sta_)) { worst_slack = worst_slack1; worst_vertex = worst_vertex1; @@ -71,8 +72,7 @@ WorstSlacks::worstSlack(const Scene *scene, Vertex *&worst_vertex) { PathAPIndex path_ap_index = scene->pathIndex(min_max); - worst_slacks_[path_ap_index].worstSlack(path_ap_index, - worst_slack, worst_vertex); + worst_slacks_[path_ap_index].worstSlack(path_ap_index, worst_slack, worst_vertex); } void @@ -105,10 +105,7 @@ WorstSlack::WorstSlack(StaState *sta) : { } -WorstSlack::~WorstSlack() -{ - delete queue_; -} +WorstSlack::~WorstSlack() { delete queue_; } WorstSlack::WorstSlack(const WorstSlack &worst_slack) : StaState(worst_slack), @@ -164,7 +161,7 @@ WorstSlack::initQueue(PathAPIndex path_ap_index) worst_vertex_ = nullptr; worst_slack_ = slack_init_; slack_threshold_ = slack_init_; - for(Vertex *vertex : search_->endpoints()) { + for (Vertex *vertex : search_->endpoints()) { Slack slack = search_->wnsSlack(vertex, path_ap_index); if (!delayEqual(slack, slack_init_, this)) { if (delayLess(slack, worst_slack_, this)) @@ -176,7 +173,7 @@ WorstSlack::initQueue(PathAPIndex path_ap_index) sortQueue(path_ap_index); } } - debugPrint(debug_, "wns", 3, "threshold %s", + debugPrint(debug_, "wns", 3, "threshold {}", delayAsString(slack_threshold_, MinMax::max(), this)); //checkQueue(); } @@ -198,7 +195,7 @@ WorstSlack::sortQueue(PathAPIndex path_ap_index) int threshold_index = std::min(min_queue_size_, vertex_count - 1); Vertex *threshold_vertex = vertices[threshold_index]; slack_threshold_ = search_->wnsSlack(threshold_vertex, path_ap_index); - debugPrint(debug_, "wns", 3, "threshold %s", + debugPrint(debug_, "wns", 3, "threshold {}", delayAsString(slack_threshold_, MinMax::max(), this)); // Reinsert vertices with slack < threshold. @@ -234,9 +231,9 @@ void WorstSlack::checkQueue(PathAPIndex path_ap_index) { VertexSeq ends; - for(Vertex *end : search_->endpoints()) { - if (delayLessEqual(search_->wnsSlack(end, path_ap_index), - slack_threshold_, this)) + for (Vertex *end : search_->endpoints()) { + if (delayLessEqual(search_->wnsSlack(end, path_ap_index), slack_threshold_, + this)) ends.push_back(end); } WnsSlackLess slack_less(path_ap_index, this); @@ -246,20 +243,18 @@ WorstSlack::checkQueue(PathAPIndex path_ap_index) for (Vertex *end : ends) { end_set.insert(end); if (!queue_->contains(end) - && delayLessEqual(search_->wnsSlack(end, path_ap_index), - slack_threshold_, this)) - report_->reportLine("WorstSlack queue missing %s %s < %s", - end->to_string(this).c_str(), - delayAsString(search_->wnsSlack(end, path_ap_index), this), - delayAsString(slack_threshold_, this)); + && delayLessEqual(search_->wnsSlack(end, path_ap_index), slack_threshold_, + this)) + report_->report("WorstSlack queue missing {} {} < {}", end->to_string(this), + delayAsString(search_->wnsSlack(end, path_ap_index), this), + delayAsString(slack_threshold_, this)); } for (Vertex *end : *queue_) { if (!end_set.contains(end)) - report_->reportLine("WorstSlack queue extra %s %s > %s", - end->to_string(this).c_str(), - delayAsString(search_->wnsSlack(end, path_ap_index), this), - delayAsString(slack_threshold_, this)); + report_->report("WorstSlack queue extra {} {} > {}", end->to_string(this), + delayAsString(search_->wnsSlack(end, path_ap_index), this), + delayAsString(slack_threshold_, this)); } } @@ -274,8 +269,7 @@ WorstSlack::updateWorstSlack(Vertex *vertex, // Locking is required because ArrivalVisitor is called by multiple // threads. LockGuard lock(lock_); - if (worst_vertex_ - && delayLess(slack, worst_slack_, this)) + if (worst_vertex_ && delayLess(slack, worst_slack_, this)) setWorstSlack(vertex, slack); else if (vertex == worst_vertex_) // Mark worst slack as unknown (updated by findWorstSlack(). @@ -283,18 +277,16 @@ WorstSlack::updateWorstSlack(Vertex *vertex, if (!delayEqual(slack, slack_init_, this) && delayLessEqual(slack, slack_threshold_, this)) { - debugPrint(debug_, "wns", 3, "insert %s %s", - vertex->to_string(this).c_str(), + debugPrint(debug_, "wns", 3, "insert {} {}", vertex->to_string(this), delayAsString(slack, this)); queue_->insert(vertex); } else { - debugPrint(debug_, "wns", 3, "delete %s %s", - vertex->to_string(this).c_str(), + debugPrint(debug_, "wns", 3, "delete {} {}", vertex->to_string(this), delayAsString(slack, this)); queue_->erase(vertex); } - //checkQueue(path_ap_index); + // checkQueue(path_ap_index); } } @@ -302,8 +294,7 @@ void WorstSlack::setWorstSlack(Vertex *vertex, Slack slack) { - debugPrint(debug_, "wns", 3, "%s %s", - vertex->to_string(this).c_str(), + debugPrint(debug_, "wns", 3, "{} {}", vertex->to_string(this), delayAsString(slack, this)); worst_vertex_ = vertex; worst_slack_ = slack; @@ -323,8 +314,7 @@ WnsSlackLess::operator()(Vertex *vertex1, Vertex *vertex2) { return delayLess(search_->wnsSlack(vertex1, path_ap_index_), - search_->wnsSlack(vertex2, path_ap_index_), - search_); + search_->wnsSlack(vertex2, path_ap_index_), search_); } -} // namespace +} // namespace sta diff --git a/spice/WritePathSpice.cc b/spice/WritePathSpice.cc index 95fabc42..e5c019bd 100644 --- a/spice/WritePathSpice.cc +++ b/spice/WritePathSpice.cc @@ -30,6 +30,7 @@ #include "Debug.hh" #include "Error.hh" #include "Report.hh" +#include "Format.hh" #include "StringUtil.hh" #include "FuncExpr.hh" #include "Units.hh" @@ -203,7 +204,7 @@ WritePathSpice::writeSpice() writeInputSource(); writeStageInstances(); writeStageSubckts(); - streamPrint(spice_stream_, ".end\n"); + sta::print(spice_stream_, ".end\n"); spice_stream_.close(); } else @@ -214,11 +215,11 @@ void WritePathSpice::writeHeader() { const Path *start_path = path_expanded_.startPath(); - std::string title = stdstrPrint("Path from %s %s to %s %s", - network_->pathName(start_path->pin(this)), - start_path->transition(this)->shortName(), - network_->pathName(path_->pin(this)), - path_->transition(this)->shortName()); + std::string title = sta::format("Path from {} {} to {} {}", + network_->pathName(start_path->pin(this)), + start_path->transition(this)->shortName(), + network_->pathName(path_->pin(this)), + path_->transition(this)->shortName()); float max_time = maxTime(); float time_step = 1e-13; writeHeader(title, max_time, time_step); @@ -281,37 +282,37 @@ WritePathSpice::pathMaxTime() void WritePathSpice::writeStageInstances() { - streamPrint(spice_stream_, "*****************\n"); - streamPrint(spice_stream_, "* Stage instances\n"); - streamPrint(spice_stream_, "*****************\n\n"); + sta::print(spice_stream_, "*****************\n"); + sta::print(spice_stream_, "* Stage instances\n"); + sta::print(spice_stream_, "*****************\n\n"); for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { std::string stage_name = stageName(stage); const char *stage_cname = stage_name.c_str(); if (stage == stageFirst()) - streamPrint(spice_stream_, "x%s %s %s %s\n", - stage_cname, - stageDrvrPinName(stage), - stageLoadPinName(stage), - stage_cname); + sta::print(spice_stream_, "x{} {} {} {}\n", + stage_cname, + stageDrvrPinName(stage), + stageLoadPinName(stage), + stage_cname); else { - streamPrint(spice_stream_, "x%s %s %s %s %s\n", - stage_cname, - stageGateInputPinName(stage), - stageDrvrPinName(stage), - stageLoadPinName(stage), - stage_cname); + sta::print(spice_stream_, "x{} {} {} {} {}\n", + stage_cname, + stageGateInputPinName(stage), + stageDrvrPinName(stage), + stageLoadPinName(stage), + stage_cname); } } - streamPrint(spice_stream_, "\n"); + sta::print(spice_stream_, "\n"); } void WritePathSpice::writeInputSource() { - streamPrint(spice_stream_, "**************\n"); - streamPrint(spice_stream_, "* Input source\n"); - streamPrint(spice_stream_, "**************\n\n"); + sta::print(spice_stream_, "**************\n"); + sta::print(spice_stream_, "* Input source\n"); + sta::print(spice_stream_, "**************\n\n"); Stage input_stage = stageFirst(); const Path *input_path = stageDrvrPath(input_stage); @@ -319,7 +320,7 @@ WritePathSpice::writeInputSource() writeClkWaveform(); else writeInputWaveform(); - streamPrint(spice_stream_, "\n"); + sta::print(spice_stream_, "\n"); } void @@ -372,17 +373,17 @@ WritePathSpice::writeClkWaveform() } float slew0 = findSlew(input_path, rf0, next_arc); float slew1 = findSlew(input_path, rf1, next_arc); - streamPrint(spice_stream_, "v1 %s 0 pwl(\n", - stageDrvrPinName(input_stage)); - streamPrint(spice_stream_, "+%.3e %.3e\n", 0.0, volt0); + sta::print(spice_stream_, "v1 {} 0 pwl(\n", + stageDrvrPinName(input_stage)); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", 0.0, volt0); for (int cycle = 0; cycle < clk_cycle_count_; cycle++) { float time0 = time_offset + cycle * period; float time1 = time0 + period / 2.0; writeWaveformEdge(rf0, time0, slew0); writeWaveformEdge(rf1, time1, slew1); } - streamPrint(spice_stream_, "+%.3e %.3e\n", max_time_, volt0); - streamPrint(spice_stream_, "+)\n"); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", max_time_, volt0); + sta::print(spice_stream_, "+)\n"); } float @@ -407,9 +408,9 @@ WritePathSpice::findSlew(const Path *path, void WritePathSpice::writeMeasureStmts() { - streamPrint(spice_stream_, "********************\n"); - streamPrint(spice_stream_, "* Measure statements\n"); - streamPrint(spice_stream_, "********************\n\n"); + sta::print(spice_stream_, "********************\n"); + sta::print(spice_stream_, "* Measure statements\n"); + sta::print(spice_stream_, "********************\n\n"); for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { const Path *gate_input_path = stageGateInputPath(stage); @@ -426,7 +427,7 @@ WritePathSpice::writeMeasureStmts() if (stage == stageLast()) writeMeasureSlewStmt(stage, load_path); } - streamPrint(spice_stream_, "\n"); + sta::print(spice_stream_, "\n"); } void @@ -452,9 +453,9 @@ WritePathSpice::writeMeasureSlewStmt(Stage stage, void WritePathSpice::writeStageSubckts() { - streamPrint(spice_stream_, "***************\n"); - streamPrint(spice_stream_, "* Stage subckts\n"); - streamPrint(spice_stream_, "***************\n\n"); + sta::print(spice_stream_, "***************\n"); + sta::print(spice_stream_, "* Stage subckts\n"); + sta::print(spice_stream_, "***************\n\n"); for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { cap_index_ = 1; @@ -476,12 +477,12 @@ WritePathSpice::writeInputStage(Stage stage) const char *drvr_pin_name = stageDrvrPinName(stage); const char *load_pin_name = stageLoadPinName(stage); std::string prefix = stageName(stage); - streamPrint(spice_stream_, ".subckt %s %s %s\n", - prefix.c_str(), - drvr_pin_name, - load_pin_name); + sta::print(spice_stream_, ".subckt {} {} {}\n", + prefix, + drvr_pin_name, + load_pin_name); writeStageParasitics(stage); - streamPrint(spice_stream_, ".ends\n\n"); + sta::print(spice_stream_, ".ends\n\n"); } // Gate and load parasitics. @@ -500,17 +501,17 @@ WritePathSpice::writeGateStage(Stage stage) const LibertyPort *input_port = stageGateInputPort(stage); const LibertyPort *drvr_port = stageDrvrPort(stage); - streamPrint(spice_stream_, ".subckt %s %s %s %s\n", - subckt_name.c_str(), - input_pin_name, - drvr_pin_name, - load_pin_name); + sta::print(spice_stream_, ".subckt {} {} {} {}\n", + subckt_name, + input_pin_name, + drvr_pin_name, + load_pin_name); // Driver subckt call. - streamPrint(spice_stream_, "* Gate %s %s -> %s\n", - network_->pathName(inst), - input_port->name(), - drvr_port->name()); + sta::print(spice_stream_, "* Gate {} {} -> {}\n", + network_->pathName(inst), + input_port->name(), + drvr_port->name()); writeSubcktInst(inst); const Path *drvr_path = stageDrvrPath(stage); @@ -525,7 +526,7 @@ WritePathSpice::writeGateStage(Stage stage) PinSet inputs(network_); inputs.insert(input_pin); writeSubcktInstVoltSrcs(inst, port_values, inputs); - streamPrint(spice_stream_, "\n"); + sta::print(spice_stream_, "\n"); PinSet drvr_loads(network_); PinConnectedPinIterator *pin_iter = network_->connectedPinIterator(drvr_pin); @@ -537,7 +538,7 @@ WritePathSpice::writeGateStage(Stage stage) writeSubcktInstLoads(drvr_pin, load_pin, drvr_loads, written_insts_); writeStageParasitics(stage); - streamPrint(spice_stream_, ".ends\n\n"); + sta::print(spice_stream_, ".ends\n\n"); } void @@ -575,7 +576,7 @@ WritePathSpice::findPathCellNames() if (arc) { LibertyCell *cell = arc->set()->libertyCell(); if (cell) { - debugPrint(debug_, "write_spice", 2, "cell %s", cell->name()); + debugPrint(debug_, "write_spice", 2, "cell {}", cell->name()); path_cell_names.insert(cell->name()); } // Include side receivers. @@ -612,9 +613,7 @@ WritePathSpice::stageLast() std::string WritePathSpice::stageName(Stage stage) { - std::string name; - stringPrint(name, "stage%d", stage); - return name; + return sta::format("stage{}", stage); } int diff --git a/spice/WriteSpice.cc b/spice/WriteSpice.cc index 1e844ed5..6a62785c 100644 --- a/spice/WriteSpice.cc +++ b/spice/WriteSpice.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 "spice/WriteSpice.hh" -#include // swap +#include // swap #include #include #include @@ -60,7 +60,7 @@ class SubcktEndsMissing : public Exception { public: SubcktEndsMissing(const char *cell_name, - const char *subckt_filename); + const char *subckt_filename); const char *what() const noexcept; protected: @@ -68,7 +68,7 @@ protected: }; SubcktEndsMissing::SubcktEndsMissing(const char *cell_name, - const char *subckt_filename) : + const char *subckt_filename) : Exception() { what_ = "spice subckt for cell "; @@ -122,7 +122,7 @@ WriteSpice::initPowerGnd() default_library_->supplyVoltage(power_name_, power_voltage_, exists); if (!exists) { const OperatingConditions *op_cond = - scene_->sdc()->operatingConditions(min_max_); + scene_->sdc()->operatingConditions(min_max_); if (op_cond == nullptr) op_cond = network_->defaultLibertyLibrary()->defaultOperatingConditions(); power_voltage_ = op_cond->voltage(); @@ -137,31 +137,31 @@ WriteSpice::writeHeader(std::string &title, float max_time, float time_step) { - streamPrint(spice_stream_, "* %s\n", title.c_str()); - streamPrint(spice_stream_, ".include \"%s\"\n", model_filename_); - std::filesystem::path subckt_filename - = std::filesystem::path(subckt_filename_).filename(); - streamPrint(spice_stream_, ".include \"%s\"\n", subckt_filename.c_str()); - streamPrint(spice_stream_, ".tran %.3g %.3g\n", time_step, max_time); + sta::print(spice_stream_, "* {}\n", title); + sta::print(spice_stream_, ".include \"{}\"\n", model_filename_); + std::filesystem::path subckt_filename = + std::filesystem::path(subckt_filename_).filename(); + sta::print(spice_stream_, ".include \"{}\"\n", subckt_filename.string()); + sta::print(spice_stream_, ".tran {:.3g} {:.3g}\n", time_step, max_time); // Suppress printing model parameters. if (ckt_sim_ == CircuitSim::hspice) - streamPrint(spice_stream_, ".options nomod\n"); - streamPrint(spice_stream_, "\n"); + sta::print(spice_stream_, ".options nomod\n"); + sta::print(spice_stream_, "\n"); max_time_ = max_time; } void WriteSpice::writePrintStmt(StringSeq &node_names) { - streamPrint(spice_stream_, ".print tran"); + sta::print(spice_stream_, ".print tran"); if (ckt_sim_ == CircuitSim::xyce) { std::string csv_filename = replaceFileExt(spice_filename_, "csv"); - streamPrint(spice_stream_, " format=csv file=%s", csv_filename.c_str()); + sta::print(spice_stream_, " format=csv file={}", csv_filename); writeGnuplotFile(node_names); } for (std::string &name : node_names) - streamPrint(spice_stream_, " v(%s)", name.c_str()); - streamPrint(spice_stream_, "\n\n"); + sta::print(spice_stream_, " v({})", name); + sta::print(spice_stream_, "\n\n"); } std::string @@ -183,17 +183,16 @@ WriteSpice::writeGnuplotFile(StringSeq &node_nanes) std::ofstream gnuplot_stream; gnuplot_stream.open(gnuplot_filename); if (gnuplot_stream.is_open()) { - streamPrint(gnuplot_stream, "set datafile separator ','\n"); - streamPrint(gnuplot_stream, "set key autotitle columnhead\n"); - streamPrint(gnuplot_stream, "plot\\\n"); - streamPrint(gnuplot_stream, "\"%s\" using 1:2 with lines", - csv_filename.c_str()); + sta::print(gnuplot_stream, "set datafile separator ','\n"); + sta::print(gnuplot_stream, "set key autotitle columnhead\n"); + sta::print(gnuplot_stream, "plot\\\n"); + sta::print(gnuplot_stream, "\"{}\" using 1:2 with lines", csv_filename); for (size_t i = 3; i <= node_nanes.size() + 1; i++) { - streamPrint(gnuplot_stream, ",\\\n"); - streamPrint(gnuplot_stream, "'' using 1:%zu with lines", i); + sta::print(gnuplot_stream, ",\\\n"); + sta::print(gnuplot_stream, "'' using 1:{} with lines", i); } - streamPrint(gnuplot_stream, "\n"); - streamPrint(gnuplot_stream, "pause mouse close\n"); + sta::print(gnuplot_stream, "\n"); + sta::print(gnuplot_stream, "pause mouse close\n"); gnuplot_stream.close(); } } @@ -208,28 +207,27 @@ WriteSpice::writeSubckts(StringSet &cell_names) if (subckts_stream.is_open()) { std::string line; while (std::getline(lib_subckts_stream, line)) { - // .subckt [args..] - StringSeq tokens = parseTokens(line, ' '); - if (tokens.size() >= 2 - && stringEqual(tokens[0].c_str(), ".subckt")) { - const char *cell_name = tokens[1].c_str(); + // .subckt [args..] + StringSeq tokens = parseTokens(line, ' '); + if (tokens.size() >= 2 && stringEqual(tokens[0].c_str(), ".subckt")) { + const char *cell_name = tokens[1].c_str(); if (cell_names.contains(cell_name)) { - subckts_stream << line << "\n"; - bool found_ends = false; - while (std::getline(lib_subckts_stream, line)) { - subckts_stream << line << "\n"; - if (stringBeginEqual(line.c_str(), ".ends")) { - subckts_stream << "\n"; - found_ends = true; - break; - } - } - if (!found_ends) - throw SubcktEndsMissing(cell_name, lib_subckt_filename_); - cell_names.erase(cell_name); - } - recordSpicePortNames(cell_name, tokens); - } + subckts_stream << line << "\n"; + bool found_ends = false; + while (std::getline(lib_subckts_stream, line)) { + subckts_stream << line << "\n"; + if (stringBeginEqual(line.c_str(), ".ends")) { + subckts_stream << "\n"; + found_ends = true; + break; + } + } + if (!found_ends) + throw SubcktEndsMissing(cell_name, lib_subckt_filename_); + cell_names.erase(cell_name); + } + recordSpicePortNames(cell_name, tokens); + } } subckts_stream.close(); lib_subckts_stream.close(); @@ -240,9 +238,8 @@ WriteSpice::writeSubckts(StringSet &cell_names) missing_cells += "\n"; missing_cells += cell_name; } - report_->error(1605, "The subkct file %s is missing definitions for %s", - lib_subckt_filename_, - missing_cells.c_str()); + report_->error(1605, "The subkct file {} is missing definitions for {}", + lib_subckt_filename_, missing_cells); } } else { @@ -265,12 +262,13 @@ WriteSpice::recordSpicePortNames(const char *cell_name, const char *port_name = tokens[i].c_str(); LibertyPort *port = cell->findLibertyPort(port_name); LibertyPort *pg_port = cell->findLibertyPort(port_name); - if (port == nullptr - && pg_port == nullptr - && !stringEqual(port_name, power_name_) - && !stringEqual(port_name, gnd_name_)) - report_->error(1606, "subckt %s port %s has no corresponding liberty port, pg_port and is not power or ground.", - cell_name, port_name); + if (port == nullptr && pg_port == nullptr + && !stringEqual(port_name, power_name_) + && !stringEqual(port_name, gnd_name_)) + report_->error(1606, + "subckt {} port {} has no corresponding liberty port, " + "pg_port and is not power or ground.", + cell_name, port_name); spice_port_names.push_back(port_name); } } @@ -286,8 +284,7 @@ WriteSpice::findCellSubckts(StringSet &cell_names) while (std::getline(lib_subckts_stream, line)) { // .subckt [args..] StringSeq tokens = parseTokens(line, ' '); - if (tokens.size() >= 2 - && stringEqual(tokens[0].c_str(), ".subckt")) { + if (tokens.size() >= 2 && stringEqual(tokens[0].c_str(), ".subckt")) { const char *cell_name = tokens[1].c_str(); if (cell_names.contains(cell_name)) { // Scan the subckt definition for subckt calls. @@ -324,7 +321,7 @@ WriteSpice::writeSubcktInst(const Instance *inst) LibertyCell *cell = network_->libertyCell(inst); const char *cell_name = cell->name(); StringSeq &spice_port_names = cell_spice_port_names_[cell_name]; - streamPrint(spice_stream_, "x%s", inst_name); + sta::print(spice_stream_, "x{}", inst_name); for (std::string subckt_port_name : spice_port_names) { const char *subckt_port_cname = subckt_port_name.c_str(); Pin *pin = network_->findPin(inst, subckt_port_cname); @@ -332,15 +329,15 @@ WriteSpice::writeSubcktInst(const Instance *inst) const char *pin_name; if (pin) { pin_name = network_->pathName(pin); - streamPrint(spice_stream_, " %s", pin_name); + sta::print(spice_stream_, " {}", pin_name); } else if (pg_port) - streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_cname); + sta::print(spice_stream_, " {}/{}", inst_name, subckt_port_cname); else if (stringEq(subckt_port_cname, power_name_) - || stringEq(subckt_port_cname, gnd_name_)) - streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_cname); + || stringEq(subckt_port_cname, gnd_name_)) + sta::print(spice_stream_, " {}/{}", inst_name, subckt_port_cname); } - streamPrint(spice_stream_, " %s\n", cell_name); + sta::print(spice_stream_, " {}\n", cell_name); } // Power/ground and input voltage sources. @@ -354,24 +351,21 @@ WriteSpice::writeSubcktInstVoltSrcs(const Instance *inst, StringSeq &spice_port_names = cell_spice_port_names_[cell_name]; const char *inst_name = network_->pathName(inst); - debugPrint(debug_, "write_spice", 2, "subckt %s", cell->name()); + debugPrint(debug_, "write_spice", 2, "subckt {}", cell->name()); for (std::string subckt_port_sname : spice_port_names) { const char *subckt_port_name = subckt_port_sname.c_str(); LibertyPort *port = cell->findLibertyPort(subckt_port_name); const Pin *pin = port ? network_->findPin(inst, port) : nullptr; bool is_pg_port = port && port->isPwrGnd(); - debugPrint(debug_, "write_spice", 2, " port %s%s", - subckt_port_name, + debugPrint(debug_, "write_spice", 2, " port {}{}", subckt_port_name, is_pg_port ? " pwr/gnd" : ""); if (is_pg_port) - writeVoltageSource(inst_name, subckt_port_name, - pgPortVoltage(port)); + writeVoltageSource(inst_name, subckt_port_name, pgPortVoltage(port)); else if (stringEq(subckt_port_name, power_name_)) writeVoltageSource(inst_name, subckt_port_name, power_voltage_); else if (stringEq(subckt_port_name, gnd_name_)) writeVoltageSource(inst_name, subckt_port_name, gnd_voltage_); - else if (port - && !excluded_input_pins.contains(pin) + else if (port && !excluded_input_pins.contains(pin) && port->direction()->isAnyInput()) { // Input voltage to sensitize path from gate input to output. // Look for tie high/low or propagated constant values. @@ -384,20 +378,18 @@ WriteSpice::writeSubcktInstVoltSrcs(const Instance *inst, port_value = value; } switch (port_value) { - case LogicValue::zero: - case LogicValue::unknown: - writeVoltageSource(cell, inst_name, subckt_port_name, - port->relatedGroundPin(), - gnd_voltage_); - break; - case LogicValue::one: - writeVoltageSource(cell, inst_name, subckt_port_name, - port->relatedPowerPin(), - power_voltage_); - break; - case LogicValue::rise: - case LogicValue::fall: - break; + case LogicValue::zero: + case LogicValue::unknown: + writeVoltageSource(cell, inst_name, subckt_port_name, + port->relatedGroundPin(), gnd_voltage_); + break; + case LogicValue::one: + writeVoltageSource(cell, inst_name, subckt_port_name, + port->relatedPowerPin(), power_voltage_); + break; + case LogicValue::rise: + case LogicValue::fall: + break; } } } @@ -426,10 +418,7 @@ WriteSpice::writeVoltageSource(LibertyCell *cell, if (pg_port) voltage = pgPortVoltage(pg_port); else - report_->error(1603, "%s pg_port %s not found,", - cell->name(), - pg_port_name); - + report_->error(1603, "{} pg_port {} not found,", cell->name(), pg_port_name); } writeVoltageSource(inst_name, subckt_port_name, voltage); } @@ -445,20 +434,18 @@ WriteSpice::pgPortVoltage(LibertyPort *pg_port) liberty->supplyVoltage(voltage_name, voltage, exists); if (!exists) { if (stringEqual(voltage_name, power_name_)) - voltage = power_voltage_; + voltage = power_voltage_; else if (stringEqual(voltage_name, gnd_name_)) - voltage = gnd_voltage_; + voltage = gnd_voltage_; else - report_->error(1601 , "pg_pin %s/%s voltage %s not found,", - pg_port->libertyCell()->name(), - pg_port->name(), - voltage_name); + report_->error(1601, "pg_pin {}/{} voltage {} not found,", + pg_port->libertyCell()->name(), pg_port->name(), + voltage_name); } } else - report_->error(1602, "Liberty pg_port %s/%s missing voltage_name attribute,", - pg_port->libertyCell()->name(), - pg_port->name()); + report_->error(1602, "Liberty pg_port {}/{} missing voltage_name attribute,", + pg_port->libertyCell()->name(), pg_port->name()); return voltage; } @@ -488,19 +475,19 @@ WriteSpice::slewAxisMinValue(const TimingArc *arc) const TableAxis *axis1 = model->axis1(); TableAxisVariable var1 = axis1->variable(); if (var1 == TableAxisVariable::input_transition_time - || var1 == TableAxisVariable::input_net_transition) + || var1 == TableAxisVariable::input_net_transition) return axis1->axisValue(0); const TableAxis *axis2 = model->axis2(); TableAxisVariable var2 = axis2->variable(); if (var2 == TableAxisVariable::input_transition_time - || var2 == TableAxisVariable::input_net_transition) + || var2 == TableAxisVariable::input_net_transition) return axis2->axisValue(0); const TableAxis *axis3 = model->axis3(); TableAxisVariable var3 = axis3->variable(); if (var3 == TableAxisVariable::input_transition_time - || var3 == TableAxisVariable::input_net_transition) + || var3 == TableAxisVariable::input_net_transition) return axis3->axisValue(0); } return 0.0; @@ -514,15 +501,16 @@ WriteSpice::writeDrvrParasitics(const Pin *drvr_pin, const NetSet &coupling_nets) { Net *net = network_->net(drvr_pin); - const char *net_name = net ? network_->pathName(net) : network_->pathName(drvr_pin); - streamPrint(spice_stream_, "* Net %s\n", net_name); + const char *net_name = + net ? network_->pathName(net) : network_->pathName(drvr_pin); + sta::print(spice_stream_, "* Net {}\n", net_name); if (parasitics_->isParasiticNetwork(parasitic)) writeParasiticNetwork(drvr_pin, parasitic, coupling_nets); else if (parasitics_->isPiElmore(parasitic)) writePiElmore(drvr_pin, parasitic); else { - streamPrint(spice_stream_, "* Net has no parasitics.\n"); + sta::print(spice_stream_, "* Net has no parasitics.\n"); writeNullParasitic(drvr_pin); } } @@ -532,22 +520,18 @@ WriteSpice::writeParasiticNetwork(const Pin *drvr_pin, const Parasitic *parasitic, const NetSet &coupling_nets) { - std::set reachable_pins; + std::set reachable_pins; // Sort resistors for consistent regression results. ParasiticResistorSeq resistors = parasitics_->resistors(parasitic); - sort(resistors, [this] (const ParasiticResistor *r1, - const ParasiticResistor *r2) { - return parasitics_->id(r1) < parasitics_->id(r2); - }); + sort(resistors, [this](const ParasiticResistor *r1, const ParasiticResistor *r2) { + return parasitics_->id(r1) < parasitics_->id(r2); + }); for (ParasiticResistor *resistor : resistors) { float resistance = parasitics_->value(resistor); ParasiticNode *node1 = parasitics_->node1(resistor); ParasiticNode *node2 = parasitics_->node2(resistor); - streamPrint(spice_stream_, "R%d %s %s %.3e\n", - res_index_++, - parasitics_->name(node1), - parasitics_->name(node2), - resistance); + sta::print(spice_stream_, "R{} {} {} {:.3e}\n", res_index_++, + parasitics_->name(node1), parasitics_->name(node2), resistance); // Necessary but not sufficient. Need a DFS. const Pin *pin1 = parasitics_->pin(node1); @@ -562,15 +546,11 @@ WriteSpice::writeParasiticNetwork(const Pin *drvr_pin, auto pin_iter = network_->connectedPinIterator(drvr_pin); while (pin_iter->hasNext()) { const Pin *pin = pin_iter->next(); - if (pin != drvr_pin - && network_->isLoad(pin) - && !network_->isHierarchical(pin) + if (pin != drvr_pin && network_->isLoad(pin) && !network_->isHierarchical(pin) && !reachable_pins.contains(pin)) { - streamPrint(spice_stream_, "R%d %s %s %.3e\n", - res_index_++, - network_->pathName(drvr_pin), - network_->pathName(pin), - short_ckt_resistance_); + sta::print(spice_stream_, "R{} {} {} {:.3e}\n", res_index_++, + network_->pathName(drvr_pin), network_->pathName(pin), + short_ckt_resistance_); } } delete pin_iter; @@ -578,28 +558,25 @@ WriteSpice::writeParasiticNetwork(const Pin *drvr_pin, // Grounded node capacitors. // Sort nodes for consistent regression results. ParasiticNodeSeq nodes = parasitics_->nodes(parasitic); - sort(nodes, [this] (const ParasiticNode *node1, - const ParasiticNode *node2) { - const char *name1 = parasitics_->name(node1); - const char *name2 = parasitics_->name(node2); - return stringLess(name1, name2); - }); + sort(nodes, [this](const ParasiticNode *node1, const ParasiticNode *node2) { + const char *name1 = parasitics_->name(node1); + const char *name2 = parasitics_->name(node2); + return stringLess(name1, name2); + }); for (ParasiticNode *node : nodes) { float cap = parasitics_->nodeGndCap(node); // Spice has a cow over zero value caps. if (cap > 0.0) { - streamPrint(spice_stream_, "C%d %s 0 %.3e\n", - cap_index_++, - parasitics_->name(node), - cap); + sta::print(spice_stream_, "C{} {} 0 {:.3e}\n", cap_index_++, + parasitics_->name(node), cap); } } // Sort coupling capacitors for consistent regression results. ParasiticCapacitorSeq capacitors = parasitics_->capacitors(parasitic); - sort(capacitors, [this] (const ParasiticCapacitor *c1, - const ParasiticCapacitor *c2) { + sort(capacitors, + [this](const ParasiticCapacitor *c1, const ParasiticCapacitor *c2) { return parasitics_->id(c1) < parasitics_->id(c2); }); const Net *net = pinNet(drvr_pin, network_); @@ -615,16 +592,11 @@ WriteSpice::writeParasiticNetwork(const Pin *drvr_pin, } if (net2 && coupling_nets.contains(net2)) // Write half the capacitance because the coupled net will do the same. - streamPrint(spice_stream_, "C%d %s %s %.3e\n", - cap_index_++, - parasitics_->name(node1), - parasitics_->name(node2), - cap * .5); + sta::print(spice_stream_, "C{} {} {} {:.3e}\n", cap_index_++, + parasitics_->name(node1), parasitics_->name(node2), cap * .5); else - streamPrint(spice_stream_, "C%d %s 0 %.3e\n", - cap_index_++, - parasitics_->name(node1), - cap); + sta::print(spice_stream_, "C{} {} 0 {:.3e}\n", cap_index_++, + parasitics_->name(node1), cap); } } @@ -650,50 +622,35 @@ WriteSpice::writePiElmore(const Pin *drvr_pin, float c2, rpi, c1; parasitics_->piModel(parasitic, c2, rpi, c1); const char *c1_node = "n1"; - streamPrint(spice_stream_, "RPI %s %s %.3e\n", - network_->pathName(drvr_pin), - c1_node, - rpi); + sta::print(spice_stream_, "RPI {} {} {:.3e}\n", network_->pathName(drvr_pin), + c1_node, rpi); if (c2 > 0.0) - streamPrint(spice_stream_, "C2 %s 0 %.3e\n", - network_->pathName(drvr_pin), - c2); + sta::print(spice_stream_, "C2 {} 0 {:.3e}\n", network_->pathName(drvr_pin), c2); if (c1 > 0.0) - streamPrint(spice_stream_, "C1 %s 0 %.3e\n", - c1_node, - c1); - + sta::print(spice_stream_, "C1 {} 0 {:.3e}\n", c1_node, c1); + int load_index = 3; auto pin_iter = network_->connectedPinIterator(drvr_pin); while (pin_iter->hasNext()) { const Pin *load_pin = pin_iter->next(); - if (load_pin != drvr_pin - && network_->isLoad(load_pin) - && !network_->isHierarchical(load_pin)) { + if (load_pin != drvr_pin && network_->isLoad(load_pin) + && !network_->isHierarchical(load_pin)) { float elmore; bool exists; parasitics_->findElmore(parasitic, load_pin, elmore, exists); if (exists) { - streamPrint(spice_stream_, "E%d el%d 0 %s 0 1.0\n", - load_index, - load_index, - network_->pathName(drvr_pin)); - streamPrint(spice_stream_, "R%d el%d %s 1.0\n", - load_index, - load_index, - network_->pathName(load_pin)); - streamPrint(spice_stream_, "C%d %s 0 %.3e\n", - load_index, - network_->pathName(load_pin), - elmore); + sta::print(spice_stream_, "E{} el{} 0 {} 0 1.0\n", load_index, load_index, + network_->pathName(drvr_pin)); + sta::print(spice_stream_, "R{} el{} {} 1.0\n", load_index, load_index, + network_->pathName(load_pin)); + sta::print(spice_stream_, "C{} {} 0 {:.3e}\n", load_index, + network_->pathName(load_pin), elmore); } else // Add resistor from drvr to load for missing elmore. - streamPrint(spice_stream_, "R%d %s %s %.3e\n", - load_index, - network_->pathName(drvr_pin), - network_->pathName(load_pin), - short_ckt_resistance_); + sta::print(spice_stream_, "R{} {} {} {:.3e}\n", load_index, + network_->pathName(drvr_pin), network_->pathName(load_pin), + short_ckt_resistance_); load_index++; } } @@ -707,14 +664,11 @@ WriteSpice::writeNullParasitic(const Pin *drvr_pin) auto pin_iter = network_->connectedPinIterator(drvr_pin); while (pin_iter->hasNext()) { const Pin *load_pin = pin_iter->next(); - if (load_pin != drvr_pin - && network_->isLoad(load_pin) - && !network_->isHierarchical(load_pin)) { - streamPrint(spice_stream_, "R%d %s %s %.3e\n", - res_index_++, - network_->pathName(drvr_pin), - network_->pathName(load_pin), - short_ckt_resistance_); + if (load_pin != drvr_pin && network_->isLoad(load_pin) + && !network_->isHierarchical(load_pin)) { + sta::print(spice_stream_, "R{} {} {} {:.3e}\n", res_index_++, + network_->pathName(drvr_pin), network_->pathName(load_pin), + short_ckt_resistance_); } } delete pin_iter; @@ -726,10 +680,7 @@ void WriteSpice::writeVoltageSource(const char *node_name, float voltage) { - streamPrint(spice_stream_, "v%d %s 0 %.3f\n", - volt_index_++, - node_name, - voltage); + sta::print(spice_stream_, "v{} {} 0 {:.3f}\n", volt_index_++, node_name, voltage); } void @@ -750,20 +701,19 @@ WriteSpice::writeWaveformVoltSource(const Pin *pin, volt1 = gnd_voltage_; volt_factor = -power_voltage_; } - streamPrint(spice_stream_, "v%d %s 0 pwl(\n", - volt_index_++, - network_->pathName(pin)); - streamPrint(spice_stream_, "+%.3e %.3e\n", 0.0, volt0); + sta::print(spice_stream_, "v{} {} 0 pwl(\n", volt_index_++, + network_->pathName(pin)); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", 0.0, volt0); Table waveform = drvr_waveform->waveform(slew); const TableAxis *time_axis = waveform.axis1(); - for (size_t time_index = 0; time_index < time_axis->size(); time_index++) { + for (size_t time_index = 0; time_index < time_axis->size(); time_index++) { float time = delay + time_axis->axisValue(time_index); float wave_volt = waveform.value(time_index); float volt = volt0 + wave_volt * volt_factor; - streamPrint(spice_stream_, "+%.3e %.3e\n", time, volt); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", time, volt); } - streamPrint(spice_stream_, "+%.3e %.3e\n", max_time_, volt1); - streamPrint(spice_stream_, "+)\n"); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", max_time_, volt1); + sta::print(spice_stream_, "+)\n"); } void @@ -781,13 +731,12 @@ WriteSpice::writeRampVoltSource(const Pin *pin, volt0 = power_voltage_; volt1 = gnd_voltage_; } - streamPrint(spice_stream_, "v%d %s 0 pwl(\n", - volt_index_++, - network_->pathName(pin)); - streamPrint(spice_stream_, "+%.3e %.3e\n", 0.0, volt0); + sta::print(spice_stream_, "v{} {} 0 pwl(\n", volt_index_++, + network_->pathName(pin)); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", 0.0, volt0); writeWaveformEdge(rf, time, slew); - streamPrint(spice_stream_, "+%.3e %.3e\n", max_time_, volt1); - streamPrint(spice_stream_, "+)\n"); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", max_time_, volt1); + sta::print(spice_stream_, "+)\n"); } // Write PWL rise/fall edge that crosses threshold at time. @@ -810,8 +759,8 @@ WriteSpice::writeWaveformEdge(const RiseFall *rf, float time0 = time - dt * threshold; float time1 = time0 + dt; if (time0 > 0.0) - streamPrint(spice_stream_, "+%.3e %.3e\n", time0, volt0); - streamPrint(spice_stream_, "+%.3e %.3e\n", time1, volt1); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", time0, volt0); + sta::print(spice_stream_, "+{:.3e} {:.3e}\n", time1, volt1); } float @@ -841,10 +790,8 @@ WriteSpice::gatePortValues(const Pin *input_pin, const LibertyPort *drvr_port = network_->libertyPort(drvr_pin); const FuncExpr *drvr_func = drvr_port->function(); if (drvr_func) { - if (gate_edge - && gate_edge->role()->genericRole() == TimingRole::regClkToQ()) - regPortValues(input_pin, drvr_rf, drvr_port, drvr_func, - port_values, is_clked); + if (gate_edge && gate_edge->role()->genericRole() == TimingRole::regClkToQ()) + regPortValues(input_pin, drvr_rf, drvr_port, drvr_func, port_values, is_clked); else gatePortValues(inst, drvr_func, input_port, port_values); } @@ -873,16 +820,16 @@ WriteSpice::gatePortValues(const Instance *, int var_index = Cudd_NodeReadIndex(port_node); LogicValue value; switch (cube[var_index]) { - case 0: - value = LogicValue::zero; - break; - case 1: - value = LogicValue::one; - break; - case 2: - default: - value = LogicValue::unknown; - break; + case 0: + value = LogicValue::zero; + break; + case 1: + value = LogicValue::one; + break; + case 2: + default: + value = LogicValue::unknown; + break; } port_values[port] = value; } @@ -914,9 +861,8 @@ WriteSpice::regPortValues(const Pin *input_pin, } else { const LibertyPort *input_port = network_->libertyPort(input_pin); - report_->error(1604, "no register/latch found for path from %s to %s,", - input_port->name(), - drvr_port->name()); + report_->error(1604, "no register/latch found for path from {} to {},", + input_port->name(), drvr_port->name()); } } } @@ -934,23 +880,23 @@ WriteSpice::seqPortValues(Sequential *seq, if (port) { TimingSense sense = data->portTimingSense(port); switch (sense) { - case TimingSense::positive_unate: - if (rf == RiseFall::rise()) - port_values[port] = LogicValue::one; - else - port_values[port] = LogicValue::zero; - break; - case TimingSense::negative_unate: - if (rf == RiseFall::rise()) - port_values[port] = LogicValue::zero; - else - port_values[port] = LogicValue::one; - break; - case TimingSense::non_unate: - case TimingSense::none: - case TimingSense::unknown: - default: - break; + case TimingSense::positive_unate: + if (rf == RiseFall::rise()) + port_values[port] = LogicValue::one; + else + port_values[port] = LogicValue::zero; + break; + case TimingSense::negative_unate: + if (rf == RiseFall::rise()) + port_values[port] = LogicValue::zero; + else + port_values[port] = LogicValue::one; + break; + case TimingSense::non_unate: + case TimingSense::none: + case TimingSense::unknown: + default: + break; } } } @@ -963,21 +909,21 @@ WriteSpice::onePort(FuncExpr *expr) FuncExpr *right = expr->right(); LibertyPort *port; switch (expr->op()) { - case FuncExpr::Op::port: - return expr->port(); - case FuncExpr::Op::not_: - return onePort(left); - case FuncExpr::Op::or_: - case FuncExpr::Op::and_: - case FuncExpr::Op::xor_: - port = onePort(left); - if (port == nullptr) - port = onePort(right); - return port; - case FuncExpr::Op::one: - case FuncExpr::Op::zero: - default: - return nullptr; + case FuncExpr::Op::port: + return expr->port(); + case FuncExpr::Op::not_: + return onePort(left); + case FuncExpr::Op::or_: + case FuncExpr::Op::and_: + case FuncExpr::Op::xor_: + port = onePort(left); + if (port == nullptr) + port = onePort(right); + return port; + case FuncExpr::Op::one: + case FuncExpr::Op::zero: + default: + return nullptr; } } @@ -1006,20 +952,18 @@ WriteSpice::writeSubcktInstLoads(const Pin *drvr_pin, const PinSet &excluded_input_pins, InstanceSet &written_insts) { - streamPrint(spice_stream_, "* Load pins\n"); + sta::print(spice_stream_, "* Load pins\n"); PinSeq drvr_loads = drvrLoads(drvr_pin); // Do not sensitize side load gates. LibertyPortLogicValues port_values; for (const Pin *load_pin : drvr_loads) { const Instance *load_inst = network_->instance(load_pin); - if (load_pin != path_load - && network_->direction(load_pin)->isAnyInput() - && !network_->isHierarchical(load_pin) - && !network_->isTopLevelPort(load_pin) + if (load_pin != path_load && network_->direction(load_pin)->isAnyInput() + && !network_->isHierarchical(load_pin) && !network_->isTopLevelPort(load_pin) && !written_insts.contains(load_inst)) { writeSubcktInst(load_inst); writeSubcktInstVoltSrcs(load_inst, port_values, excluded_input_pins); - streamPrint(spice_stream_, "\n"); + sta::print(spice_stream_, "\n"); written_insts.insert(load_inst); } } @@ -1038,21 +982,12 @@ WriteSpice::writeMeasureDelayStmt(const Pin *from_pin, float from_threshold = power_voltage_ * default_library_->inputThreshold(from_rf); const char *to_pin_name = network_->pathName(to_pin); float to_threshold = power_voltage_ * default_library_->inputThreshold(to_rf); - streamPrint(spice_stream_, - ".measure tran %s_%s_delay_%s\n", - prefix.c_str(), - from_pin_name, - to_pin_name); - streamPrint(spice_stream_, - "+trig v(%s) val=%.3f %s=last\n", - from_pin_name, - from_threshold, - spiceTrans(from_rf)); - streamPrint(spice_stream_, - "+targ v(%s) val=%.3f %s=last\n", - to_pin_name, - to_threshold, - spiceTrans(to_rf)); + sta::print(spice_stream_, ".measure tran {}_{}_delay_{}\n", prefix, + from_pin_name, to_pin_name); + sta::print(spice_stream_, "+trig v({}) val={:.3f} {}=last\n", from_pin_name, + from_threshold, spiceTrans(from_rf)); + sta::print(spice_stream_, "+targ v({}) val={:.3f} {}=last\n", to_pin_name, + to_threshold, spiceTrans(to_rf)); } void @@ -1073,25 +1008,15 @@ WriteSpice::writeMeasureSlewStmt(const Pin *pin, threshold1 = upper; threshold2 = lower; } - streamPrint(spice_stream_, - ".measure tran %s_%s_slew\n", - prefix.c_str(), - pin_name); - streamPrint(spice_stream_, - "+trig v(%s) val=%.3f %s=last\n", - pin_name, - threshold1, - spice_rf); - streamPrint(spice_stream_, - "+targ v(%s) val=%.3f %s=last\n", - pin_name, - threshold2, - spice_rf); + sta::print(spice_stream_, ".measure tran {}_{}_slew\n", prefix, pin_name); + sta::print(spice_stream_, "+trig v({}) val={:.3f} {}=last\n", pin_name, threshold1, + spice_rf); + sta::print(spice_stream_, "+targ v({}) val={:.3f} {}=last\n", pin_name, threshold2, + spice_rf); } //////////////////////////////////////////////////////////////// - const char * WriteSpice::spiceTrans(const RiseFall *rf) { @@ -1101,23 +1026,6 @@ WriteSpice::spiceTrans(const RiseFall *rf) return "FALL"; } -// fprintf for c++ streams. -// Yes, I hate formatted output to ostream THAT much. -void -streamPrint(std::ofstream &stream, - const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - char *result = nullptr; - if (vasprintf(&result, fmt, args) == -1) - criticalError(267, "out of memory"); - stream << result; - free(result); - va_end(args); -} - //////////////////////////////////////////////////////////////// // Unused @@ -1139,4 +1047,4 @@ WriteSpice::clkWaveformTimeOffset(const Clock *clk) return clk->period() / 10; } -} // namespace +} // namespace sta diff --git a/spice/WriteSpice.hh b/spice/WriteSpice.hh index ace2b78b..74fecf00 100644 --- a/spice/WriteSpice.hh +++ b/spice/WriteSpice.hh @@ -29,6 +29,7 @@ #include #include +#include "Format.hh" #include "StaState.hh" #include "StringUtil.hh" #include "Liberty.hh" @@ -186,9 +187,4 @@ protected: Parasitics *parasitics_; }; -void -streamPrint(std::ofstream &stream, - const char *fmt, - ...) __attribute__((format (printf, 2, 3))); - -} // namespace +} // namespace sta diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index 732a651a..b01986a2 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -444,7 +444,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); Transition *tr = Transition::find(arg); if (tr == nullptr) { - tclArgError(interp, 2150, "Unknown transition '%s'.", arg); + tclArgError(interp, 2150, "Unknown transition '{}'.", arg); return TCL_ERROR; } else @@ -464,7 +464,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); const RiseFall *rf = RiseFall::find(arg); if (rf == nullptr) { - tclArgError(interp, 2151, "Unknown rise/fall edge '%s'.", arg); + tclArgError(interp, 2151, "Unknown rise/fall edge '{}'.", arg); return TCL_ERROR; } // Swig is retarded and drops const on args. @@ -484,7 +484,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); const RiseFallBoth *rf = RiseFallBoth::find(arg); if (rf == nullptr) { - tclArgError(interp, 2152, "Unknown transition name '%s'.", arg); + tclArgError(interp, 2152, "Unknown transition name '{}'.", arg); return TCL_ERROR; } // Swig is retarded and drops const on args. @@ -504,7 +504,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); PortDirection *dir = PortDirection::find(arg); if (dir == nullptr) { - tclArgError(interp, 2153, "Unknown port direction '%s'.", arg); + tclArgError(interp, 2153, "Unknown port direction '{}'.", arg); return TCL_ERROR; } else @@ -519,7 +519,7 @@ using namespace sta; // Swig is retarded and drops const on args. $1 = const_cast(TimingRole::find(arg)); else { - tclArgError(interp, 2154, "Unknown timing role '%s'.", arg); + tclArgError(interp, 2154, "Unknown timing role '{}'.", arg); return TCL_ERROR; } } @@ -542,7 +542,7 @@ using namespace sta; else if (stringEq(arg, "fall") || stringEq(arg, "falling")) $1 = LogicValue::fall; else { - tclArgError(interp, 2155, "Unknown logic value '%s'.", arg); + tclArgError(interp, 2155, "Unknown logic value '{}'.", arg); return TCL_ERROR; } } @@ -557,7 +557,7 @@ using namespace sta; else if (stringEq(arg, "on_chip_variation")) $1 = AnalysisType::ocv; else { - tclArgError(interp, 2156, "Unknown analysis type '%s'.", arg); + tclArgError(interp, 2156, "Unknown analysis type '{}'.", arg); return TCL_ERROR; } } @@ -762,7 +762,7 @@ using namespace sta; floats->push_back(static_cast(value)); else { delete floats; - tclArgError(interp, 2157, "%s is not a floating point number.", arg); + tclArgError(interp, 2157, "{} is not a floating point number.", arg); return TCL_ERROR; } } @@ -807,7 +807,7 @@ using namespace sta; ints->push_back(value); else { delete ints; - tclArgError(interp, 2158, "%s is not an integer.", arg); + tclArgError(interp, 2158, "{} is not an integer.", arg); return TCL_ERROR; } } @@ -869,7 +869,7 @@ using namespace sta; if (min_max) $1 = min_max; else { - tclArgError(interp, 2159, "%s not min or max.", arg); + tclArgError(interp, 2159, "{} not min or max.", arg); return TCL_ERROR; } } @@ -890,7 +890,7 @@ using namespace sta; if (min_max) $1 = min_max; else { - tclArgError(interp, 2160, "%s not min, max or min_max.", arg); + tclArgError(interp, 2160, "{} not min, max or min_max.", arg); return TCL_ERROR; } } @@ -906,7 +906,7 @@ using namespace sta; if (min_max) $1 = min_max; else { - tclArgError(interp, 2161, "%s not min, max or min_max.", arg); + tclArgError(interp, 2161, "{} not min, max or min_max.", arg); return TCL_ERROR; } } @@ -928,7 +928,7 @@ using namespace sta; || stringEqual(arg, "max")) $1 = const_cast(MinMax::max()); else { - tclArgError(interp, 2162, "%s not setup, hold, min or max.", arg); + tclArgError(interp, 2162, "{} not setup, hold, min or max.", arg); return TCL_ERROR; } } @@ -948,7 +948,7 @@ using namespace sta; || stringEqual(arg, "min_max")) $1 = const_cast(SetupHoldAll::all()); else { - tclArgError(interp, 2163, "%s not setup, hold, setup_hold, min, max or min_max.", + tclArgError(interp, 2163, "{} not setup, hold, setup_hold, min, max or min_max.", arg); return TCL_ERROR; } @@ -963,7 +963,7 @@ using namespace sta; if (early_late) $1 = early_late; else { - tclArgError(interp, 2164, "%s not early/min, late/max or early_late/min_max.", arg); + tclArgError(interp, 2164, "{} not early/min, late/max or early_late/min_max.", arg); return TCL_ERROR; } } @@ -977,7 +977,7 @@ using namespace sta; if (early_late) $1 = early_late; else { - tclArgError(interp, 2165, "%s not early/min, late/max or early_late/min_max.", arg); + tclArgError(interp, 2165, "{} not early/min, late/max or early_late/min_max.", arg); return TCL_ERROR; } } @@ -992,7 +992,7 @@ using namespace sta; else if (stringEq(arg, "cell_check")) $1 = TimingDerateType::cell_check; else { - tclArgError(interp, 2166, "%s not net_delay, cell_delay or cell_check.", arg); + tclArgError(interp, 2166, "{} not net_delay, cell_delay or cell_check.", arg); return TCL_ERROR; } } @@ -1005,7 +1005,7 @@ using namespace sta; else if (stringEq(arg, "cell_check")) $1 = TimingDerateCellType::cell_check; else { - tclArgError(interp, 2167, "%s not cell_delay or cell_check.", arg); + tclArgError(interp, 2167, "{} not cell_delay or cell_check.", arg); return TCL_ERROR; } } @@ -1018,7 +1018,7 @@ using namespace sta; else if (stringEq(arg, "data")) $1 = PathClkOrData::data; else { - tclArgError(interp, 2168, "%s not clk or data.", arg); + tclArgError(interp, 2168, "{} not clk or data.", arg); return TCL_ERROR; } } @@ -1031,7 +1031,7 @@ using namespace sta; else if (stringEq(arg, "slack")) $1 = sort_by_slack; else { - tclArgError(interp, 2169, "%s not group or slack.", arg); + tclArgError(interp, 2169, "{} not group or slack.", arg); return TCL_ERROR; } } @@ -1056,7 +1056,7 @@ using namespace sta; else if (stringEq(arg, "json")) $1 = ReportPathFormat::json; else { - tclArgError(interp, 2170, "unknown path type %s.", arg); + tclArgError(interp, 2170, "unknown path type {}.", arg); return TCL_ERROR; } } @@ -1225,7 +1225,7 @@ using namespace sta; if (mode) seq.push_back(mode); else { - tclArgError(interp, 2174, "mode %s not found.", mode_name); + tclArgError(interp, 2174, "mode {} not found.", mode_name); return TCL_ERROR; } } @@ -1256,7 +1256,7 @@ using namespace sta; if (scene) $1 = scene; else { - tclArgError(interp, 2173, "scene %s not found.", scene_name); + tclArgError(interp, 2173, "scene {} not found.", scene_name); return TCL_ERROR; } } @@ -1285,7 +1285,7 @@ using namespace sta; if (scene) seq.push_back(scene); else { - tclArgError(interp, 2172, "scene %s not found.", scene_name); + tclArgError(interp, 2172, "scene {} not found.", scene_name); return TCL_ERROR; } } @@ -1321,8 +1321,8 @@ using namespace sta; break; case PropertyValue::Type::float_: { const Unit *unit = value.unit(); - const char *float_string = unit->asString(value.floatValue(), 6); - Tcl_SetResult(interp, const_cast(float_string), TCL_VOLATILE); + std::string float_string = unit->asString(value.floatValue(), 6); + Tcl_SetResult(interp, const_cast(float_string.c_str()), TCL_VOLATILE); } break; case PropertyValue::Type::bool_: { @@ -1422,18 +1422,17 @@ using namespace sta; PwrActivity activity = value.pwrActivity(); Tcl_Obj *list = Tcl_NewListObj(0, nullptr); Tcl_Obj *obj; - const char *str; - str = stringPrintTmp("%.5e", activity.density()); - obj = Tcl_NewStringObj(str, strlen(str)); + std::string density = sta::format("{:.5e}", activity.density()); + obj = Tcl_NewStringObj(density.c_str(), density.size()); Tcl_ListObjAppendElement(interp, list, obj); - str = stringPrintTmp("%.3f", activity.duty()); - obj = Tcl_NewStringObj(str, strlen(str)); + std::string duty = sta::format("{:.3f}", activity.duty()); + obj = Tcl_NewStringObj(duty.c_str(), duty.size()); Tcl_ListObjAppendElement(interp, list, obj); - str = activity.originName(); - obj = Tcl_NewStringObj(str, strlen(str)); + std::string name = activity.originName(); + obj = Tcl_NewStringObj(name.c_str(), name.size()); Tcl_ListObjAppendElement(interp, list, obj); Tcl_SetObjResult(interp, list); @@ -1452,7 +1451,7 @@ using namespace sta; else if (stringEq(arg, "xyce")) $1 = CircuitSim::xyce; else { - tclArgError(interp, 2171, "unknown circuit simulator %s.", arg); + tclArgError(interp, 2171, "unknown circuit simulator {}.", arg); return TCL_ERROR; } } diff --git a/tcl/TclTypeHelpers.cc b/tcl/TclTypeHelpers.cc index 0de899c5..66dc529c 100644 --- a/tcl/TclTypeHelpers.cc +++ b/tcl/TclTypeHelpers.cc @@ -170,8 +170,8 @@ tclArcDcalcArg(ArcDcalcArg &gate, obj = Tcl_NewStringObj(to_edge, strlen(to_edge)); Tcl_ListObjAppendElement(interp, list, obj); - const char *input_delay = delayAsString(gate.inputDelay(), sta); - obj = Tcl_NewStringObj(input_delay, strlen(input_delay)); + std::string input_delay = delayAsString(gate.inputDelay(), sta); + obj = Tcl_NewStringObj(input_delay.c_str(), input_delay.size()); Tcl_ListObjAppendElement(interp, list, obj); return list; diff --git a/util/Debug.cc b/util/Debug.cc index c2429db4..917e40fa 100644 --- a/util/Debug.cc +++ b/util/Debug.cc @@ -81,19 +81,4 @@ Debug::setLevel(const char *what, } } -void -Debug::reportLine(const char *what, - const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - std::unique_lock lock(buffer_lock_); - report_->printToBuffer("%s", what); - report_->printToBufferAppend(": "); - report_->printToBufferAppend(fmt, args); - report_->printBufferLine(); - va_end(args); -} - } // namespace diff --git a/util/Error.cc b/util/Error.cc index aa4b85e5..88914f26 100644 --- a/util/Error.cc +++ b/util/Error.cc @@ -27,6 +27,7 @@ #include #include +#include "Format.hh" #include "StringUtil.hh" namespace sta { @@ -36,7 +37,7 @@ Exception::Exception() : { } -ExceptionMsg::ExceptionMsg(const char *msg, +ExceptionMsg::ExceptionMsg(const std::string &msg, const bool suppressed) : Exception(), msg_(msg), @@ -50,7 +51,7 @@ ExceptionMsg::what() const noexcept return msg_.c_str(); } -ExceptionLine::ExceptionLine(const char *filename, +ExceptionLine::ExceptionLine(const std::string &filename, int line) : Exception(), filename_(filename), @@ -58,26 +59,28 @@ ExceptionLine::ExceptionLine(const char *filename, { } -FileNotReadable::FileNotReadable(const char *filename) : - filename_(filename) +FileNotReadable::FileNotReadable(std::string filename) : + filename_(std::move(filename)), + msg_(sta::format("cannot read file {}.", filename_)) { } const char * FileNotReadable::what() const noexcept { - return stringPrintTmp("cannot read file %s.", filename_); + return msg_.c_str(); } -FileNotWritable::FileNotWritable(const char *filename) : - filename_(filename) +FileNotWritable::FileNotWritable(std::string filename) : + filename_(std::move(filename)), + msg_(sta::format("cannot write file {}.", filename_)) { } const char * FileNotWritable::what() const noexcept { - return stringPrintTmp("cannot write file %s.", filename_); + return msg_.c_str(); } } // namespace diff --git a/util/MachineLinux.cc b/util/MachineLinux.cc index 261d143f..7be581f6 100644 --- a/util/MachineLinux.cc +++ b/util/MachineLinux.cc @@ -33,6 +33,7 @@ #include "StaConfig.hh" #include "StringUtil.hh" +#include "Format.hh" namespace sta { @@ -81,8 +82,7 @@ systemRunTime() size_t memoryUsage() { - std::string proc_filename; - stringPrint(proc_filename, "/proc/%d/status", getpid()); + std::string proc_filename = sta::format("/proc/{}/status", getpid()); size_t memory = 0; FILE *status = fopen(proc_filename.c_str(), "r"); if (status) { diff --git a/util/Report.cc b/util/Report.cc index 4a6e6bf8..d539c574 100644 --- a/util/Report.cc +++ b/util/Report.cc @@ -1,35 +1,36 @@ // 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 "Report.hh" -#include // min -#include // exit -#include // strlen +#include // min +#include // exit +#include // strlen -#include "Machine.hh" #include "Error.hh" +#include "Machine.hh" +#include "Format.hh" namespace sta { @@ -46,10 +47,7 @@ Report::Report() : default_ = this; } -Report::~Report() -{ - delete [] buffer_; -} +Report::~Report() { delete[] buffer_; } size_t Report::printConsole(const char *buffer, @@ -85,17 +83,6 @@ Report::printString(const char *buffer, return ret; } -void -Report::reportLine(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - std::unique_lock lock(buffer_lock_); - printToBuffer(fmt, args); - printBufferLine(); - va_end(args); -} - void Report::reportBlankLine() { @@ -103,13 +90,7 @@ Report::reportBlankLine() } void -Report::reportLineString(const char *line) -{ - printLine(line, strlen(line)); -} - -void -Report::reportLineString(const std::string &line) +Report::reportLine(const std::string &line) { printLine(line.c_str(), line.length()); } @@ -151,16 +132,16 @@ Report::printToBufferAppend(const char *fmt, // Copy args in case we need to grow the buffer. va_list args_copy; va_copy(args_copy, args); - size_t length = vsnprint(buffer_ + buffer_length_, buffer_size_- buffer_length_, - fmt, args); + size_t length = + vsnprint(buffer_ + buffer_length_, buffer_size_ - buffer_length_, fmt, args); if (length >= buffer_size_ - buffer_length_) { buffer_size_ = buffer_length_ + length * 2; char *new_buffer = new char[buffer_size_]; strncpy(new_buffer, buffer_, buffer_length_); - delete [] buffer_; + delete[] buffer_; buffer_ = new_buffer; - length = vsnprint(buffer_ + buffer_length_, buffer_size_ - buffer_length_, - fmt, args_copy); + length = vsnprint(buffer_ + buffer_length_, buffer_size_ - buffer_length_, fmt, + args_copy); } buffer_length_ += length; va_end(args_copy); @@ -175,152 +156,10 @@ Report::printBufferLine() //////////////////////////////////////////////////////////////// void -Report::warn(int id, - const char *fmt, - ...) +reportThrowExceptionMsg(const std::string &msg, + bool suppressed) { - // Skip suppressed messages. - if (!isSuppressed(id)) { - va_list args; - va_start(args, fmt); - printToBuffer("Warning %d: ", id); - printToBufferAppend(fmt, args); - printBufferLine(); - va_end(args); - } -} - -void -Report::vwarn(int id, - const char *fmt, - va_list args) -{ - // Skip suppressed messages. - if (!isSuppressed(id)) { - printToBuffer("Warning %d: ", id); - printToBufferAppend(fmt, args); - printBufferLine(); - } -} - -void -Report::fileWarn(int id, - const char *filename, - int line, - const char *fmt, - ...) -{ - // Skip suppressed messages. - if (!isSuppressed(id)) { - va_list args; - va_start(args, fmt); - printToBuffer("Warning %d: %s line %d, ", id, filename, line); - printToBufferAppend(fmt, args); - printBufferLine(); - va_end(args); - } -} - -void -Report::vfileWarn(int id, - const char *filename, - int line, - const char *fmt, - va_list args) -{ - // Skip suppressed messages. - if (!isSuppressed(id)) { - printToBuffer("Warning %d: %s line %d, ", id, filename, line); - printToBufferAppend(fmt, args); - printBufferLine(); - } -} - -//////////////////////////////////////////////////////////////// - -void -Report::error(int id, - const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - // No prefix msg, no \n. - printToBuffer("%d ", id); - printToBufferAppend(fmt, args); - va_end(args); - throw ExceptionMsg(buffer_, isSuppressed(id)); -} - -void -Report::verror(int id, - const char *fmt, - va_list args) -{ - // No prefix msg, no \n. - printToBuffer("%d ", id); - printToBufferAppend(fmt, args); - throw ExceptionMsg(buffer_, isSuppressed(id)); -} - -void -Report::fileError(int id, - const char *filename, - int line, - const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - // No prefix msg, no \n. - printToBuffer("%d %s line %d, ", id, filename, line); - printToBufferAppend(fmt, args); - va_end(args); - throw ExceptionMsg(buffer_, isSuppressed(id)); -} - -void -Report::vfileError(int id, - const char *filename, - int line, - const char *fmt, - va_list args) -{ - // No prefix msg, no \n. - printToBuffer("%d %s line %d, ", id, filename, line); - printToBufferAppend(fmt, args); - throw ExceptionMsg(buffer_, isSuppressed(id)); -} - -//////////////////////////////////////////////////////////////// - -void -Report::critical(int id, - const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - printToBuffer("Critical %d: ", id); - printToBufferAppend(fmt, args); - printBufferLine(); - va_end(args); - exit(1); -} - -void -Report::fileCritical(int id, - const char *filename, - int line, - const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - printToBuffer("Critical %d: %s line %d, ", id, filename, line); - printToBufferAppend(fmt, args); - printBufferLine(); - va_end(args); - exit(1); + throw ExceptionMsg(msg, suppressed); } //////////////////////////////////////////////////////////////// @@ -346,11 +185,12 @@ Report::isSuppressed(int id) //////////////////////////////////////////////////////////////// void -Report::logBegin(const char *filename) +Report::logBegin(std::string_view filename) { - log_stream_ = fopen(filename, "w"); + std::string filename_str(filename); + log_stream_ = fopen(filename_str.c_str(), "w"); if (log_stream_ == nullptr) - throw FileNotWritable(filename); + throw FileNotWritable(std::move(filename_str)); } void @@ -362,19 +202,21 @@ Report::logEnd() } void -Report::redirectFileBegin(const char *filename) +Report::redirectFileBegin(std::string_view filename) { - redirect_stream_ = fopen(filename, "w"); + std::string filename_str(filename); + redirect_stream_ = fopen(filename_str.c_str(), "w"); if (redirect_stream_ == nullptr) - throw FileNotWritable(filename); + throw FileNotWritable(std::move(filename_str)); } void -Report::redirectFileAppendBegin(const char *filename) +Report::redirectFileAppendBegin(std::string_view filename) { - redirect_stream_ = fopen(filename, "a"); + std::string filename_str(filename); + redirect_stream_ = fopen(filename_str.c_str(), "a"); if (redirect_stream_ == nullptr) - throw FileNotWritable(filename); + throw FileNotWritable(std::move(filename_str)); } void @@ -406,4 +248,4 @@ Report::redirectStringPrint(const char *buffer, redirect_string_.append(buffer, length); } -} // namespace +} // namespace sta diff --git a/util/ReportTcl.cc b/util/ReportTcl.cc index d3e07048..a418a53a 100644 --- a/util/ReportTcl.cc +++ b/util/ReportTcl.cc @@ -183,7 +183,7 @@ ReportTcl::flush() // Tcl_Main can eval multiple commands before the flushing the command // output, so the log/redirect commands must force a flush. void -ReportTcl::logBegin(const char *filename) +ReportTcl::logBegin(std::string_view filename) { flush(); Report::logBegin(filename); @@ -197,14 +197,14 @@ ReportTcl::logEnd() } void -ReportTcl::redirectFileBegin(const char *filename) +ReportTcl::redirectFileBegin(std::string_view filename) { flush(); Report::redirectFileBegin(filename); } void -ReportTcl::redirectFileAppendBegin(const char *filename) +ReportTcl::redirectFileAppendBegin(std::string_view filename) { flush(); Report::redirectFileAppendBegin(filename); diff --git a/util/Stats.cc b/util/Stats.cc index ac6d98dd..07fb62a1 100644 --- a/util/Stats.cc +++ b/util/Stats.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 "Stats.hh" @@ -57,12 +57,11 @@ Stats::report(const char *step) double memory_begin = static_cast(memory_begin_); double memory_end = static_cast(memoryUsage()); double memory_delta = memory_end - memory_begin; - report_->reportLine("stats: %5.1f/%5.1fe %5.1f/%5.1fu %5.1f/%5.1fMB %s", - elapsed_end - elapsed_begin_, elapsed_end, - user_end - user_begin_, user_end, - memory_delta * 1e-6, memory_end * 1e-6, - step); + report_->report("stats: {:5.1f}/{:5.1f}e {:5.1f}/{:5.1f}u {:5.1f}/{:5.1f}MB {}", + elapsed_end - elapsed_begin_, elapsed_end, + user_end - user_begin_, user_end, memory_delta * 1e-6, + memory_end * 1e-6, step); } } -} // namespace +} // namespace sta diff --git a/util/StringUtil.cc b/util/StringUtil.cc index 2b93704c..cc77196c 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -32,20 +32,10 @@ #include "Machine.hh" #include "Mutex.hh" +#include "Error.hh" namespace sta { -static void -stringPrintTmp(const char *fmt, - va_list args, - // Return values. - char *&str, - size_t &length); -static void -getTmpString(// Return values. - char *&str, - size_t &length); - char * stringCopy(const char *str) { @@ -70,112 +60,6 @@ isDigits(const char *str) //////////////////////////////////////////////////////////////// -// print for c++ strings. -void -stringPrint(std::string &str, - const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - char *tmp; - size_t tmp_length; - stringPrintTmp(fmt, args, tmp, tmp_length); - va_end(args); - str = tmp; -} - -void -stringAppend(std::string &str, - const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - char *tmp; - size_t tmp_length; - stringPrintTmp(fmt, args, tmp, tmp_length); - va_end(args); - str += tmp; -} - -std::string -stdstrPrint(const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - char *tmp; - size_t tmp_length; - stringPrintTmp(fmt, args, tmp, tmp_length); - va_end(args); - return tmp; -} - -char * -stringPrint(const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - char *result = stringPrintArgs(fmt, args); - va_end(args); - return result; -} - -char * -stringPrintArgs(const char *fmt, - va_list args) -{ - char *tmp; - size_t tmp_length; - stringPrintTmp(fmt, args, tmp, tmp_length); - char *result = new char[tmp_length + 1]; - strcpy(result, tmp); - return result; -} - -char * -stringPrintTmp(const char *fmt, - ...) -{ - va_list args; - va_start(args, fmt); - char *tmp; - size_t tmp_length; - stringPrintTmp(fmt, args, tmp, tmp_length); - va_end(args); - return tmp; -} - -static void -stringPrintTmp(const char *fmt, - va_list args, - // Return values. - char *&tmp, - // strlen(tmp), not including terminating '\0'. - size_t &tmp_length) -{ - size_t tmp_length1; - getTmpString(tmp, tmp_length1); - - va_list args_copy; - va_copy(args_copy, args); - // Returned length does NOT include trailing '\0'. - tmp_length = vsnprint(tmp, tmp_length1, fmt, args_copy); - va_end(args_copy); - - if (tmp_length >= tmp_length1) { - tmp_length1 = tmp_length + 1; - tmp = makeTmpString(tmp_length1); - va_copy(args_copy, args); - tmp_length = vsnprint(tmp, tmp_length1, fmt, args_copy); - va_end(args_copy); - } -} - -//////////////////////////////////////////////////////////////// - static constexpr size_t tmp_string_count = 256; static constexpr size_t tmp_string_initial_length = 256; thread_local static std::array tmp_strings; @@ -193,22 +77,6 @@ deleteTmpStrings() tmp_string_next = 0; } -static void -getTmpString(// Return values. - char *&str, - size_t &length) -{ - if (tmp_string_next == tmp_string_count) - tmp_string_next = 0; - str = tmp_strings[tmp_string_next]; - length = tmp_string_lengths[tmp_string_next]; - if (str == nullptr) { - str = tmp_strings[tmp_string_next] = new char[tmp_string_initial_length]; - length = tmp_string_lengths[tmp_string_next] = tmp_string_initial_length; - } - tmp_string_next++; -} - char * makeTmpString(size_t length) { @@ -239,10 +107,8 @@ makeTmpString(std::string &str) void stringDeleteCheck(const char *str) { - if (isTmpString(str)) { - printf("Critical error: stringDelete for tmp string."); - exit(1); - } + if (isTmpString(str)) + criticalError(2600, "stringDelete for tmp string."); } bool diff --git a/util/Util.i b/util/Util.i index 32d9e0c1..e68de5ef 100644 --- a/util/Util.i +++ b/util/Util.i @@ -115,7 +115,7 @@ report_error(int id, const char *msg) { Report *report = Sta::sta()->report(); - report->error(id, "%s", msg); + report->error(id, "{}", msg); } void @@ -125,7 +125,7 @@ report_file_error(int id, const char *msg) { Report *report = Sta::sta()->report(); - report->error(id, filename, line, "%s", msg); + report->error(id, filename, line, "{}", msg); } void @@ -133,7 +133,7 @@ report_warn(int id, const char *msg) { Report *report = Sta::sta()->report(); - report->warn(id, "%s", msg); + report->warn(id, "{}", msg); } void @@ -143,7 +143,7 @@ report_file_warn(int id, const char *msg) { Report *report = Sta::sta()->report(); - report->fileWarn(id, filename, line, "%s", msg); + report->fileWarn(id, filename, line, "{}", msg); } void @@ -151,9 +151,9 @@ report_line(const char *msg) { Sta *sta = Sta::sta(); if (sta) - sta->report()->reportLineString(msg); + sta->report()->reportLine(msg); else - // After sta::delete_all_memory souce -echo prints the cmd file line + // After sta::delete_all_memory include -echo prints the cmd file line. printf("%s\n", msg); } @@ -471,7 +471,7 @@ unit_scale(const char *unit_name) // format_unit functions print with fixed digits and suffix. // Pass value arg as string to support NaNs. -const char * +std::string format_time(const char *value, int digits) { @@ -479,7 +479,7 @@ format_time(const char *value, return Sta::sta()->units()->timeUnit()->asString(value1, digits); } -const char * +std::string format_capacitance(const char *value, int digits) { @@ -487,7 +487,7 @@ format_capacitance(const char *value, return Sta::sta()->units()->capacitanceUnit()->asString(value1, digits); } -const char * +std::string format_resistance(const char *value, int digits) { @@ -495,7 +495,7 @@ format_resistance(const char *value, return Sta::sta()->units()->resistanceUnit()->asString(value1, digits); } -const char * +std::string format_voltage(const char *value, int digits) { @@ -503,7 +503,7 @@ format_voltage(const char *value, return Sta::sta()->units()->voltageUnit()->asString(value1, digits); } -const char * +std::string format_current(const char *value, int digits) { @@ -511,7 +511,7 @@ format_current(const char *value, return Sta::sta()->units()->currentUnit()->asString(value1, digits); } -const char * +std::string format_power(const char *value, int digits) { @@ -519,7 +519,7 @@ format_power(const char *value, return Sta::sta()->units()->powerUnit()->asString(value1, digits); } -const char * +std::string format_distance(const char *value, int digits) { @@ -528,7 +528,7 @@ format_distance(const char *value, return dist_unit->asString(value1, digits); } -const char * +std::string format_area(const char *value, int digits) { diff --git a/verilog/VerilogParse.yy b/verilog/VerilogParse.yy index 71f056ad..5888f993 100644 --- a/verilog/VerilogParse.yy +++ b/verilog/VerilogParse.yy @@ -44,8 +44,7 @@ void sta::VerilogParse::error(const location_type &loc, const std::string &msg) { - reader->report()->fileError(164,reader->filename(),loc.begin.line, - "%s",msg.c_str()); + reader->report()->fileError(171,reader->filename(),loc.begin.line, "{}",msg); } %} diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index e018fae9..a539a311 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.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 "VerilogReader.hh" @@ -73,35 +73,10 @@ deleteVerilogReader(VerilogReader *verilog_reader) //////////////////////////////////////////////////////////////// -class VerilogError -{ -public: - VerilogError(int id, - const char *filename, - int line, - const char *msg, - bool warn); - ~VerilogError(); - const char *msg() const { return msg_; } - const char *filename() const { return filename_; } - int id() const { return id_; } - int line() const { return line_; } - bool warn() const { return warn_; } - -private: - int id_; - const char *filename_; - int line_; - const char *msg_; - bool warn_; - - friend class VerilogErrorCmp; -}; - VerilogError::VerilogError(int id, - const char *filename, + std::string_view filename, int line, - const char *msg, + std::string_view msg, bool warn) : id_(id), filename_(filename), @@ -111,22 +86,16 @@ VerilogError::VerilogError(int id, { } -VerilogError::~VerilogError() -{ - // filename is owned by VerilogReader. - stringDelete(msg_); -} - class VerilogErrorCmp { public: bool operator()(const VerilogError *error1, const VerilogError *error2) const { - int file_cmp = strcmp(error1->filename_, error2->filename_); + int file_cmp = error1->filename_.compare(error2->filename_); if (file_cmp == 0) { if (error1->line_ == error2->line_) - return strcmp(error1->msg_, error2->msg_) < 0; + return error1->msg_ < error2->msg_; else return error1->line_ < error2->line_; } @@ -146,17 +115,14 @@ VerilogReader::VerilogReader(NetworkReader *network) : zero_net_name_("zero_"), one_net_name_("one_") { - network->setLinkFunc([this] (const char *top_cell_name, - bool make_black_boxes) -> Instance* { - return linkNetwork(top_cell_name, make_black_boxes, true); - }); - constant10_max_ = stdstrPrint("%llu", std::numeric_limits::max()); + network->setLinkFunc( + [this](const char *top_cell_name, bool make_black_boxes) -> Instance * { + return linkNetwork(top_cell_name, make_black_boxes, true); + }); + constant10_max_ = std::to_string(std::numeric_limits::max()); } -VerilogReader::~VerilogReader() -{ - deleteModules(); -} +VerilogReader::~VerilogReader() { deleteModules(); } void VerilogReader::deleteModules() @@ -232,7 +198,7 @@ VerilogReader::makeModule(const std::string *module_vname, VerilogAttrStmtSeq *attr_stmts, int line) { - const std::string module_name = moduleVerilogToSta(module_vname); + const std::string module_name = moduleVerilogToSta(*module_vname); Cell *cell = network_->findCell(library_, module_name.c_str()); if (cell) { VerilogModule *module = module_map_[cell]; @@ -267,7 +233,7 @@ VerilogReader::makeModule(const std::string *module_name, // Pull the port names out of the port declarations. for (VerilogStmt *dcl : *port_dcls) { if (dcl->isDeclaration()) { - VerilogDcl *dcl1 = dynamic_cast(dcl); + VerilogDcl *dcl1 = dynamic_cast(dcl); for (VerilogDclArg *arg : *dcl1->args()) { VerilogNetNamed *port = new VerilogNetScalar(arg->netName()); ports->push_back(port); @@ -299,8 +265,7 @@ VerilogReader::makeCellPorts(Cell *cell, } else warn(165, module->filename(), module->line(), - "module %s repeated port name %s.", - module->name().c_str(), + "module {} repeated port name {}.", module->name().c_str(), port_name.c_str()); } checkModuleDcls(module, port_names); @@ -314,18 +279,17 @@ VerilogReader::makeCellPort(Cell *cell, VerilogDcl *dcl = module->declaration(port_name.c_str()); if (dcl) { PortDirection *dir = dcl->direction(); - VerilogDclBus *dcl_bus = dynamic_cast(dcl); + VerilogDclBus *dcl_bus = dynamic_cast(dcl); Port *port = dcl->isBus() - ? network_->makeBusPort(cell, port_name.c_str(), dcl_bus->fromIndex(), - dcl_bus->toIndex()) - : network_->makePort(cell, port_name.c_str()); + ? network_->makeBusPort(cell, port_name.c_str(), dcl_bus->fromIndex(), + dcl_bus->toIndex()) + : network_->makePort(cell, port_name.c_str()); network_->setDirection(port, dir); return port; } else { warn(166, module->filename(), module->line(), - "module %s missing declaration for port %s.", - module->name().c_str(), + "module {} missing declaration for port {}.", module->name().c_str(), port_name.c_str()); return network_->makePort(cell, port_name.c_str()); } @@ -338,7 +302,7 @@ VerilogReader::makeNamedPortRefCellPorts(Cell *cell, StringSet &port_names) { PortSeq *member_ports = new PortSeq; - VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module,this); + VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module, this); while (net_name_iter->hasNext()) { const std::string &net_name = net_name_iter->next(); port_names.insert(net_name); @@ -355,16 +319,13 @@ void VerilogReader::checkModuleDcls(VerilogModule *module, std::set &port_names) { - for (auto const & [port_name, dcl] : *module->declarationMap()) { + for (auto const &[port_name, dcl] : *module->declarationMap()) { PortDirection *dir = dcl->direction(); - if (dir->isInput() - || dir->isOutput() - || dir->isBidirect()) { + if (dir->isInput() || dir->isOutput() || dir->isBidirect()) { if (!port_names.contains(port_name)) linkWarn(197, module->filename(), module->line(), - "module %s declared signal %s is not in the port list.", - module->name().c_str(), - port_name.c_str()); + "module {} declared signal {} is not in the port list.", + module->name(), port_name); } } } @@ -425,8 +386,7 @@ VerilogReader::makeDclBus(PortDirection *dir, int line) { dcl_bus_count_++; - return new VerilogDclBus(dir, from_index, to_index, arg, attr_stmts, - line); + return new VerilogDclBus(dir, from_index, to_index, arg, attr_stmts, line); } VerilogDclBus * @@ -438,16 +398,15 @@ VerilogReader::makeDclBus(PortDirection *dir, int line) { dcl_bus_count_++; - return new VerilogDclBus(dir, from_index, to_index, args, attr_stmts, - line); + return new VerilogDclBus(dir, from_index, to_index, args, attr_stmts, line); } VerilogDclArg * VerilogReader::makeDclArg(const std::string *net_vname) { dcl_arg_count_++; - const std::string net_name = netVerilogToSta(net_vname); - VerilogDclArg *dcl =new VerilogDclArg(net_name); + const std::string net_name = netVerilogToSta(*net_vname); + VerilogDclArg *dcl = new VerilogDclArg(net_name); delete net_vname; return dcl; } @@ -467,10 +426,9 @@ VerilogReader::makeNetPartSelect(const std::string *net_vname, net_part_select_count_++; if (report_stmt_stats_) net_bus_names_ += net_vname->size() + 1; - const std::string net_name = netVerilogToSta(net_vname); - VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name, - from_index, - to_index); + const std::string net_name = netVerilogToSta(*net_vname); + VerilogNetPartSelect *select = + new VerilogNetPartSelect(net_name, from_index, to_index); delete net_vname; return select; } @@ -489,7 +447,7 @@ VerilogReader::makeNetScalar(const std::string *net_vname) net_scalar_count_++; if (report_stmt_stats_) net_scalar_names_ += net_vname->size() + 1; - const std::string net_name = netVerilogToSta(net_vname); + const std::string net_name = netVerilogToSta(*net_vname); VerilogNetScalar *scalar = new VerilogNetScalar(net_name); delete net_vname; return scalar; @@ -502,7 +460,7 @@ VerilogReader::makeNetBitSelect(const std::string *net_vname, net_bit_select_count_++; if (report_stmt_stats_) net_bus_names_ += net_vname->size() + 1; - const std::string net_name = netVerilogToSta(net_vname); + const std::string net_name = netVerilogToSta(*net_vname); VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name, index); delete net_vname; return select; @@ -524,21 +482,20 @@ VerilogReader::makeModuleInst(const std::string *module_vname, VerilogAttrStmtSeq *attr_stmts, const int line) { - const std::string module_name = moduleVerilogToSta(module_vname); - const std::string inst_name = instanceVerilogToSta(inst_vname); + const std::string module_name = moduleVerilogToSta(*module_vname); + const std::string inst_name = instanceVerilogToSta(*inst_vname); Cell *cell = network_->findAnyCell(module_name.c_str()); LibertyCell *liberty_cell = nullptr; if (cell) liberty_cell = network_->libertyCell(cell); // Instances of liberty with scalar ports are special cased // to reduce the memory footprint of the verilog parser. - if (liberty_cell - && hasScalarNamedPortRefs(liberty_cell, pins)) { + if (liberty_cell && hasScalarNamedPortRefs(liberty_cell, pins)) { const int port_count = liberty_cell->portBitCount(); StringSeq net_names(port_count); for (VerilogNet *vnet : *pins) { VerilogNetPortRefScalarNet *vpin = - dynamic_cast(vnet); + dynamic_cast(vnet); const char *port_name = vpin->name().c_str(); const std::string &net_name = vpin->netName(); Port *port = network_->findPort(cell, port_name); @@ -552,8 +509,8 @@ VerilogReader::makeModuleInst(const std::string *module_vname, delete vpin; net_port_ref_scalar_net_count_--; } - VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name, - net_names, attr_stmts, line); + VerilogInst *inst = + new VerilogLibertyInst(liberty_cell, inst_name, net_names, attr_stmts, line); delete pins; if (report_stmt_stats_) { inst_names_ += inst_name.size() + 1; @@ -565,11 +522,8 @@ VerilogReader::makeModuleInst(const std::string *module_vname, return inst; } else { - VerilogInst *inst = new VerilogModuleInst(module_name.c_str(), - inst_name.c_str(), - pins, - attr_stmts, - line); + VerilogInst *inst = new VerilogModuleInst(module_name.c_str(), inst_name.c_str(), + pins, attr_stmts, line); if (report_stmt_stats_) { inst_module_names_ += module_name.size() + 1; inst_names_ += inst_name.size() + 1; @@ -585,15 +539,12 @@ bool VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell, VerilogNetSeq *pins) { - if (pins - && pins->size() > 0 - && (*pins)[0]->isNamedPortRef()) { + if (pins && pins->size() > 0 && (*pins)[0]->isNamedPortRef()) { for (VerilogNet *vpin : *pins) { const char *port_name = vpin->name().c_str(); LibertyPort *port = liberty_cell->findLibertyPort(port_name); if (port) { - if (!(port->size() == 1 - && (vpin->isNamedPortRefScalarNet()))) + if (!(port->size() == 1 && (vpin->isNamedPortRefScalarNet()))) return false; } else @@ -611,7 +562,7 @@ VerilogReader::makeNetNamedPortRefScalarNet(const std::string *port_vname) net_port_ref_scalar_net_count_++; if (report_stmt_stats_) port_names_ += port_vname->size() + 1; - const std::string port_name = portVerilogToSta(port_vname); + const std::string port_name = portVerilogToSta(*port_vname); VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str()); delete port_vname; return ref; @@ -627,10 +578,10 @@ VerilogReader::makeNetNamedPortRefScalarNet(const std::string *port_vname, net_scalar_names_ += net_vname->size() + 1; port_names_ += port_vname->size() + 1; } - const std::string port_name = portVerilogToSta(port_vname); - const std::string net_name = netVerilogToSta(net_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(), - net_name.c_str()); + const std::string port_name = portVerilogToSta(*port_vname); + const std::string net_name = netVerilogToSta(*net_vname); + VerilogNetPortRef *ref = + new VerilogNetPortRefScalarNet(port_name.c_str(), net_name.c_str()); delete port_vname; delete net_vname; return ref; @@ -642,15 +593,15 @@ VerilogReader::makeNetNamedPortRefBitSelect(const std::string *port_vname, int index) { net_port_ref_scalar_net_count_++; - const std::string bus_name = portVerilogToSta(bus_vname); + const std::string bus_name = portVerilogToSta(*bus_vname); const std::string net_name = verilogBusBitName(bus_name, index); if (report_stmt_stats_) { net_scalar_names_ += net_name.length() + 1; port_names_ += port_vname->size() + 1; } - const std::string port_name = portVerilogToSta(port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(), - net_name.c_str()); + const std::string port_name = portVerilogToSta(*port_vname); + VerilogNetPortRef *ref = + new VerilogNetPortRefScalarNet(port_name.c_str(), net_name.c_str()); delete port_vname; delete bus_vname; return ref; @@ -663,7 +614,7 @@ VerilogReader::makeNetNamedPortRefScalar(const std::string *port_vname, net_port_ref_scalar_count_++; if (report_stmt_stats_) port_names_ += port_vname->size() + 1; - const std::string port_name = portVerilogToSta(port_vname); + const std::string port_name = portVerilogToSta(*port_vname); VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name.c_str(), net); delete port_vname; return ref; @@ -675,9 +626,8 @@ VerilogReader::makeNetNamedPortRefBit(const std::string *port_vname, VerilogNet *net) { net_port_ref_bit_count_++; - const std::string port_name = portVerilogToSta(port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name.c_str(), - index, net); + const std::string port_name = portVerilogToSta(*port_vname); + VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name.c_str(), index, net); delete port_vname; return ref; } @@ -689,10 +639,9 @@ VerilogReader::makeNetNamedPortRefPart(const std::string *port_vname, VerilogNet *net) { net_port_ref_part_count_++; - const std::string port_name = portVerilogToSta(port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name, - from_index, - to_index, net); + const std::string port_name = portVerilogToSta(*port_vname); + VerilogNetPortRef *ref = + new VerilogNetPortRefPart(port_name, from_index, to_index, net); delete port_vname; return ref; } @@ -704,21 +653,18 @@ VerilogReader::makeNetConcat(VerilogNetSeq *nets) return new VerilogNetConcat(nets); } -#define printClassMemory(name, class_name, count) \ - report_->reportLine(" %-20s %9d * %3zu = %6.1fMb\n", \ - name, \ - count, \ - sizeof(class_name), \ - (count * sizeof(class_name) * 1e-6)) +#define printClassMemory(name, class_name, count) \ + report_->report(" {:<20} {:9} * {:3} = {:6.1f}Mb\n", name, count, \ + sizeof(class_name), (count * sizeof(class_name) * 1e-6)) -#define printStringMemory(name, count) \ - report_->reportLine(" %-20s %6.1fMb", name, count * 1e-6) +#define printStringMemory(name, count) \ + report_->report(" {:<20} {:6.1f}Mb", name, count * 1e-6) void VerilogReader::reportStmtCounts() { if (debug_->check("verilog", 1)) { - report_->reportLine("Verilog stats"); + report_->report("Verilog stats"); printClassMemory("modules", VerilogModule, module_count_); printClassMemory("module insts", VerilogModuleInst, inst_mod_count_); printClassMemory("liberty insts", VerilogLibertyInst, inst_lib_count_); @@ -730,14 +676,12 @@ VerilogReader::reportStmtCounts() net_port_ref_scalar_count_); printClassMemory("port ref scalar net", VerilogNetPortRefScalarNet, net_port_ref_scalar_net_count_); - printClassMemory("port ref bit", VerilogNetPortRefBit, - net_port_ref_bit_count_); + printClassMemory("port ref bit", VerilogNetPortRefBit, net_port_ref_bit_count_); printClassMemory("port ref part", VerilogNetPortRefPart, net_port_ref_part_count_); printClassMemory("scalar nets", VerilogNetScalar, net_scalar_count_); - printClassMemory("bus bit nets",VerilogNetBitSelect,net_bit_select_count_); - printClassMemory("bus range nets", VerilogNetPartSelect, - net_part_select_count_); + printClassMemory("bus bit nets", VerilogNetBitSelect, net_bit_select_count_); + printClassMemory("bus range nets", VerilogNetPartSelect, net_part_select_count_); printClassMemory("constant nets", VerilogNetConstant, net_constant_count_); printClassMemory("concats", VerilogNetConcat, concat_count_); printClassMemory("assigns", VerilogAssign, assign_count_); @@ -749,30 +693,6 @@ VerilogReader::reportStmtCounts() } } -void -VerilogReader::error(int id, - const char *filename, - int line, - const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - report_->vfileError(id, filename, line, fmt, args); - va_end(args); -} - -void -VerilogReader::warn(int id, - const char *filename, - int line, - const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - report_->vfileWarn(id, filename, line, fmt, args); - va_end(args); -} - //////////////////////////////////////////////////////////////// VerilogModule::VerilogModule(const std::string &name, @@ -808,10 +728,9 @@ VerilogModule::parseStmts(VerilogReader *reader) StringSet inst_names; for (VerilogStmt *stmt : *stmts_) { if (stmt->isDeclaration()) - parseDcl(dynamic_cast(stmt), reader); + parseDcl(dynamic_cast(stmt), reader); else if (stmt->isInstance()) - checkInstanceName(dynamic_cast(stmt), inst_names, - reader); + checkInstanceName(dynamic_cast(stmt), inst_names, reader); } } @@ -837,18 +756,16 @@ VerilogModule::parseDcl(VerilogDcl *dcl, dcl_map_[net_name.c_str()] = dcl; } else if (dcl->direction()->isPowerGround() - && (existing_dir->isOutput() - || existing_dir->isInput() + && (existing_dir->isOutput() || existing_dir->isInput() || existing_dir->isBidirect())) // supply0/supply1 dcl can be used as modifier for // input/output/inout dcls. dcl_map_[net_name.c_str()] = dcl; else if (!dcl->direction()->isInternal()) { std::string net_vname = netVerilogName(net_name.c_str()); - reader->warn(1395, filename_.c_str(), dcl->line(), - "signal %s previously declared on line %d.", - net_vname.c_str(), - existing_dcl->line()); + reader->warn(1395, filename_, dcl->line(), + "signal {} previously declared on line {}.", + net_vname, existing_dcl->line()); } } else @@ -869,13 +786,12 @@ VerilogModule::checkInstanceName(VerilogInst *inst, int i = 1; std::string replacement_name; do { - replacement_name = stdstrPrint("%s_%d", inst_name.c_str(), i++); + replacement_name = sta::format("{}_{}", inst_name, i++); } while (inst_names.contains(replacement_name)); std::string inst_vname = instanceVerilogName(inst_name.c_str()); - reader->warn(1396, filename_.c_str(), inst->line(), - "instance name %s duplicated - renamed to %s.", - inst_vname.c_str(), - replacement_name.c_str()); + reader->warn(1396, filename_, inst->line(), + "instance name {} duplicated - renamed to {}.", inst_vname, + replacement_name); inst_name = replacement_name; inst->setInstanceName(inst_name); } @@ -921,7 +837,9 @@ VerilogModuleInst::VerilogModuleInst(const std::string &module_name, VerilogNetSeq *pins, VerilogAttrStmtSeq *attr_stmts, int line) : - VerilogInst(inst_name, attr_stmts, line), + VerilogInst(inst_name, + attr_stmts, + line), module_name_(module_name), pins_(pins) { @@ -938,17 +856,13 @@ VerilogModuleInst::~VerilogModuleInst() bool VerilogModuleInst::hasPins() { - return pins_ - && pins_->size() > 0; - + return pins_ && pins_->size() > 0; } bool VerilogModuleInst::namedPins() { - return pins_ - && pins_->size() > 0 - && (*pins_)[0]->isNamedPortRef(); + return pins_ && pins_->size() > 0 && (*pins_)[0]->isNamedPortRef(); } VerilogLibertyInst::VerilogLibertyInst(LibertyCell *cell, @@ -956,7 +870,9 @@ VerilogLibertyInst::VerilogLibertyInst(LibertyCell *cell, const StringSeq &net_names, VerilogAttrStmtSeq *attr_stmts, const int line) : - VerilogInst(inst_name, attr_stmts, line), + VerilogInst(inst_name, + attr_stmts, + line), cell_(cell), net_names_(net_names) { @@ -1011,7 +927,10 @@ VerilogDclBus::VerilogDclBus(PortDirection *dir, VerilogDclArgSeq *args, VerilogAttrStmtSeq *attr_stmts, int line) : - VerilogDcl(dir, args, attr_stmts, line), + VerilogDcl(dir, + args, + attr_stmts, + line), from_index_(from_index), to_index_(to_index) { @@ -1023,7 +942,10 @@ VerilogDclBus::VerilogDclBus(PortDirection *dir, VerilogDclArg *arg, VerilogAttrStmtSeq *attr_stmts, int line) : - VerilogDcl(dir, arg, attr_stmts, line), + VerilogDcl(dir, + arg, + attr_stmts, + line), from_index_(from_index), to_index_(to_index) { @@ -1046,10 +968,7 @@ VerilogDclArg::VerilogDclArg(VerilogAssign *assign) : { } -VerilogDclArg::~VerilogDclArg() -{ - delete assign_; -} +VerilogDclArg::~VerilogDclArg() { delete assign_; } const std::string & VerilogDclArg::netName() @@ -1152,10 +1071,8 @@ VerilogBusNetNameIterator::VerilogBusNetNameIterator(const std::string bus_name, bool VerilogBusNetNameIterator::hasNext() { - return (to_index_ > from_index_ - && index_ <= to_index_) - || (to_index_ <= from_index_ - && index_ >= to_index_); + return (to_index_ > from_index_ && index_ <= to_index_) + || (to_index_ <= from_index_ && index_ >= to_index_); } const std::string & @@ -1173,7 +1090,7 @@ static std::string verilogBusBitName(const std::string &bus_name, int index) { - return stdstrPrint("%s[%d]", bus_name.c_str(), index); + return sta::format("{}[{}]", bus_name.c_str(), index); } class VerilogConstantNetNameIterator : public VerilogNetNameIterator @@ -1192,10 +1109,10 @@ private: int bit_index_; }; -VerilogConstantNetNameIterator:: -VerilogConstantNetNameIterator(VerilogConstantValue *value, - const std::string &zero, - const std::string &one) : +VerilogConstantNetNameIterator::VerilogConstantNetNameIterator( + VerilogConstantValue *value, + const std::string &zero, + const std::string &one) : value_(value), zero_(zero), one_(one), @@ -1233,10 +1150,9 @@ private: VerilogNetNameIterator *net_name_iter_; }; -VerilogNetConcatNameIterator:: -VerilogNetConcatNameIterator(VerilogNetSeq *nets, - VerilogModule *module, - VerilogReader *reader) : +VerilogNetConcatNameIterator::VerilogNetConcatNameIterator(VerilogNetSeq *nets, + VerilogModule *module, + VerilogReader *reader) : module_(module), reader_(reader), nets_(nets), @@ -1257,8 +1173,7 @@ VerilogNetConcatNameIterator::~VerilogNetConcatNameIterator() bool VerilogNetConcatNameIterator::hasNext() { - return (net_name_iter_ && net_name_iter_->hasNext()) - || net_iter_ != nets_->end(); + return (net_name_iter_ && net_name_iter_->hasNext()) || net_iter_ != nets_->end(); } const std::string & @@ -1289,9 +1204,7 @@ VerilogNetNamed::VerilogNetNamed(const std::string &name) : { } -VerilogNetNamed::~VerilogNetNamed() -{ -} +VerilogNetNamed::~VerilogNetNamed() {} VerilogNetScalar::VerilogNetScalar(const std::string &name) : VerilogNetNamed(name) @@ -1340,7 +1253,8 @@ VerilogNetScalar::nameIterator(VerilogModule *module, VerilogNetBitSelect::VerilogNetBitSelect(const std::string &name, int index) : - VerilogNetNamed(verilogBusBitName(name, index)), + VerilogNetNamed(verilogBusBitName(name, + index)), index_(index) { } @@ -1360,7 +1274,7 @@ VerilogNetBitSelect::nameIterator(VerilogModule *, VerilogNetPartSelect::VerilogNetPartSelect(const std::string &name, int from_index, - int to_index): + int to_index) : VerilogNetNamed(name), from_index_(from_index), to_index_(to_index) @@ -1407,27 +1321,27 @@ VerilogNetConstant::parseConstant(const std::string *constant, size_t base_idx = csize_end + 1; char base = constant->at(base_idx); switch (base) { - case 'b': - case 'B': - parseConstant(constant, base_idx, 2, 1); - break; - case 'o': - case 'O': - parseConstant(constant, base_idx, 8, 3); - break; - case 'h': - case 'H': - parseConstant(constant, base_idx, 16, 4); - break; - case 'd': - case 'D': - parseConstant10(constant, base_idx, reader, line); - break; - default: - case '\0': - reader->report()->fileWarn(1861, reader->filename(), line, - "unknown constant base."); - break; + case 'b': + case 'B': + parseConstant(constant, base_idx, 2, 1); + break; + case 'o': + case 'O': + parseConstant(constant, base_idx, 8, 3); + break; + case 'h': + case 'H': + parseConstant(constant, base_idx, 16, 4); + break; + case 'd': + case 'D': + parseConstant10(constant, base_idx, reader, line); + break; + default: + case '\0': + reader->report()->fileWarn(1861, reader->filename(), line, + "unknown constant base."); + break; } delete constant; } @@ -1472,19 +1386,17 @@ VerilogNetConstant::parseConstant10(const std::string *constant, for (size_t i = base_idx + 1; i < constant->size(); i++) { char ch = constant->at(i); if (ch != '_') - tmp += ch; + tmp += ch; } size_t size = value_->size(); size_t length = tmp.size(); const std::string &constant10_max = reader->constant10Max(); size_t max_length = constant10_max.size(); - if (length > max_length - || (length == max_length - && tmp > constant10_max)) + if (length > max_length || (length == max_length && tmp > constant10_max)) reader->warn(1397, reader->filename(), line, - "base 10 constant greater than %s not supported.", - constant10_max.c_str()); + "base 10 constant greater than {} not supported.", + constant10_max); else { size_t *end = nullptr; VerilogConstant10 value = std::stoull(tmp, end, 10); @@ -1496,28 +1408,22 @@ VerilogNetConstant::parseConstant10(const std::string *constant, } } -VerilogNetConstant::~VerilogNetConstant() -{ - delete value_; -} +VerilogNetConstant::~VerilogNetConstant() { delete value_; } VerilogNetNameIterator * VerilogNetConstant::nameIterator(VerilogModule *, VerilogReader *reader) { - return new VerilogConstantNetNameIterator(value_, - reader->zeroNetName(), + return new VerilogConstantNetNameIterator(value_, reader->zeroNetName(), reader->oneNetName()); } - int VerilogNetConstant::size(VerilogModule *) { return value_->size(); } - VerilogNetConcat::VerilogNetConcat(VerilogNetSeq *nets) : nets_(nets) { @@ -1590,10 +1496,7 @@ VerilogNetPortRefScalar::VerilogNetPortRefScalar(const std::string &name, { } -VerilogNetPortRefScalar::~VerilogNetPortRefScalar() -{ - delete net_; -} +VerilogNetPortRefScalar::~VerilogNetPortRefScalar() { delete net_; } int VerilogNetPortRefScalar::size(VerilogModule *module) @@ -1617,8 +1520,10 @@ VerilogNetPortRefScalar::nameIterator(VerilogModule *module, VerilogNetPortRefBit::VerilogNetPortRefBit(const std::string &name, int index, VerilogNet *net) : - VerilogNetPortRefScalar(name, net), - bit_name_(verilogBusBitName(name, index)) + VerilogNetPortRefScalar(name, + net), + bit_name_(verilogBusBitName(name, + index)) { } @@ -1626,7 +1531,9 @@ VerilogNetPortRefPart::VerilogNetPortRefPart(const std::string &name, int from_index, int to_index, VerilogNet *net) : - VerilogNetPortRefBit(name, from_index, net), + VerilogNetPortRefBit(name, + from_index, + net), to_index_(to_index) { } @@ -1656,8 +1563,8 @@ VerilogAttrEntry::value() return value_; } -VerilogAttrStmt::VerilogAttrStmt(VerilogAttrEntrySeq *attrs): - attrs_(attrs) +VerilogAttrStmt::VerilogAttrStmt(VerilogAttrEntrySeq *attrs) : + attrs_(attrs) { } @@ -1667,13 +1574,12 @@ VerilogAttrStmt::~VerilogAttrStmt() delete attrs_; } -VerilogAttrEntrySeq* +VerilogAttrEntrySeq * VerilogAttrStmt::attrs() { return attrs_; } - //////////////////////////////////////////////////////////////// // // Link verilog network @@ -1681,7 +1587,7 @@ VerilogAttrStmt::attrs() //////////////////////////////////////////////////////////////// // Verilog net name to network net map. -using BindingMap = std::map; +using BindingMap = std::map; class VerilogBindingTbl { @@ -1712,15 +1618,16 @@ VerilogReader::linkNetwork(const char *top_cell_name, VerilogModule *module = this->module(top_cell); if (module) { // Seed the recursion for expansion with the top level instance. - Instance *top_instance = network_->makeInstance(top_cell, top_cell_name, nullptr); + Instance *top_instance = + network_->makeInstance(top_cell, top_cell_name, nullptr); VerilogBindingTbl bindings(zero_net_name_, one_net_name_); for (VerilogNet *mod_port : *module->ports()) { - VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module, - this); + VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module, this); while (net_name_iter->hasNext()) { const std::string &net_name = net_name_iter->next(); Port *port = network_->findPort(top_cell, net_name.c_str()); - Net *net = bindings.ensureNetBinding(net_name.c_str(), top_instance, network_); + Net *net = + bindings.ensureNetBinding(net_name.c_str(), top_instance, network_); // Guard against repeated port name. if (network_->findPin(top_instance, port) == nullptr) { Pin *pin = network_->makePin(top_instance, port, nullptr); @@ -1741,12 +1648,12 @@ VerilogReader::linkNetwork(const char *top_cell_name, return top_instance; } else { - report_->error(1398, "%s is not a verilog module.", top_cell_name); + report_->error(1398, "{} is not a verilog module.", top_cell_name); return nullptr; } } else { - report_->error(1399, "%s is not a verilog module.", top_cell_name); + report_->error(1399, "{} is not a verilog module.", top_cell_name); return nullptr; } } @@ -1759,31 +1666,32 @@ VerilogReader::makeModuleInstBody(VerilogModule *module, { for (VerilogStmt *stmt : *module->stmts()) { if (stmt->isModuleInst()) - makeModuleInstNetwork(dynamic_cast(stmt), - inst, module, bindings, make_black_boxes); + makeModuleInstNetwork(dynamic_cast(stmt), inst, module, + bindings, make_black_boxes); else if (stmt->isLibertyInst()) - makeLibertyInst(dynamic_cast(stmt), - inst, module, bindings); + makeLibertyInst(dynamic_cast(stmt), inst, module, + bindings); else if (stmt->isDeclaration()) { - VerilogDcl *dcl = dynamic_cast(stmt); + VerilogDcl *dcl = dynamic_cast(stmt); PortDirection *dir = dcl->direction(); for (VerilogDclArg *arg : *dcl->args()) { VerilogAssign *assign = arg->assign(); if (assign) mergeAssignNet(assign, module, inst, bindings); if (dir->isGround()) { - Net *net = bindings->ensureNetBinding(arg->netName().c_str(),inst,network_); + Net *net = + bindings->ensureNetBinding(arg->netName().c_str(), inst, network_); network_->addConstantNet(net, LogicValue::zero); } if (dir->isPower()) { - Net *net = bindings->ensureNetBinding(arg->netName().c_str(),inst,network_); + Net *net = + bindings->ensureNetBinding(arg->netName().c_str(), inst, network_); network_->addConstantNet(net, LogicValue::one); } } } else if (stmt->isAssign()) - mergeAssignNet(dynamic_cast(stmt), module, inst, - bindings); + mergeAssignNet(dynamic_cast(stmt), module, inst, bindings); } } @@ -1801,22 +1709,20 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, if (make_black_boxes) { cell = makeBlackBox(mod_inst, parent_module); linkWarn(198, parent_module->filename(), mod_inst->line(), - "module %s not found. Creating black box for %s.", - mod_inst->moduleName().c_str(), - inst_vname.c_str()); + "module {} not found. Creating black box for {}.", + mod_inst->moduleName(), inst_vname); } else linkError(199, parent_module->filename(), mod_inst->line(), - "module %s not found for instance %s.", - mod_inst->moduleName().c_str(), - inst_vname.c_str()); + "module {} not found for instance {}.", + mod_inst->moduleName(), inst_vname); } if (cell) { LibertyCell *lib_cell = network_->libertyCell(cell); if (lib_cell) cell = network_->cell(lib_cell); - Instance *inst = network_->makeInstance(cell, mod_inst->instanceName().c_str(), - parent); + Instance *inst = + network_->makeInstance(cell, mod_inst->instanceName().c_str(), parent); VerilogAttrStmtSeq *attr_stmts = mod_inst->attrStmts(); for (VerilogAttrStmt *stmt : *attr_stmts) { for (VerilogAttrEntry *entry : *stmt->attrs()) { @@ -1835,11 +1741,11 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, VerilogBindingTbl bindings(zero_net_name_, one_net_name_); if (mod_inst->hasPins()) { if (mod_inst->namedPins()) - makeNamedInstPins(cell, inst, mod_inst, &bindings, parent, - parent_module, parent_bindings, is_leaf); + makeNamedInstPins(cell, inst, mod_inst, &bindings, parent, parent_module, + parent_bindings, is_leaf); else - makeOrderedInstPins(cell, inst, mod_inst, &bindings, parent, - parent_module, parent_bindings, is_leaf); + makeOrderedInstPins(cell, inst, mod_inst, &bindings, parent, parent_module, + parent_bindings, is_leaf); } if (!is_leaf) { VerilogModule *module = this->module(cell); @@ -1861,43 +1767,38 @@ VerilogReader::makeNamedInstPins(Cell *cell, { std::string inst_vname = instanceVerilogName(mod_inst->instanceName().c_str()); for (auto mpin : *mod_inst->pins()) { - VerilogNetPortRef *vpin = dynamic_cast(mpin); + VerilogNetPortRef *vpin = dynamic_cast(mpin); const char *port_name = vpin->name().c_str(); Port *port = network_->findPort(cell, port_name); if (port) { - if (vpin->hasNet() - && network_->size(port) != vpin->size(parent_module)) { + if (vpin->hasNet() && network_->size(port) != vpin->size(parent_module)) { linkWarn(200, parent_module->filename(), mod_inst->line(), - "instance %s port %s size %d does not match net size %d.", - inst_vname.c_str(), - network_->name(port), - network_->size(port), + "instance {} port {} size {} does not match net size {}.", + inst_vname, network_->name(port), network_->size(port), vpin->size(parent_module)); } else { VerilogNetNameIterator *net_name_iter = - vpin->nameIterator(parent_module, this); + vpin->nameIterator(parent_module, this); if (network_->hasMembers(port)) { PortMemberIterator *port_iter = network_->memberIterator(port); while (port_iter->hasNext()) { Port *port = port_iter->next(); - makeInstPin(inst, port, net_name_iter, bindings, - parent, parent_bindings, is_leaf); + makeInstPin(inst, port, net_name_iter, bindings, parent, parent_bindings, + is_leaf); } delete port_iter; } else { - makeInstPin(inst, port, net_name_iter, bindings, - parent, parent_bindings, is_leaf); + makeInstPin(inst, port, net_name_iter, bindings, parent, parent_bindings, + is_leaf); } delete net_name_iter; } } else linkWarn(201, parent_module->filename(), mod_inst->line(), - "instance %s port %s not found.", - inst_vname.c_str(), - port_name); + "instance {} port {} not found.", inst_vname, port_name); } } @@ -1914,34 +1815,30 @@ VerilogReader::makeOrderedInstPins(Cell *cell, CellPortIterator *port_iter = network_->portIterator(cell); VerilogNetSeq *mod_pins = mod_inst->pins(); VerilogNetSeq::iterator pin_iter = mod_pins->begin(); - while (pin_iter != mod_pins->end() - && port_iter->hasNext()) { + while (pin_iter != mod_pins->end() && port_iter->hasNext()) { VerilogNet *net = *pin_iter++; Port *port = port_iter->next(); if (network_->size(port) != net->size(parent_module)) { std::string inst_vname = instanceVerilogName(mod_inst->instanceName().c_str()); linkWarn(202, parent_module->filename(), mod_inst->line(), - "instance %s port %s size %d does not match net size %d.", - inst_vname.c_str(), - network_->name(port), - network_->size(port), + "instance {} port {} size {} does not match net size {}.", + inst_vname, network_->name(port), network_->size(port), net->size(parent_module)); } else { - VerilogNetNameIterator *net_name_iter=net->nameIterator(parent_module, - this); + VerilogNetNameIterator *net_name_iter = net->nameIterator(parent_module, this); if (network_->isBus(port)) { PortMemberIterator *member_iter = network_->memberIterator(port); while (member_iter->hasNext() && net_name_iter->hasNext()) { Port *port = member_iter->next(); - makeInstPin(inst, port, net_name_iter, bindings, - parent, parent_bindings, is_leaf); + makeInstPin(inst, port, net_name_iter, bindings, parent, parent_bindings, + is_leaf); } delete member_iter; } else - makeInstPin(inst, port, net_name_iter, bindings, - parent, parent_bindings, is_leaf); + makeInstPin(inst, port, net_name_iter, bindings, parent, parent_bindings, + is_leaf); delete net_name_iter; } } @@ -1960,8 +1857,7 @@ VerilogReader::makeInstPin(Instance *inst, std::string net_name; if (net_name_iter->hasNext()) net_name = net_name_iter->next(); - makeInstPin(inst, port, net_name, bindings, parent, parent_bindings, - is_leaf); + makeInstPin(inst, port, net_name, bindings, parent, parent_bindings, is_leaf); } void @@ -2001,9 +1897,9 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst, VerilogBindingTbl *parent_bindings) { LibertyCell *lib_cell = lib_inst->cell(); - Cell *cell = reinterpret_cast(lib_cell); - Instance *inst = network_->makeInstance(cell, lib_inst->instanceName().c_str(), - parent); + Cell *cell = reinterpret_cast(lib_cell); + Instance *inst = + network_->makeInstance(cell, lib_inst->instanceName().c_str(), parent); VerilogAttrStmtSeq *attr_stmts = lib_inst->attrStmts(); for (VerilogAttrStmt *stmt : *attr_stmts) { for (VerilogAttrEntry *entry : *stmt->attrs()) { @@ -2029,11 +1925,11 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst, } else net = parent_bindings->ensureNetBinding(net_name.c_str(), parent, network_); - network_->makePin(inst, reinterpret_cast(port), net); + network_->makePin(inst, reinterpret_cast(port), net); } else // Make unconnected pin. - network_->makePin(inst, reinterpret_cast(port), nullptr); + network_->makePin(inst, reinterpret_cast(port), nullptr); } } @@ -2059,12 +1955,11 @@ VerilogReader::makeBlackBoxNamedPorts(Cell *cell, VerilogModule *parent_module) { for (VerilogNet *mpin : *mod_inst->pins()) { - VerilogNetNamed *vpin = dynamic_cast(mpin); + VerilogNetNamed *vpin = dynamic_cast(mpin); const char *port_name = vpin->name().c_str(); size_t size = vpin->size(parent_module); - Port *port = (size == 1) - ? network_->makePort(cell, port_name) - : network_->makeBusPort(cell, port_name, 0, size - 1); + Port *port = (size == 1) ? network_->makePort(cell, port_name) + : network_->makeBusPort(cell, port_name, 0, size - 1); network_->setDirection(port, PortDirection::unknown()); } } @@ -2079,11 +1974,10 @@ VerilogReader::makeBlackBoxOrderedPorts(Cell *cell, if (nets) { for (VerilogNet *net : *nets) { size_t size = net->size(parent_module); - char *port_name = stringPrint("p_%d", port_index); + std::string port_name = format("p_{}", port_index); Port *port = (size == 1) - ? network_->makePort(cell, port_name) - : network_->makeBusPort(cell, port_name, size - 1, 0); - stringDelete(port_name); + ? network_->makePort(cell, port_name.c_str()) + : network_->makeBusPort(cell, port_name.c_str(), size - 1, 0); network_->setDirection(port, PortDirection::unknown()); port_index++; } @@ -2117,7 +2011,7 @@ VerilogReader::mergeAssignNet(VerilogAssign *assign, // Merge lower level net into higher level net so that deleting // instances from the bottom up does not reference deleted nets // by referencing the mergedInto field. - if (hierarchyLevel(lhs_net,network_) >= hierarchyLevel(rhs_net,network_)) + if (hierarchyLevel(lhs_net, network_) >= hierarchyLevel(rhs_net, network_)) network_->mergeInto(lhs_net, rhs_net); else network_->mergeInto(rhs_net, lhs_net); @@ -2129,9 +2023,8 @@ VerilogReader::mergeAssignNet(VerilogAssign *assign, } else linkWarn(203, module->filename(), assign->line(), - "assign left hand side size %d not equal right hand size %d.", - lhs->size(module), - rhs->size(module)); + "assign left hand side size {} not equal right hand size {}.", + lhs->size(module), rhs->size(module)); } static int @@ -2160,7 +2053,8 @@ VerilogBindingTbl::VerilogBindingTbl(const std::string &zero_net_name, // binding tables up the call tree when nodes are merged // because the name changes up the hierarchy. Net * -VerilogBindingTbl::find(const char *name, NetworkReader *network) +VerilogBindingTbl::find(const char *name, + NetworkReader *network) { Net *net = findKey(map_, name); while (net && network->mergedInto(net)) @@ -2194,34 +2088,6 @@ VerilogBindingTbl::ensureNetBinding(const char *net_name, //////////////////////////////////////////////////////////////// -void -VerilogReader::linkWarn(int id, - const char *filename, - int line, - const char *msg, ...) -{ - va_list args; - va_start(args, msg); - char *msg_str = stringPrintArgs(msg, args); - VerilogError *error = new VerilogError(id, filename, line, msg_str, true); - link_errors_.push_back(error); - va_end(args); -} - -void -VerilogReader::linkError(int id, - const char *filename, - int line, - const char *msg, ...) -{ - va_list args; - va_start(args, msg); - char *msg_str = stringPrintArgs(msg, args); - VerilogError *error = new VerilogError(id, filename, line, msg_str, false); - link_errors_.push_back(error); - va_end(args); -} - bool VerilogReader::reportLinkErrors() { @@ -2231,7 +2097,8 @@ VerilogReader::reportLinkErrors() bool errors = false; for (VerilogError *error : link_errors_) { // Report as warnings to avoid throwing. - report_->fileWarn(error->id(), error->filename(), error->line(), "%s", error->msg()); + report_->fileWarn(error->id(), error->filename(), error->line(), "{}", + error->msg()); errors |= !error->warn(); delete error; } @@ -2253,7 +2120,7 @@ VerilogScanner::VerilogScanner(std::istream *stream, void VerilogScanner::error(const char *msg) { - report_->fileError(1870, filename_, lineno(), "%s", msg); + report_->fileError(1870, filename_, lineno(), "{}", msg); } -} // namespace +} // namespace sta diff --git a/verilog/VerilogWriter.cc b/verilog/VerilogWriter.cc index d8ee7c6f..3531b865 100644 --- a/verilog/VerilogWriter.cc +++ b/verilog/VerilogWriter.cc @@ -30,6 +30,7 @@ #include #include "Error.hh" +#include "Format.hh" #include "Liberty.hh" #include "PortDirection.hh" #include "Network.hh" @@ -173,15 +174,15 @@ VerilogWriter::writeModule(const Instance *inst) { Cell *cell = network_->cell(inst); std::string cell_vname = cellVerilogName(network_->name(cell)); - fprintf(stream_, "module %s (", cell_vname.c_str()); + sta::print(stream_, "module {} (", cell_vname); writePorts(cell); writePortDcls(cell); - fprintf(stream_, "\n"); + sta::print(stream_, "\n"); writeWireDcls(inst); - fprintf(stream_, "\n"); + sta::print(stream_, "\n"); writeChildren(inst); writeAssigns(inst); - fprintf(stream_, "endmodule\n"); + sta::print(stream_, "endmodule\n"); } void @@ -194,14 +195,14 @@ VerilogWriter::writePorts(const Cell *cell) if (include_pwr_gnd_ || !network_->direction(port)->isPowerGround()) { if (!first) - fprintf(stream_, ",\n "); + sta::print(stream_, ",\n "); std::string verilog_name = portVerilogName(network_->name(port)); - fprintf(stream_, "%s", verilog_name.c_str()); + sta::print(stream_, "{}", verilog_name); first = false; } } delete port_iter; - fprintf(stream_, ");\n"); + sta::print(stream_, ");\n"); } void @@ -216,19 +217,19 @@ VerilogWriter::writePortDcls(const Cell *cell) std::string port_vname = portVerilogName(network_->name(port)); const char *vtype = verilogPortDir(dir); if (vtype) { - fprintf(stream_, " %s", vtype); + sta::print(stream_, " {}", vtype); if (network_->isBus(port)) - fprintf(stream_, " [%d:%d]", - network_->fromIndex(port), - network_->toIndex(port)); - fprintf(stream_, " %s;\n", port_vname.c_str()); - if (dir->isTristate()) { - fprintf(stream_, " tri"); - if (network_->isBus(port)) - fprintf(stream_, " [%d:%d]", + sta::print(stream_, " [{}:{}]", network_->fromIndex(port), network_->toIndex(port)); - fprintf(stream_, " %s;\n", port_vname.c_str()); + sta::print(stream_, " {};\n", port_vname); + if (dir->isTristate()) { + sta::print(stream_, " tri"); + if (network_->isBus(port)) + sta::print(stream_, " [{}:{}]", + network_->fromIndex(port), + network_->toIndex(port)); + sta::print(stream_, " {};\n", port_vname); } } } @@ -286,7 +287,7 @@ VerilogWriter::writeWireDcls(const Instance *inst) } else { std::string net_vname = netVerilogName(net_name); - fprintf(stream_, " wire %s;\n", net_vname.c_str());; + sta::print(stream_, " wire {};\n", net_vname); } } } @@ -296,16 +297,16 @@ VerilogWriter::writeWireDcls(const Instance *inst) for (const auto& [bus_name1, range] : bus_ranges) { const char *bus_name = bus_name1.c_str(); std::string net_vname = netVerilogName(bus_name); - fprintf(stream_, " wire [%d:%d] %s;\n", - range.first, - range.second, - net_vname.c_str());; + sta::print(stream_, " wire [{}:{}] {};\n", + range.first, + range.second, + net_vname); } // Wire net dcls for writeInstBusPinBit. int nc_count = findUnconnectedNetCount(inst); for (int i = 1; i < nc_count + 1; i++) - fprintf(stream_, " wire _NC%d;\n", i); + sta::print(stream_, " wire _NC{};\n", i); } void @@ -336,9 +337,9 @@ VerilogWriter::writeChild(const Instance *child) const char *child_name = network_->name(child); std::string child_vname = instanceVerilogName(child_name); std::string child_cell_vname = cellVerilogName(network_->name(child_cell)); - fprintf(stream_, " %s %s (", - child_cell_vname.c_str(), - child_vname.c_str()); + sta::print(stream_, " {} {} (", + child_cell_vname, + child_vname); bool first_port = true; CellPortIterator *port_iter = network_->portIterator(child_cell); while (port_iter->hasNext()) { @@ -352,7 +353,7 @@ VerilogWriter::writeChild(const Instance *child) } } delete port_iter; - fprintf(stream_, ");\n"); + sta::print(stream_, ");\n"); } } @@ -368,11 +369,11 @@ VerilogWriter::writeInstPin(const Instance *inst, const char *net_name = network_->name(net); std::string net_vname = netVerilogName(net_name); if (!first_port) - fprintf(stream_, ",\n "); + sta::print(stream_, ",\n "); std::string port_vname = portVerilogName(network_->name(port)); - fprintf(stream_, ".%s(%s)", - port_vname.c_str(), - net_vname.c_str()); + sta::print(stream_, ".{}({})", + port_vname, + net_vname); first_port = false; } } @@ -384,10 +385,10 @@ VerilogWriter::writeInstBusPin(const Instance *inst, bool &first_port) { if (!first_port) - fprintf(stream_, ",\n "); + sta::print(stream_, ",\n "); std::string port_vname = portVerilogName(network_->name(port)); - fprintf(stream_, ".%s({", port_vname.c_str()); + sta::print(stream_, ".{}({{", port_vname); first_port = false; bool first_member = true; @@ -410,7 +411,7 @@ VerilogWriter::writeInstBusPin(const Instance *inst, } delete member_iter; } - fprintf(stream_, "})"); + sta::print(stream_, "}})"); } void @@ -420,16 +421,15 @@ VerilogWriter::writeInstBusPinBit(const Instance *inst, { Pin *pin = network_->findPin(inst, port); Net *net = pin ? network_->net(pin) : nullptr; - std::string net_name; - if (net) - net_name = network_->name(net); - else + std::string net_name = net + ? network_->name(net) // There is no verilog syntax to "skip" a bit in the concatentation. - stringPrint(net_name, "_NC%d", unconnected_net_index_++); + : sta::format("_NC{}", unconnected_net_index_++); + std::string net_vname = netVerilogName(net_name.c_str()); if (!first_member) - fprintf(stream_, ",\n "); - fprintf(stream_, "%s", net_vname.c_str()); + sta::print(stream_, ",\n "); + sta::print(stream_, "{}", net_vname); first_member = false; } @@ -455,9 +455,9 @@ VerilogWriter::writeAssigns(const Instance *inst) // Port name is different from net name. std::string port_vname = netVerilogName(network_->name(port)); std::string net_vname = netVerilogName(network_->name(net)); - fprintf(stream_, " assign %s = %s;\n", - port_vname.c_str(), - net_vname.c_str()); + sta::print(stream_, " assign {} = {};\n", + port_vname, + net_vname); } } }