From e5c9bc43fd26b53759c1820467f044eefb00e7f1 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Tue, 12 Mar 2019 17:25:53 -0700 Subject: [PATCH] 2.0.10 --- CMakeLists.txt | 41 +- README.md | 10 +- dcalc/Arnoldi.hh | 2 +- dcalc/ArnoldiDelayCalc.cc | 6 +- dcalc/ArnoldiReduce.cc | 10 +- dcalc/DelayCalc.cc | 8 +- dcalc/DmpCeff.cc | 82 ++-- dcalc/DmpDelayCalc.cc | 12 +- dcalc/GraphDelayCalc.cc | 4 +- dcalc/GraphDelayCalc1.cc | 58 ++- dcalc/GraphDelayCalc1.hh | 6 +- dcalc/LumpedCapDelayCalc.cc | 8 +- dcalc/RCDelayCalc.cc | 10 +- dcalc/UnitDelayCalc.cc | 2 +- doc/OpenSTA.odt | Bin 74217 -> 74393 bytes doc/OpenSTA.pdf | Bin 152132 -> 152104 bytes graph/Delay.hh | 1 - graph/DelayFloat.cc | 91 +--- graph/DelayFloat.hh | 48 +- graph/DelayNormal2.cc | 77 ++-- graph/DelayNormal2.hh | 48 +- graph/Graph.cc | 126 +++-- graph/Graph.hh | 36 +- graph/GraphClass.hh | 11 +- liberty/EquivCells.cc | 8 +- liberty/FuncExpr.cc | 108 ++--- liberty/FuncExpr.hh | 2 +- liberty/InternalPower.cc | 20 +- liberty/LeakagePower.cc | 2 +- liberty/Liberty.cc | 372 +++++++-------- liberty/Liberty.hh | 55 +-- liberty/LibertyBuilder.cc | 140 +++--- liberty/LibertyClass.hh | 120 +++-- liberty/LibertyExpr.cc | 16 +- liberty/LibertyParser.cc | 80 ++-- liberty/LibertyParser.hh | 23 +- liberty/LibertyReader.cc | 438 +++++++++--------- liberty/TableModel.cc | 155 ++++--- liberty/TableModel.hh | 11 +- liberty/TimingArc.cc | 358 +++++++-------- liberty/TimingArc.hh | 86 ++-- liberty/TimingRole.cc | 86 ++-- liberty/TimingRole.hh | 2 +- liberty/Transition.cc | 24 +- liberty/Units.cc | 2 +- liberty/Wireload.cc | 36 +- network/ConcreteLibrary.cc | 18 +- network/ConcreteNetwork.cc | 125 ++--- network/ConcreteNetwork.hh | 4 +- network/HpinDrvrLoad.cc | 32 +- network/Network.cc | 68 +-- network/Network.hh | 4 +- network/NetworkClass.hh | 8 +- network/ParseBus.cc | 6 +- network/PortDirection.cc | 16 +- network/SdcNetwork.cc | 18 +- parasitics/ConcreteParasitics.cc | 135 +++--- parasitics/ConcreteParasitics.hh | 4 +- parasitics/ConcreteParasiticsPvt.hh | 2 +- parasitics/EstimateParasitics.cc | 10 +- parasitics/NullParasitics.cc | 42 +- parasitics/NullParasitics.hh | 4 +- parasitics/Parasitics.cc | 24 +- parasitics/ParasiticsClass.hh | 6 +- parasitics/ReduceParasitics.cc | 10 +- parasitics/SpefReader.cc | 34 +- sdc/Clock.cc | 58 +-- sdc/ClockGatingCheck.cc | 2 +- sdc/ClockGroups.cc | 6 +- sdc/ClockGroups.hh | 4 +- sdc/CycleAccting.cc | 16 + sdc/CycleAccting.hh | 13 + sdc/DeratingFactors.cc | 50 +- sdc/DisabledPorts.cc | 16 +- sdc/ExceptionPath.cc | 162 +++---- sdc/ExceptionPath.hh | 20 +- sdc/InputDrive.cc | 9 +- sdc/InputDrive.hh | 3 +- sdc/PortDelay.cc | 34 +- sdc/PortDelay.hh | 38 +- sdc/Sdc.cc | 689 ++++++++++++++-------------- sdc/Sdc.hh | 94 +++- sdc/SdcClass.hh | 45 +- sdc/SdcCmdComment.cc | 6 +- sdc/WriteSdc.cc | 154 +++---- sdc/WriteSdcPvt.hh | 2 +- sdf/SdfReader.cc | 66 +-- sdf/SdfReader.hh | 2 +- sdf/SdfWriter.cc | 31 +- search/Bfs.cc | 291 ++++-------- search/Bfs.hh | 33 +- search/CheckMaxSkews.cc | 8 +- search/CheckMinPeriods.cc | 33 +- search/CheckMinPeriods.hh | 7 +- search/CheckMinPulseWidths.cc | 16 +- search/CheckMinPulseWidths.hh | 8 +- search/CheckSlewLimits.cc | 8 +- search/CheckSlewLimits.hh | 8 +- search/CheckTiming.cc | 18 +- search/ClkInfo.cc | 12 +- search/ClkInfo.hh | 2 +- search/ClkSkew.cc | 6 +- search/Corner.cc | 33 +- search/Corner.hh | 4 +- search/Crpr.cc | 34 +- search/Crpr.hh | 1 - search/FindRegister.cc | 143 +++--- search/GatedClk.cc | 20 +- search/Genclks.cc | 63 ++- search/Latches.cc | 46 +- search/Latches.hh | 6 +- search/Levelize.cc | 26 +- search/Path.cc | 20 +- search/Path.hh | 4 +- search/PathAnalysisPt.cc | 2 +- search/PathEnd.cc | 168 ++++--- search/PathEnd.hh | 50 +- search/PathEnum.cc | 20 +- search/PathEnumed.cc | 2 +- search/PathExpanded.cc | 12 +- search/PathGroup.cc | 84 ++-- search/PathGroup.hh | 5 +- search/PathRef.cc | 12 +- search/PathRef.hh | 2 +- search/PathVertex.cc | 46 +- search/PathVertex.hh | 1 - search/PathVertexRep.cc | 8 +- search/Power.cc | 14 +- search/Property.cc | 339 ++++++++++---- search/Property.hh | 39 +- search/ReportPath.cc | 126 ++--- search/Search.cc | 464 ++++++++----------- search/Search.hh | 19 +- search/SearchClass.hh | 17 +- search/SearchPred.cc | 19 +- search/Sim.cc | 381 ++++++++------- search/Sim.hh | 4 +- search/Sta.cc | 137 +++--- search/Sta.hh | 47 +- search/StaState.cc | 32 +- search/StaState.hh | 2 + search/Tag.cc | 24 +- search/TagGroup.cc | 2 +- search/VertexVisitor.cc | 2 +- search/VisitPathEnds.cc | 60 ++- search/VisitPathEnds.hh | 2 +- search/VisitPathGroupVertices.cc | 4 +- search/WorstSlack.cc | 44 +- search/WorstSlack.hh | 5 +- search/WritePathSpice.cc | 200 +++++--- tcl/Sta.tcl | 6 +- tcl/StaTcl.i | 265 ++++++----- util/Debug.cc | 4 +- util/DisallowCopyAssign.hh | 4 +- util/EnumNameMap.hh | 97 ++++ util/Fuzzy.hh | 4 + util/HashSet.hh | 34 +- util/Machine.cc | 4 +- util/Map.hh | 35 +- util/MinMax.cc | 16 +- util/Mutex.hh | 49 +- util/PatternMatch.cc | 14 +- util/Pool.hh | 68 +-- util/Report.cc | 14 +- util/ReportTcl.cc | 90 ++-- util/Set.hh | 44 +- util/StaConfig.hh.cmake | 2 - util/StringUtil.cc | 19 +- util/StringUtil.hh | 8 +- util/ThreadForEach.hh | 101 ++-- util/TokenParser.cc | 8 +- util/UnorderedMap.hh | 34 +- util/UnorderedSet.hh | 137 ++++++ util/Vector.hh | 9 +- util/Zlib.hh | 2 +- verilog/Verilog.hh | 7 +- verilog/VerilogReader.cc | 82 ++-- 177 files changed, 4678 insertions(+), 4655 deletions(-) create mode 100644 util/EnumNameMap.hh create mode 100644 util/UnorderedSet.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index e9fa6bda..7f233a8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required (VERSION 3.9) -project(STA VERSION 2.0.8) +project(STA VERSION 2.0.10) set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_STANDARD 11) @@ -186,16 +186,12 @@ set(STA_SOURCE search/WorstSlack.cc search/WritePathSpice.cc - util/Condition.cc util/Debug.cc util/Error.cc util/Fuzzy.cc util/Machine.cc util/MinMax.cc - util/Mutex.cc util/PatternMatch.cc - util/Pthread.cc - util/ReadWriteLock.cc util/Report.cc util/ReportStd.cc util/ReportTcl.cc @@ -203,10 +199,6 @@ set(STA_SOURCE util/StringSeq.cc util/StringSet.cc util/StringUtil.cc - util/Thread.cc - util/ThreadException.cc - util/ThreadPool.cc - util/ThreadWorker.cc util/TokenParser.cc verilog/VerilogReader.cc @@ -353,14 +345,13 @@ set(STA_HEADERS search/WorstSlack.hh search/WritePathSpice.hh - util/Condition.hh util/Debug.hh util/DisallowCopyAssign.hh + util/EnumNameMap.hh util/Error.hh util/Fuzzy.hh util/Hash.hh util/HashSet.hh - util/HashMap.hh util/Iterator.hh util/Machine.hh util/Map.hh @@ -368,9 +359,7 @@ set(STA_HEADERS util/Mutex.hh util/ObjectIndex.hh util/PatternMatch.hh - util/Pthread.hh util/Pool.hh - util/ReadWriteLock.hh util/Report.hh util/ReportStd.hh util/ReportTcl.hh @@ -379,13 +368,10 @@ set(STA_HEADERS util/StringSeq.hh util/StringSet.hh util/StringUtil.hh - util/Thread.hh - util/ThreadException.hh util/ThreadForEach.hh - util/ThreadPool.hh - util/ThreadWorker.hh util/TokenParser.hh util/UnorderedMap.hh + util/UnorderedSet.hh util/Vector.hh util/Zlib.hh @@ -431,15 +417,6 @@ set(STA_SWIG_FILES # ################################################################ -# Pthreads -set(CMAKE_THREAD_PREFER_PTHREAD TRUE) -set(THREADS_PREFER_PTHREAD_FLAG TRUE) -find_package(Threads) -set(PTHREADS ${CMAKE_USE_PTHREADS_INIT}) -if (PTHREADS) - message(STATUS "Found pthreads") -endif() - # Zlib include(FindZLIB) # translate cmake bool to ifdef bool @@ -458,11 +435,12 @@ if("${CUDD}" STREQUAL "") set(CUDD $ENV{CUDD}) endif() -if("${CUDD}" STREQUAL "") +if("${CUDD}" STREQUAL "" OR "${CUDD}" STREQUAL "0") set(CUDD_INCLUDE "") set(CUDD_LIB "") set(CUDD_FOUND FALSE) set(CUDD 0) + message(STATUS "CUDD library: not found") else() set(CUDD_INCLUDE ${CUDD}/include) find_library(CUDD_LIB NAMES cudd PATHS ${CUDD}/lib) @@ -476,7 +454,7 @@ endif() if("${SSTA}" STREQUAL "") set(SSTA 0) endif() -message(STATUS "Enable SSTA: ${SSTA}") +message(STATUS "SSTA: ${SSTA}") # configure a header file to pass some of the CMake settins configure_file(${STA_HOME}/util/StaConfig.hh.cmake @@ -689,7 +667,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${STA_HOME}/app) add_executable(sta app/Main.cc) target_link_libraries(sta OpenSTA - Threads::Threads ${TCL_LIB} ${CUDD_LIB} ) @@ -701,12 +678,18 @@ message(STATUS "STA executable: ${STA_HOME}/app/sta") set(STA_COMPILE_OPTIONS -Wall -Wcast-qual -Wunused-parameter -Wno-deprecated-register -Wredundant-decls) +# Compiler specific options. if (CMAKE_CXX_COMPILER_ID MATCHES AppleClang|Clang|GNU) target_compile_options(OpenSTA PUBLIC ${STA_COMPILE_OPTIONS}) target_compile_options(sta PUBLIC ${STA_COMPILE_OPTIONS}) message(STATUS "Compiler options: ${STA_COMPILE_OPTIONS}") endif() +# g++ still needs -pthreads when using std::thread +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_link_libraries(sta -pthread) +endif() + ################################################################ # Install # cmake .. -DCMAKE_INSTALL_PREFIX= diff --git a/README.md b/README.md index 4b2f33ea..b8eb4db5 100644 --- a/README.md +++ b/README.md @@ -108,9 +108,8 @@ make make install ``` -The Zlib library is an optional. If CMake or the configure script -finds libz, OpenSTA can read Verilog, SDF, SPF, and SPEF files -compressed with gzip. +The Zlib library is an optional. If CMake finds libz, OpenSTA can +read Verilog, SDF, SPF, and SPEF files compressed with gzip. ### Installing with CMake @@ -163,11 +162,6 @@ files in the build directory. ### Installing on Windoz -The Win32 API does not natively support the pthreads API. The -pthreads-win32 package is one way to get support for pthreads for 32 -bit builds. It is available from [pthreads](www.sourceware.org/pthreads-win32). -If Cmake does not find `pthreads.h` the build proceeds without thread support. - Use a .bat file to start a cygwin shell that has its path set to support the Microcruft cl compiler by calling the vsvars32.bat script from the Visual C++ installation. diff --git a/dcalc/Arnoldi.hh b/dcalc/Arnoldi.hh index 726353cd..af29794f 100644 --- a/dcalc/Arnoldi.hh +++ b/dcalc/Arnoldi.hh @@ -37,7 +37,7 @@ class Pin; class arnoldi1 { public: - arnoldi1() { order=0; n=0; d=NULL; e=NULL; U=NULL; ctot=0.0; sqc=0.0; } + arnoldi1() { order=0; n=0; d=nullptr; e=nullptr; U=nullptr; ctot=0.0; sqc=0.0; } ~arnoldi1(); double elmore(int term_index); diff --git a/dcalc/ArnoldiDelayCalc.cc b/dcalc/ArnoldiDelayCalc.cc index c9b90a31..79449687 100644 --- a/dcalc/ArnoldiDelayCalc.cc +++ b/dcalc/ArnoldiDelayCalc.cc @@ -269,7 +269,7 @@ ArnoldiDelayCalc::findParasitic(const Pin *drvr_pin, Parasitic *¶sitic, bool &delete_at_finish) { - parasitic = NULL; + parasitic = nullptr; delete_at_finish = false; // set_load has precidence over parasitics. if (!sdc_->drvrPinHasWireCap(drvr_pin)) { @@ -280,7 +280,7 @@ ArnoldiDelayCalc::findParasitic(const Pin *drvr_pin, Parasitic *parasitic_network = parasitics_->findParasiticNetwork(drvr_pin, parasitic_ap); bool delete_parasitic_network = false; - if (parasitic_network == NULL) { + if (parasitic_network == nullptr) { Wireload *wireload = sdc_->wireloadDefaulted(cnst_min_max); if (wireload) { float pin_cap, wire_cap, fanout; @@ -318,7 +318,7 @@ ArnoldiDelayCalc::inputPortDelay(const Pin *drvr_pin, const DcalcAnalysisPt *dcalc_ap) { RCDelayCalc::inputPortDelay(drvr_pin, in_slew, tr, parasitic, dcalc_ap); - rcmodel_ = NULL; + rcmodel_ = nullptr; _delayV[0] = 0.0; _slewV[0] = in_slew; diff --git a/dcalc/ArnoldiReduce.cc b/dcalc/ArnoldiReduce.cc index 90f4f8e5..d018afc9 100644 --- a/dcalc/ArnoldiReduce.cc +++ b/dcalc/ArnoldiReduce.cc @@ -35,7 +35,7 @@ namespace sta { rcmodel::rcmodel() : - pinV(NULL) + pinV(nullptr) { } @@ -188,7 +188,7 @@ ArnoldiReduce::loadWork() ts_edge *e; int tindex; for (p = p0; p!=pend; p++) { - p->node_ = NULL; + p->node_ = nullptr; p->eN = 0; p->is_term = false; } @@ -323,7 +323,7 @@ ArnoldiReduce::makeRcmodelDrv() makeRcmodelDfs(pdrv); getRC(); if (ctot_ < 1e-22) // 1e-10ps - return NULL; + return nullptr; setTerms(pdrv); makeRcmodelFromTs(); rcmodel *mod = makeRcmodelFromW(); @@ -350,7 +350,7 @@ ArnoldiReduce::makeRcmodelDfs(ts_point *pdrv) stackV[0] = e = pdrv->eV[0]; ts_orient(pdrv,e); pdrv->visited = 1; - pdrv->in_edge = NULL; + pdrv->in_edge = nullptr; pdrv->ts = 0; ts_ordV[0] = pdrv-p0; ts_pordV[0] = pdrv; @@ -620,7 +620,7 @@ ArnoldiReduce::makeRcmodelFromW() 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 = NULL; + 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; diff --git a/dcalc/DelayCalc.cc b/dcalc/DelayCalc.cc index 684676a3..bd389615 100644 --- a/dcalc/DelayCalc.cc +++ b/dcalc/DelayCalc.cc @@ -28,7 +28,7 @@ namespace sta { typedef Map DelayCalcMap; -static DelayCalcMap *delay_calcs = NULL; +static DelayCalcMap *delay_calcs = nullptr; void registerDelayCalcs() @@ -45,7 +45,7 @@ void registerDelayCalc(const char *name, MakeArcDelayCalc maker) { - if (delay_calcs == NULL) + if (delay_calcs == nullptr) delay_calcs = new DelayCalcMap; (*delay_calcs)[name] = maker; } @@ -54,7 +54,7 @@ void deleteDelayCalcs() { delete delay_calcs; - delay_calcs = NULL; + delay_calcs = nullptr; } ArcDelayCalc * @@ -65,7 +65,7 @@ makeDelayCalc(const char *name, if (maker) return maker(sta); else - return NULL; + return nullptr; } bool diff --git a/dcalc/DmpCeff.cc b/dcalc/DmpCeff.cc index ffe4e666..7ca8acf8 100644 --- a/dcalc/DmpCeff.cc +++ b/dcalc/DmpCeff.cc @@ -53,20 +53,12 @@ static const double tiny_double = 1.0e-20; static const int find_root_max_iter = 20; // Indices of Newton-Raphson parameter vector. -enum { - dmp_param_t0, - dmp_param_dt, - dmp_param_ceff -}; +enum DmpParam { t0, dt, ceff }; static const char *dmp_param_index_strings[] = {"t0", "dt", "Ceff"}; // Indices of Newton-Raphson function value vector. -enum { - dmp_func_y20, - dmp_func_y50, - dmp_func_ipi -}; +enum DmpFunc { y20, y50, ipi }; static const char *dmp_func_index_strings[] = {"y20", "y50", "Ipi"}; @@ -330,7 +322,7 @@ DmpAlg::init(const LibertyLibrary *drvr_library, } // Find Ceff, delta_t and t0 for the driver. -// Caller must initialize/retrieve x_[dmp_param_ceff] because +// Caller must initialize/retrieve x_[DmpParam::ceff] because // order 2 eqns don't have a ceff eqn. // Return true if successful. bool @@ -340,17 +332,17 @@ DmpAlg::findDriverParams(double &ceff) gateDelays(ceff, t_vth, t_vl, slew); double dt = slew / (vh_ - vl_); double t0 = t_vth + log(1.0 - vth_) * rd_ * ceff - vth_ * dt; - x_[dmp_param_dt] = dt; - x_[dmp_param_t0] = t0; + x_[DmpParam::dt] = dt; + x_[DmpParam::t0] = t0; const char *nr_error; if (newtonRaphson(100, x_, nr_order_, driver_param_tol, evalDmpEqnsState, this, fvec_, fjac_, index_, p_, scale_, nr_error)) { - t0_ = x_[dmp_param_t0]; - dt_ = x_[dmp_param_dt]; + t0_ = x_[DmpParam::t0]; + dt_ = x_[DmpParam::dt]; debugPrint3(debug_, "delay_calc", 3, " t0 = %s dt = %s ceff = %s\n", units_->timeUnit()->asString(t0_), units_->timeUnit()->asString(dt_), - units_->capacitanceUnit()->asString(x_[dmp_param_ceff])); + units_->capacitanceUnit()->asString(x_[DmpParam::ceff])); if (debug_->check("delay_calc", 4)) showVo(); return true; @@ -929,7 +921,7 @@ DmpPi::gateDelaySlew(double &delay, double &slew) { if (findDriverParamsPi()) { - ceff_ = x_[dmp_param_ceff]; + ceff_ = x_[DmpParam::ceff]; driver_valid_ = true; double table_slew; // Table gate delays are more accurate than using Vo waveform delay @@ -955,8 +947,8 @@ bool DmpPi::findDriverParamsPi() { double ceff = c1_ + c2_; - x_[dmp_param_ceff] = ceff; - return findDriverParams(x_[dmp_param_ceff]); + x_[DmpParam::ceff] = ceff; + return findDriverParams(x_[DmpParam::ceff]); } // Given x_ as a vector of input parameters, fill fvec_ with the @@ -964,9 +956,9 @@ DmpPi::findDriverParamsPi() bool DmpPi::evalDmpEqns() { - double t0 = x_[dmp_param_t0]; - double dt = x_[dmp_param_dt]; - double ceff = x_[dmp_param_ceff]; + double t0 = x_[DmpParam::t0]; + double dt = x_[DmpParam::dt]; + double ceff = x_[DmpParam::ceff]; if (ceff > (c1_ + c2_) || ceff < 0.0) return false; @@ -988,29 +980,29 @@ DmpPi::evalDmpEqns() double y_t_vth = y(t_vth, t0, dt, ceff); // y20 in the paper. Match Vl. double y_t_vl = y(t_vl, t0, dt, ceff); - fvec_[dmp_func_ipi] = ipiIceff(t0, dt, ceff_time, ceff); - fvec_[dmp_func_y50] = y_t_vth - vth_; - fvec_[dmp_func_y20] = y_t_vl - vl_; - fjac_[dmp_func_ipi][dmp_param_t0] = 0.0; - fjac_[dmp_func_ipi][dmp_param_dt] = + fvec_[DmpFunc::ipi] = ipiIceff(t0, dt, ceff_time, ceff); + fvec_[DmpFunc::y50] = y_t_vth - vth_; + fvec_[DmpFunc::y20] = y_t_vl - 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); - fjac_[dmp_func_ipi][dmp_param_ceff] = + fjac_[DmpFunc::ipi][DmpParam::ceff] = (2 * rd_ * ceff - dt - (2 * rd_ * ceff + dt) * exp(-dt / (rd_ * ceff))) / (dt * dt); dy(t_vl, t0, dt, ceff, - fjac_[dmp_func_y20][dmp_param_t0], - fjac_[dmp_func_y20][dmp_param_dt], - fjac_[dmp_func_y20][dmp_param_ceff]); + fjac_[DmpFunc::y20][DmpParam::t0], + fjac_[DmpFunc::y20][DmpParam::dt], + fjac_[DmpFunc::y20][DmpParam::ceff]); dy(t_vth, t0, dt, ceff, - fjac_[dmp_func_y50][dmp_param_t0], - fjac_[dmp_func_y50][dmp_param_dt], - fjac_[dmp_func_y50][dmp_param_ceff]); + fjac_[DmpFunc::y50][DmpParam::t0], + fjac_[DmpFunc::y50][DmpParam::dt], + fjac_[DmpFunc::y50][DmpParam::ceff]); if (debug_->check("delay_calc", 4)) { showX(); @@ -1099,17 +1091,17 @@ DmpOnePole::DmpOnePole(StaState *sta) : bool DmpOnePole::evalDmpEqns() { - double t0 = x_[dmp_param_t0]; - double dt = x_[dmp_param_dt]; + double t0 = x_[DmpParam::t0]; + double dt = x_[DmpParam::dt]; double t_vth, t_vl, ignore, dummy; gateDelays(ceff_, t_vth, t_vl, ignore); if (dt <= 0.0) - dt = x_[dmp_param_dt] = (t_vl - t_vth) / 100; + dt = x_[DmpParam::dt] = (t_vl - t_vth) / 100; - fvec_[dmp_func_y50] = y(t_vth, t0, dt, ceff_) - vth_; - fvec_[dmp_func_y20] = y(t_vl, t0, dt, ceff_) - vl_; + fvec_[DmpFunc::y50] = y(t_vth, t0, dt, ceff_) - vth_; + fvec_[DmpFunc::y20] = y(t_vl, t0, dt, ceff_) - vl_; if (debug_->check("delay_calc", 4)) { showX(); @@ -1117,13 +1109,13 @@ DmpOnePole::evalDmpEqns() } dy(t_vl, t0, dt, ceff_, - fjac_[dmp_func_y20][dmp_param_t0], - fjac_[dmp_func_y20][dmp_param_dt], + fjac_[DmpFunc::y20][DmpParam::t0], + fjac_[DmpFunc::y20][DmpParam::dt], dummy); dy(t_vth, t0, dt, ceff_, - fjac_[dmp_func_y50][dmp_param_t0], - fjac_[dmp_func_y50][dmp_param_dt], + fjac_[DmpFunc::y50][DmpParam::t0], + fjac_[DmpFunc::y50][DmpParam::dt], dummy); if (debug_->check("delay_calc", 4)) { @@ -1560,7 +1552,7 @@ DmpCeffDelayCalc::DmpCeffDelayCalc(StaState *sta) : dmp_cap_(new DmpCap(sta)), dmp_pi_(new DmpPi(sta)), dmp_zero_c2_(new DmpZeroC2(sta)), - dmp_alg_(NULL) + dmp_alg_(nullptr) { } @@ -1578,7 +1570,7 @@ DmpCeffDelayCalc::inputPortDelay(const Pin *port_pin, Parasitic *parasitic, const DcalcAnalysisPt *dcalc_ap) { - dmp_alg_ = NULL; + dmp_alg_ = nullptr; input_port_ = true; RCDelayCalc::inputPortDelay(port_pin, in_slew, tr, parasitic, dcalc_ap); } diff --git a/dcalc/DmpDelayCalc.cc b/dcalc/DmpDelayCalc.cc index dab2ae96..a3ea44d6 100644 --- a/dcalc/DmpDelayCalc.cc +++ b/dcalc/DmpDelayCalc.cc @@ -206,7 +206,7 @@ DmpCeffTwoPoleDelayCalc::findParasitic(const Pin *drvr_pin, Parasitic *¶sitic, bool &delete_at_finish) { - parasitic = NULL; + parasitic = nullptr; delete_at_finish = false; // set_load has precidence over parasitics. if (!sdc_->drvrPinHasWireCap(drvr_pin)) { @@ -216,7 +216,7 @@ DmpCeffTwoPoleDelayCalc::findParasitic(const Pin *drvr_pin, const MinMax *cnst_min_max = dcalc_ap->constraintMinMax(); // Prefer PiPoleResidue. parasitic = parasitics_->findPiPoleResidue(drvr_pin, tr, parasitic_ap); - if (parasitic == NULL) { + if (parasitic == nullptr) { Parasitic *parasitic_network = parasitics_->findParasiticNetwork(drvr_pin, parasitic_ap); if (parasitic_network) @@ -227,11 +227,11 @@ DmpCeffTwoPoleDelayCalc::findParasitic(const Pin *drvr_pin, parasitic_ap); delete_at_finish = true; } - if (parasitic == NULL) + if (parasitic == nullptr) parasitic = parasitics_->findPiElmore(drvr_pin, tr, parasitic_ap); - if (parasitic == NULL) + if (parasitic == nullptr) parasitic = parasitics_->findLumpedElmore(drvr_pin, tr, parasitic_ap); - if (parasitic == NULL) { + if (parasitic == nullptr) { Wireload *wireload = sdc_->wireloadDefaulted(cnst_min_max); if (wireload) { float pin_cap, wire_cap, fanout; @@ -343,7 +343,7 @@ DmpCeffTwoPoleDelayCalc::loadDelay(Parasitic *pole_residue, { ComplexFloat pole2, residue2; parasitics_->poleResidue(pole_residue, 1, pole2, residue2); - if (!delayFuzzyZero(drvr_slew_) + if (!fuzzyZero(drvr_slew_) && pole2.imag() == 0.0 && residue2.imag() == 0.0) { double p2 = pole2.real(); diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index f1a836e5..2cf7e962 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -126,7 +126,7 @@ GraphDelayCalc::minPulseWidth(const Pin *pin, LibertyPort *port = network_->libertyPort(pin); if (port) { Instance *inst = network_->instance(pin); - Pvt *pvt = inst ? sdc_->pvt(inst, min_max) : NULL; + Pvt *pvt = inst ? sdc_->pvt(inst, min_max) : nullptr; OperatingConditions *op_cond=sdc_->operatingConditions(min_max); port->minPulseWidth(hi_low, op_cond, pvt, min_width, exists); } @@ -161,7 +161,7 @@ GraphDelayCalc::minPeriod(const Pin *pin, // Liberty library. Instance *inst = network_->instance(pin); OperatingConditions *op_cond = sdc_->operatingConditions(min_max); - Pvt *pvt = inst ? sdc_->pvt(inst, min_max) : NULL; + Pvt *pvt = inst ? sdc_->pvt(inst, min_max) : nullptr; port->minPeriod(op_cond, pvt, min_period, exists); } } diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index 0164b126..51f81aab 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -17,6 +17,7 @@ #include "Machine.hh" #include "Debug.hh" #include "Stats.hh" +#include "Mutex.hh" #include "MinMax.hh" #include "PortDirection.hh" #include "TimingRole.hh" @@ -92,11 +93,11 @@ private: }; MultiDrvrNet::MultiDrvrNet(VertexSet *drvrs) : - dcalc_drvr_(NULL), + dcalc_drvr_(nullptr), drvrs_(drvrs), - parallel_delays_(NULL), - parallel_slews_(NULL), - net_caps_(NULL), + parallel_delays_(nullptr), + parallel_slews_(nullptr), + net_caps_(nullptr), delays_valid_(false) { } @@ -217,13 +218,13 @@ MultiDrvrNet::setDcalcDrvr(Vertex *drvr) GraphDelayCalc1::GraphDelayCalc1(StaState *sta) : GraphDelayCalc(sta), - observer_(NULL), + observer_(nullptr), delays_seeded_(false), incremental_(false), search_pred_(new SearchPred1(sta)), search_non_latch_pred_(new SearchPredNonLatch2(sta)), clk_pred_(new ClkTreeSearchPred(sta)), - iter_(new BfsFwdIterator(bfs_dcalc, search_non_latch_pred_, sta)), + iter_(new BfsFwdIterator(BfsIndex::dcalc, search_non_latch_pred_, sta)), multi_drvr_nets_found_(false), incremental_delay_tolerance_(0.0) { @@ -525,7 +526,7 @@ GraphDelayCalc1::makeMultiDrvrNet(PinSet &drvr_pins) VertexSet *drvr_vertices = new VertexSet; MultiDrvrNet *multi_drvr = new MultiDrvrNet(drvr_vertices); Level max_drvr_level = 0; - Vertex *max_drvr = NULL; + Vertex *max_drvr = nullptr; PinSet::Iterator pin_iter(drvr_pins); while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); @@ -535,7 +536,7 @@ GraphDelayCalc1::makeMultiDrvrNet(PinSet &drvr_pins) multi_drvr_net_map_[drvr_vertex] = multi_drvr; drvr_vertices->insert(drvr_vertex); Level drvr_level = drvr_vertex->level(); - if (max_drvr == NULL + if (max_drvr == nullptr || drvr_level > max_drvr_level) max_drvr = drvr_vertex; } @@ -606,7 +607,7 @@ GraphDelayCalc1::seedDrvrSlew(Vertex *drvr_vertex, drive->driveCell(tr, cnst_min_max, drvr_cell, from_port, from_slews, to_port); if (drvr_cell) { - if (from_port == NULL) + if (from_port == nullptr) from_port = driveCellDefaultFromPort(drvr_cell, to_port); findInputDriverDelay(drvr_cell, drvr_pin, drvr_vertex, tr, from_port, from_slews, to_port, dcalc_ap); @@ -747,7 +748,7 @@ GraphDelayCalc1::driveCellDefaultFromPort(LibertyCell *cell, if (arc_set->to() == to_port) { LibertyPort *set_from_port = arc_set->from(); int set_from_port_index = findPortIndex(cell, set_from_port); - if (from_port == NULL + if (from_port == nullptr || set_from_port_index < from_port_index) { from_port = set_from_port; from_port_index = set_from_port_index; @@ -904,9 +905,8 @@ GraphDelayCalc1::enqueueTimingChecksEdges(Vertex *vertex) { if (vertex->hasChecks() || vertex->isCheckClk()) { - check_vertices_lock_.lock(); + UniqueLock lock(check_vertices_lock_); invalid_checks_.insert(vertex); - check_vertices_lock_.unlock(); } } @@ -951,7 +951,7 @@ GraphDelayCalc1::findDriverDelays(Vertex *drvr_vertex, return delay_changed; } else - return findDriverDelays1(drvr_vertex, true, NULL, arc_delay_calc); + return findDriverDelays1(drvr_vertex, true, nullptr, arc_delay_calc); } bool @@ -1021,7 +1021,7 @@ GraphDelayCalc1::findDriverEdgeDelays(LibertyCell *drvr_cell, while (ap_iter.hasNext()) { DcalcAnalysisPt *dcalc_ap = ap_iter.next(); const Pvt *pvt = sdc_->pvt(drvr_inst, dcalc_ap->constraintMinMax()); - if (pvt == NULL) + if (pvt == nullptr) pvt = dcalc_ap->operatingConditions(); TimingArcSetArcIterator arc_iter(arc_set); while (arc_iter.hasNext()) { @@ -1069,7 +1069,7 @@ GraphDelayCalc1::loadCap(const Pin *drvr_pin, bool delete_parasitic; arc_delay_calc_->findParasitic(drvr_pin, drvr_tr, dcalc_ap, drvr_parasitic, delete_parasitic); - float load_cap = loadCap(drvr_pin, NULL, drvr_parasitic, drvr_tr, dcalc_ap); + float load_cap = loadCap(drvr_pin, nullptr, drvr_parasitic, drvr_tr, dcalc_ap); arc_delay_calc_->finish(drvr_pin, drvr_tr, dcalc_ap, drvr_parasitic, delete_parasitic); return load_cap; @@ -1081,7 +1081,7 @@ GraphDelayCalc1::loadCap(const Pin *drvr_pin, const TransRiseFall *tr, const DcalcAnalysisPt *dcalc_ap) const { - return loadCap(drvr_pin, NULL, drvr_parasitic, tr, dcalc_ap); + return loadCap(drvr_pin, nullptr, drvr_parasitic, tr, dcalc_ap); } float @@ -1283,7 +1283,7 @@ GraphDelayCalc1::findArcDelay(LibertyCell *drvr_cell, // Merge slews. const Slew &drvr_slew = graph_->slew(drvr_vertex, drvr_tr, ap_index); const MinMax *slew_min_max = dcalc_ap->slewMinMax(); - if (delayFuzzyGreater(gate_slew, drvr_slew, dcalc_ap->slewMinMax()) + if (fuzzyGreater(gate_slew, drvr_slew, dcalc_ap->slewMinMax()) && !drvr_vertex->slewAnnotated(drvr_tr, slew_min_max)) graph_->setSlew(drvr_vertex, drvr_tr, ap_index, gate_slew); if (!graph_->arcDelayAnnotated(edge, arc, ap_index)) { @@ -1493,7 +1493,7 @@ GraphDelayCalc1::annotateLoadDelays(Vertex *drvr_vertex, else { const Slew &slew = graph_->slew(load_vertex, drvr_tr, ap_index); if (!merge - || delayFuzzyGreater(load_slew, slew, slew_min_max)) + || fuzzyGreater(load_slew, slew, slew_min_max)) graph_->setSlew(load_vertex, drvr_tr, ap_index, load_slew); } } @@ -1506,7 +1506,7 @@ GraphDelayCalc1::annotateLoadDelays(Vertex *drvr_vertex, Delay wire_delay_extra = extra_delay + wire_delay; const MinMax *delay_min_max = dcalc_ap->delayMinMax(); if (!merge - || delayFuzzyGreater(wire_delay_extra, delay, delay_min_max)) { + || fuzzyGreater(wire_delay_extra, delay, delay_min_max)) { graph_->setWireArcDelay(wire_edge, drvr_tr, ap_index, wire_delay_extra); if (observer_) @@ -1583,7 +1583,7 @@ GraphDelayCalc1::findCheckEdgeDelays(Edge *edge, DcalcAPIndex ap_index = dcalc_ap->index(); if (!graph_->arcDelayAnnotated(edge, arc, ap_index)) { const Pvt *pvt = sdc_->pvt(inst,dcalc_ap->constraintMinMax()); - if (pvt == NULL) + if (pvt == nullptr) pvt = dcalc_ap->operatingConditions(); const Slew &from_slew = checkEdgeClkSlew(from_vertex, from_tr, dcalc_ap); @@ -1650,7 +1650,7 @@ bool GraphDelayCalc1::findIdealClks(Vertex *vertex) { const Pin *pin = vertex->pin(); - ClockSet *ideal_clks = NULL; + ClockSet *ideal_clks = nullptr; if (sdc_->isVertexPinClock(pin)) { // Seed ideal clocks pins. if (!sdc_->isPropagatedClock(pin)) { @@ -1659,7 +1659,7 @@ GraphDelayCalc1::findIdealClks(Vertex *vertex) while (clk_iter.hasNext()) { Clock *clk = clk_iter.next(); if (!clk->isPropagated()) { - if (ideal_clks == NULL) { + if (ideal_clks == nullptr) { ideal_clks = new ClockSet; debugPrint1(debug_, "ideal_clks", 1, " %s\n", vertex->name(sdc_network_)); @@ -1682,7 +1682,7 @@ GraphDelayCalc1::findIdealClks(Vertex *vertex) ClockSet::ConstIterator from_clk_iter(from_clks); while (from_clk_iter.hasNext()) { Clock *from_clk = from_clk_iter.next(); - if (ideal_clks == NULL) { + if (ideal_clks == nullptr) { ideal_clks = new ClockSet; debugPrint1(debug_, "ideal_clks", 1, " %s\n", vertex->name(sdc_network_)); @@ -1709,7 +1709,7 @@ GraphDelayCalc1::setIdealClks(const Vertex *vertex, ClockSet *clks) { bool changed = false; - ideal_clks_map_lock_.lock(); + UniqueLock lock(ideal_clks_map_lock_); ClockSet *clks1 = ideal_clks_map_.findKey(vertex); if (ClockSet::equal(clks, clks1)) delete clks; @@ -1718,16 +1718,14 @@ GraphDelayCalc1::setIdealClks(const Vertex *vertex, ideal_clks_map_[vertex] = clks; changed = true; } - ideal_clks_map_lock_.unlock(); return changed; } ClockSet * GraphDelayCalc1::idealClks(const Vertex *vertex) { - ideal_clks_map_lock_.lock(); + UniqueLock lock(ideal_clks_map_lock_); ClockSet *clks = ideal_clks_map_.findKey(vertex); - ideal_clks_map_lock_.unlock(); return clks; } @@ -1752,7 +1750,7 @@ GraphDelayCalc1::ceff(Edge *edge, TimingArcSet *arc_set = edge->timingArcSet(); float ceff = 0.0; const Pvt *pvt = sdc_->pvt(inst, dcalc_ap->constraintMinMax()); - if (pvt == NULL) + if (pvt == nullptr) pvt = dcalc_ap->operatingConditions(); TransRiseFall *from_tr = arc->fromTrans()->asRiseFall(); TransRiseFall *to_tr = arc->toTrans()->asRiseFall(); @@ -1806,7 +1804,7 @@ GraphDelayCalc1::reportDelayCalc(Edge *edge, string *result = new string; DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max); const Pvt *pvt = sdc_->pvt(inst, dcalc_ap->constraintMinMax()); - if (pvt == NULL) + if (pvt == nullptr) pvt = dcalc_ap->operatingConditions(); TransRiseFall *from_tr = arc->fromTrans()->asRiseFall(); TransRiseFall *to_tr = arc->toTrans()->asRiseFall(); @@ -1831,7 +1829,7 @@ GraphDelayCalc1::reportDelayCalc(Edge *edge, int slew_index = dcalc_ap->checkDataSlewIndex(); const Slew &to_slew = graph_->slew(to_vertex, to_tr, slew_index); bool from_ideal_clk = isIdealClk(from_vertex); - const char *from_slew_annotation = from_ideal_clk ? " (ideal clock)" : NULL; + const char *from_slew_annotation = from_ideal_clk ? " (ideal clock)" : nullptr; arc_delay_calc_->reportCheckDelay(cell, arc, from_slew, from_slew_annotation, to_slew, related_out_cap, pvt, dcalc_ap, digits, result); diff --git a/dcalc/GraphDelayCalc1.hh b/dcalc/GraphDelayCalc1.hh index f6d95d00..3417b834 100644 --- a/dcalc/GraphDelayCalc1.hh +++ b/dcalc/GraphDelayCalc1.hh @@ -17,7 +17,7 @@ #ifndef STA_GRAPH_DELAY_CALC1_H #define STA_GRAPH_DELAY_CALC1_H -#include "Mutex.hh" +#include #include "GraphDelayCalc.hh" namespace sta { @@ -222,7 +222,7 @@ protected: VertexSet invalid_delays_; // Vertices with invalid -from/-to timing checks. VertexSet invalid_checks_; - Mutex check_vertices_lock_; + std::mutex check_vertices_lock_; SearchPred *search_pred_; SearchPred *search_non_latch_pred_; SearchPred *clk_pred_; @@ -233,7 +233,7 @@ protected: // delays to be recomputed during incremental delay calculation. float incremental_delay_tolerance_; VertexIdealClksMap ideal_clks_map_; - Mutex ideal_clks_map_lock_; + std::mutex ideal_clks_map_lock_; friend class FindVertexDelays; friend class MultiDrvrNet; diff --git a/dcalc/LumpedCapDelayCalc.cc b/dcalc/LumpedCapDelayCalc.cc index 2a63d394..c58ef96e 100644 --- a/dcalc/LumpedCapDelayCalc.cc +++ b/dcalc/LumpedCapDelayCalc.cc @@ -54,16 +54,16 @@ LumpedCapDelayCalc::findParasitic(const Pin *drvr_pin, Parasitic *¶sitic, bool &delete_at_finish) { - parasitic = NULL; + parasitic = nullptr; delete_at_finish = false; // set_load has precidence over parasitics. if (!sdc_->drvrPinHasWireCap(drvr_pin)) { const ParasiticAnalysisPt *parasitic_ap = dcalc_ap->parasiticAnalysisPt(); // Prefer capacitive load. parasitic = parasitics_->findLumpedElmore(drvr_pin, tr, parasitic_ap); - if (parasitic == NULL) + if (parasitic == nullptr) parasitic = parasitics_->findPiElmore(drvr_pin, tr, parasitic_ap); - if (parasitic == NULL) { + if (parasitic == nullptr) { parasitic = parasitics_->findParasiticNetwork(drvr_pin, parasitic_ap); if (parasitic) { parasitic = parasitics_->reduceToPiElmore(parasitic, drvr_pin, tr, @@ -74,7 +74,7 @@ LumpedCapDelayCalc::findParasitic(const Pin *drvr_pin, delete_at_finish = true; } } - if (parasitic == NULL) { + if (parasitic == nullptr) { const MinMax *cnst_min_max = dcalc_ap->constraintMinMax(); Wireload *wireload = sdc_->wireloadDefaulted(cnst_min_max); if (wireload) { diff --git a/dcalc/RCDelayCalc.cc b/dcalc/RCDelayCalc.cc index 12b816b0..b1ddf41f 100644 --- a/dcalc/RCDelayCalc.cc +++ b/dcalc/RCDelayCalc.cc @@ -43,7 +43,7 @@ RCDelayCalc::findParasitic(const Pin *drvr_pin, Parasitic *¶sitic, bool &delete_at_finish) { - parasitic = NULL; + parasitic = nullptr; delete_at_finish = false; // set_load has precidence over parasitics. if (!sdc_->drvrPinHasWireCap(drvr_pin)) { @@ -53,7 +53,7 @@ RCDelayCalc::findParasitic(const Pin *drvr_pin, const ParasiticAnalysisPt *parasitic_ap = dcalc_ap->parasiticAnalysisPt(); // Prefer PiElmore. parasitic = parasitics_->findPiElmore(drvr_pin, tr, parasitic_ap); - if (parasitic == NULL) { + if (parasitic == nullptr) { Parasitic *parasitic_network = parasitics_->findParasiticNetwork(drvr_pin, parasitic_ap); if (parasitic_network) { @@ -63,9 +63,9 @@ RCDelayCalc::findParasitic(const Pin *drvr_pin, delete_at_finish = true; } } - if (parasitic == NULL) + if (parasitic == nullptr) parasitic = parasitics_->findLumpedElmore(drvr_pin, tr, parasitic_ap); - if (parasitic == NULL) { + if (parasitic == nullptr) { Wireload *wireload = sdc_->wireloadDefaulted(cnst_min_max); if (wireload) { float pin_cap, wire_cap, fanout; @@ -92,7 +92,7 @@ RCDelayCalc::inputPortDelay(const Pin *, drvr_parasitic_ = parasitic; drvr_slew_ = in_slew; drvr_tr_ = tr; - drvr_cell_ = NULL; + drvr_cell_ = nullptr; drvr_library_ = network_->defaultLibertyLibrary(); multi_drvr_slew_factor_ = 1.0F; } diff --git a/dcalc/UnitDelayCalc.cc b/dcalc/UnitDelayCalc.cc index b2c56e5b..8a37aebf 100644 --- a/dcalc/UnitDelayCalc.cc +++ b/dcalc/UnitDelayCalc.cc @@ -46,7 +46,7 @@ UnitDelayCalc::findParasitic(const Pin *, bool &delete_at_finish) { // No parasitics are required for this delay calculator. - parasitic = NULL; + parasitic = nullptr; delete_at_finish = false; } diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index f3924f37ed1eac229d09f249be0517f5df786256..60c44a0f9ffda32dbc7d719411209153877b415c 100644 GIT binary patch delta 44587 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 z

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 diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index 6a3d2dc1604ff87763988d91f8fff9db58354048..d174b61253dadc7b3d26105e825e026d8f0a531b 100644 GIT binary patch delta 28574 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 delta 28602 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

Vya#8DoCRjMRw# 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 diff --git a/graph/Delay.hh b/graph/Delay.hh index 25284d45..dd3bd551 100644 --- a/graph/Delay.hh +++ b/graph/Delay.hh @@ -27,7 +27,6 @@ #include "DelayFloat.hh" #endif -// API common to DelayFloat and DelayNormal2. namespace sta { typedef Delay ArcDelay; diff --git a/graph/DelayFloat.cc b/graph/DelayFloat.cc index 7d29a84e..e769c8e6 100644 --- a/graph/DelayFloat.cc +++ b/graph/DelayFloat.cc @@ -49,72 +49,20 @@ delayIsInitValue(const Delay &delay, } bool -delayFuzzyZero(const Delay &delay) -{ - return fuzzyZero(delay); -} - -bool -delayFuzzyEqual(const Delay &delay1, - const Delay &delay2) -{ - return fuzzyEqual(delay1, delay2); -} - -bool -delayFuzzyLess(const Delay &delay1, - const Delay &delay2) -{ - return fuzzyLess(delay1, delay2); -} - -bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2) -{ - return fuzzyLessEqual(delay1, delay2); -} - -bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max) +fuzzyGreater(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max) { if (min_max == MinMax::max()) - return fuzzyLessEqual(delay1, delay2); + return fuzzyGreater(delay1, delay2); else - return fuzzyGreaterEqual(delay1, delay2); + return fuzzyLess(delay1, delay2); } bool -delayFuzzyGreater(const Delay &delay1, - const Delay &delay2) -{ - return fuzzyGreater(delay1, delay2); -} - -bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2) -{ - return fuzzyGreaterEqual(delay1, delay2); -} - -bool -delayFuzzyGreater(const Delay &delay1, +fuzzyGreaterEqual(const Delay &delay1, const Delay &delay2, const MinMax *min_max) -{ - if (min_max == MinMax::max()) - return fuzzyGreater(delay1, delay2); - else - return fuzzyLess(delay1, delay2); -} - -bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max) { if (min_max == MinMax::max()) return fuzzyGreaterEqual(delay1, delay2); @@ -123,9 +71,9 @@ delayFuzzyGreaterEqual(const Delay &delay1, } bool -delayFuzzyLess(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max) +fuzzyLess(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max) { if (min_max == MinMax::max()) return fuzzyLess(delay1, delay2); @@ -133,6 +81,17 @@ delayFuzzyLess(const Delay &delay1, return fuzzyGreater(delay1, delay2); } +bool +fuzzyLessEqual(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max) +{ + if (min_max == MinMax::max()) + return fuzzyLessEqual(delay1, delay2); + else + return fuzzyGreaterEqual(delay1, delay2); +} + float delayRatio(const Delay &delay1, const Delay &delay2) @@ -167,18 +126,12 @@ delayAsString(const Delay &delay, float delayAsFloat(const Delay &delay, - const EarlyLate *) + const EarlyLate *, + float ) { return delay; } -float -delaySigma(const Delay &, - const EarlyLate *) -{ - return 0.0; -} - float delaySigma2(const Delay &, const EarlyLate *) diff --git a/graph/DelayFloat.hh b/graph/DelayFloat.hh index 5d5df1d2..1b898b52 100644 --- a/graph/DelayFloat.hh +++ b/graph/DelayFloat.hh @@ -18,6 +18,7 @@ #define STA_DELAY_FLOAT_H #include "MinMax.hh" +#include "Fuzzy.hh" // Delay values defined as floats. @@ -57,10 +58,8 @@ delayAsFloat(const Delay &delay) // mean late+/early- sigma float delayAsFloat(const Delay &delay, - const EarlyLate *early_late); -float -delaySigma(const Delay &delay, - const EarlyLate *early_late); + const EarlyLate *early_late, + float sigma_factor); float delaySigma2(const Delay &delay, const EarlyLate *early_late); @@ -82,38 +81,21 @@ bool delayIsInitValue(const Delay &delay, const MinMax *min_max); bool -delayFuzzyZero(const Delay &delay); +fuzzyGreater(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max); bool -delayFuzzyEqual(const Delay &delay1, - const Delay &delay2); -bool -delayFuzzyLess(const Delay &delay1, - const Delay &delay2); -bool -delayFuzzyLess(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max); -bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2); -bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max); -bool -delayFuzzyGreater(const Delay &delay1, - const Delay &delay2); -bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2); -bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max); -bool -delayFuzzyGreater(const Delay &delay1, +fuzzyGreaterEqual(const Delay &delay1, const Delay &delay2, const MinMax *min_max); +bool +fuzzyLess(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max); +bool +fuzzyLessEqual(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max); float delayRatio(const Delay &delay1, const Delay &delay2); diff --git a/graph/DelayNormal2.cc b/graph/DelayNormal2.cc index b58309c3..ff092c87 100644 --- a/graph/DelayNormal2.cc +++ b/graph/DelayNormal2.cc @@ -238,17 +238,16 @@ delayIsInitValue(const Delay &delay, } bool -delayFuzzyZero(const Delay &delay) +fuzzyZero(const Delay &delay) { return fuzzyZero(delay.mean()) - // && fuzzyZero(delay.sigma2(EarlyLate::early())) && fuzzyZero(delay.sigma2Early()) && fuzzyZero(delay.sigma2Late()); } bool -delayFuzzyEqual(const Delay &delay1, - const Delay &delay2) +fuzzyEqual(const Delay &delay1, + const Delay &delay2) { return fuzzyEqual(delay1.mean(), delay2.mean()) && fuzzyEqual(delay1.sigma2Early(), delay2.sigma2Early()) @@ -256,37 +255,37 @@ delayFuzzyEqual(const Delay &delay1, } bool -delayFuzzyLess(const Delay &delay1, - const Delay &delay2) +fuzzyLess(const Delay &delay1, + const Delay &delay2) { return fuzzyLess(delay1.mean(), delay2.mean()); } bool -delayFuzzyLess(const Delay &delay1, - float delay2) +fuzzyLess(const Delay &delay1, + float delay2) { return fuzzyLess(delay1.mean(), delay2); } bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2) +fuzzyLessEqual(const Delay &delay1, + const Delay &delay2) { return fuzzyLessEqual(delay1.mean(), delay2.mean()); } bool -delayFuzzyLessEqual(const Delay &delay1, +fuzzyLessEqual(const Delay &delay1, float delay2) { return fuzzyLessEqual(delay1.mean(), delay2); } bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max) +fuzzyLessEqual(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max) { if (min_max == MinMax::max()) return fuzzyLessEqual(delay1.mean(), delay2.mean()); @@ -295,37 +294,37 @@ delayFuzzyLessEqual(const Delay &delay1, } bool -delayFuzzyGreater(const Delay &delay1, - const Delay &delay2) +fuzzyGreater(const Delay &delay1, + const Delay &delay2) { return fuzzyGreater(delay1.mean(), delay2.mean()); } bool -delayFuzzyGreater(const Delay &delay1, - float delay2) +fuzzyGreater(const Delay &delay1, + float delay2) { return fuzzyGreater(delay1.mean(), delay2); } bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2) +fuzzyGreaterEqual(const Delay &delay1, + const Delay &delay2) { return fuzzyGreaterEqual(delay1.mean(), delay2.mean()); } bool -delayFuzzyGreaterEqual(const Delay &delay1, - float delay2) +fuzzyGreaterEqual(const Delay &delay1, + float delay2) { return fuzzyGreaterEqual(delay1.mean(), delay2); } bool -delayFuzzyGreater(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max) +fuzzyGreater(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max) { if (min_max == MinMax::max()) return fuzzyGreater(delay1.mean(), delay2.mean()); @@ -334,9 +333,9 @@ delayFuzzyGreater(const Delay &delay1, } bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max) +fuzzyGreaterEqual(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max) { if (min_max == MinMax::max()) return fuzzyGreaterEqual(delay1.mean(), delay2.mean()); @@ -345,9 +344,9 @@ delayFuzzyGreaterEqual(const Delay &delay1, } bool -delayFuzzyLess(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max) +fuzzyLess(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max) { if (min_max == MinMax::max()) return fuzzyLess(delay1.mean(), delay2.mean()); @@ -392,23 +391,17 @@ delayRatio(const Delay &delay1, float delayAsFloat(const Delay &delay, - const EarlyLate *early_late) + const EarlyLate *early_late, + float sigma_factor) { if (early_late == EarlyLate::early()) - return delay.mean() - delay.sigma(early_late); + return delay.mean() - delay.sigma(early_late) * sigma_factor; else if (early_late == EarlyLate::late()) - return delay.mean() + delay.sigma(early_late); + return delay.mean() + delay.sigma(early_late) * sigma_factor; else internalError("unknown early/late value."); } -float -delaySigma(const Delay &delay, - const EarlyLate *early_late) -{ - return delay.sigma(early_late); -} - float delaySigma2(const Delay &delay, const EarlyLate *early_late) @@ -452,7 +445,7 @@ delayAsString(const Delay &delay, const StaState *sta, int digits) { - float mean_sigma = delayAsFloat(delay, early_late); + float mean_sigma = delayAsFloat(delay, early_late, sta->sigmaFactor()); return sta->units()->timeUnit()->asString(mean_sigma, digits); } diff --git a/graph/DelayNormal2.hh b/graph/DelayNormal2.hh index 97ca6762..6773f428 100644 --- a/graph/DelayNormal2.hh +++ b/graph/DelayNormal2.hh @@ -21,8 +21,6 @@ namespace sta { -// Delay values defined as objects that hold a float value. - class Delay; class StaState; @@ -103,10 +101,8 @@ Delay operator*(const Delay &delay1, // mean late+/early- sigma float delayAsFloat(const Delay &delay, - const EarlyLate *early_late); -float -delaySigma(const Delay &delay, - const EarlyLate *early_late); + const EarlyLate *early_late, + float sigma_factor); float delaySigma2(const Delay &delay, const EarlyLate *early_late); @@ -128,38 +124,38 @@ bool delayIsInitValue(const Delay &delay, const MinMax *min_max); bool -delayFuzzyZero(const Delay &delay); +fuzzyZero(const Delay &delay); bool -delayFuzzyEqual(const Delay &delay1, - const Delay &delay2); +fuzzyEqual(const Delay &delay1, + const Delay &delay2); bool -delayFuzzyLess(const Delay &delay1, +fuzzyLess(const Delay &delay1, + const Delay &delay2); +bool +fuzzyLess(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max); +bool +fuzzyLessEqual(const Delay &delay1, const Delay &delay2); bool -delayFuzzyLess(const Delay &delay1, +fuzzyLessEqual(const Delay &delay1, const Delay &delay2, const MinMax *min_max); bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2); +fuzzyGreater(const Delay &delay1, + const Delay &delay2); bool -delayFuzzyLessEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max); -bool -delayFuzzyGreater(const Delay &delay1, +fuzzyGreaterEqual(const Delay &delay1, const Delay &delay2); bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2); -bool -delayFuzzyGreaterEqual(const Delay &delay1, - const Delay &delay2, - const MinMax *min_max); -bool -delayFuzzyGreater(const Delay &delay1, +fuzzyGreaterEqual(const Delay &delay1, const Delay &delay2, const MinMax *min_max); +bool +fuzzyGreater(const Delay &delay1, + const Delay &delay2, + const MinMax *min_max); float delayRatio(const Delay &delay1, const Delay &delay2); diff --git a/graph/Graph.cc b/graph/Graph.cc index 4066f0d3..def24383 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -32,8 +32,6 @@ namespace sta { -const char *bfs_index_names[] = {"dcalc", "arrival", "required", "other"}; - //////////////////////////////////////////////////////////////// // // Graph @@ -45,17 +43,17 @@ Graph::Graph(StaState *sta, bool have_arc_delays, DcalcAPIndex ap_count) : StaState(sta), - vertices_(NULL), - edges_(NULL), + vertices_(nullptr), + edges_(nullptr), vertex_count_(0), edge_count_(0), arc_count_(0), slew_tr_count_(slew_tr_count), have_arc_delays_(have_arc_delays), ap_count_(ap_count), - float_pool_(NULL), - width_check_annotations_(NULL), - period_check_annotations_(NULL) + float_pool_(nullptr), + width_check_annotations_(nullptr), + period_check_annotations_(nullptr) { } @@ -144,7 +142,7 @@ Graph::vertexAndEdgeCounts(const Instance *inst, vertex_count++; if (cell) { LibertyPort *port = network_->libertyPort(pin); - LibertyCellTimingArcSetIterator set_iter(cell, port, NULL); + LibertyCellTimingArcSetIterator set_iter(cell, port, nullptr); while (set_iter.hasNext()) { TimingArcSet *arc_set = set_iter.next(); LibertyPort *to_port = arc_set->to(); @@ -261,7 +259,7 @@ Graph::makeInstanceEdges(const Instance *inst) { LibertyCell *cell = network_->libertyCell(inst); if (cell) - makePortInstanceEdges(inst, cell, NULL); + makePortInstanceEdges(inst, cell, nullptr); } void @@ -287,7 +285,7 @@ Graph::makePortInstanceEdges(const Instance *inst, TimingArcSet *arc_set = timing_iter.next(); LibertyPort *from_port = arc_set->from(); LibertyPort *to_port = arc_set->to(); - if (from_to_port == NULL + if (from_to_port == nullptr || from_port == from_to_port || to_port == from_to_port) { Pin *from_pin = network_->findPin(inst, from_port); @@ -362,9 +360,7 @@ Graph::makeWireEdgesFromPin(Pin *drvr_pin) FindNetDrvrLoads visitor(drvr_pin, visited_drvrs, loads, drvrs, network_); network_->visitConnectedPins(drvr_pin, visitor); - PinSeq::Iterator load_iter(loads); - while (load_iter.hasNext()) { - Pin *load_pin = load_iter.next(); + for (auto load_pin : loads) { if (drvr_pin != load_pin) makeWireEdge(drvr_pin, load_pin); } @@ -380,12 +376,8 @@ Graph::makeWireEdgesFromPin(Pin *drvr_pin, FindNetDrvrLoads visitor(drvr_pin, visited_drvrs, loads, drvrs, network_); network_->visitConnectedPins(drvr_pin, visitor); - PinSeq::Iterator drvr_iter(drvrs); - while (drvr_iter.hasNext()) { - Pin *drvr_pin = drvr_iter.next(); - PinSeq::Iterator load_iter(loads); - while (load_iter.hasNext()) { - Pin *load_pin = load_iter.next(); + for (auto drvr_pin : drvrs) { + for (auto load_pin : loads) { if (drvr_pin != load_pin) makeWireEdge(drvr_pin, load_pin); } @@ -397,9 +389,7 @@ Graph::makeWireEdgesToPin(Pin *to_pin) { PinSet *drvrs = network_->drivers(to_pin); if (drvrs) { - PinSet::Iterator drvr_iter(drvrs); - while (drvr_iter.hasNext()) { - Pin *drvr = drvr_iter.next(); + for (auto drvr : *drvrs) { if (drvr != to_pin) makeWireEdge(drvr, to_pin); } @@ -409,8 +399,7 @@ Graph::makeWireEdgesToPin(Pin *to_pin) class MakeEdgesThruHierPin : public HierPinThruVisitor { public: - MakeEdgesThruHierPin(Graph *graph, - Network *network); + MakeEdgesThruHierPin(Graph *graph); private: DISALLOW_COPY_AND_ASSIGN(MakeEdgesThruHierPin); @@ -418,14 +407,11 @@ private: Pin *load); Graph *graph_; - Network *network_; }; -MakeEdgesThruHierPin::MakeEdgesThruHierPin(Graph *graph, - Network *network) : +MakeEdgesThruHierPin::MakeEdgesThruHierPin(Graph *graph) : HierPinThruVisitor(), - graph_(graph), - network_(network) + graph_(graph) { } @@ -439,7 +425,7 @@ MakeEdgesThruHierPin::visit(Pin *drvr, void Graph::makeWireEdgesThruPin(Pin *hpin) { - MakeEdgesThruHierPin visitor(this, network_); + MakeEdgesThruHierPin visitor(this); visitDrvrLoadsThruHierPin(hpin, network_, &visitor); } @@ -494,7 +480,7 @@ Graph::makePinVertices(Pin *pin, pin_bidirect_drvr_vertex_map_[pin] = bidir_drvr_vertex; } else - bidir_drvr_vertex = NULL; + bidir_drvr_vertex = nullptr; } } @@ -522,7 +508,7 @@ Graph::pinVertices(const Pin *pin, if (network_->direction(pin)->isBidirect()) bidirect_drvr_vertex = pin_bidirect_drvr_vertex_map_.findKey(pin); else - bidirect_drvr_vertex = NULL; + bidirect_drvr_vertex = nullptr; } Vertex * @@ -1017,10 +1003,10 @@ Graph::setWidthCheckAnnotation(const Pin *pin, DcalcAPIndex ap_index, float width) { - if (width_check_annotations_ == NULL) + if (width_check_annotations_ == nullptr) width_check_annotations_ = new WidthCheckAnnotations; float *widths = width_check_annotations_->findKey(pin); - if (widths == NULL) { + if (widths == nullptr) { int width_count = TransRiseFall::index_count * ap_count_; widths = makeFloats(width_count); // Use negative (illegal) width values to indicate unannotated checks. @@ -1043,7 +1029,7 @@ Graph::removeWidthCheckAnnotations() deleteFloats(widths, width_count); } delete width_check_annotations_; - width_check_annotations_ = NULL; + width_check_annotations_ = nullptr; } } @@ -1072,10 +1058,10 @@ Graph::setPeriodCheckAnnotation(const Pin *pin, DcalcAPIndex ap_index, float period) { - if (period_check_annotations_ == NULL) + if (period_check_annotations_ == nullptr) period_check_annotations_ = new PeriodCheckAnnotations; float *periods = period_check_annotations_->findKey(pin); - if (periods == NULL) { + if (periods == nullptr) { periods = makeFloats(ap_count_); // Use negative (illegal) period values to indicate unannotated checks. for (DcalcAPIndex i = 0; i < ap_count_; i++) @@ -1089,13 +1075,12 @@ void Graph::removePeriodCheckAnnotations() { if (period_check_annotations_) { - PeriodCheckAnnotations::Iterator check_iter(period_check_annotations_); - while (check_iter.hasNext()) { - float *periods = check_iter.next(); + for (auto pin_floats : *period_check_annotations_) { + float *periods = pin_floats.second; deleteFloats(periods, ap_count_); } delete period_check_annotations_; - period_check_annotations_ = NULL; + period_check_annotations_ = nullptr; } } @@ -1119,7 +1104,7 @@ Graph::removeDelaySlewAnnotations() float * Graph::makeFloats(ObjectIndex count) { - if (float_pool_ == NULL) + if (float_pool_ == nullptr) float_pool_ = new Pool(100); return float_pool_->makeObjects(count); } @@ -1138,7 +1123,7 @@ Graph::deleteFloats(float *floats, ObjectIndex count) Vertex::Vertex() { - init(NULL, false, false); + init(nullptr, false, false); } void @@ -1151,19 +1136,19 @@ Vertex::init(Pin *pin, is_bidirect_drvr_ = is_bidirect_drvr; in_edges_ = 0; out_edges_ = 0; - arrivals_ = NULL; - prev_paths_ = NULL; + arrivals_ = nullptr; + prev_paths_ = nullptr; has_requireds_ = false; tag_group_index_ = tag_group_index_max; slew_annotated_ = false; - sim_value_ = logic_unknown; + sim_value_ = unsigned(LogicValue::unknown); is_disabled_constraint_ = false; is_gated_clk_enable_ = false; has_checks_ = false; is_check_clk_ = false; is_constrained_ = false; has_downstream_clk_pin_ = false; - color_ = vertex_color_white; + color_ = unsigned(LevelColor::white); level_ = 0; bfs_in_queue_ = 0; crpr_path_pruning_disabled_ = false; @@ -1190,9 +1175,9 @@ Vertex::setLevel(Level level) } void -Vertex::setColor(VertexColor color) +Vertex::setColor(LevelColor color) { - color_ = color; + color_ = unsigned(color); } bool @@ -1282,14 +1267,15 @@ Vertex::simValue() const void Vertex::setSimValue(LogicValue value) { - sim_value_ = value; + sim_value_ = unsigned(value); } bool Vertex::isConstant() const { - return sim_value_ == logic_zero - || sim_value_ == logic_one; + LogicValue value = static_cast(sim_value_); + return value == LogicValue::zero + || value == LogicValue::one; } void @@ -1331,7 +1317,7 @@ Vertex::setHasDownstreamClkPin(bool has_clk_pin) bool Vertex::bfsInQueue(BfsIndex index) const { - return (bfs_in_queue_ >> index) & 1; + return (bfs_in_queue_ >> unsigned(index)) & 1; } void @@ -1339,9 +1325,9 @@ Vertex::setBfsInQueue(BfsIndex index, bool value) { if (value) - bfs_in_queue_ |= 1 << index; + bfs_in_queue_ |= 1 << int(index); else - bfs_in_queue_ &= ~(1 << index); + bfs_in_queue_ &= ~(1 << int(index)); } //////////////////////////////////////////////////////////////// @@ -1352,7 +1338,7 @@ Vertex::setBfsInQueue(BfsIndex index, Edge::Edge() { - init(0, 0, NULL); + init(0, 0, nullptr); } void @@ -1371,7 +1357,7 @@ Edge::init(VertexIndex from, is_bidirect_inst_path_ = false; is_bidirect_net_path_ = false; delay_annotation_is_incremental_ = false; - sim_timing_sense_ = timing_sense_unknown; + sim_timing_sense_ = unsigned(TimingSense::unknown); is_disabled_constraint_ = false; is_disabled_cond_ = false; is_disabled_loop_ = false; @@ -1423,13 +1409,13 @@ Edge::sense() const TimingSense Edge::simTimingSense() const { - return static_cast(sim_timing_sense_); + return static_cast(sim_timing_sense_); } void Edge::setSimTimingSense(TimingSense sense) { - sim_timing_sense_ = sense; + sim_timing_sense_ = unsigned(sense); } bool @@ -1486,9 +1472,9 @@ VertexIterator::VertexIterator(Graph *graph) : network_(graph->network()), top_inst_(network_->topInstance()), inst_iter_(network_->leafInstanceIterator()), - pin_iter_(NULL), - vertex_(NULL), - bidir_vertex_(NULL) + pin_iter_(nullptr), + vertex_(nullptr), + bidir_vertex_(nullptr) { if (inst_iter_) findNext(); @@ -1497,16 +1483,16 @@ VertexIterator::VertexIterator(Graph *graph) : Vertex * VertexIterator::next() { - Vertex *next = NULL; + Vertex *next = nullptr; if (vertex_) { next = vertex_; - vertex_ = NULL; + vertex_ = nullptr; } else if (bidir_vertex_) { next = bidir_vertex_; - bidir_vertex_ = NULL; + bidir_vertex_ = nullptr; } - if (bidir_vertex_ == NULL) + if (bidir_vertex_ == nullptr) findNext(); return next; } @@ -1519,12 +1505,12 @@ VertexIterator::findNextPin() vertex_ = graph_->vertex(network_->vertexIndex(pin)); bidir_vertex_ = network_->direction(pin)->isBidirect() ? graph_->pin_bidirect_drvr_vertex_map_.findKey(pin) - : NULL; + : nullptr; if (vertex_ || bidir_vertex_) return true; } delete pin_iter_; - pin_iter_ = NULL; + pin_iter_ = nullptr; return false; } @@ -1541,10 +1527,10 @@ VertexIterator::findNext() pin_iter_ = network_->pinIterator(inst); } else { delete inst_iter_; - inst_iter_ = NULL; + inst_iter_ = nullptr; if (top_inst_) { pin_iter_ = network_->pinIterator(top_inst_); - top_inst_ = NULL; + top_inst_ = nullptr; } } } diff --git a/graph/Graph.hh b/graph/Graph.hh index 68176e62..393fcc6b 100644 --- a/graph/Graph.hh +++ b/graph/Graph.hh @@ -34,11 +34,7 @@ class MinMax; class Sdc; class PathVertexRep; -enum VertexColor { - vertex_color_white, - vertex_color_gray, - vertex_color_black -}; +enum class LevelColor { white, gray, black }; typedef Pool DelayPool; typedef Pool VertexPool; @@ -271,8 +267,8 @@ public: Level level() const { return level_; } void setLevel(Level level); bool isRoot() const{ return level_ == 0; } - VertexColor color() const { return (VertexColor) color_; } - void setColor(VertexColor color); + LevelColor color() const { return static_cast(color_); } + void setColor(LevelColor color); Arrival *arrivals() const { return arrivals_; } void setArrivals(Arrival *arrivals); PathVertexRep *prevPaths() const { return prev_paths_; } @@ -337,14 +333,16 @@ protected: // 4 bytes unsigned int tag_group_index_:tag_group_index_bits; // 24 // Each bit corresponds to a different BFS queue. - unsigned int bfs_in_queue_:bfs_index_bits; // 4 + unsigned int bfs_in_queue_:int(BfsIndex::bits); // 4 unsigned int slew_annotated_:slew_annotated_bits; // 4 bytes (32 bits) unsigned int level_:16; // Levelization search state. - unsigned int color_:2; - unsigned int sim_value_:3; // LogicValue + // LevelColor gcc barfs if this is dcl'd. + unsigned color_:2; + // LogicValue gcc barfs if this is dcl'd. + unsigned sim_value_:3; bool has_requireds_:1; // Bidirect pins have two vertices. // This flag distinguishes the driver and load vertices. @@ -418,14 +416,14 @@ protected: VertexIndex vertex_out_next_; // Vertex out edges doubly linked list. VertexIndex vertex_out_prev_; ArcIndex arc_delays_; - unsigned int delay_annotation_is_incremental_:1; - unsigned int is_bidirect_inst_path_:1; - unsigned int is_bidirect_net_path_:1; + bool delay_annotation_is_incremental_:1; + bool is_bidirect_inst_path_:1; + bool is_bidirect_net_path_:1; // Timing sense from function and constants on edge instance. - unsigned int sim_timing_sense_:timing_sense_bit_count; - unsigned int is_disabled_constraint_:1; - unsigned int is_disabled_cond_:1; - unsigned int is_disabled_loop_:1; + unsigned sim_timing_sense_:timing_sense_bit_count; + bool is_disabled_constraint_:1; + bool is_disabled_cond_:1; + bool is_disabled_loop_:1; private: DISALLOW_COPY_AND_ASSIGN(Edge); @@ -468,7 +466,7 @@ public: const Graph *graph); VertexInEdgeIterator(VertexIndex vertex_index, const Graph *graph); - bool hasNext() { return (next_ != NULL); } + bool hasNext() { return (next_ != nullptr); } Edge *next(); private: @@ -483,7 +481,7 @@ class VertexOutEdgeIterator : public VertexEdgeIterator public: VertexOutEdgeIterator(Vertex *vertex, const Graph *graph); - bool hasNext() { return (next_ != NULL); } + bool hasNext() { return (next_ != nullptr); } Edge *next(); private: diff --git a/graph/GraphClass.hh b/graph/GraphClass.hh index d5f03d72..17285e24 100644 --- a/graph/GraphClass.hh +++ b/graph/GraphClass.hh @@ -51,15 +51,8 @@ static const int tag_group_index_bits = 24; static const TagGroupIndex tag_group_index_max = (1<(arc->model()); if (model) { - float drive = model->driveResistance(cell, NULL); + float drive = model->driveResistance(cell, nullptr); if (drive > max_drive) max_drive = drive; } @@ -217,8 +217,8 @@ hashCellSequentials(const LibertyCell *cell) hash += hashPort(seq->outputInv()) * 9; hash += hashFuncExpr(seq->clear()) * 11; hash += hashFuncExpr(seq->preset()) * 13; - hash += seq->clearPresetOutput() * 17; - hash += seq->clearPresetOutputInv() * 19; + hash += int(seq->clearPresetOutput()) * 17; + hash += int(seq->clearPresetOutputInv()) * 19; } return hash; } @@ -226,7 +226,7 @@ hashCellSequentials(const LibertyCell *cell) static unsigned hashFuncExpr(const FuncExpr *expr) { - if (expr == NULL) + if (expr == nullptr) return 0; else { switch (expr->op()) { diff --git a/liberty/FuncExpr.cc b/liberty/FuncExpr.cc index 9da0122a..76d7e368 100644 --- a/liberty/FuncExpr.cc +++ b/liberty/FuncExpr.cc @@ -25,13 +25,13 @@ namespace sta { FuncExpr * FuncExpr::makePort(LibertyPort *port) { - return new FuncExpr(op_port, NULL, NULL, port); + return new FuncExpr(op_port, nullptr, nullptr, port); } FuncExpr * FuncExpr::makeNot(FuncExpr *expr) { - return new FuncExpr(op_not, expr, NULL, NULL); + return new FuncExpr(op_not, expr, nullptr, nullptr); } @@ -39,33 +39,33 @@ FuncExpr * FuncExpr::makeAnd(FuncExpr *left, FuncExpr *right) { - return new FuncExpr(op_and, left, right, NULL); + return new FuncExpr(op_and, left, right, nullptr); } FuncExpr * FuncExpr::makeOr(FuncExpr *left, FuncExpr *right) { - return new FuncExpr(op_or, left, right, NULL); + return new FuncExpr(op_or, left, right, nullptr); } FuncExpr * FuncExpr::makeXor(FuncExpr *left, FuncExpr *right) { - return new FuncExpr(op_xor, left, right, NULL); + return new FuncExpr(op_xor, left, right, nullptr); } FuncExpr * FuncExpr::makeZero() { - return new FuncExpr(op_zero, NULL, NULL, NULL); + return new FuncExpr(op_zero, nullptr, nullptr, nullptr); } FuncExpr * FuncExpr::makeOne() { - return new FuncExpr(op_one, NULL, NULL, NULL); + return new FuncExpr(op_one, nullptr, nullptr, nullptr); } FuncExpr::FuncExpr(Operator op, @@ -95,7 +95,7 @@ FuncExpr::port() const if (op_ == op_port) return port_; else - return NULL; + return nullptr; } // Protect against null sub-expressions caused by unknown port refs. @@ -107,29 +107,29 @@ FuncExpr::portTimingSense(const LibertyPort *port) const switch (op_) { case op_port: if (port == port_) - return timing_sense_positive_unate; + return TimingSense::positive_unate; else - return timing_sense_none; + return TimingSense::none; case op_not: if (left_) { switch (left_->portTimingSense(port)) { - case timing_sense_positive_unate: - return timing_sense_negative_unate; - case timing_sense_negative_unate: - return timing_sense_positive_unate; - case timing_sense_non_unate: - return timing_sense_non_unate; - case timing_sense_none: - return timing_sense_none; - case timing_sense_unknown: - return timing_sense_unknown; + case TimingSense::positive_unate: + return TimingSense::negative_unate; + case TimingSense::negative_unate: + return TimingSense::positive_unate; + case TimingSense::non_unate: + return TimingSense::non_unate; + case TimingSense::none: + return TimingSense::none; + case TimingSense::unknown: + return TimingSense::unknown; } } - return timing_sense_unknown; + return TimingSense::unknown; case op_or: case op_and: - left_sense = timing_sense_unknown; - right_sense = timing_sense_unknown; + left_sense = TimingSense::unknown; + right_sense = TimingSense::unknown; if (left_) left_sense = left_->portTimingSense(port); if (right_) @@ -137,44 +137,44 @@ FuncExpr::portTimingSense(const LibertyPort *port) const if (left_sense == right_sense) return left_sense; - else if (left_sense == timing_sense_non_unate - || right_sense == timing_sense_non_unate - || (left_sense == timing_sense_positive_unate - && right_sense == timing_sense_negative_unate) - || (left_sense == timing_sense_negative_unate - && right_sense == timing_sense_positive_unate)) - return timing_sense_non_unate; - else if (left_sense == timing_sense_none - || left_sense == timing_sense_unknown) + else if (left_sense == TimingSense::non_unate + || right_sense == TimingSense::non_unate + || (left_sense == TimingSense::positive_unate + && right_sense == TimingSense::negative_unate) + || (left_sense == TimingSense::negative_unate + && right_sense == TimingSense::positive_unate)) + return TimingSense::non_unate; + else if (left_sense == TimingSense::none + || left_sense == TimingSense::unknown) return right_sense; - else if (right_sense == timing_sense_none - || right_sense == timing_sense_unknown) + else if (right_sense == TimingSense::none + || right_sense == TimingSense::unknown) return left_sense; else - return timing_sense_unknown; + return TimingSense::unknown; case op_xor: - left_sense = timing_sense_unknown; - right_sense = timing_sense_unknown; + left_sense = TimingSense::unknown; + right_sense = TimingSense::unknown; if (left_) left_sense = left_->portTimingSense(port); if (right_) right_sense = right_->portTimingSense(port); - if (left_sense == timing_sense_positive_unate - || left_sense == timing_sense_negative_unate - || left_sense == timing_sense_non_unate - || right_sense == timing_sense_positive_unate - || right_sense == timing_sense_negative_unate - || right_sense == timing_sense_non_unate) - return timing_sense_non_unate; + if (left_sense == TimingSense::positive_unate + || left_sense == TimingSense::negative_unate + || left_sense == TimingSense::non_unate + || right_sense == TimingSense::positive_unate + || right_sense == TimingSense::negative_unate + || right_sense == TimingSense::non_unate) + return TimingSense::non_unate; else - return timing_sense_unknown; + return TimingSense::unknown; case op_one: - return timing_sense_none; + return TimingSense::none; case op_zero: - return timing_sense_none; + return TimingSense::none; } // Prevent warnings from lame compilers. - return timing_sense_unknown; + return TimingSense::unknown; } const char * @@ -270,7 +270,7 @@ FuncExpr::bitSubExpr(int bit_offset) return this; } // Prevent warnings from lame compilers. - return NULL; + return nullptr; } bool @@ -360,9 +360,9 @@ bool FuncExpr::equiv(const FuncExpr *expr1, const FuncExpr *expr2) { - if (expr1 == NULL && expr2 == NULL) + if (expr1 == nullptr && expr2 == nullptr) return true; - else if (expr1 != NULL && expr2 != NULL + else if (expr1 != nullptr && expr2 != nullptr && expr1->op() == expr2->op()) { switch (expr1->op()) { case FuncExpr::op_port: @@ -382,7 +382,7 @@ bool FuncExpr::less(const FuncExpr *expr1, const FuncExpr *expr2) { - if (expr1 != NULL && expr2 != NULL) { + if (expr1 != nullptr && expr2 != nullptr) { Operator op1 = expr1->op(); Operator op2 = expr2->op(); if (op1 == op2) { @@ -401,10 +401,10 @@ FuncExpr::less(const FuncExpr *expr1, else return op1 < op2; } - else if (expr1 == NULL && expr2 == NULL) + else if (expr1 == nullptr && expr2 == nullptr) return false; else - return (expr1 == NULL && expr2 != NULL); + return (expr1 == nullptr && expr2 != nullptr); } } // namespace diff --git a/liberty/FuncExpr.hh b/liberty/FuncExpr.hh index 15659056..a605910c 100644 --- a/liberty/FuncExpr.hh +++ b/liberty/FuncExpr.hh @@ -58,7 +58,7 @@ public: Operator op() const { return op_; } // When operator is NOT left is the only operand. FuncExpr *left() const { return left_; } - // NULL when op == op_not + // nullptr when op == op_not FuncExpr *right() const { return right_; } TimingSense portTimingSense(const LibertyPort *port) const; // Return true if expression has port as an input. diff --git a/liberty/InternalPower.cc b/liberty/InternalPower.cc index 19207e31..49eb6adb 100644 --- a/liberty/InternalPower.cc +++ b/liberty/InternalPower.cc @@ -23,9 +23,9 @@ namespace sta { InternalPowerAttrs::InternalPowerAttrs() : - when_(NULL), - models_{NULL, NULL}, - related_pg_pin_(NULL) + when_(nullptr), + models_{nullptr, nullptr}, + related_pg_pin_(nullptr) { } @@ -157,7 +157,7 @@ InternalPowerModel::reportPower(const LibertyCell *cell, axis_value1, axis_value2, axis_value3); const LibertyLibrary *library = cell->libertyLibrary(); model_->reportValue("Power", library, cell, pvt, - axis_value1, NULL, axis_value2, axis_value3, digits, result); + axis_value1, nullptr, axis_value2, axis_value3, digits, result); } } @@ -201,9 +201,9 @@ InternalPowerModel::axisValue(TableAxis *axis, float load_cap) const { TableAxisVariable var = axis->variable(); - if (var == table_axis_input_transition_time) + if (var == TableAxisVariable::input_transition_time) return in_slew; - else if (var == table_axis_total_output_net_capacitance) + else if (var == TableAxisVariable::total_output_net_capacitance) return load_cap; else { internalError("unsupported table axes"); @@ -222,7 +222,7 @@ InternalPowerModel::checkAxes(const TableModel *model) axis_ok &= checkAxis(model->axis1()); if (axis2) axis_ok &= checkAxis(model->axis2()); - axis_ok &= (axis3 == NULL); + axis_ok &= (axis3 == nullptr); return axis_ok; } @@ -230,9 +230,9 @@ bool InternalPowerModel::checkAxis(TableAxis *axis) { TableAxisVariable var = axis->variable(); - return var == table_axis_constrained_pin_transition - || var == table_axis_related_pin_transition - || var == table_axis_related_out_total_output_net_capacitance; + return var == TableAxisVariable::constrained_pin_transition + || var == TableAxisVariable::related_pin_transition + || var == TableAxisVariable::related_out_total_output_net_capacitance; } } // namespace diff --git a/liberty/LeakagePower.cc b/liberty/LeakagePower.cc index e6fb84e3..25be739e 100644 --- a/liberty/LeakagePower.cc +++ b/liberty/LeakagePower.cc @@ -23,7 +23,7 @@ namespace sta { LeakagePowerAttrs::LeakagePowerAttrs() : - when_(NULL), + when_(nullptr), power_(0.0) { } diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 8f9629ca..72df1e4d 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -16,6 +16,7 @@ #include "Machine.hh" #include "DisallowCopyAssign.hh" +#include "EnumNameMap.hh" #include "Report.hh" #include "Debug.hh" #include "Error.hh" @@ -44,29 +45,16 @@ typedef Set FuncExprSet; typedef Set LatchEnableSet; bool LibertyLibrary::found_rise_fall_caps_ = false; -const float LibertyLibrary::input_threshold_default_ = .5F; -const float LibertyLibrary::output_threshold_default_ = .5F; -const float LibertyLibrary::slew_lower_threshold_default_ = .2F; -const float LibertyLibrary::slew_upper_threshold_default_ = .8F; - -void -makeScaleFactorTypeMap(); -void -deleteScaleFactorTypeMap(); void initLiberty() { - makeTimingTypeMap(); - makeScaleFactorTypeMap(); TimingArcSet::init(); } void deleteLiberty() { - deleteTimingTypeMap(); - deleteScaleFactorTypeMap(); TimingArcSet::destroy(); } @@ -74,11 +62,11 @@ LibertyLibrary::LibertyLibrary(const char *name, const char *filename) : ConcreteLibrary(name, filename), units_(new Units()), - delay_model_type_(delay_model_cmos_linear), // default + delay_model_type_(DelayModelType::cmos_linear), // default nominal_process_(0.0), nominal_voltage_(0.0), nominal_temperature_(0.0), - scale_factors_(NULL), + scale_factors_(nullptr), default_input_pin_cap_(0.0), default_output_pin_cap_(0.0), default_bidirect_pin_cap_(0.0), @@ -90,18 +78,18 @@ LibertyLibrary::LibertyLibrary(const char *name, default_max_slew_(0.0), default_max_slew_exists_(false), slew_derate_from_library_(1.0), - default_wire_load_(NULL), - default_wire_load_mode_(wire_load_mode_unknown), - default_wire_load_selection_(NULL), - default_operating_conditions_(NULL), - equiv_cell_map_(NULL), + default_wire_load_(nullptr), + default_wire_load_mode_(WireloadMode::unknown), + default_wire_load_selection_(nullptr), + default_operating_conditions_(nullptr), + equiv_cell_map_(nullptr), ocv_arc_depth_(0.0), - default_ocv_derate_(NULL) + default_ocv_derate_(nullptr) { // Scalar templates are builtin. - for (int i = 0; i != table_template_count; i++) { + for (int i = 0; i != int(TableTemplateType::count); i++) { TableTemplateType type = static_cast(i); - TableTemplate *scalar_template = new TableTemplate("scalar", NULL, NULL, NULL); + TableTemplate *scalar_template = new TableTemplate("scalar", nullptr, nullptr, nullptr); addTableTemplate(scalar_template, type); } @@ -109,7 +97,7 @@ LibertyLibrary::LibertyLibrary(const char *name, while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); int tr_index = tr->index(); - wire_slew_degradation_tbls_[tr_index] = NULL; + wire_slew_degradation_tbls_[tr_index] = nullptr; input_threshold_[tr_index] = input_threshold_default_; output_threshold_[tr_index] = output_threshold_default_; slew_lower_threshold_[tr_index] = slew_lower_threshold_default_; @@ -120,7 +108,7 @@ LibertyLibrary::LibertyLibrary(const char *name, LibertyLibrary::~LibertyLibrary() { bus_dcls_.deleteContents(); - for (int i = 0; i < table_template_count; i++) + for (int i = 0; i < int(TableTemplateType::count); i++) template_maps_[i].deleteContents(); scale_factors_map_.deleteContents(); delete scale_factors_; @@ -189,14 +177,14 @@ void LibertyLibrary::addTableTemplate(TableTemplate *tbl_template, TableTemplateType type) { - template_maps_[type][tbl_template->name()] = tbl_template; + template_maps_[int(type)][tbl_template->name()] = tbl_template; } TableTemplate * LibertyLibrary::findTableTemplate(const char *name, TableTemplateType type) { - return template_maps_[type][name]; + return template_maps_[int(type)][name]; } void @@ -239,7 +227,7 @@ float LibertyLibrary::scaleFactor(ScaleFactorType type, const Pvt *pvt) const { - return scaleFactor(type, 0, NULL, pvt); + return scaleFactor(type, 0, nullptr, pvt); } float @@ -256,24 +244,24 @@ LibertyLibrary::scaleFactor(ScaleFactorType type, const LibertyCell *cell, const Pvt *pvt) const { - if (pvt == NULL) + if (pvt == nullptr) pvt = default_operating_conditions_; // If there is no operating condition, nominal pvt values are used. // All scale factors are unity for nominal pvt. if (pvt) { - ScaleFactors *scale_factors = NULL; + ScaleFactors *scale_factors = nullptr; // Cell level scale factors have precidence over library scale factors. if (cell) scale_factors = cell->scaleFactors(); - if (scale_factors == NULL) + if (scale_factors == nullptr) scale_factors = scale_factors_; if (scale_factors) { float process_scale = 1.0F + (pvt->process() - nominal_process_) - * scale_factors->scale(type, scale_factor_process, tr_index); + * scale_factors->scale(type, ScaleFactorPvt::process, tr_index); float temp_scale = 1.0F + (pvt->temperature() - nominal_temperature_) - * scale_factors->scale(type, scale_factor_temp, tr_index); + * scale_factors->scale(type, ScaleFactorPvt::temp, tr_index); float volt_scale = 1.0F + (pvt->voltage() - nominal_voltage_) - * scale_factors->scale(type, scale_factor_volt, tr_index); + * scale_factors->scale(type, ScaleFactorPvt::volt, tr_index); float scale = process_scale * temp_scale * volt_scale; return scale; } @@ -324,9 +312,9 @@ LibertyLibrary::degradeWireSlew(const LibertyCell *cell, case 1: { TableAxis *axis1 = model->axis1(); TableAxisVariable var1 = axis1->variable(); - if (var1 == table_axis_output_pin_transition) + if (var1 == TableAxisVariable::output_pin_transition) return model->findValue(this, cell, pvt, in_slew, 0.0, 0.0); - else if (var1 == table_axis_connect_delay) + else if (var1 == TableAxisVariable::connect_delay) return model->findValue(this, cell, pvt, wire_delay, 0.0, 0.0); else { internalError("unsupported slew degradation table axes"); @@ -338,11 +326,11 @@ LibertyLibrary::degradeWireSlew(const LibertyCell *cell, TableAxis *axis2 = model->axis2(); TableAxisVariable var1 = axis1->variable(); TableAxisVariable var2 = axis2->variable(); - if (var1 == table_axis_output_pin_transition - && var2 == table_axis_connect_delay) + if (var1 == TableAxisVariable::output_pin_transition + && var2 == TableAxisVariable::connect_delay) return model->findValue(this, cell, pvt, in_slew, wire_delay, 0.0); - else if (var1 == table_axis_connect_delay - && var2 == table_axis_output_pin_transition) + else if (var1 == TableAxisVariable::connect_delay + && var2 == TableAxisVariable::output_pin_transition) return model->findValue(this, cell, pvt, wire_delay, in_slew, 0.0); else { internalError("unsupported slew degradation table axes"); @@ -366,18 +354,18 @@ LibertyLibrary::checkSlewDegradationAxes(Table *table) case 1: { TableAxis *axis1 = table->axis1(); TableAxisVariable var1 = axis1->variable(); - return var1 == table_axis_output_pin_transition - || var1 == table_axis_connect_delay; + return var1 == TableAxisVariable::output_pin_transition + || var1 == TableAxisVariable::connect_delay; } case 2: { TableAxis *axis1 = table->axis1(); TableAxis *axis2 = table->axis2(); TableAxisVariable var1 = axis1->variable(); TableAxisVariable var2 = axis2->variable(); - return (var1 == table_axis_output_pin_transition - && var2 == table_axis_connect_delay) - || (var1 == table_axis_connect_delay - && var2 == table_axis_output_pin_transition); + return (var1 == TableAxisVariable::output_pin_transition + && var2 == TableAxisVariable::connect_delay) + || (var1 == TableAxisVariable::connect_delay + && var2 == TableAxisVariable::output_pin_transition); } default: internalError("unsupported slew degradation table axes"); @@ -518,7 +506,7 @@ LibertyLibrary::setDefaultOutputPinRes(const TransRiseFall *tr, LibertyCellSeq * LibertyLibrary::findEquivCells(LibertyCell *cell) { - if (equiv_cell_map_ == NULL) + if (equiv_cell_map_ == nullptr) equiv_cell_map_ = makeEquivCellMap(this); LibertyCellSeq *equivs = equiv_cell_map_->findKey(cell); return equivs; @@ -777,13 +765,13 @@ LibertyLibrary::addSupplyVoltage(const char *supply_name, supply_voltage_map_[stringCopy(supply_name)] = voltage; } -float -LibertyLibrary::supplyVoltage(const char *supply_name) const +void +LibertyLibrary::supplyVoltage(const char *supply_name, + // Return value. + float &voltage, + bool &exists) const { - float voltage; - bool exists; supply_voltage_map_.findKey(supply_name, voltage, exists); - return voltage; } bool @@ -825,22 +813,22 @@ LibertyCell::LibertyCell(LibertyLibrary *library, is_pad_(false), has_internal_ports_(false), interface_timing_(false), - clock_gate_type_(clock_gate_none), - timing_arc_sets_(NULL), - port_timing_arc_set_map_(NULL), - timing_arc_set_from_map_(NULL), - timing_arc_set_to_map_(NULL), + clock_gate_type_(ClockGateType::none), + timing_arc_sets_(nullptr), + port_timing_arc_set_map_(nullptr), + timing_arc_set_from_map_(nullptr), + timing_arc_set_to_map_(nullptr), has_infered_reg_timing_arcs_(false), - internal_powers_(NULL), - leakage_powers_(NULL), - sequentials_(NULL), - port_to_seq_map_(NULL), - mode_defs_(NULL), - scale_factors_(NULL), - scaled_cells_(NULL), - test_cell_(NULL), + internal_powers_(nullptr), + leakage_powers_(nullptr), + sequentials_(nullptr), + port_to_seq_map_(nullptr), + mode_defs_(nullptr), + scale_factors_(nullptr), + scaled_cells_(nullptr), + test_cell_(nullptr), ocv_arc_depth_(0.0), - ocv_derate_(NULL), + ocv_derate_(nullptr), is_disabled_constraint_(false), leakage_power_(0.0) { @@ -971,7 +959,7 @@ ModeDef * LibertyCell::makeModeDef(const char *name) { ModeDef *mode = new ModeDef(name); - if (mode_defs_ == NULL) + if (mode_defs_ == nullptr) mode_defs_ = new ModeDefMap; (*mode_defs_)[mode->name()] = mode; return mode; @@ -1034,37 +1022,37 @@ LibertyCell::setInterfaceTiming(bool value) bool LibertyCell::isClockGateLatchPosedge() const { - return clock_gate_type_ == clock_gate_latch_posedge; + return clock_gate_type_ == ClockGateType::latch_posedge; } bool LibertyCell::isClockGateLatchNegedge() const { - return clock_gate_type_ == clock_gate_latch_posedge; + return clock_gate_type_ == ClockGateType::latch_posedge; } bool LibertyCell::isClockGateOther() const { - return clock_gate_type_ == clock_gate_other; + return clock_gate_type_ == ClockGateType::other; } bool LibertyCell::isClockGate() const { - return clock_gate_type_ != clock_gate_none; + return clock_gate_type_ != ClockGateType::none; } void -LibertyCell::setClockGateType(ClockGateType clock_gate_type) +LibertyCell::setClockGateType(ClockGateType type) { - clock_gate_type_ = clock_gate_type; + clock_gate_type_ = type; } unsigned LibertyCell::addTimingArcSet(TimingArcSet *arc_set) { - if (timing_arc_sets_ == NULL) { + if (timing_arc_sets_ == nullptr) { timing_arc_sets_ = new TimingArcSetSeq; timing_arc_set_map_ = new TimingArcSetMap; port_timing_arc_set_map_ = new LibertyPortPairTimingArcMap; @@ -1088,7 +1076,7 @@ LibertyCell::addTimingArcSet(TimingArcSet *arc_set) LibertyPortPair port_pair(from, to); TimingArcSetSeq *sets = port_timing_arc_set_map_->findKey(&port_pair); - if (sets == NULL) { + if (sets == nullptr) { // First arc set for from/to ports. sets = new TimingArcSetSeq; LibertyPortPair *port_pair1 = new LibertyPortPair(from, to); @@ -1097,14 +1085,14 @@ LibertyCell::addTimingArcSet(TimingArcSet *arc_set) sets->push_back(arc_set); sets = timing_arc_set_from_map_->findKey(from); - if (sets == NULL) { + if (sets == nullptr) { sets = new TimingArcSetSeq; (*timing_arc_set_from_map_)[from] = sets; } sets->push_back(arc_set); sets = timing_arc_set_to_map_->findKey(to); - if (sets == NULL) { + if (sets == nullptr) { sets = new TimingArcSetSeq; (*timing_arc_set_to_map_)[to] = sets; } @@ -1121,7 +1109,7 @@ LibertyCell::addTimingArcAttrs(TimingArcAttrs *attrs) void LibertyCell::addInternalPower(InternalPower *power) { - if (internal_powers_ == NULL) + if (internal_powers_ == nullptr) internal_powers_ = new InternalPowerSeq; internal_powers_->push_back(power); } @@ -1147,7 +1135,7 @@ LibertyCell::deleteInternalPowerAttrs() void LibertyCell::addLeakagePower(LeakagePower *power) { - if (leakage_powers_ == NULL) + if (leakage_powers_ == nullptr) leakage_powers_ = new LeakagePowerSeq; leakage_powers_->push_back(power); } @@ -1241,7 +1229,7 @@ LibertyCell::timingArcSets(const LibertyPort *from, else if (to) return timing_arc_set_to_map_->findKey(to); } - return NULL; + return nullptr; } TimingArcSet * @@ -1250,7 +1238,7 @@ LibertyCell::findTimingArcSet(TimingArcSet *key) const if (timing_arc_sets_) return timing_arc_set_map_->findKey(key); else - return NULL; + return nullptr; } TimingArcSet * @@ -1289,16 +1277,16 @@ LibertyCell::makeSequential(int size, LibertyPort *output_inv) { for (int bit = 0; bit < size; bit++) { - FuncExpr *clk_bit = NULL; + FuncExpr *clk_bit = nullptr; if (clk) clk_bit = clk->bitSubExpr(bit); - FuncExpr *data_bit = NULL; + FuncExpr *data_bit = nullptr; if (data) data_bit = data->bitSubExpr(bit); - FuncExpr *clear_bit = NULL; + FuncExpr *clear_bit = nullptr; if (clear) clear_bit = clear->bitSubExpr(bit); - FuncExpr *preset_bit = NULL; + FuncExpr *preset_bit = nullptr; if (preset) preset_bit = preset->bitSubExpr(bit); LibertyPort *out_bit = output; @@ -1311,7 +1299,7 @@ LibertyCell::makeSequential(int size, clear_bit,preset_bit, clr_preset_out, clr_preset_out_inv, out_bit, out_inv_bit); - if (sequentials_ == NULL) { + if (sequentials_ == nullptr) { sequentials_ = new SequentialSeq; port_to_seq_map_ = new PortToSequentialMap; } @@ -1327,7 +1315,7 @@ LibertyCell::outputPortSequential(LibertyPort *port) if (port_to_seq_map_) return port_to_seq_map_->findKey(port); else - return NULL; + return nullptr; } bool @@ -1340,7 +1328,7 @@ void LibertyCell::addScaledCell(OperatingConditions *op_cond, LibertyCell *scaled_cell) { - if (scaled_cells_ == NULL) + if (scaled_cells_ == nullptr) scaled_cells_ = new ScaledCellMap; (*scaled_cells_)[op_cond] = scaled_cell; @@ -1402,7 +1390,7 @@ LibertyCell::cornerCell(int ap_index) if (ap_index < static_cast(corner_cells_.size())) return corner_cells_[ap_index]; else - return NULL; + return nullptr; } void @@ -1539,7 +1527,7 @@ LibertyCell::makeLatchEnables(Report *report, if (en_to_q->role() == TimingRole::latchEnToQ()) { LibertyPort *en = en_to_q->from(); LibertyPort *q = en_to_q->to(); - LibertyCellTimingArcSetIterator to_iter(this, NULL, q); + LibertyCellTimingArcSetIterator to_iter(this, nullptr, q); while (to_iter.hasNext()) { TimingArcSet *d_to_q = to_iter.next(); if (d_to_q->role() == TimingRole::latchDtoQ()) { @@ -1571,7 +1559,7 @@ LibertyCell::makeLatchEnables(Report *report, FuncExpr *en_func = latch_enable->enableFunc(); if (en_func) { TimingSense en_sense = en_func->portTimingSense(en); - if (en_sense == timing_sense_positive_unate + if (en_sense == TimingSense::positive_unate && en_tr != TransRiseFall::rise()) report->warn("%s, cell %s latch enable %s -> %s %s_edge is inconsistent with latch group enable function positive sense.\n", filename_, @@ -1579,7 +1567,7 @@ LibertyCell::makeLatchEnables(Report *report, en->name(), q->name(), en_tr == TransRiseFall::rise()?"rising":"falling"); - else if (en_sense == timing_sense_negative_unate + else if (en_sense == TimingSense::negative_unate && en_tr != TransRiseFall::fall()) report->warn("%s, cell %s latch enable %s -> %s %s_edge is inconsistent with latch group enable function negative sense.\n", filename_, @@ -1613,7 +1601,7 @@ LibertyCell::findLatchEnableFunc(LibertyPort *data, && seq->clock()->hasPort(enable)) return seq->clock(); } - return NULL; + return nullptr; } LatchEnable * @@ -1653,15 +1641,15 @@ LibertyCell::inferLatchRoles(Debug *debug) if (en_to_q->role() == TimingRole::regClkToQ()) { LibertyPort *en = en_to_q->from(); LibertyPort *q = en_to_q->to(); - LibertyCellTimingArcSetIterator to_iter(this, NULL, q); + LibertyCellTimingArcSetIterator to_iter(this, nullptr, q); while (to_iter.hasNext()) { TimingArcSet *d_to_q = to_iter.next(); // Look for combinational d->q arcs. TimingRole *d_to_q_role = d_to_q->role(); if ((d_to_q_role == TimingRole::combinational() && ((d_to_q->arcCount() == 2 - && (d_to_q->sense() == timing_sense_positive_unate - || d_to_q->sense() == timing_sense_negative_unate)) + && (d_to_q->sense() == TimingSense::positive_unate + || d_to_q->sense() == TimingSense::negative_unate)) || (d_to_q->arcCount() == 4))) // Previously identified as D->Q arc. || d_to_q_role == TimingRole::latchDtoQ()) { @@ -1696,7 +1684,7 @@ LibertyCell::latchEnable(TimingArcSet *d_to_q_set, FuncExpr *&enable_func, TransRiseFall *&enable_tr) const { - enable_port = NULL; + enable_port = nullptr; LatchEnable *latch_enable = latch_d_to_q_map_.findKey(d_to_q_set); if (latch_enable) { enable_port = latch_enable->enable(); @@ -1712,7 +1700,7 @@ LibertyCell::latchCheckEnableTrans(TimingArcSet *check_set) if (latch_enable) return latch_enable->enableTransition(); else - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -1769,14 +1757,14 @@ LibertyPort::LibertyPort(LibertyCell *cell, ConcretePortSeq *members) : ConcretePort(cell, name, is_bus, from_index, to_index, is_bundle, members), liberty_cell_(cell), - function_(NULL), - tristate_enable_(NULL), - scaled_ports_(NULL), + function_(nullptr), + tristate_enable_(nullptr), + scaled_ports_(nullptr), min_period_(0.0), - pulse_clk_trigger_(NULL), - pulse_clk_sense_(NULL), - related_ground_pin_(NULL), - related_power_pin_(NULL), + pulse_clk_trigger_(nullptr), + pulse_clk_sense_(nullptr), + related_ground_pin_(nullptr), + related_power_pin_(nullptr), min_pulse_width_exists_(false), min_period_exists_(false), is_clk_(false), @@ -1885,7 +1873,7 @@ LibertyPort::capacitance(const TransRiseFall *tr, } LibertyLibrary *lib = liberty_cell_->libertyLibrary(); float cap = capacitance(tr, min_max); - return cap * lib->scaleFactor(scale_factor_pin_cap, liberty_cell_, pvt); + return cap * lib->scaleFactor(ScaleFactorType::pin_cap, liberty_cell_, pvt); } void @@ -1897,7 +1885,7 @@ LibertyPort::setFunction(FuncExpr *func) int bit_offset = 0; while (member_iter.hasNext()) { LibertyPort *port_bit = member_iter.next(); - FuncExpr *sub_expr = (func) ? func->bitSubExpr(bit_offset) : NULL; + FuncExpr *sub_expr = (func) ? func->bitSubExpr(bit_offset) : nullptr; port_bit->setFunction(sub_expr); bit_offset++; } @@ -1913,7 +1901,7 @@ LibertyPort::setTristateEnable(FuncExpr *enable) while (member_iter.hasNext()) { LibertyPort *port_bit = member_iter.next(); FuncExpr *sub_expr = - (enable) ? enable->bitSubExpr(port_bit->busBitIndex()) : NULL; + (enable) ? enable->bitSubExpr(port_bit->busBitIndex()) : nullptr; port_bit->setTristateEnable(sub_expr); } } @@ -1980,7 +1968,7 @@ LibertyPort::minPeriod(const OperatingConditions *op_cond, } } LibertyLibrary *lib = liberty_cell_->libertyLibrary(); - min_period = min_period_ * lib->scaleFactor(scale_factor_min_period, + min_period = min_period_ * lib->scaleFactor(ScaleFactorType::min_period, liberty_cell_, pvt); exists = min_period_exists_; } @@ -2017,7 +2005,7 @@ LibertyPort::minPulseWidth(const TransRiseFall *hi_low, int hi_low_index = hi_low->index(); LibertyLibrary *lib = liberty_cell_->libertyLibrary(); min_width = min_pulse_width_[hi_low_index] - * lib->scaleFactor(scale_factor_min_pulse_width, hi_low_index, + * lib->scaleFactor(ScaleFactorType::min_pulse_width, hi_low_index, liberty_cell_, pvt); exists = min_pulse_width_exists_ & (1 << hi_low_index); } @@ -2045,8 +2033,8 @@ bool LibertyPort::equiv(const LibertyPort *port1, const LibertyPort *port2) { - return (port1 == NULL && port2 == NULL) - || (port1 != NULL && port2 != NULL + return (port1 == nullptr && port2 == nullptr) + || (port1 != nullptr && port2 != nullptr && stringEq(port1->name(), port2->name()) && port1->direction() == port2->direction()); } @@ -2072,7 +2060,7 @@ void LibertyPort::addScaledPort(OperatingConditions *op_cond, LibertyPort *scaled_port) { - if (scaled_ports_ == NULL) + if (scaled_ports_ == nullptr) scaled_ports_ = new ScaledPortMap; (*scaled_ports_)[op_cond] = scaled_port; } @@ -2298,9 +2286,9 @@ ModeValueDef::setSdfCond(const char *sdf_cond) TableTemplate::TableTemplate(const char *name) : name_(stringCopy(name)), - axis1_(NULL), - axis2_(NULL), - axis3_(NULL) + axis1_(nullptr), + axis2_(nullptr), + axis3_(nullptr) { } @@ -2381,7 +2369,7 @@ OperatingConditions::OperatingConditions(const char *name) : Pvt(0.0, 0.0, 0.0), name_(stringCopy(name)), // Default wireload tree. - wire_load_tree_(wire_load_balanced_tree) + wire_load_tree_(WireloadTree::balanced) { } @@ -2409,115 +2397,87 @@ OperatingConditions::setWireloadTree(WireloadTree tree) //////////////////////////////////////////////////////////////// -typedef Map ScaleFactorTypeMap; - -static const char *scale_factor_type_names[] = {"pin_cap", - "wire_cap", - "wire_res", - "min_period", - "cell", - "hold", - "setup", - "recovery", - "removal", - "nochange", - "skew", - "leakage_power", - "internal_power", - "transition", - "min_pulse_width", - "count", - "unknown"}; - -static ScaleFactorTypeMap *scale_factor_type_name_map = NULL; - -void -makeScaleFactorTypeMap() -{ - scale_factor_type_name_map = new ScaleFactorTypeMap; - for (int i = 0; i < scale_factor_count; i++) { - ScaleFactorType type = (ScaleFactorType) i; - (*scale_factor_type_name_map)[scale_factor_type_names[type]] = type; - } -} - -void -deleteScaleFactorTypeMap() -{ - delete scale_factor_type_name_map; - scale_factor_type_name_map = NULL; -} +static EnumNameMap scale_factor_type_map = + {{ScaleFactorType::pin_cap, "pin_cap"}, + {ScaleFactorType::wire_cap, "wire_res"}, + {ScaleFactorType::min_period, "min_period"}, + {ScaleFactorType::cell, "cell"}, + {ScaleFactorType::hold, "hold"}, + {ScaleFactorType::setup, "setup"}, + {ScaleFactorType::recovery, "recovery"}, + {ScaleFactorType::removal, "removal"}, + {ScaleFactorType::nochange, "nochange"}, + {ScaleFactorType::skew, "skew"}, + {ScaleFactorType::leakage_power, "leakage_power"}, + {ScaleFactorType::internal_power, "internal_power"}, + {ScaleFactorType::transition, "transition"}, + {ScaleFactorType::min_pulse_width, "min_pulse_width"}, + {ScaleFactorType::unknown, "unknown"} + }; const char * scaleFactorTypeName(ScaleFactorType type) { - return scale_factor_type_names[type]; + return scale_factor_type_map.find(type); } ScaleFactorType findScaleFactorType(const char *name) { - ScaleFactorType type; - bool exists; - scale_factor_type_name_map->findKey(name, type, exists); - if (exists) - return type; - else - return scale_factor_unknown; + return scale_factor_type_map.find(name, ScaleFactorType::unknown); } bool scaleFactorTypeRiseFallSuffix(ScaleFactorType type) { - return type == scale_factor_cell - || type == scale_factor_hold - || type == scale_factor_setup - || type == scale_factor_recovery - || type == scale_factor_removal - || type == scale_factor_nochange - || type == scale_factor_skew; + return type == ScaleFactorType::cell + || type == ScaleFactorType::hold + || type == ScaleFactorType::setup + || type == ScaleFactorType::recovery + || type == ScaleFactorType::removal + || type == ScaleFactorType::nochange + || type == ScaleFactorType::skew; } bool scaleFactorTypeRiseFallPrefix(ScaleFactorType type) { - return type == scale_factor_transition; + return type == ScaleFactorType::transition; } bool scaleFactorTypeLowHighSuffix(ScaleFactorType type) { - return type == scale_factor_min_pulse_width; + return type == ScaleFactorType::min_pulse_width; } -static const char *scale_factor_pvt_names[] = {"process", - "volt", - "temp"}; +//////////////////////////////////////////////////////////////// + +EnumNameMap scale_factor_pvt_names = + {{ScaleFactorPvt::process, "process"}, + {ScaleFactorPvt::volt, "volt"}, + {ScaleFactorPvt::temp, "temp"} + }; ScaleFactorPvt findScaleFactorPvt(const char *name) { - if (stringEq(name, scale_factor_pvt_names[scale_factor_process])) - return scale_factor_process; - else if (stringEq(name, scale_factor_pvt_names[scale_factor_temp])) - return scale_factor_temp; - else if (stringEq(name, scale_factor_pvt_names[scale_factor_volt])) - return scale_factor_volt; - else - return scale_factor_pvt_unknown; + return scale_factor_pvt_names.find(name, ScaleFactorPvt::unknown); } const char * scaleFactorPvtName(ScaleFactorPvt pvt) { - return scale_factor_pvt_names[pvt]; + return scale_factor_pvt_names.find(pvt); } +//////////////////////////////////////////////////////////////// + ScaleFactors::ScaleFactors(const char *name) : name_(stringCopy(name)) { - for (int type = 0; type < scale_factor_count; type++) { - for (int pvt = 0; pvt < scale_factor_pvt_count; pvt++) { + for (int type = 0; type < scale_factor_type_count; type++) { + for (int pvt = 0; pvt < int(ScaleFactorPvt::count); pvt++) { TransRiseFallIterator tr_iter; while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); @@ -2539,7 +2499,7 @@ ScaleFactors::setScale(ScaleFactorType type, TransRiseFall *tr, float scale) { - scales_[type][pvt][tr->index()] = scale; + scales_[int(type)][int(pvt)][tr->index()] = scale; } void @@ -2547,7 +2507,7 @@ ScaleFactors::setScale(ScaleFactorType type, ScaleFactorPvt pvt, float scale) { - scales_[type][pvt][0] = scale; + scales_[int(type)][int(pvt)][0] = scale; } float @@ -2555,7 +2515,7 @@ ScaleFactors::scale(ScaleFactorType type, ScaleFactorPvt pvt, TransRiseFall *tr) { - return scales_[type][pvt][tr->index()]; + return scales_[int(type)][int(pvt)][tr->index()]; } float @@ -2563,29 +2523,29 @@ ScaleFactors::scale(ScaleFactorType type, ScaleFactorPvt pvt, int tr_index) { - return scales_[type][pvt][tr_index]; + return scales_[int(type)][int(pvt)][tr_index]; } float ScaleFactors::scale(ScaleFactorType type, ScaleFactorPvt pvt) { - return scales_[type][pvt][0]; + return scales_[int(type)][int(pvt)][0]; } void ScaleFactors::print() { printf("%10s", " "); - for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) { + for (int pvt_index = 0; pvt_index < int(ScaleFactorPvt::count); pvt_index++) { ScaleFactorPvt pvt = (ScaleFactorPvt) pvt_index; printf("%10s", scaleFactorPvtName(pvt)); } printf("\n"); - for (int type_index = 0; type_index < scale_factor_count; type_index++) { + for (int type_index = 0; type_index < scale_factor_type_count; type_index++) { ScaleFactorType type = (ScaleFactorType) type_index; printf("%10s ", scaleFactorTypeName(type)); - for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) { + for (int pvt_index = 0; pvt_index < int(ScaleFactorPvt::count); pvt_index++) { TransRiseFallIterator tr_iter; if (scaleFactorTypeRiseFallSuffix(type) || scaleFactorTypeRiseFallPrefix(type) @@ -2617,11 +2577,11 @@ TestCell::TestCell(LibertyPort *data_in, } TestCell::TestCell() : - data_in_(NULL), - scan_in_(NULL), - scan_enable_(NULL), - scan_out_(NULL), - scan_out_inv_(NULL) + data_in_(nullptr), + scan_in_(nullptr), + scan_enable_(nullptr), + scan_out_(nullptr), + scan_out_inv_(nullptr) { } @@ -2668,8 +2628,8 @@ OcvDerate::OcvDerate(const char *name) : while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); int tr_index = tr->index(); - derate_[tr_index][el_index][path_type_clk] = NULL; - derate_[tr_index][el_index][path_type_data] = NULL; + derate_[tr_index][el_index][int(PathType::clk)] = nullptr; + derate_[tr_index][el_index][int(PathType::data)] = nullptr; } } } @@ -2689,10 +2649,10 @@ OcvDerate::~OcvDerate() TransRiseFall *tr = tr_iter.next(); int tr_index = tr->index(); Table *derate; - derate = derate_[tr_index][el_index][path_type_clk]; + derate = derate_[tr_index][el_index][int(PathType::clk)]; if (derate) models.insert(derate); - derate = derate_[tr_index][el_index][path_type_data]; + derate = derate_[tr_index][el_index][int(PathType::data)]; if (derate) models.insert(derate); } @@ -2709,7 +2669,7 @@ OcvDerate::derateTable(const TransRiseFall *tr, const EarlyLate *early_late, PathType path_type) { - return derate_[tr->index()][early_late->index()][path_type]; + return derate_[tr->index()][early_late->index()][int(path_type)]; } void @@ -2718,7 +2678,7 @@ OcvDerate::setDerateTable(const TransRiseFall *tr, const PathType path_type, Table *derate) { - derate_[tr->index()][early_late->index()][path_type] = derate; + derate_[tr->index()][early_late->index()][int(path_type)] = derate; } //////////////////////////////////////////////////////////////// @@ -2727,7 +2687,7 @@ LibertyPgPort::LibertyPgPort(const char *name, LibertyCell *cell) : name_(stringCopy(name)), pg_type_(unknown), - voltage_name_(NULL), + voltage_name_(nullptr), cell_(cell) { } diff --git a/liberty/Liberty.hh b/liberty/Liberty.hh index 41dcfe64..a226cc3f 100644 --- a/liberty/Liberty.hh +++ b/liberty/Liberty.hh @@ -72,37 +72,13 @@ typedef Vector InternalPowerAttrsSeq; typedef Map SupplyVoltageMap; typedef Map LibertyPgPortMap; -typedef enum { - clock_gate_none, - clock_gate_latch_posedge, - clock_gate_latch_negedge, - clock_gate_other -} ClockGateType; +enum class ClockGateType { none, latch_posedge, latch_negedge, other }; -typedef enum { - delay_model_cmos_linear, - delay_model_cmos_pwl, - delay_model_cmos2, - delay_model_table, - delay_model_polynomial, - delay_model_dcm -} DelayModelType; +enum class DelayModelType { cmos_linear, cmos_pwl, cmos2, table, polynomial, dcm }; -typedef enum { - scale_factor_process, - scale_factor_volt, - scale_factor_temp, - scale_factor_pvt_count, - scale_factor_pvt_unknown -} ScaleFactorPvt; +enum class ScaleFactorPvt { process, volt, temp, count, unknown }; -typedef enum { - table_template_delay, - table_template_power, - table_template_output_current, - table_template_ocv, - table_template_count -} TableTemplateType; +enum class TableTemplateType { delay, power, output_current, ocv, count }; void initLiberty(); @@ -279,7 +255,10 @@ public: void addSupplyVoltage(const char *suppy_name, float voltage); bool supplyExists(const char *suppy_name) const; - float supplyVoltage(const char *suppy_name) const; + void supplyVoltage(const char *supply_name, + // Return value. + float &voltage, + bool &exists) const; // Make scaled cell. Call LibertyCell::addScaledCell after it is complete. LibertyCell *makeScaledCell(const char *name, @@ -303,7 +282,7 @@ protected: Units *units_; DelayModelType delay_model_type_; BusDclMap bus_dcls_; - TableTemplateMap template_maps_[table_template_count]; + TableTemplateMap template_maps_[int(TableTemplateType::count)]; float nominal_process_; float nominal_voltage_; float nominal_temperature_; @@ -343,12 +322,10 @@ protected: // Set if any library has rise/fall capacitances. static bool found_rise_fall_caps_; - static const float input_threshold_default_; - static const float output_threshold_default_; - static const float slew_lower_threshold_default_; - static const float slew_upper_threshold_default_; - static const float slew_lower_measure_threshold_default_; - static const float slew_upper_measure_threshold_default_; + static constexpr float input_threshold_default_ = .5; + static constexpr float output_threshold_default_ = .5; + static constexpr float slew_lower_threshold_default_ = .2; + static constexpr float slew_upper_threshold_default_ = .8; private: DISALLOW_COPY_AND_ASSIGN(LibertyLibrary); @@ -376,7 +353,7 @@ class TableTemplateIterator : public TableTemplateMap::ConstIterator public: TableTemplateIterator(const LibertyLibrary *library, TableTemplateType type) : - TableTemplateMap::ConstIterator(library->template_maps_[type]) {} + TableTemplateMap::ConstIterator(library->template_maps_[int(type)]) {} }; class OperatingConditionsIterator : public OperatingConditionsMap::ConstIterator @@ -424,7 +401,7 @@ public: bool isClockGateLatchNegedge() const; bool isClockGateOther() const; bool isClockGate() const; - void setClockGateType(ClockGateType clock_gate_type); + void setClockGateType(ClockGateType type); virtual unsigned addTimingArcSet(TimingArcSet *set); void addTimingArcAttrs(TimingArcAttrs *attrs); virtual void addInternalPower(InternalPower *power); @@ -865,7 +842,7 @@ public: protected: const char *name_; - float scales_[scale_factor_count][scale_factor_pvt_count][TransRiseFall::index_count]; + float scales_[scale_factor_type_count][int(ScaleFactorPvt::count)][TransRiseFall::index_count]; private: DISALLOW_COPY_AND_ASSIGN(ScaleFactors); diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc index b6f145e6..ad38c95d 100644 --- a/liberty/LibertyBuilder.cc +++ b/liberty/LibertyBuilder.cc @@ -41,7 +41,7 @@ LibertyPort * LibertyBuilder::makePort(LibertyCell *cell, const char *name) { - LibertyPort *port = new LibertyPort(cell, name, false, -1, -1, false, NULL); + LibertyPort *port = new LibertyPort(cell, name, false, -1, -1, false, nullptr); cell->addPort(port); return port; } @@ -100,7 +100,7 @@ LibertyBuilder::makePort(LibertyCell *cell, int bit_index) { ConcretePort *port = new LibertyPort(cell, bit_name, false, - bit_index, bit_index, false, NULL); + bit_index, bit_index, false, nullptr); return port; } @@ -124,9 +124,9 @@ LibertyBuilder::makeTimingArcs(LibertyCell *cell, TimingArcAttrs *attrs) { FuncExpr *to_func; - Sequential *seq = NULL; + Sequential *seq = nullptr; switch (attrs->timingType()) { - case timing_type_combinational: + case TimingType::combinational: to_func = to_port->function(); if (to_func && to_func->op() == FuncExpr::op_port) seq = cell->outputPortSequential(to_func->port()); @@ -135,114 +135,114 @@ LibertyBuilder::makeTimingArcs(LibertyCell *cell, else return makeCombinationalArcs(cell, from_port, to_port, related_out, true, true, attrs); - case timing_type_combinational_fall: + case TimingType::combinational_fall: return makeCombinationalArcs(cell, from_port, to_port, related_out, false, true, attrs); - case timing_type_combinational_rise: + case TimingType::combinational_rise: return makeCombinationalArcs(cell, from_port, to_port, related_out, true, false, attrs); - case timing_type_setup_rising: + case TimingType::setup_rising: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), TimingRole::setup(), attrs); - case timing_type_setup_falling: + case TimingType::setup_falling: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), TimingRole::setup(), attrs); - case timing_type_hold_rising: + case TimingType::hold_rising: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), TimingRole::hold(), attrs); - case timing_type_hold_falling: + case TimingType::hold_falling: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), TimingRole::hold(), attrs); - case timing_type_rising_edge: + case TimingType::rising_edge: return makeRegLatchArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), attrs); - case timing_type_falling_edge: + case TimingType::falling_edge: return makeRegLatchArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), attrs); - case timing_type_preset: + case TimingType::preset: return makePresetClrArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), attrs); - case timing_type_clear: + case TimingType::clear: return makePresetClrArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), attrs); - case timing_type_recovery_rising: + case TimingType::recovery_rising: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(),TimingRole::recovery(), attrs); - case timing_type_recovery_falling: + case TimingType::recovery_falling: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(),TimingRole::recovery(), attrs); - case timing_type_removal_rising: + case TimingType::removal_rising: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), TimingRole::removal(), attrs); - case timing_type_removal_falling: + case TimingType::removal_falling: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), TimingRole::removal(), attrs); - case timing_type_three_state_disable: + case TimingType::three_state_disable: return makeTristateDisableArcs(cell, from_port, to_port, related_out, true, true, attrs); - case timing_type_three_state_disable_fall: + case TimingType::three_state_disable_fall: return makeTristateDisableArcs(cell, from_port, to_port, related_out, false, true, attrs); - case timing_type_three_state_disable_rise: + case TimingType::three_state_disable_rise: return makeTristateDisableArcs(cell, from_port, to_port, related_out, true, false, attrs); - case timing_type_three_state_enable: + case TimingType::three_state_enable: return makeTristateEnableArcs(cell, from_port, to_port, related_out, true, true, attrs); - case timing_type_three_state_enable_fall: + case TimingType::three_state_enable_fall: return makeTristateEnableArcs(cell, from_port, to_port, related_out, false, true, attrs); - case timing_type_three_state_enable_rise: + case TimingType::three_state_enable_rise: return makeTristateEnableArcs(cell, from_port, to_port, related_out, true, false, attrs); - case timing_type_skew_falling: + case TimingType::skew_falling: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), TimingRole::skew(), attrs); - case timing_type_skew_rising: + case TimingType::skew_rising: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), TimingRole::skew(), attrs); - case timing_type_non_seq_setup_rising: + case TimingType::non_seq_setup_rising: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), TimingRole::nonSeqSetup(), attrs); - case timing_type_non_seq_setup_falling: + case TimingType::non_seq_setup_falling: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), TimingRole::nonSeqSetup(), attrs); - case timing_type_non_seq_hold_rising: + case TimingType::non_seq_hold_rising: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::rise(), TimingRole::nonSeqHold(), attrs); - case timing_type_non_seq_hold_falling: + case TimingType::non_seq_hold_falling: return makeFromTransitionArcs(cell, from_port, to_port, related_out, TransRiseFall::fall(), TimingRole::nonSeqHold(), attrs); - case timing_type_min_pulse_width: - case timing_type_minimum_period: - case timing_type_nochange_high_high: - case timing_type_nochange_high_low: - case timing_type_nochange_low_high: - case timing_type_nochange_low_low: - case timing_type_retaining_time: - case timing_type_unknown: - case timing_type_min_clock_tree_path: - case timing_type_max_clock_tree_path: - return NULL; + case TimingType::min_pulse_width: + case TimingType::minimum_period: + case TimingType::nochange_high_high: + case TimingType::nochange_high_low: + case TimingType::nochange_low_high: + case TimingType::nochange_low_low: + case TimingType::retaining_time: + case TimingType::unknown: + case TimingType::min_clock_tree_path: + case TimingType::max_clock_tree_path: + return nullptr; } // Prevent warnings from lame compilers. - return NULL; + return nullptr; } TimingArcSet * @@ -258,21 +258,21 @@ LibertyBuilder::makeCombinationalArcs(LibertyCell *cell, TimingArcSet *arc_set = makeTimingArcSet(cell, from_port, to_port, related_out, TimingRole::combinational(), attrs); TimingSense sense = attrs->timingSense(); - if (sense == timing_sense_unknown && func) { + if (sense == TimingSense::unknown && func) { // Timing sense not specified - find it from function. sense = func->portTimingSense(from_port); - if (sense == timing_sense_none + if (sense == TimingSense::none && to_port->direction()->isAnyTristate()) { // from_port is not an input to function, check tristate enable. FuncExpr *enable = to_port->tristateEnable(); if (enable && enable->hasPort(from_port)) - sense = timing_sense_non_unate; + sense = TimingSense::non_unate; } } TimingModel *model; TransRiseFall *to_tr; switch (sense) { - case timing_sense_positive_unate: + case TimingSense::positive_unate: if (to_rise) { to_tr = TransRiseFall::rise(); model = attrs->model(to_tr); @@ -286,7 +286,7 @@ LibertyBuilder::makeCombinationalArcs(LibertyCell *cell, makeTimingArc(arc_set, TransRiseFall::fall(), to_tr, model); } break; - case timing_sense_negative_unate: + case TimingSense::negative_unate: if (to_fall) { to_tr = TransRiseFall::fall(); model = attrs->model(to_tr); @@ -300,12 +300,12 @@ LibertyBuilder::makeCombinationalArcs(LibertyCell *cell, makeTimingArc(arc_set, TransRiseFall::fall(), to_tr, model); } break; - case timing_sense_non_unate: - case timing_sense_unknown: + case TimingSense::non_unate: + case TimingSense::unknown: // Timing sense none means function does not mention from_port. // This can happen if the function references an internal port, // as in fpga lut cells. - case timing_sense_none: + case TimingSense::none: if (to_fall) { to_tr = TransRiseFall::fall(); model = attrs->model(to_tr); @@ -342,14 +342,14 @@ LibertyBuilder::makeLatchDtoQArcs(LibertyCell *cell, model = attrs->model(to_tr); TimingSense sense = attrs->timingSense(); if (model) { - TransRiseFall *from_tr = (sense == timing_sense_negative_unate) ? + TransRiseFall *from_tr = (sense == TimingSense::negative_unate) ? to_tr->opposite() : to_tr; makeTimingArc(arc_set, from_tr, to_tr, model); } to_tr = TransRiseFall::fall(); model = attrs->model(to_tr); if (model) { - TransRiseFall *from_tr = (sense == timing_sense_negative_unate) ? + TransRiseFall *from_tr = (sense == TimingSense::negative_unate) ? to_tr->opposite() : to_tr; makeTimingArc(arc_set, from_tr, to_tr, model); } @@ -425,25 +425,25 @@ LibertyBuilder::makePresetClrArcs(LibertyCell *cell, TransRiseFall *to_tr, TimingArcAttrs *attrs) { - TimingArcSet *arc_set = NULL; + TimingArcSet *arc_set = nullptr; TimingModel *model = attrs->model(to_tr); if (model) { arc_set = makeTimingArcSet(cell, from_port, to_port, related_out, TimingRole::regSetClr(), attrs); TransRiseFall *opp_tr = to_tr->opposite(); switch (attrs->timingSense()) { - case timing_sense_positive_unate: + case TimingSense::positive_unate: makeTimingArc(arc_set, to_tr, to_tr, model); break; - case timing_sense_negative_unate: + case TimingSense::negative_unate: makeTimingArc(arc_set, opp_tr, to_tr, model); break; - case timing_sense_non_unate: - case timing_sense_unknown: + case TimingSense::non_unate: + case TimingSense::unknown: makeTimingArc(arc_set, to_tr, to_tr, model); makeTimingArc(arc_set, opp_tr, to_tr, model); break; - case timing_sense_none: + case TimingSense::none: break; } } @@ -466,12 +466,12 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell, TimingRole::tristateEnable(),attrs); FuncExpr *tristate_enable = to_port->tristateEnable(); TimingSense sense = attrs->timingSense(); - if (sense == timing_sense_unknown && tristate_enable) + if (sense == TimingSense::unknown && tristate_enable) sense = tristate_enable->portTimingSense(from_port); TimingModel *model; TransRiseFall *to_tr; switch (sense) { - case timing_sense_positive_unate: + case TimingSense::positive_unate: if (to_rise) { to_tr = TransRiseFall::rise(); model = attrs->model(to_tr); @@ -485,7 +485,7 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell, makeTimingArc(arc_set, Transition::rise(), Transition::trZ0(), model); } break; - case timing_sense_negative_unate: + case TimingSense::negative_unate: if (to_rise) { to_tr = TransRiseFall::rise(); model = attrs->model(to_tr); @@ -499,8 +499,8 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell, makeTimingArc(arc_set, Transition::fall(), Transition::trZ0(), model); } break; - case timing_sense_non_unate: - case timing_sense_unknown: + case TimingSense::non_unate: + case TimingSense::unknown: if (to_rise) { to_tr = TransRiseFall::rise(); model = attrs->model(to_tr); @@ -518,7 +518,7 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell, } } break; - case timing_sense_none: + case TimingSense::none: break; } return arc_set; @@ -539,12 +539,12 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell, attrs); TimingSense sense = attrs->timingSense(); FuncExpr *tristate_enable = to_port->tristateEnable(); - if (sense == timing_sense_unknown && tristate_enable) + if (sense == TimingSense::unknown && tristate_enable) sense = timingSenseOpposite(tristate_enable->portTimingSense(from_port)); TimingModel *model; TransRiseFall *to_tr; switch (sense) { - case timing_sense_positive_unate: + case TimingSense::positive_unate: if (to_rise) { to_tr = TransRiseFall::rise(); model = attrs->model(to_tr); @@ -558,7 +558,7 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell, makeTimingArc(arc_set, Transition::rise(), Transition::tr1Z(), model); } break; - case timing_sense_negative_unate: + case TimingSense::negative_unate: if (to_rise) { to_tr = TransRiseFall::rise(); model = attrs->model(to_tr); @@ -572,8 +572,8 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell, makeTimingArc(arc_set, Transition::fall(), Transition::tr1Z(), model); } break; - case timing_sense_non_unate: - case timing_sense_unknown: + case TimingSense::non_unate: + case TimingSense::unknown: if (to_rise) { to_tr = TransRiseFall::rise(); model = attrs->model(to_tr); @@ -591,7 +591,7 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell, } } break; - case timing_sense_none: + case TimingSense::none: break; } return arc_set; diff --git a/liberty/LibertyClass.hh b/liberty/LibertyClass.hh index 8d2b41ae..2ad0ca37 100644 --- a/liberty/LibertyClass.hh +++ b/liberty/LibertyClass.hh @@ -67,86 +67,70 @@ typedef Set LibertyCellSet; typedef Vector FloatSeq; typedef Vector FloatTable; -typedef enum { - scale_factor_pin_cap, - scale_factor_wire_cap, - scale_factor_wire_res, - scale_factor_min_period, +enum class ScaleFactorType : unsigned { + pin_cap, + wire_cap, + wire_res, + min_period, // Liberty attributes have rise/fall suffix. - scale_factor_cell, - scale_factor_hold, - scale_factor_setup, - scale_factor_recovery, - scale_factor_removal, - scale_factor_nochange, - scale_factor_skew, - scale_factor_leakage_power, - scale_factor_internal_power, + cell, + hold, + setup, + recovery, + removal, + nochange, + skew, + leakage_power, + internal_power, // Liberty attributes have rise/fall prefix. - scale_factor_transition, + transition, // Liberty attributes have low/high suffix (indexed as rise/fall). - scale_factor_min_pulse_width, - scale_factor_unknown, - scale_factor_count -} ScaleFactorType; - + min_pulse_width, + unknown, +}; +const int scale_factor_type_count = int(ScaleFactorType::unknown) + 1; // Enough bits to hold a ScaleFactorType enum. const int scale_factor_bits = 4; -typedef enum { - wire_load_worst_case_tree, - wire_load_best_case_tree, - wire_load_balanced_tree, - wire_load_unknown_tree -} WireloadTree; +enum class WireloadTree { worst_case, best_case, balanced, unknown }; -typedef enum { - wire_load_mode_top, - wire_load_mode_enclosed, - wire_load_mode_segmented, - wire_load_mode_unknown -} WireloadMode; +enum class WireloadMode { top, enclosed, segmented, unknown }; -typedef enum { - timing_sense_positive_unate, - timing_sense_negative_unate, - timing_sense_non_unate, - timing_sense_none, - timing_sense_unknown -} TimingSense; +enum class TimingSense { + positive_unate, + negative_unate, + non_unate, + none, + unknown +}; +const int timing_sense_count = int(TimingSense::unknown) + 1; +const int timing_sense_bit_count = 3; -typedef enum { - table_axis_total_output_net_capacitance, - table_axis_equal_or_opposite_output_net_capacitance, - table_axis_input_net_transition, - table_axis_input_transition_time, - table_axis_related_pin_transition, - table_axis_constrained_pin_transition, - table_axis_output_pin_transition, - table_axis_connect_delay, - table_axis_related_out_total_output_net_capacitance, - table_axis_time, - table_axis_iv_output_voltage, - table_axis_input_noise_width, - table_axis_input_noise_height, - table_axis_input_voltage, - table_axis_output_voltage, - table_axis_path_depth, - table_axis_path_distance, - table_axis_normalized_voltage, - table_axis_unknown -} TableAxisVariable; - -typedef enum { - path_type_clk, - path_type_data, - path_type_clk_and_data -} PathType; +enum class TableAxisVariable { + total_output_net_capacitance, + equal_or_opposite_output_net_capacitance, + input_net_transition, + input_transition_time, + related_pin_transition, + constrained_pin_transition, + output_pin_transition, + connect_delay, + related_out_total_output_net_capacitance, + time, + iv_output_voltage, + input_noise_width, + input_noise_height, + input_voltage, + output_voltage, + path_depth, + path_distance, + normalized_voltage, + unknown +}; +enum class PathType { clk, data, clk_and_data }; const int path_type_count = 2; -const int timing_sense_count = timing_sense_unknown + 1; -const int timing_sense_bit_count = 3; // Rise/fall to rise/fall. const int timing_arc_index_bit_count = 2; const int timing_arc_index_max = (1<findLibertyPort(port_name); - FuncExpr *expr = NULL; + FuncExpr *expr = nullptr; if (port) expr = FuncExpr::makePort(port); else @@ -80,7 +80,7 @@ LibExprParser::makeFuncExprNot(FuncExpr *arg) if (arg) return FuncExpr::makeNot(arg); else - return NULL; + return nullptr; } FuncExpr * @@ -89,7 +89,7 @@ LibExprParser::makeFuncExprXor(FuncExpr *arg1, FuncExpr *arg2) if (arg1 && arg2) return FuncExpr::makeXor(arg1, arg2); else - return NULL; + return nullptr; } FuncExpr * @@ -98,7 +98,7 @@ LibExprParser::makeFuncExprAnd(FuncExpr *arg1, FuncExpr *arg2) if (arg1 && arg2) return FuncExpr::makeAnd(arg1, arg2); else - return NULL; + return nullptr; } FuncExpr * @@ -107,7 +107,7 @@ LibExprParser::makeFuncExprOr(FuncExpr *arg1, FuncExpr *arg2) if (arg1 && arg2) return FuncExpr::makeOr(arg1, arg2); else - return NULL; + return nullptr; } void diff --git a/liberty/LibertyParser.cc b/liberty/LibertyParser.cc index d5e10579..56074a3a 100644 --- a/liberty/LibertyParser.cc +++ b/liberty/LibertyParser.cc @@ -46,7 +46,7 @@ static Report *liberty_report; static LibertyStmt * makeLibertyDefine(LibertyAttrValueSeq *values, int line); -static AttrType +static LibertyAttrType attrValueType(const char *value_type_name); static LibertyGroupType groupType(const char *group_type_name); @@ -63,8 +63,8 @@ parseLibertyFile(const char *filename, liberty_group_visitor = library_visitor; liberty_group_stack.clear(); liberty_filename = filename; - liberty_filename_prev = NULL; - liberty_stream_prev = NULL; + liberty_filename_prev = nullptr; + liberty_stream_prev = nullptr; liberty_line = 1; liberty_report = report; LibertyParse_parse(); @@ -91,14 +91,14 @@ libertyGroupEnd() liberty_group_visitor->end(group); liberty_group_stack.pop_back(); LibertyGroup *parent = - liberty_group_stack.empty() ? NULL : liberty_group_stack.back(); + liberty_group_stack.empty() ? nullptr : liberty_group_stack.back(); if (parent && liberty_group_visitor->save(group)) { parent->addSubgroup(group); return group; } else { delete group; - return NULL; + return nullptr; } } @@ -115,17 +115,17 @@ LibertyGroup::LibertyGroup(const char *type, LibertyStmt(line), type_(type), params_(params), - attrs_(NULL), - attr_map_(NULL), - subgroups_(NULL), - define_map_(NULL) + attrs_(nullptr), + attr_map_(nullptr), + subgroups_(nullptr), + define_map_(nullptr) { } void LibertyGroup::addSubgroup(LibertyGroup *subgroup) { - if (subgroups_ == NULL) + if (subgroups_ == nullptr) subgroups_ = new LibertyGroupSeq; subgroups_->push_back(subgroup); } @@ -133,7 +133,7 @@ LibertyGroup::addSubgroup(LibertyGroup *subgroup) void LibertyGroup::addDefine(LibertyDefine *define) { - if (define_map_ == NULL) + if (define_map_ == nullptr) define_map_ = new LibertyDefineMap; const char *define_name = define->name(); LibertyDefine *prev_define = define_map_->findKey(define_name); @@ -147,7 +147,7 @@ LibertyGroup::addDefine(LibertyDefine *define) void LibertyGroup::addAttribute(LibertyAttr *attr) { - if (attrs_ == NULL) + if (attrs_ == nullptr) attrs_ = new LibertyAttrSeq; attrs_->push_back(attr); if (attr_map_) @@ -185,7 +185,7 @@ LibertyGroup::firstName() if (value->isString()) return value->stringValue(); } - return NULL; + return nullptr; } const char * @@ -196,14 +196,14 @@ LibertyGroup::secondName() if (value->isString()) return value->stringValue(); } - return NULL; + return nullptr; } LibertyAttr * LibertyGroup::findAttr(const char *name) { if (attrs_) { - if (attr_map_ == NULL) { + if (attr_map_ == nullptr) { // Build attribute name map on demand. LibertyAttrSeq::Iterator attr_iter(attrs_); while (attr_iter.hasNext()) { @@ -214,7 +214,7 @@ LibertyGroup::findAttr(const char *name) return attr_map_->findKey(name); } else - return NULL; + return nullptr; } LibertySubgroupIterator::LibertySubgroupIterator(LibertyGroup *group) : @@ -256,7 +256,7 @@ makeLibertySimpleAttr(const char *name, } else { delete attr; - return NULL; + return nullptr; } } @@ -283,7 +283,7 @@ LibertyAttrValueSeq * LibertySimpleAttr::values() const { internalError("valueIterator called for LibertySimpleAttribute"); - return NULL; + return nullptr; } LibertyStmt * @@ -313,7 +313,7 @@ makeLibertyComplexAttr(const char *name, } else { delete attr; - return NULL; + return nullptr; } } } @@ -340,7 +340,7 @@ LibertyComplexAttr::firstValue() if (values_ && values_->size() > 0) return (*values_)[0]; else - return NULL; + return nullptr; } LibertyAttrValue * @@ -394,7 +394,7 @@ const char * LibertyFloatAttrValue::stringValue() { internalError("LibertyStringAttrValue called for float value"); - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -403,12 +403,12 @@ static LibertyStmt * makeLibertyDefine(LibertyAttrValueSeq *values, int line) { - LibertyDefine *define = NULL; + LibertyDefine *define = nullptr; if (values->size() == 3) { const char *define_name = (*values)[0]->stringValue(); const char *group_type_name = (*values)[1]->stringValue(); const char *value_type_name = (*values)[2]->stringValue(); - AttrType value_type = attrValueType(value_type_name); + LibertyAttrType value_type = attrValueType(value_type_name); LibertyGroupType group_type = groupType(group_type_name); define = new LibertyDefine(stringCopy(define_name), group_type, value_type, line); @@ -424,39 +424,39 @@ makeLibertyDefine(LibertyAttrValueSeq *values, // The Liberty User Guide Version 2001.08 fails to define the strings // used to define valid attribute types. Beyond "string" these are // guesses. -static AttrType +static LibertyAttrType attrValueType(const char *value_type_name) { if (stringEq(value_type_name, "string")) - return liberty_attr_string; + return LibertyAttrType::attr_string; else if (stringEq(value_type_name, "integer")) - return liberty_attr_int; + return LibertyAttrType::attr_int; else if (stringEq(value_type_name, "float")) - return liberty_attr_double; + return LibertyAttrType::attr_double; else if (stringEq(value_type_name, "boolean")) - return liberty_attr_boolean; + return LibertyAttrType::attr_boolean; else - return liberty_attr_unknown; + return LibertyAttrType::attr_unknown; } static LibertyGroupType groupType(const char *group_type_name) { if (stringEq(group_type_name, "library")) - return liberty_group_library; + return LibertyGroupType::library; else if (stringEq(group_type_name, "cell")) - return liberty_group_cell; + return LibertyGroupType::cell; else if (stringEq(group_type_name, "pin")) - return liberty_group_pin; + return LibertyGroupType::pin; else if (stringEq(group_type_name, "timing")) - return liberty_group_timing; + return LibertyGroupType::timing; else - return liberty_group_unknown; + return LibertyGroupType::unknown; } LibertyDefine::LibertyDefine(const char *name, LibertyGroupType group_type, - AttrType value_type, + LibertyAttrType value_type, int line) : LibertyStmt(line), name_(name), @@ -483,7 +483,7 @@ makeLibertyVariable(char *var, return variable; else { delete variable; - return NULL; + return nullptr; } } @@ -506,14 +506,14 @@ LibertyVariable::~LibertyVariable() bool libertyInInclude() { - return liberty_filename_prev != NULL; + return liberty_filename_prev != nullptr; } FILE * libertyIncludeBegin(const char *filename) { FILE *stream = fopen(filename, "r" ); - if (stream == NULL) + if (stream == nullptr) libertyParseError("cannot open include file %s.\n", filename); else { liberty_filename_prev = liberty_filename; @@ -533,8 +533,8 @@ libertyIncludeEnd() liberty_filename = liberty_filename_prev; liberty_line = liberty_line_prev; LibertyLex_in = liberty_stream_prev; - liberty_filename_prev = NULL; - liberty_stream_prev = NULL; + liberty_filename_prev = nullptr; + liberty_stream_prev = nullptr; } void diff --git a/liberty/LibertyParser.hh b/liberty/LibertyParser.hh index 469bf388..6f79b0e6 100644 --- a/liberty/LibertyParser.hh +++ b/liberty/LibertyParser.hh @@ -47,21 +47,10 @@ typedef Map LibertyVariableMap; typedef MapLibertyGroupVisitorMap; typedef LibertyAttrValueSeq::Iterator LibertyAttrValueIterator; -typedef enum { - liberty_attr_string, - liberty_attr_int, - liberty_attr_double, - liberty_attr_boolean, - liberty_attr_unknown -} AttrType; +enum class LibertyAttrType { attr_string, attr_int, attr_double, + attr_boolean, attr_unknown }; -typedef enum { - liberty_group_library, - liberty_group_cell, - liberty_group_pin, - liberty_group_timing, - liberty_group_unknown -} LibertyGroupType; +enum class LibertyGroupType { library, cell, pin, timing, unknown }; // Abstract base class for liberty statements. class LibertyStmt @@ -254,18 +243,20 @@ class LibertyDefine : public LibertyStmt public: LibertyDefine(const char *name, LibertyGroupType group_type, - AttrType value_type, + LibertyAttrType value_type, int line); virtual ~LibertyDefine(); virtual bool isDefine() const { return true; } const char *name() const { return name_; } + LibertyGroupType groupType() const { return group_type_; } + LibertyAttrType valueType() const { return value_type_; } private: DISALLOW_COPY_AND_ASSIGN(LibertyDefine); const char *name_; LibertyGroupType group_type_; - AttrType value_type_; + LibertyAttrType value_type_; }; // The Liberty User Guide Version 2003.12 fails to document variables. diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 16e9687d..2e630d52 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -100,38 +100,38 @@ LibertyReader::readLibertyFile(const char *filename, report_ = report; debug_ = debug; network_ = network; - var_map_ = NULL; - library_ = NULL; - wireload_ = NULL; - wireload_selection_ = NULL; - default_wireload_ = NULL; - default_wireload_selection_ = NULL; - scale_factors_ = NULL; - save_scale_factors_ = NULL; - tbl_template_ = NULL; - cell_ = NULL; - save_cell_ = NULL; - scaled_cell_owner_ = NULL; - test_cell_ = NULL; - ocv_derate_name_ = NULL; - op_cond_ = NULL; - ports_ = NULL; - port_ = NULL; - port_group_ = NULL; - saved_ports_ = NULL; - saved_port_group_ = NULL; + var_map_ = nullptr; + library_ = nullptr; + wireload_ = nullptr; + wireload_selection_ = nullptr; + default_wireload_ = nullptr; + default_wireload_selection_ = nullptr; + scale_factors_ = nullptr; + save_scale_factors_ = nullptr; + tbl_template_ = nullptr; + cell_ = nullptr; + save_cell_ = nullptr; + scaled_cell_owner_ = nullptr; + test_cell_ = nullptr; + ocv_derate_name_ = nullptr; + op_cond_ = nullptr; + ports_ = nullptr; + port_ = nullptr; + port_group_ = nullptr; + saved_ports_ = nullptr; + saved_port_group_ = nullptr; in_bus_ = false; in_bundle_ = false; - sequential_ = NULL; - timing_ = NULL; - internal_power_ = NULL; - leakage_power_ = NULL; - table_ = NULL; + sequential_ = nullptr; + timing_ = nullptr; + internal_power_ = nullptr; + leakage_power_ = nullptr; + table_ = nullptr; table_model_scale_ = 1.0; - mode_def_ = NULL; - mode_value_ = NULL; - ocv_derate_ = NULL; - pg_port_ = NULL; + mode_def_ = nullptr; + mode_value_ = nullptr; + ocv_derate_ = nullptr; + pg_port_ = nullptr; have_resistance_unit_ = false; TransRiseFallIterator tr_iter; @@ -450,10 +450,10 @@ LibertyReader::defineVisitors() void LibertyReader::defineScalingFactorVisitors() { - for (int type_index = 0; type_index < scale_factor_count; type_index++) { + for (int type_index = 0; type_index < scale_factor_type_count; type_index++) { ScaleFactorType type = static_cast(type_index); const char *type_name = scaleFactorTypeName(type); - for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) { + for (int pvt_index = 0; pvt_index < int(ScaleFactorPvt::count); pvt_index++) { ScaleFactorPvt pvt = static_cast(pvt_index); const char *pvt_name = scaleFactorPvtName(pvt); if (scaleFactorTypeRiseFallSuffix(type)) { @@ -558,7 +558,7 @@ LibertyReader::beginLibrary(LibertyGroup *group) library_->units()->currentUnit()->setScale(curr_scale_); - library_->setDelayModelType(delay_model_cmos_linear); + library_->setDelayModelType(DelayModelType::cmos_linear); scale_factors_ = new ScaleFactors(""); library_->setScaleFactors(scale_factors_); } @@ -781,24 +781,24 @@ LibertyReader::visitDelayModel(LibertyAttr *attr) const char *type_name = getAttrString(attr); if (type_name) { if (stringEq(type_name, "table_lookup")) - library_->setDelayModelType(delay_model_table); + library_->setDelayModelType(DelayModelType::table); else if (stringEq(type_name, "generic_cmos")) - library_->setDelayModelType(delay_model_cmos_linear); + library_->setDelayModelType(DelayModelType::cmos_linear); else if (stringEq(type_name, "piecewise_cmos")) { - library_->setDelayModelType(delay_model_cmos_pwl); + library_->setDelayModelType(DelayModelType::cmos_pwl); libWarn(attr, "delay_model %s not supported.\n.", type_name); } else if (stringEq(type_name, "cmos2")) { - library_->setDelayModelType(delay_model_cmos2); + library_->setDelayModelType(DelayModelType::cmos2); libWarn(attr, "delay_model %s not supported.\n.", type_name); } else if (stringEq(type_name, "polynomial")) { - library_->setDelayModelType(delay_model_polynomial); + library_->setDelayModelType(DelayModelType::polynomial); libWarn(attr, "delay_model %s not supported.\n.", type_name); } // Evil IBM garbage. else if (stringEq(type_name, "dcm")) { - library_->setDelayModelType(delay_model_dcm); + library_->setDelayModelType(DelayModelType::dcm); libWarn(attr, "delay_model %s not supported.\n.", type_name); } else @@ -1058,7 +1058,7 @@ LibertyReader::visitDefaultWireLoadMode(LibertyAttr *attr) const char *wire_load_mode = getAttrString(attr); if (wire_load_mode) { WireloadMode mode = stringWireloadMode(wire_load_mode); - if (mode != wire_load_mode_unknown) + if (mode != WireloadMode::unknown) library_->setDefaultWireloadMode(mode); else libWarn(attr, "default_wire_load_mode %s not found.\n", @@ -1213,13 +1213,13 @@ LibertyReader::visitSlewDerateFromLibrary(LibertyAttr *attr) void LibertyReader::beginTableTemplateDelay(LibertyGroup *group) { - beginTableTemplate(group, table_template_delay); + beginTableTemplate(group, TableTemplateType::delay); } void LibertyReader::beginTableTemplateOutputCurrent(LibertyGroup *group) { - beginTableTemplate(group, table_template_output_current); + beginTableTemplate(group, TableTemplateType::output_current); } void @@ -1234,7 +1234,7 @@ LibertyReader::beginTableTemplate(LibertyGroup *group, } else libWarn(group, "table template does not have a name.\n"); - axis_var_[0] = axis_var_[1] = axis_var_[2] = table_axis_unknown; + axis_var_[0] = axis_var_[1] = axis_var_[2] = TableAxisVariable::unknown; clearAxisValues(); } } @@ -1242,7 +1242,7 @@ LibertyReader::beginTableTemplate(LibertyGroup *group, void LibertyReader::clearAxisValues() { - axis_values_[0] = axis_values_[1] = axis_values_[2] = NULL; + axis_values_[0] = axis_values_[1] = axis_values_[2] = nullptr; } void @@ -1259,7 +1259,7 @@ LibertyReader::endTableTemplate(LibertyGroup *group) makeAxis(2, group, axis); if (axis) tbl_template_->setAxis3(axis); - tbl_template_ = NULL; + tbl_template_ = nullptr; } } @@ -1268,19 +1268,19 @@ LibertyReader::makeAxis(int index, LibertyGroup *group, TableAxis *&axis) { - axis = NULL; + axis = nullptr; TableAxisVariable axis_var = axis_var_[index]; FloatSeq *axis_values = axis_values_[index]; - if (axis_var != table_axis_unknown && axis_values) { + if (axis_var != TableAxisVariable::unknown && axis_values) { const Units *units = library_->units(); float scale = tableVariableUnit(axis_var, units)->scale(); scaleFloats(axis_values, scale); axis = new TableAxis(axis_var, axis_values); } - else if (axis_var == table_axis_unknown && axis_values) { + else if (axis_var == TableAxisVariable::unknown && axis_values) { libWarn(group, "missing variable_%d attribute.\n", index + 1); delete axis_values; - axis_values_[index] = NULL; + axis_values_[index] = nullptr; } // No warning for missing index_xx attributes because they are // not required by ic_shell. @@ -1319,7 +1319,7 @@ LibertyReader::visitVariable(int index, if (tbl_template_) { const char *type = getAttrString(attr); TableAxisVariable var = stringTableAxisVariable(type); - if (var == table_axis_unknown) + if (var == TableAxisVariable::unknown) libWarn(attr, "axis type %s not supported.\n", type); else axis_var_[index] = var; @@ -1426,9 +1426,9 @@ void LibertyReader::visitScaleFactorSuffix(LibertyAttr *attr) { if (scale_factors_) { - ScaleFactorPvt pvt = scale_factor_pvt_unknown; - ScaleFactorType type = scale_factor_unknown; - TransRiseFall *tr = NULL; + ScaleFactorPvt pvt = ScaleFactorPvt::unknown; + ScaleFactorType type = ScaleFactorType::unknown; + TransRiseFall *tr = nullptr; // Parse the attribute name. TokenParser parser(attr->name(), "_"); if (parser.hasNext()) @@ -1448,8 +1448,8 @@ LibertyReader::visitScaleFactorSuffix(LibertyAttr *attr) else if (stringEq(tr_name, "fall")) tr = TransRiseFall::fall(); } - if (pvt != scale_factor_pvt_unknown - && type != scale_factor_unknown + if (pvt != ScaleFactorPvt::unknown + && type != ScaleFactorType::unknown && tr) { float value; bool exists; @@ -1464,9 +1464,9 @@ void LibertyReader::visitScaleFactorPrefix(LibertyAttr *attr) { if (scale_factors_) { - ScaleFactorPvt pvt = scale_factor_pvt_unknown; - ScaleFactorType type = scale_factor_unknown; - TransRiseFall *tr = NULL; + ScaleFactorPvt pvt = ScaleFactorPvt::unknown; + ScaleFactorType type = ScaleFactorType::unknown; + TransRiseFall *tr = nullptr; // Parse the attribute name. TokenParser parser(attr->name(), "_"); if (parser.hasNext()) @@ -1486,8 +1486,8 @@ LibertyReader::visitScaleFactorPrefix(LibertyAttr *attr) const char *type_name = parser.next(); type = findScaleFactorType(type_name); } - if (pvt != scale_factor_pvt_unknown - && type != scale_factor_unknown + if (pvt != ScaleFactorPvt::unknown + && type != ScaleFactorType::unknown && tr) { float value; bool exists; @@ -1502,12 +1502,12 @@ void LibertyReader::visitScaleFactorHiLow(LibertyAttr *attr) { if (scale_factors_) { - ScaleFactorPvt pvt = scale_factor_pvt_unknown; - ScaleFactorType type = scale_factor_unknown; - TransRiseFall *tr = NULL; - const char *pvt_name = NULL; - const char *type_name = NULL; - const char *tr_name = NULL; + ScaleFactorPvt pvt = ScaleFactorPvt::unknown; + ScaleFactorType type = ScaleFactorType::unknown; + TransRiseFall *tr = nullptr; + const char *pvt_name = nullptr; + const char *type_name = nullptr; + const char *tr_name = nullptr; // Parse the attribute name. TokenParser parser(attr->name(), "_"); if (parser.hasNext()) @@ -1527,8 +1527,8 @@ LibertyReader::visitScaleFactorHiLow(LibertyAttr *attr) else if (stringEq(tr_name, "low")) tr = TransRiseFall::fall(); } - if (pvt != scale_factor_pvt_unknown - && type != scale_factor_unknown + if (pvt != ScaleFactorPvt::unknown + && type != ScaleFactorType::unknown && tr) { float value; bool exists; @@ -1543,10 +1543,10 @@ void LibertyReader::visitScaleFactor(LibertyAttr *attr) { if (scale_factors_) { - ScaleFactorPvt pvt = scale_factor_pvt_unknown; - ScaleFactorType type = scale_factor_unknown; - const char *pvt_name = NULL; - const char *type_name = NULL; + ScaleFactorPvt pvt = ScaleFactorPvt::unknown; + ScaleFactorType type = ScaleFactorType::unknown; + const char *pvt_name = nullptr; + const char *type_name = nullptr; // Parse the attribute name. TokenParser parser(attr->name(), " "); if (parser.hasNext()) @@ -1559,8 +1559,8 @@ LibertyReader::visitScaleFactor(LibertyAttr *attr) type_name = parser.next(); type = findScaleFactorType(type_name); } - if (pvt != scale_factor_pvt_unknown - && type != scale_factor_unknown) { + if (pvt != ScaleFactorPvt::unknown + && type != ScaleFactorType::unknown) { float value; bool exists; getAttrFloat(attr, value, exists); @@ -1635,7 +1635,7 @@ LibertyReader::visitTreeType(LibertyAttr *attr) void LibertyReader::endOpCond(LibertyGroup *) { - op_cond_ = NULL; + op_cond_ = nullptr; } //////////////////////////////////////////////////////////////// @@ -1657,7 +1657,7 @@ LibertyReader::beginWireload(LibertyGroup *group) void LibertyReader::endWireload(LibertyGroup *) { - wireload_ = NULL; + wireload_ = nullptr; } void @@ -1732,7 +1732,7 @@ LibertyReader::beginWireloadSelection(LibertyGroup *group) void LibertyReader::endWireloadSelection(LibertyGroup *) { - wireload_selection_ = NULL; + wireload_selection_ = nullptr; } void @@ -1808,7 +1808,7 @@ LibertyReader::endCell(LibertyGroup *group) if (ocv_derate_name_) { OcvDerate *derate = cell_->findOcvDerate(ocv_derate_name_); - if (derate == NULL) + if (derate == nullptr) derate = library_->findOcvDerate(ocv_derate_name_); if (derate) cell_->setOcvDerate(derate); @@ -1816,10 +1816,10 @@ LibertyReader::endCell(LibertyGroup *group) libWarn(group, "cell %s ocv_derate_group %s not found.\n", cell_->name(), ocv_derate_name_); stringDelete(ocv_derate_name_); - ocv_derate_name_ = NULL; + ocv_derate_name_ = nullptr; } cell_->finish(infer_latches_, report_, debug_); - cell_ = NULL; + cell_ = nullptr; } } @@ -1913,45 +1913,45 @@ LibertyReader::makeCellSequential(SequentialGroup *seq) ? (is_bank ? "ff_bank" : "ff") : (is_bank ? "latch_bank" : "latch"); const char *clk = seq->clock(); - FuncExpr *clk_expr = NULL; + FuncExpr *clk_expr = nullptr; if (clk) { const char *clk_attr = is_register ? "clocked_on" : "enable"; clk_expr = parseFunc(clk, clk_attr, line); if (clk_expr && clk_expr->checkSize(size)) { libWarn(line, "%s %s bus width mismatch.\n", type, clk_attr); clk_expr->deleteSubexprs(); - clk_expr = NULL; + clk_expr = nullptr; } } const char *data = seq->data(); - FuncExpr *data_expr = NULL; + FuncExpr *data_expr = nullptr; if (data) { const char *data_attr = is_register ? "next_state" : "data_in"; data_expr = parseFunc(data, data_attr, line); if (data_expr && data_expr->checkSize(size)) { libWarn(line, "%s %s bus width mismatch.\n", type, data_attr); data_expr->deleteSubexprs(); - data_expr = NULL; + data_expr = nullptr; } } const char *clr = seq->clear(); - FuncExpr *clr_expr = NULL; + FuncExpr *clr_expr = nullptr; if (clr) { clr_expr = parseFunc(clr, "clear", line); if (clr_expr && clr_expr->checkSize(size)) { libWarn(line, "%s %s bus width mismatch.\n", type, "clear"); clr_expr->deleteSubexprs(); - clr_expr = NULL; + clr_expr = nullptr; } } const char *preset = seq->preset(); - FuncExpr *preset_expr = NULL; + FuncExpr *preset_expr = nullptr; if (preset) { preset_expr = parseFunc(preset, "preset", line); if (preset_expr && preset_expr->checkSize(size)) { libWarn(line, "%s %s bus width mismatch.\n", type, "preset"); preset_expr->deleteSubexprs(); - preset_expr = NULL; + preset_expr = nullptr; } } cell_->makeSequential(size, is_register, clk_expr, data_expr, clr_expr, @@ -1981,15 +1981,15 @@ LibertyReader::checkLatchEnableSense(FuncExpr *enable_func, LibertyPort *enable_port = enable_iter.next(); TimingSense enable_sense = enable_func->portTimingSense(enable_port); switch (enable_sense) { - case timing_sense_positive_unate: - case timing_sense_negative_unate: + case TimingSense::positive_unate: + case TimingSense::negative_unate: break; - case timing_sense_non_unate: + case TimingSense::non_unate: libWarn(line, "latch enable function is non-unate for port %s.\n", enable_port->name()); break; - case timing_sense_none: - case timing_sense_unknown: + case TimingSense::none: + case TimingSense::unknown: libWarn(line, "latch enable function is unknown for port %s.\n", enable_port->name()); break; @@ -2089,9 +2089,9 @@ LibertyReader::endScaledCell(LibertyGroup *group) checkScaledCell(group); // Add scaled cell AFTER ports and timing arcs are defined. scaled_cell_owner_->addScaledCell(op_cond_, cell_); - cell_ = NULL; - scaled_cell_owner_ = NULL; - op_cond_ = NULL; + cell_ = nullptr; + scaled_cell_owner_ = nullptr; + op_cond_ = nullptr; } } @@ -2117,7 +2117,7 @@ void LibertyReader::makeTimingArcs(LibertyPort *to_port, TimingGroup *timing) { - LibertyPort *related_out_port = NULL; + LibertyPort *related_out_port = nullptr; const char *related_out_port_name = timing->relatedOutputPortName(); if (related_out_port_name) related_out_port = findPort(related_out_port_name); @@ -2125,7 +2125,7 @@ LibertyReader::makeTimingArcs(LibertyPort *to_port, PortDirection *to_port_dir = to_port->direction(); // Should be more comprehensive (timing checks on inputs, etc). TimingType type = timing->timingType(); - if (type == timing_type_combinational && + if (type == TimingType::combinational && to_port_dir->isInput()) libWarn(line, "combinational timing to an input port.\n"); StringSeq::Iterator related_port_iter(timing->relatedPortNames()); @@ -2146,16 +2146,16 @@ TimingGroup::makeTimingModels(LibertyLibrary *library, LibertyReader *visitor) { switch (library->delayModelType()) { - case delay_model_cmos_linear: + case DelayModelType::cmos_linear: makeLinearModels(library); break; - case delay_model_table: + case DelayModelType::table: makeTableModels(visitor); break; - case delay_model_cmos_pwl: - case delay_model_cmos2: - case delay_model_polynomial: - case delay_model_dcm: + case DelayModelType::cmos_pwl: + case DelayModelType::cmos2: + case DelayModelType::polynomial: + case DelayModelType::dcm: break; } } @@ -2171,7 +2171,7 @@ TimingGroup::makeLinearModels(LibertyLibrary *library) bool intr_exists = intrinsic_exists_[tr_index]; if (!intr_exists) library->defaultIntrinsic(tr, intr, intr_exists); - TimingModel *model = NULL; + TimingModel *model = nullptr; if (timingTypeIsCheck(timing_type_)) { if (intr_exists) model = new CheckLinearModel(intr); @@ -2204,22 +2204,22 @@ TimingGroup::makeTableModels(LibertyReader *visitor) if (cell || transition) { models_[tr_index] = new GateTableModel(cell, delay_sigma_[tr_index], transition, slew_sigma_[tr_index]); - if (timing_type_ == timing_type_clear - || timing_type_ == timing_type_combinational - || timing_type_ == timing_type_combinational_fall - || timing_type_ == timing_type_combinational_rise - || timing_type_ == timing_type_falling_edge - || timing_type_ == timing_type_preset - || timing_type_ == timing_type_rising_edge - || timing_type_ == timing_type_three_state_disable - || timing_type_ == timing_type_three_state_disable_rise - || timing_type_ == timing_type_three_state_disable_fall - || timing_type_ == timing_type_three_state_enable - || timing_type_ == timing_type_three_state_enable_fall - || timing_type_ == timing_type_three_state_enable_rise) { - if (transition == NULL) + if (timing_type_ == TimingType::clear + || timing_type_ == TimingType::combinational + || timing_type_ == TimingType::combinational_fall + || timing_type_ == TimingType::combinational_rise + || timing_type_ == TimingType::falling_edge + || timing_type_ == TimingType::preset + || timing_type_ == TimingType::rising_edge + || timing_type_ == TimingType::three_state_disable + || timing_type_ == TimingType::three_state_disable_rise + || timing_type_ == TimingType::three_state_disable_fall + || timing_type_ == TimingType::three_state_enable + || timing_type_ == TimingType::three_state_enable_fall + || timing_type_ == TimingType::three_state_enable_rise) { + if (transition == nullptr) visitor->libWarn(line_, "missing %s_transition.\n", tr->name()); - if (cell == NULL) + if (cell == nullptr) visitor->libWarn(line_, "missing cell_%s.\n", tr->name()); } } @@ -2320,11 +2320,11 @@ LibertyReader::makeInternalPowers(LibertyPort *port, LibertyPortMemberIterator bit_iter(port); while (bit_iter.hasNext()) { LibertyPort *port_bit = bit_iter.next(); - builder_->makeInternalPower(cell_, port_bit, NULL, power_group); + builder_->makeInternalPower(cell_, port_bit, nullptr, power_group); } } else - builder_->makeInternalPower(cell_, port, NULL, power_group); + builder_->makeInternalPower(cell_, port, nullptr, power_group); } } @@ -2474,11 +2474,11 @@ LibertyReader::visitClockGatingIntegratedCell(LibertyAttr *attr) const char *clock_gate_type = getAttrString(attr); if (clock_gate_type) { if (stringBeginEq(clock_gate_type, "latch_posedge")) - cell_->setClockGateType(clock_gate_latch_posedge); + cell_->setClockGateType(ClockGateType::latch_posedge); else if (stringBeginEq(clock_gate_type, "latch_negedge")) - cell_->setClockGateType(clock_gate_latch_negedge); + cell_->setClockGateType(ClockGateType::latch_negedge); else - cell_->setClockGateType(clock_gate_other); + cell_->setClockGateType(ClockGateType::other); } } } @@ -2521,7 +2521,7 @@ LibertyReader::beginPin(LibertyGroup *group) const char *name = param->stringValue(); debugPrint1(debug_, "liberty", 1, " port %s\n", name); LibertyPort *port = findPort(name); - if (port == NULL) + if (port == nullptr) port = builder_->makePort(cell_, name); ports_->push_back(port); setPortDefaults(port); @@ -2591,7 +2591,7 @@ LibertyReader::endPin(LibertyGroup *) port_group_ = saved_port_group_; } } - port_ = NULL; + port_ = nullptr; } void @@ -2614,8 +2614,8 @@ LibertyReader::endPorts() else setPortCapDefault(port); } - ports_ = NULL; - port_group_ = NULL; + ports_ = nullptr; + port_group_ = nullptr; } void @@ -2680,8 +2680,8 @@ LibertyReader::endBusOrBundle() endPorts(); deleteContents(&bus_names_); bus_names_.clear(); - ports_ = NULL; - port_group_ = NULL; + ports_ = nullptr; + port_group_ = nullptr; } // Bus port are not made until the bus_type is specified. @@ -2693,7 +2693,7 @@ LibertyReader::visitBusType(LibertyAttr *attr) if (bus_type) { // Look for bus dcl local to cell first. BusDcl *bus_dcl = cell_->findBusDcl(bus_type); - if (bus_dcl == NULL) + if (bus_dcl == nullptr) bus_dcl = library_->findBusDcl(bus_type); if (bus_dcl) { StringSeq::Iterator name_iter(bus_names_); @@ -2750,7 +2750,7 @@ LibertyReader::visitMembers(LibertyAttr *attr) if (value->isString()) { const char *port_name = value->stringValue(); LibertyPort *port = findPort(port_name); - if (port == NULL) + if (port == nullptr) port = builder_->makePort(cell_, port_name); members->push_back(port); } @@ -2777,7 +2777,7 @@ LibertyReader::findPort(LibertyCell *cell, const char *port_name) { LibertyPort *port = cell->findLibertyPort(port_name); - if (port == NULL) { + if (port == nullptr) { char brkt_left = library_->busBrktLeft(); char brkt_right = library_->busBrktRight(); if (isBusName(port_name, brkt_left, brkt_right)) { @@ -3129,8 +3129,8 @@ LibertyReader::visitPulseClock(LibertyAttr *attr) if (cell_) { const char *pulse_clk = getAttrString(attr); if (pulse_clk) { - TransRiseFall *trigger = NULL; - TransRiseFall *sense = NULL; + TransRiseFall *trigger = nullptr; + TransRiseFall *sense = nullptr; if (stringEq(pulse_clk, "rise_triggered_high_pulse")) { trigger = TransRiseFall::rise(); sense = TransRiseFall::rise(); @@ -3253,7 +3253,7 @@ LibertyReader::beginFF(LibertyGroup *group) void LibertyReader::endFF(LibertyGroup *) { - sequential_ = NULL; + sequential_ = nullptr; } void @@ -3265,7 +3265,7 @@ LibertyReader::beginFFBank(LibertyGroup *group) void LibertyReader::endFFBank(LibertyGroup *) { - sequential_ = NULL; + sequential_ = nullptr; } void @@ -3277,7 +3277,7 @@ LibertyReader::beginLatch(LibertyGroup *group) void LibertyReader::endLatch(LibertyGroup *) { - sequential_ = NULL; + sequential_ = nullptr; } void @@ -3289,7 +3289,7 @@ LibertyReader::beginLatchBank(LibertyGroup *group) void LibertyReader::endLatchBank(LibertyGroup *) { - sequential_ = NULL; + sequential_ = nullptr; } void @@ -3303,8 +3303,8 @@ LibertyReader::beginSequential(LibertyGroup *group, int size; bool has_size; seqPortNames(group, out_name, out_inv_name, has_size, size); - LibertyPort *out_port = NULL; - LibertyPort *out_port_inv = NULL; + LibertyPort *out_port = nullptr; + LibertyPort *out_port_inv = nullptr; if (out_name) { if (has_size) out_port = builder_->makeBusPort(cell_, out_name, size - 1, 0); @@ -3334,8 +3334,8 @@ LibertyReader::seqPortNames(LibertyGroup *group, int &size) { int i = 0; - out_name = NULL; - out_inv_name = NULL; + out_name = nullptr; + out_inv_name = nullptr; size = 1; has_size = false; LibertyAttrValueIterator param_iter(group->params()); @@ -3448,7 +3448,7 @@ LibertyReader::endTiming(LibertyGroup *) model->setScaleFactorType(type); } } - timing_ = NULL; + timing_ = nullptr; } } @@ -3526,7 +3526,7 @@ LibertyReader::visitTimingType(LibertyAttr *attr) const char *type_name = getAttrString(attr); if (type_name) { TimingType type = findTimingType(type_name); - if (type == timing_type_unknown) + if (type == TimingType::unknown) libWarn(attr, "unknown timing_type %s.\n", type_name); else timing_->setTimingType(type); @@ -3541,11 +3541,11 @@ LibertyReader::visitTimingSense(LibertyAttr *attr) const char *sense_name = getAttrString(attr); if (sense_name) { if (stringEq(sense_name, "non_unate")) - timing_->setTimingSense(timing_sense_non_unate); + timing_->setTimingSense(TimingSense::non_unate); else if (stringEq(sense_name, "positive_unate")) - timing_->setTimingSense(timing_sense_positive_unate); + timing_->setTimingSense(TimingSense::positive_unate); else if (stringEq(sense_name, "negative_unate")) - timing_->setTimingSense(timing_sense_negative_unate); + timing_->setTimingSense(TimingSense::negative_unate); else libWarn(attr, "unknown timing_sense %s.\n", sense_name); } @@ -3656,13 +3656,13 @@ LibertyReader::visitRiseFallResistance(LibertyAttr *attr, void LibertyReader::beginCellRise(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::rise(), scale_factor_cell); + beginTimingTableModel(group, TransRiseFall::rise(), ScaleFactorType::cell); } void LibertyReader::beginCellFall(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::fall(), scale_factor_cell); + beginTimingTableModel(group, TransRiseFall::fall(), ScaleFactorType::cell); } void @@ -3684,13 +3684,13 @@ LibertyReader::endCellRiseFall(LibertyGroup *group) void LibertyReader::beginRiseTransition(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::rise(), scale_factor_transition); + beginTimingTableModel(group, TransRiseFall::rise(), ScaleFactorType::transition); } void LibertyReader::beginFallTransition(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::fall(), scale_factor_transition); + beginTimingTableModel(group, TransRiseFall::fall(), ScaleFactorType::transition); } void @@ -3713,14 +3713,14 @@ void LibertyReader::beginRiseConstraint(LibertyGroup *group) { // Scale factor depends on timing_type, which may follow this stmt. - beginTimingTableModel(group, TransRiseFall::rise(), scale_factor_unknown); + beginTimingTableModel(group, TransRiseFall::rise(), ScaleFactorType::unknown); } void LibertyReader::beginFallConstraint(LibertyGroup *group) { // Scale factor depends on timing_type, which may follow this stmt. - beginTimingTableModel(group, TransRiseFall::fall(), scale_factor_unknown); + beginTimingTableModel(group, TransRiseFall::fall(), ScaleFactorType::unknown); } void @@ -3745,18 +3745,18 @@ void LibertyReader::beginRiseTransitionDegredation(LibertyGroup *group) { if (library_) - beginTableModel(group, table_template_delay, + beginTableModel(group, TableTemplateType::delay, TransRiseFall::rise(), time_scale_, - scale_factor_transition); + ScaleFactorType::transition); } void LibertyReader::beginFallTransitionDegredation(LibertyGroup *group) { if (library_) - beginTableModel(group, table_template_delay, + beginTableModel(group, TableTemplateType::delay, TransRiseFall::fall(), time_scale_, - scale_factor_transition); + ScaleFactorType::transition); } void @@ -3783,7 +3783,7 @@ LibertyReader::beginTimingTableModel(LibertyGroup *group, ScaleFactorType scale_factor_type) { if (timing_) - beginTableModel(group, table_template_delay, tr, + beginTableModel(group, TableTemplateType::delay, tr, time_scale_, scale_factor_type); } @@ -3821,11 +3821,11 @@ LibertyReader::beginTable(LibertyGroup *group, } else { libWarn(group, "table template %s not found.\n", template_name); - axis_[0] = axis_[1] = axis_[2] = NULL; + axis_[0] = axis_[1] = axis_[2] = nullptr; } clearAxisValues(); own_axis_[0] = own_axis_[1] = own_axis_[2] = false; - table_ = NULL; + table_ = nullptr; table_model_scale_ = scale; } } @@ -3833,8 +3833,8 @@ LibertyReader::beginTable(LibertyGroup *group, void LibertyReader::endTable() { - table_ = NULL; - tbl_template_ = NULL; + table_ = nullptr; + tbl_template_ = nullptr; } void @@ -4017,14 +4017,14 @@ LibertyReader::beginTestCell(LibertyGroup *) test_cell_ = new TestCell; cell_->setTestCell(test_cell_); save_cell_ = cell_; - cell_ = NULL; + cell_ = nullptr; } void LibertyReader::endTestCell(LibertyGroup *) { cell_ = save_cell_; - test_cell_ = NULL; + test_cell_ = nullptr; } //////////////////////////////////////////////////////////////// @@ -4042,7 +4042,7 @@ LibertyReader::beginModeDef(LibertyGroup *group) void LibertyReader::endModeDef(LibertyGroup *) { - mode_def_ = NULL; + mode_def_ = nullptr; } void @@ -4051,7 +4051,7 @@ LibertyReader::beginModeValue(LibertyGroup *group) if (mode_def_) { const char *name = group->firstName(); if (name) - mode_value_ = mode_def_->defineValue(name, NULL, NULL); + mode_value_ = mode_def_->defineValue(name, nullptr, nullptr); else libWarn(group, "mode value does not have a name.\n"); } @@ -4060,7 +4060,7 @@ LibertyReader::beginModeValue(LibertyGroup *group) void LibertyReader::endModeValue(LibertyGroup *) { - mode_value_ = NULL; + mode_value_ = nullptr; } void @@ -4120,7 +4120,7 @@ LibertyReader::getAttrString(LibertyAttr *attr) } else libWarn(attr, "%s is not a simple attribute.\n", attr->name()); - return NULL; + return nullptr; } void @@ -4238,7 +4238,7 @@ LibertyReader::parseStringFloatList(const char *float_list, if (end == token || (end && !(*end == '\0' || isspace(*end) - || strchr(delimiters, *end) != NULL + || strchr(delimiters, *end) != nullptr || *end == '}'))) libWarn(attr, "%s is not a float.\n", token); values->push_back(value); @@ -4249,7 +4249,7 @@ FloatSeq * LibertyReader::readFloatSeq(LibertyAttr *attr, float scale) { - FloatSeq *values = NULL; + FloatSeq *values = nullptr; if (attr->isComplex()) { LibertyAttrValueIterator value_iter(attr->values()); if (value_iter.hasNext()) { @@ -4312,17 +4312,17 @@ LibertyReader::getAttrLogicValue(LibertyAttr *attr) const char *str = getAttrString(attr); if (str) { if (stringEq(str, "L")) - return logic_zero; + return LogicValue::zero; else if (stringEq(str, "H")) - return logic_one; + return LogicValue::one; else if (stringEq(str, "X")) - return logic_unknown; + return LogicValue::unknown; else libWarn(attr, "attribute %s value %s not recognized.\n", attr->name(), str); // fall thru } - return logic_unknown; + return LogicValue::unknown; } FuncExpr * @@ -4356,7 +4356,7 @@ LibertyReader::getAttrEarlyLate(LibertyAttr *attr) void LibertyReader::visitVariable(LibertyVariable *var) { - if (var_map_ == NULL) + if (var_map_ == nullptr) var_map_ = new LibertyVariableMap; const char *var_name = var->variable(); const char *key; @@ -4422,7 +4422,7 @@ LibertyReader::libError(LibertyStmt *stmt, void LibertyReader::beginTableTemplatePower(LibertyGroup *group) { - beginTableTemplate(group, table_template_power); + beginTableTemplate(group, TableTemplateType::power); } void @@ -4437,7 +4437,7 @@ LibertyReader::beginLeakagePower(LibertyGroup *group) void LibertyReader::endLeakagePower(LibertyGroup *) { - leakage_power_ = NULL; + leakage_power_ = nullptr; } void @@ -4458,25 +4458,25 @@ LibertyReader::makeInternalPowerGroup(int line) void LibertyReader::endInternalPower(LibertyGroup *) { - internal_power_ = NULL; + internal_power_ = nullptr; } void LibertyReader::beginFallPower(LibertyGroup *group) { if (internal_power_) - beginTableModel(group, table_template_power, + beginTableModel(group, TableTemplateType::power, TransRiseFall::fall(), energy_scale_, - scale_factor_internal_power); + ScaleFactorType::internal_power); } void LibertyReader::beginRisePower(LibertyGroup *group) { if (internal_power_) - beginTableModel(group, table_template_power, + beginTableModel(group, TableTemplateType::power, TransRiseFall::rise(), energy_scale_, - scale_factor_internal_power); + ScaleFactorType::internal_power); } void @@ -4527,7 +4527,7 @@ LibertyReader::visitRelatedPgPin(LibertyAttr *attr) void LibertyReader::beginTableTemplateOcv(LibertyGroup *group) { - beginTableTemplate(group, table_template_ocv); + beginTableTemplate(group, TableTemplateType::ocv); } void @@ -4580,7 +4580,7 @@ LibertyReader::endOcvDerate(LibertyGroup *) library_->addOcvDerate(ocv_derate_); else if (library_) library_->addOcvDerate(ocv_derate_); - ocv_derate_ = NULL; + ocv_derate_ = nullptr; } void @@ -4589,8 +4589,8 @@ LibertyReader::beginOcvDerateFactors(LibertyGroup *group) if (ocv_derate_) { rf_type_ = TransRiseFallBoth::riseFall(); derate_type_ = EarlyLateAll::all(); - path_type_ = path_type_clk_and_data; - beginTable(group, table_template_ocv, 1.0); + path_type_ = PathType::clk_and_data; + beginTable(group, TableTemplateType::ocv, 1.0); } } @@ -4604,9 +4604,9 @@ LibertyReader::endOcvDerateFactors(LibertyGroup *) TransRiseFallIterator tr_iter(rf_type_); while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); - if (path_type_ == path_type_clk_and_data) { - ocv_derate_->setDerateTable(tr, early_late, path_type_clk, table_); - ocv_derate_->setDerateTable(tr, early_late, path_type_data, table_); + if (path_type_ == PathType::clk_and_data) { + ocv_derate_->setDerateTable(tr, early_late, PathType::clk, table_); + ocv_derate_->setDerateTable(tr, early_late, PathType::data, table_); } else ocv_derate_->setDerateTable(tr, early_late, path_type_, table_); @@ -4641,11 +4641,11 @@ LibertyReader::visitPathType(LibertyAttr *attr) { const char *path_type = getAttrString(attr); if (stringEq(path_type, "clock")) - path_type_ = path_type_clk; + path_type_ = PathType::clk; else if (stringEq(path_type, "data")) - path_type_ = path_type_data; + path_type_ = PathType::data; else if (stringEq(path_type, "clock_and_data")) - path_type_ = path_type_clk_and_data; + path_type_ = PathType::clk_and_data; else libWarn(attr, "unknown derate type.\n"); } @@ -4655,13 +4655,13 @@ LibertyReader::visitPathType(LibertyAttr *attr) void LibertyReader::beginOcvSigmaCellRise(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::rise(), scale_factor_unknown); + beginTimingTableModel(group, TransRiseFall::rise(), ScaleFactorType::unknown); } void LibertyReader::beginOcvSigmaCellFall(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::fall(), scale_factor_unknown); + beginTimingTableModel(group, TransRiseFall::fall(), ScaleFactorType::unknown); } void @@ -4688,13 +4688,13 @@ LibertyReader::endOcvSigmaCell(LibertyGroup *group) void LibertyReader::beginOcvSigmaRiseTransition(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::rise(), scale_factor_unknown); + beginTimingTableModel(group, TransRiseFall::rise(), ScaleFactorType::unknown); } void LibertyReader::beginOcvSigmaFallTransition(LibertyGroup *group) { - beginTimingTableModel(group, TransRiseFall::fall(), scale_factor_unknown); + beginTimingTableModel(group, TransRiseFall::fall(), ScaleFactorType::unknown); } void @@ -4749,7 +4749,7 @@ LibertyReader::beginPgPin(LibertyGroup *group) void LibertyReader::endPgPin(LibertyGroup *) { - pg_port_ = NULL; + pg_port_ = nullptr; } void @@ -4860,12 +4860,12 @@ SequentialGroup::SequentialGroup(bool is_register, out_port_(out_port), out_inv_port_(out_inv_port), size_(size), - clk_(NULL), - data_(NULL), - preset_(NULL), - clear_(NULL), - clr_preset_var1_(logic_unknown), - clr_preset_var2_(logic_unknown), + clk_(nullptr), + data_(nullptr), + preset_(nullptr), + clear_(nullptr), + clr_preset_var1_(LogicValue::unknown), + clr_preset_var2_(LogicValue::unknown), line_(line) { } @@ -4921,7 +4921,7 @@ SequentialGroup::setClrPresetVar2(LogicValue var) //////////////////////////////////////////////////////////////// RelatedPortGroup::RelatedPortGroup(int line) : - related_port_names_(NULL), + related_port_names_(nullptr), line_(line) { } @@ -4951,15 +4951,15 @@ RelatedPortGroup::setIsOneToOne(bool one) TimingGroup::TimingGroup(int line) : TimingArcAttrs(), RelatedPortGroup(line), - related_output_port_name_(NULL) + related_output_port_name_(nullptr) { TransRiseFallIterator tr_iter; while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); int tr_index = tr->index(); - cell_[tr_index] = NULL; - constraint_[tr_index] = NULL; - transition_[tr_index] = NULL; + cell_[tr_index] = nullptr; + constraint_[tr_index] = nullptr; + transition_[tr_index] = nullptr; intrinsic_[tr_index] = 0.0F; intrinsic_exists_[tr_index] = false; resistance_[tr_index] = 0.0F; @@ -4969,8 +4969,8 @@ TimingGroup::TimingGroup(int line) : while (el_iter.hasNext()) { EarlyLate *early_late = el_iter.next(); int el_index = early_late->index(); - delay_sigma_[tr_index][el_index] = NULL; - slew_sigma_[tr_index][el_index] = NULL; + delay_sigma_[tr_index][el_index] = nullptr; + slew_sigma_[tr_index][el_index] = nullptr; } } } @@ -5117,11 +5117,11 @@ PortNameBitIterator::PortNameBitIterator(LibertyCell *cell, cell_(cell), visitor_(visitor), line_(line), - port_(NULL), - bit_iterator_(NULL), - range_bus_port_(NULL), - range_bus_name_(NULL), - range_name_next_(NULL), + port_(nullptr), + bit_iterator_(nullptr), + range_bus_port_(nullptr), + range_bus_name_(nullptr), + range_name_next_(nullptr), size_(0) { init(port_name); @@ -5204,7 +5204,7 @@ PortNameBitIterator::next() { if (port_) { LibertyPort *next = port_; - port_ = NULL; + port_ = nullptr; return next; } else if (bit_iterator_) @@ -5223,7 +5223,7 @@ PortNameBitIterator::next() return next; } else - return NULL; + return nullptr; } void @@ -5249,7 +5249,7 @@ PortNameBitIterator::findRangeBusNameNext() visitor_->libWarn(line_, "port %s not found.\n", bus_bit_name); } else - range_name_next_ = NULL; + range_name_next_ = nullptr; } } // namespace diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index ac89fe41..21e1bb4c 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -168,7 +168,7 @@ GateTableModel::reportTableLookup(const char *result_name, findAxisValues(model, in_slew, load_cap, related_out_cap, axis_value1, axis_value2, axis_value3); model->reportValue(result_name, library, cell, pvt, - axis_value1, NULL, axis_value2, axis_value3, + axis_value1, nullptr, axis_value2, axis_value3, digits, result); } } @@ -258,19 +258,19 @@ GateTableModel::maxCapSlew(const LibertyCell *cell, TableAxis *axis2 = slew_model_->axis2(); TableAxis *axis3 = slew_model_->axis3(); if (axis1 - && axis1->variable() == table_axis_total_output_net_capacitance) { + && axis1->variable() == TableAxisVariable::total_output_net_capacitance) { cap = axis1->axisValue(axis1->size() - 1); slew = findValue(library, cell, pvt, slew_model_, in_slew, cap, 0.0); } else if (axis2 - && axis2->variable()==table_axis_total_output_net_capacitance) { + && axis2->variable()==TableAxisVariable::total_output_net_capacitance) { cap = axis2->axisValue(axis2->size() - 1); slew = findValue(library, cell, pvt, slew_model_, in_slew, cap, 0.0); } else if (axis3 - && axis3->variable()==table_axis_total_output_net_capacitance) { + && axis3->variable()==TableAxisVariable::total_output_net_capacitance) { cap = axis3->axisValue(axis3->size() - 1); slew = findValue(library, cell, pvt, slew_model_, in_slew, cap, 0.0); @@ -292,12 +292,12 @@ GateTableModel::axisValue(TableAxis *axis, float related_out_cap) const { TableAxisVariable var = axis->variable(); - if (var == table_axis_input_transition_time - || var == table_axis_input_net_transition) + if (var == TableAxisVariable::input_transition_time + || var == TableAxisVariable::input_net_transition) return in_slew; - else if (var == table_axis_total_output_net_capacitance) + else if (var == TableAxisVariable::total_output_net_capacitance) return load_cap; - else if (var == table_axis_related_out_total_output_net_capacitance) + else if (var == TableAxisVariable::related_out_total_output_net_capacitance) return related_out_cap; else { internalError("unsupported table axes"); @@ -325,10 +325,10 @@ bool GateTableModel::checkAxis(TableAxis *axis) { TableAxisVariable var = axis->variable(); - return var == table_axis_total_output_net_capacitance - || var == table_axis_input_transition_time - || var == table_axis_input_net_transition - || var == table_axis_related_out_total_output_net_capacitance; + 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; } //////////////////////////////////////////////////////////////// @@ -498,11 +498,11 @@ CheckTableModel::axisValue(TableAxis *axis, float related_out_cap) const { TableAxisVariable var = axis->variable(); - if (var == table_axis_related_pin_transition) + if (var == TableAxisVariable::related_pin_transition) return from_slew; - else if (var == table_axis_constrained_pin_transition) + else if (var == TableAxisVariable::constrained_pin_transition) return to_slew; - else if (var == table_axis_related_out_total_output_net_capacitance) + else if (var == TableAxisVariable::related_out_total_output_net_capacitance) return related_out_cap; else { internalError("unsupported table axes"); @@ -530,9 +530,9 @@ bool CheckTableModel::checkAxis(TableAxis *axis) { TableAxisVariable var = axis->variable(); - return var == table_axis_constrained_pin_transition - || var == table_axis_related_pin_transition - || var == table_axis_related_out_total_output_net_capacitance; + return var == TableAxisVariable::constrained_pin_transition + || var == TableAxisVariable::related_pin_transition + || var == TableAxisVariable::related_out_total_output_net_capacitance; } //////////////////////////////////////////////////////////////// @@ -541,7 +541,7 @@ TableModel::TableModel(Table *table, ScaleFactorType scale_factor_type, TransRiseFall *tr) : table_(table), - scale_factor_type_(scale_factor_type), + scale_factor_type_(int(scale_factor_type)), tr_index_(tr->index()), is_scaled_(false) { @@ -561,7 +561,7 @@ TableModel::order() const void TableModel::setScaleFactorType(ScaleFactorType type) { - scale_factor_type_ = type; + scale_factor_type_ = int(type); } void @@ -609,10 +609,9 @@ TableModel::scaleFactor(const LibertyLibrary *library, // Scaled tables are not derated because scale factors are wrt // nominal pvt. return 1.0F; - else { - ScaleFactorType type = static_cast(scale_factor_type_); - return library->scaleFactor(type, tr_index_, cell, pvt); - } + else + return library->scaleFactor(static_cast(scale_factor_type_), + tr_index_, cell, pvt); } void @@ -647,7 +646,7 @@ reportPvt(const LibertyLibrary *library, int digits, string *result) { - if (pvt == NULL) + if (pvt == nullptr) pvt = library->defaultOperatingConditions(); if (pvt) { string pvt_str; @@ -666,7 +665,7 @@ TableModel::reportPvtScaleFactor(const LibertyLibrary *library, int digits, string *result) const { - if (pvt == NULL) + if (pvt == nullptr) pvt = library->defaultOperatingConditions(); if (pvt) { string scale_str; @@ -1332,74 +1331,74 @@ TableAxisVariable stringTableAxisVariable(const char *variable) { if (stringEq(variable, "total_output_net_capacitance")) - return table_axis_total_output_net_capacitance; + return TableAxisVariable::total_output_net_capacitance; if (stringEq(variable, "equal_or_opposite_output_net_capacitance")) - return table_axis_equal_or_opposite_output_net_capacitance; + return TableAxisVariable::equal_or_opposite_output_net_capacitance; else if (stringEq(variable, "input_net_transition")) - return table_axis_input_net_transition; + return TableAxisVariable::input_net_transition; else if (stringEq(variable, "input_transition_time")) - return table_axis_input_transition_time; + return TableAxisVariable::input_transition_time; else if (stringEq(variable, "related_pin_transition")) - return table_axis_related_pin_transition; + return TableAxisVariable::related_pin_transition; else if (stringEq(variable, "constrained_pin_transition")) - return table_axis_constrained_pin_transition; + return TableAxisVariable::constrained_pin_transition; else if (stringEq(variable, "output_pin_transition")) - return table_axis_output_pin_transition; + return TableAxisVariable::output_pin_transition; else if (stringEq(variable, "connect_delay")) - return table_axis_connect_delay; + return TableAxisVariable::connect_delay; else if (stringEq(variable,"related_out_total_output_net_capacitance")) - return table_axis_related_out_total_output_net_capacitance; + return TableAxisVariable::related_out_total_output_net_capacitance; else if (stringEq(variable, "time")) - return table_axis_time; + return TableAxisVariable::time; else if (stringEq(variable, "iv_output_voltage")) - return table_axis_iv_output_voltage; + return TableAxisVariable::iv_output_voltage; else if (stringEq(variable, "input_noise_width")) - return table_axis_input_noise_width; + return TableAxisVariable::input_noise_width; else if (stringEq(variable, "input_noise_height")) - return table_axis_input_noise_height; + return TableAxisVariable::input_noise_height; else if (stringEq(variable, "input_voltage")) - return table_axis_input_voltage; + return TableAxisVariable::input_voltage; else if (stringEq(variable, "output_voltage")) - return table_axis_output_voltage; + return TableAxisVariable::output_voltage; else if (stringEq(variable, "path_depth")) - return table_axis_path_depth; + return TableAxisVariable::path_depth; else if (stringEq(variable, "path_distance")) - return table_axis_path_distance; + return TableAxisVariable::path_distance; else if (stringEq(variable, "normalzied_voltage")) - return table_axis_normalized_voltage; + return TableAxisVariable::normalized_voltage; else - return table_axis_unknown; + return TableAxisVariable::unknown; } const char * tableVariableString(TableAxisVariable variable) { switch (variable) { - case table_axis_total_output_net_capacitance: + case TableAxisVariable::total_output_net_capacitance: return "total_output_net_capacitance"; - case table_axis_equal_or_opposite_output_net_capacitance: + case TableAxisVariable::equal_or_opposite_output_net_capacitance: return "equal_or_opposite_output_net_capacitance"; - case table_axis_input_net_transition: + case TableAxisVariable::input_net_transition: return "input_net_transition"; - case table_axis_input_transition_time: + case TableAxisVariable::input_transition_time: return "input_transition_time"; - case table_axis_related_pin_transition: + case TableAxisVariable::related_pin_transition: return "related_pin_transition"; - case table_axis_constrained_pin_transition: + case TableAxisVariable::constrained_pin_transition: return "constrained_pin_transition"; - case table_axis_output_pin_transition: + case TableAxisVariable::output_pin_transition: return "output_pin_transition"; - case table_axis_connect_delay: + case TableAxisVariable::connect_delay: return "connect_delay"; - case table_axis_related_out_total_output_net_capacitance: + case TableAxisVariable::related_out_total_output_net_capacitance: return "related_out_total_output_net_capacitance"; - case table_axis_time: + case TableAxisVariable::time: return "time"; - case table_axis_iv_output_voltage: + case TableAxisVariable::iv_output_voltage: return "iv_output_voltage"; - case table_axis_input_noise_width: + case TableAxisVariable::input_noise_width: return "input_noise_width"; - case table_axis_input_noise_height: + case TableAxisVariable::input_noise_height: return "input_noise_height"; default: return "unknown"; @@ -1411,33 +1410,33 @@ tableVariableUnit(TableAxisVariable variable, const Units *units) { switch (variable) { - case table_axis_total_output_net_capacitance: - case table_axis_related_out_total_output_net_capacitance: - case table_axis_equal_or_opposite_output_net_capacitance: + 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 table_axis_input_net_transition: - case table_axis_input_transition_time: - case table_axis_related_pin_transition: - case table_axis_constrained_pin_transition: - case table_axis_output_pin_transition: - case table_axis_connect_delay: - case table_axis_time: - case table_axis_input_noise_height: + 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 table_axis_input_voltage: - case table_axis_output_voltage: - case table_axis_iv_output_voltage: - case table_axis_input_noise_width: + case TableAxisVariable::input_voltage: + case TableAxisVariable::output_voltage: + case TableAxisVariable::iv_output_voltage: + case TableAxisVariable::input_noise_width: return units->voltageUnit(); - case table_axis_path_distance: + case TableAxisVariable::path_distance: return units->distanceUnit(); - case table_axis_path_depth: - case table_axis_normalized_voltage: - case table_axis_unknown: + case TableAxisVariable::path_depth: + case TableAxisVariable::normalized_voltage: + case TableAxisVariable::unknown: return units->scalarUnit(); } // Prevent warnings from lame compilers. - return NULL; + return nullptr; } } // namespace diff --git a/liberty/TableModel.hh b/liberty/TableModel.hh index d96b4354..9c08a20d 100644 --- a/liberty/TableModel.hh +++ b/liberty/TableModel.hh @@ -239,8 +239,9 @@ protected: string *result) const; Table *table_; - unsigned int scale_factor_type_:scale_factor_bits; - unsigned int tr_index_:TransRiseFall::index_bit_count; + // ScaleFactorType gcc barfs if this is dcl'd. + unsigned scale_factor_type_:scale_factor_bits; + unsigned tr_index_:TransRiseFall::index_bit_count; bool is_scaled_:1; private: @@ -255,9 +256,9 @@ public: virtual ~Table() {} void setScaleFactorType(ScaleFactorType type); virtual int order() const = 0; - virtual TableAxis *axis1() const { return NULL; } - virtual TableAxis *axis2() const { return NULL; } - virtual TableAxis *axis3() const { return NULL; } + virtual TableAxis *axis1() const { return nullptr; } + virtual TableAxis *axis2() const { return nullptr; } + virtual TableAxis *axis3() const { return nullptr; } void setIsScaled(bool is_scaled); // Table interpolated lookup. virtual float findValue(float value1, diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index 1f339ec7..aa022939 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -15,6 +15,7 @@ // along with this program. If not, see . #include "Machine.hh" +#include "EnumNameMap.hh" #include "FuncExpr.hh" #include "TimingRole.hh" #include "Liberty.hh" @@ -33,16 +34,16 @@ timingArcsLess(const TimingArcSet *set1, //////////////////////////////////////////////////////////////// TimingArcAttrs::TimingArcAttrs() : - timing_type_(timing_type_combinational), - timing_sense_(timing_sense_unknown), - cond_(NULL), - sdf_cond_(NULL), - sdf_cond_start_(NULL), - sdf_cond_end_(NULL), - mode_name_(NULL), - mode_value_(NULL), + timing_type_(TimingType::combinational), + timing_sense_(TimingSense::unknown), + cond_(nullptr), + sdf_cond_(nullptr), + sdf_cond_start_(nullptr), + sdf_cond_end_(nullptr), + mode_name_(nullptr), + mode_value_(nullptr), ocv_arc_depth_(0.0), - models_{NULL, NULL} + models_{nullptr, nullptr} { } @@ -135,7 +136,7 @@ TimingArcAttrs::setOcvArcDepth(float depth) //////////////////////////////////////////////////////////////// -TimingArcSet *TimingArcSet::wire_timing_arc_set_ = NULL; +TimingArcSet *TimingArcSet::wire_timing_arc_set_ = nullptr; TimingArcSet::TimingArcSet(LibertyCell *cell, LibertyPort *from, @@ -165,20 +166,20 @@ TimingArcSet::TimingArcSet(LibertyCell *cell, } TimingArcSet::TimingArcSet(TimingRole *role) : - from_(NULL), - to_(NULL), - related_out_(NULL), + from_(nullptr), + to_(nullptr), + related_out_(nullptr), role_(role), - cond_(NULL), + cond_(nullptr), is_cond_default_(false), - sdf_cond_start_(NULL), - sdf_cond_end_(NULL), - mode_name_(NULL), - mode_value_(NULL), + sdf_cond_start_(nullptr), + sdf_cond_end_(nullptr), + mode_name_(nullptr), + mode_value_(nullptr), index_(0), is_disabled_constraint_(false) { - init(NULL); + init(nullptr); } void @@ -191,8 +192,8 @@ TimingArcSet::init(LibertyCell *cell) while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); int tr_index = tr->index(); - from_arc1_[tr_index] = NULL; - from_arc2_[tr_index] = NULL; + from_arc1_[tr_index] = nullptr; + from_arc2_[tr_index] = nullptr; } } @@ -208,7 +209,7 @@ TimingArcSet::libertyCell() const return from_->libertyCell(); else // Wire timing arc set. - return NULL; + return nullptr; } TimingArcSetArcIterator * @@ -226,9 +227,9 @@ TimingArcSet::addTimingArc(TimingArc *arc) arcs_.push_back(arc); int from_tr_index = arc->fromTrans()->asRiseFall()->index(); - if (from_arc1_[from_tr_index] == NULL) + if (from_arc1_[from_tr_index] == nullptr) from_arc1_[from_tr_index] = arc; - else if (from_arc2_[from_tr_index] == NULL) + else if (from_arc2_[from_tr_index] == nullptr) from_arc2_[from_tr_index] = arc; return arc_index; @@ -248,10 +249,10 @@ TimingArcSet::deleteTimingArc(TimingArc *arc) int from_tr_index = arc->fromTrans()->asRiseFall()->index(); if (from_arc1_[from_tr_index] == arc) { from_arc1_[from_tr_index] = from_arc2_[from_tr_index]; - from_arc2_[from_tr_index] = NULL; + from_arc2_[from_tr_index] = nullptr; } else if (from_arc2_[from_tr_index] == arc) - from_arc2_[from_tr_index] = NULL; + from_arc2_[from_tr_index] = nullptr; delete arc; } @@ -292,7 +293,7 @@ TimingArcSet::sense() const else if (arcs_.size() == 2 && arcs_[0]->sense() == arcs_[1]->sense()) return arcs_[0]->sense(); else - return timing_sense_non_unate; + return TimingSense::non_unate; } TransRiseFall * @@ -308,7 +309,7 @@ TimingArcSet::isRisingFallingEdge() const if (arcs_.size() == 1) return arcs_[0]->fromTrans()->asRiseFall(); else - return NULL; + return nullptr; } void @@ -475,16 +476,16 @@ TimingArcSet::init() { wire_timing_arc_set_ = new TimingArcSet(TimingRole::wire()); new TimingArc(wire_timing_arc_set_, Transition::rise(), - Transition::rise(), NULL); + Transition::rise(), nullptr); new TimingArc(wire_timing_arc_set_, Transition::fall(), - Transition::fall(), NULL); + Transition::fall(), nullptr); } void TimingArcSet::destroy() { delete wire_timing_arc_set_; - wire_timing_arc_set_ = NULL; + wire_timing_arc_set_ = nullptr; } //////////////////////////////////////////////////////////////// @@ -504,7 +505,7 @@ TimingArc::TimingArc(TimingArcSet *set, from_tr_(from_tr), to_tr_(to_tr), model_(model), - scaled_models_(NULL) + scaled_models_(nullptr) { index_ = set->addTimingArc(this); } @@ -534,7 +535,7 @@ void TimingArc::addScaledModel(const OperatingConditions *op_cond, TimingModel *scaled_model) { - if (scaled_models_ == NULL) + if (scaled_models_ == nullptr) scaled_models_ = new ScaledTimingModelMap; (*scaled_models_)[op_cond] = scaled_model; } @@ -582,154 +583,129 @@ TimingArc::sense() const && to_tr_ == Transition::rise()) || (from_tr_ == Transition::fall() && to_tr_ == Transition::fall())) - return timing_sense_positive_unate; + return TimingSense::positive_unate; else if ((from_tr_ == Transition::rise() && to_tr_ == Transition::fall()) || (from_tr_ == Transition::fall() && to_tr_ == Transition::rise())) - return timing_sense_negative_unate; + return TimingSense::negative_unate; else - return timing_sense_non_unate; + return TimingSense::non_unate; } +static EnumNameMap timing_sense_name_map = + {{TimingSense::positive_unate, "positive_unate"}, + {TimingSense::negative_unate, "negative_unate"}, + {TimingSense::non_unate, "non_unate"}, + {TimingSense::none, "none"}, + {TimingSense::unknown, "unknown"} + }; + const char * timingSenseString(TimingSense sense) { - static const char *sense_string[] = {"positive_unate", - "negative_unate", - "non_unate", - "none", - "unknown"}; - return sense_string[sense]; + return timing_sense_name_map.find(sense); } TimingSense timingSenseOpposite(TimingSense sense) { switch (sense) { - case timing_sense_positive_unate: - return timing_sense_negative_unate; - case timing_sense_negative_unate: - return timing_sense_positive_unate; - case timing_sense_non_unate: - return timing_sense_non_unate; - case timing_sense_unknown: - return timing_sense_unknown; - case timing_sense_none: - return timing_sense_none; + case TimingSense::positive_unate: + return TimingSense::negative_unate; + case TimingSense::negative_unate: + return TimingSense::positive_unate; + case TimingSense::non_unate: + return TimingSense::non_unate; + case TimingSense::unknown: + return TimingSense::unknown; + case TimingSense::none: + return TimingSense::none; } // Prevent warnings from lame compilers. - return timing_sense_unknown; + return TimingSense::unknown; } //////////////////////////////////////////////////////////////// // Same order as enum TimingType. -static const char *timing_type_strings[] = { - "clear", - "combinational", - "combinational_fall", - "combinational_rise", - "falling_edge", - "hold_falling", - "hold_rising", - "min_pulse_width", - "minimum_period", - "nochange_high_high", - "nochange_high_low", - "nochange_low_high", - "nochange_low_low", - "non_seq_hold_falling", - "non_seq_hold_rising", - "non_seq_setup_falling", - "non_seq_setup_rising", - "preset", - "recovery_falling", - "recovery_rising", - "removal_falling", - "removal_rising", - "retaining_time", - "rising_edge", - "setup_falling", - "setup_rising", - "skew_falling", - "skew_rising", - "three_state_disable", - "three_state_disable_fall", - "three_state_disable_rise", - "three_state_enable", - "three_state_enable_fall", - "three_state_enable_rise", - "min_clock_tree_path", - "max_clock_tree_path", - "unknown" -}; - -typedef Map TimingTypeMap; - -static TimingTypeMap *timing_type_string_map = NULL; - -void -makeTimingTypeMap() -{ - timing_type_string_map = new TimingTypeMap(); - int count = sizeof(timing_type_strings) / sizeof(const char*); - for (int i = 0; i < count; i++) { - const char *type_name = timing_type_strings[i]; - (*timing_type_string_map)[type_name] = (TimingType) i; - } -} - -void -deleteTimingTypeMap() -{ - delete timing_type_string_map; - timing_type_string_map = NULL; -} +EnumNameMap timing_type_name_map = + {{TimingType::clear, "clear"}, + {TimingType::combinational, "combinational"}, + {TimingType::combinational_fall, "combinational_fall"}, + {TimingType::combinational_rise, "combinational_rise"}, + {TimingType::falling_edge, "falling_edge"}, + {TimingType::hold_falling, "hold_falling"}, + {TimingType::hold_rising, "hold_rising"}, + {TimingType::min_pulse_width, "min_pulse_width"}, + {TimingType::minimum_period, "minimum_period"}, + {TimingType::nochange_high_high, "nochange_high_high"}, + {TimingType::nochange_high_low, "nochange_high_low"}, + {TimingType::nochange_low_high, "nochange_low_high"}, + {TimingType::nochange_low_low, "nochange_low_low"}, + {TimingType::non_seq_hold_falling, "non_seq_hold_falling"}, + {TimingType::non_seq_hold_rising, "non_seq_hold_rising"}, + {TimingType::non_seq_setup_falling, "non_seq_setup_falling"}, + {TimingType::non_seq_setup_rising, "non_seq_setup_rising"}, + {TimingType::preset, "preset"}, + {TimingType::recovery_falling, "recovery_falling"}, + {TimingType::recovery_rising, "recovery_rising"}, + {TimingType::removal_falling, "removal_falling"}, + {TimingType::removal_rising, "removal_rising"}, + {TimingType::retaining_time, "retaining_time"}, + {TimingType::rising_edge, "rising_edge"}, + {TimingType::setup_falling, "setup_falling"}, + {TimingType::setup_rising, "setup_rising"}, + {TimingType::skew_falling, "skew_falling"}, + {TimingType::skew_rising, "skew_rising"}, + {TimingType::three_state_disable, "three_state_disable"}, + {TimingType::three_state_disable_fall, "three_state_disable_fall"}, + {TimingType::three_state_disable_rise, "three_state_disable_rise"}, + {TimingType::three_state_enable, "three_state_enable"}, + {TimingType::three_state_enable_fall, "three_state_enable_fall"}, + {TimingType::three_state_enable_rise, "three_state_enable_rise"}, + {TimingType::min_clock_tree_path, "min_clock_tree_path"}, + {TimingType::max_clock_tree_path, "max_clock_tree_path"}, + {TimingType::unknown, "unknown"} + }; const char * timingTypeString(TimingType type) { - return timing_type_strings[type]; + return timing_type_name_map.find(type); } TimingType findTimingType(const char *type_name) { - TimingType type; - bool exists; - timing_type_string_map->findKey(type_name, type, exists); - if (exists) - return type; - else - return timing_type_unknown; + return timing_type_name_map.find(type_name, TimingType::unknown); } bool timingTypeIsCheck(TimingType type) { switch (type) { - case timing_type_hold_falling: - case timing_type_hold_rising: - case timing_type_min_pulse_width: - case timing_type_minimum_period: - case timing_type_nochange_high_high: - case timing_type_nochange_high_low: - case timing_type_nochange_low_high: - case timing_type_nochange_low_low: - case timing_type_non_seq_hold_falling: - case timing_type_non_seq_hold_rising: - case timing_type_non_seq_setup_falling: - case timing_type_non_seq_setup_rising: - case timing_type_recovery_falling: - case timing_type_recovery_rising: - case timing_type_removal_falling: - case timing_type_removal_rising: - case timing_type_retaining_time: - case timing_type_setup_falling: - case timing_type_setup_rising: - case timing_type_skew_falling: - case timing_type_skew_rising: + case TimingType::hold_falling: + case TimingType::hold_rising: + case TimingType::min_pulse_width: + case TimingType::minimum_period: + case TimingType::nochange_high_high: + case TimingType::nochange_high_low: + case TimingType::nochange_low_high: + case TimingType::nochange_low_low: + case TimingType::non_seq_hold_falling: + case TimingType::non_seq_hold_rising: + case TimingType::non_seq_setup_falling: + case TimingType::non_seq_setup_rising: + case TimingType::recovery_falling: + case TimingType::recovery_rising: + case TimingType::removal_falling: + case TimingType::removal_rising: + case TimingType::retaining_time: + case TimingType::setup_falling: + case TimingType::setup_rising: + case TimingType::skew_falling: + case TimingType::skew_rising: return true; default: return false; @@ -740,55 +716,55 @@ ScaleFactorType timingTypeScaleFactorType(TimingType type) { switch (type) { - case timing_type_non_seq_setup_falling: - case timing_type_non_seq_setup_rising: - case timing_type_setup_falling: - case timing_type_setup_rising: - return scale_factor_setup; - case timing_type_hold_falling: - case timing_type_hold_rising: - case timing_type_non_seq_hold_falling: - case timing_type_non_seq_hold_rising: - return scale_factor_hold; - case timing_type_recovery_falling: - case timing_type_recovery_rising: - return scale_factor_recovery; - case timing_type_removal_falling: - case timing_type_removal_rising: - return scale_factor_removal; - case timing_type_skew_falling: - case timing_type_skew_rising: - return scale_factor_skew; - case timing_type_minimum_period: - return scale_factor_min_period; - case timing_type_nochange_high_high: - case timing_type_nochange_high_low: - case timing_type_nochange_low_high: - case timing_type_nochange_low_low: - return scale_factor_nochange; - case timing_type_min_pulse_width: - return scale_factor_min_pulse_width; - case timing_type_clear: - case timing_type_combinational: - case timing_type_combinational_fall: - case timing_type_combinational_rise: - case timing_type_falling_edge: - case timing_type_preset: - case timing_type_retaining_time: - case timing_type_rising_edge: - case timing_type_three_state_disable: - case timing_type_three_state_disable_fall: - case timing_type_three_state_disable_rise: - case timing_type_three_state_enable: - case timing_type_three_state_enable_fall: - case timing_type_three_state_enable_rise: - case timing_type_min_clock_tree_path: - case timing_type_max_clock_tree_path: - return scale_factor_cell; - case timing_type_unknown: - return scale_factor_unknown; + case TimingType::non_seq_setup_falling: + case TimingType::non_seq_setup_rising: + case TimingType::setup_falling: + case TimingType::setup_rising: + return ScaleFactorType::setup; + case TimingType::hold_falling: + case TimingType::hold_rising: + case TimingType::non_seq_hold_falling: + case TimingType::non_seq_hold_rising: + return ScaleFactorType::hold; + case TimingType::recovery_falling: + case TimingType::recovery_rising: + return ScaleFactorType::recovery; + case TimingType::removal_falling: + case TimingType::removal_rising: + return ScaleFactorType::removal; + case TimingType::skew_falling: + case TimingType::skew_rising: + return ScaleFactorType::skew; + case TimingType::minimum_period: + return ScaleFactorType::min_period; + case TimingType::nochange_high_high: + case TimingType::nochange_high_low: + case TimingType::nochange_low_high: + case TimingType::nochange_low_low: + return ScaleFactorType::nochange; + case TimingType::min_pulse_width: + return ScaleFactorType::min_pulse_width; + case TimingType::clear: + case TimingType::combinational: + case TimingType::combinational_fall: + case TimingType::combinational_rise: + case TimingType::falling_edge: + case TimingType::preset: + case TimingType::retaining_time: + case TimingType::rising_edge: + case TimingType::three_state_disable: + case TimingType::three_state_disable_fall: + case TimingType::three_state_disable_rise: + case TimingType::three_state_enable: + case TimingType::three_state_enable_fall: + case TimingType::three_state_enable_rise: + case TimingType::min_clock_tree_path: + case TimingType::max_clock_tree_path: + return ScaleFactorType::cell; + case TimingType::unknown: + return ScaleFactorType::unknown; } - return scale_factor_unknown; + return ScaleFactorType::unknown; } } // namespace diff --git a/liberty/TimingArc.hh b/liberty/TimingArc.hh index 16b70579..a6507e71 100644 --- a/liberty/TimingArc.hh +++ b/liberty/TimingArc.hh @@ -33,50 +33,45 @@ typedef int TimingArcIndex; typedef Vector TimingArcSeq; typedef Map ScaledTimingModelMap; -typedef enum { - timing_type_clear, - timing_type_combinational, - timing_type_combinational_fall, - timing_type_combinational_rise, - timing_type_falling_edge, - timing_type_hold_falling, - timing_type_hold_rising, - timing_type_min_pulse_width, - timing_type_minimum_period, - timing_type_nochange_high_high, - timing_type_nochange_high_low, - timing_type_nochange_low_high, - timing_type_nochange_low_low, - timing_type_non_seq_hold_falling, - timing_type_non_seq_hold_rising, - timing_type_non_seq_setup_falling, - timing_type_non_seq_setup_rising, - timing_type_preset, - timing_type_recovery_falling, - timing_type_recovery_rising, - timing_type_removal_falling, - timing_type_removal_rising, - timing_type_retaining_time, - timing_type_rising_edge, - timing_type_setup_falling, - timing_type_setup_rising, - timing_type_skew_falling, - timing_type_skew_rising, - timing_type_three_state_disable, - timing_type_three_state_disable_fall, - timing_type_three_state_disable_rise, - timing_type_three_state_enable, - timing_type_three_state_enable_fall, - timing_type_three_state_enable_rise, - timing_type_min_clock_tree_path, - timing_type_max_clock_tree_path, - timing_type_unknown -} TimingType; - -void -makeTimingTypeMap(); -void -deleteTimingTypeMap(); +enum class TimingType { + clear, + combinational, + combinational_fall, + combinational_rise, + falling_edge, + hold_falling, + hold_rising, + min_pulse_width, + minimum_period, + nochange_high_high, + nochange_high_low, + nochange_low_high, + nochange_low_low, + non_seq_hold_falling, + non_seq_hold_rising, + non_seq_setup_falling, + non_seq_setup_rising, + preset, + recovery_falling, + recovery_rising, + removal_falling, + removal_rising, + retaining_time, + rising_edge, + setup_falling, + setup_rising, + skew_falling, + skew_rising, + three_state_disable, + three_state_disable_fall, + three_state_disable_rise, + three_state_enable, + three_state_enable_fall, + three_state_enable_rise, + min_clock_tree_path, + max_clock_tree_path, + unknown +}; const char * timingTypeString(TimingType type); @@ -164,8 +159,7 @@ public: TimingArc *&arc1, TimingArc *&arc2); const TimingArcSeq &arcs() const { return arcs_; } - // Use the TimingArcSetArcIterator(arc_set) constructor instead. - TimingArcSetArcIterator *timingArcIterator() __attribute__ ((deprecated)); + TimingArcSetArcIterator *timingArcIterator(); TimingArcIndex addTimingArc(TimingArc *arc); void deleteTimingArc(TimingArc *arc); TimingArc *findTimingArc(unsigned arc_index); diff --git a/liberty/TimingRole.cc b/liberty/TimingRole.cc index 8464c511..f23b5d09 100644 --- a/liberty/TimingRole.cc +++ b/liberty/TimingRole.cc @@ -52,43 +52,43 @@ TimingRoleMap TimingRole::timing_roles_; void TimingRole::init() { - wire_ = new TimingRole("wire", false, false, false, NULL, NULL, 0); + wire_ = new TimingRole("wire", false, false, false, nullptr, nullptr, 0); combinational_ = new TimingRole("combinational", true, false, false, - NULL, NULL, 1); + nullptr, nullptr, 1); tristate_enable_ = new TimingRole("tristate enable", true, false, false, - NULL, NULL, 2); + nullptr, nullptr, 2); tristate_disable_ = new TimingRole("tristate disable", true, false, false, - NULL, NULL, 3); + nullptr, nullptr, 3); reg_clk_q_ = new TimingRole("Reg Clk to Q", true, false, false, - NULL, NULL, 4); + nullptr, nullptr, 4); reg_set_clr_ = new TimingRole("Reg Set/Clr", true, false, false, - NULL, NULL, 5); + nullptr, nullptr, 5); latch_en_q_ = new TimingRole("Latch En to Q", true, false, false, - NULL, TimingRole::regClkToQ(), 6); + nullptr, TimingRole::regClkToQ(), 6); latch_d_q_ = new TimingRole("Latch D to Q", true, false, false, - NULL, NULL, 7); + nullptr, nullptr, 7); sdf_iopath_ = new TimingRole("sdf IOPATH", true, false, false, - NULL, NULL, 8); + nullptr, nullptr, 8); setup_ = new TimingRole("setup", false, true, false, - MinMax::max(), NULL, 9); + MinMax::max(), nullptr, 9); hold_ = new TimingRole("hold", false, true, false, - MinMax::min(), NULL, 10); + MinMax::min(), nullptr, 10); recovery_ = new TimingRole("recovery", false, true, false, MinMax::max(), TimingRole::setup(), 11); removal_ = new TimingRole("removal", false, true, false, MinMax::min(), TimingRole::hold(), 12); width_ = new TimingRole("width", false, true, false, - NULL, NULL, 13); + nullptr, nullptr, 13); period_ = new TimingRole("period", false, true, false, - NULL, NULL, 14); + nullptr, nullptr, 14); skew_ = new TimingRole("skew", false, true, false, - NULL, NULL, 15); + nullptr, nullptr, 15); nochange_ = new TimingRole("nochange", true, false, false, - NULL, NULL, 16); + nullptr, nullptr, 16); output_setup_ = new TimingRole("output setup", false, true, false, MinMax::max(), TimingRole::setup(), 17); @@ -118,59 +118,59 @@ void TimingRole::destroy() { delete wire_; - wire_ = NULL; + wire_ = nullptr; delete combinational_; - combinational_ = NULL; + combinational_ = nullptr; delete tristate_enable_; - tristate_enable_ = NULL; + tristate_enable_ = nullptr; delete tristate_disable_; - tristate_disable_ = NULL; + tristate_disable_ = nullptr; delete reg_clk_q_; - reg_clk_q_ = NULL; + reg_clk_q_ = nullptr; delete reg_set_clr_; - reg_set_clr_ = NULL; + reg_set_clr_ = nullptr; delete latch_en_q_; - latch_en_q_ = NULL; + latch_en_q_ = nullptr; delete latch_d_q_; - latch_d_q_ = NULL; + latch_d_q_ = nullptr; delete sdf_iopath_; - sdf_iopath_ = NULL; + sdf_iopath_ = nullptr; delete setup_; - setup_ = NULL; + setup_ = nullptr; delete hold_; - hold_ = NULL; + hold_ = nullptr; delete recovery_; - recovery_ = NULL; + recovery_ = nullptr; delete removal_; - removal_ = NULL; + removal_ = nullptr; delete width_; - width_ = NULL; + width_ = nullptr; delete period_; - period_ = NULL; + period_ = nullptr; delete skew_; - skew_ = NULL; + skew_ = nullptr; delete nochange_; - nochange_ = NULL; + nochange_ = nullptr; delete output_setup_; - output_setup_ = NULL; + output_setup_ = nullptr; delete output_hold_; - output_hold_ = NULL; + output_hold_ = nullptr; delete gated_clk_setup_; - gated_clk_setup_ = NULL; + gated_clk_setup_ = nullptr; delete gated_clk_hold_; - gated_clk_hold_ = NULL; + gated_clk_hold_ = nullptr; delete latch_setup_; - latch_setup_ = NULL; + latch_setup_ = nullptr; delete latch_hold_; - latch_hold_ = NULL; + latch_hold_ = nullptr; delete data_check_setup_; - data_check_setup_ = NULL; + data_check_setup_ = nullptr; delete data_check_hold_; - data_check_hold_ = NULL; + data_check_hold_ = nullptr; delete non_seq_setup_; - non_seq_setup_ = NULL; + non_seq_setup_ = nullptr; delete non_seq_hold_; - non_seq_hold_ = NULL; + non_seq_hold_ = nullptr; timing_roles_.clear(); } @@ -210,7 +210,7 @@ TimingRole::sdfRole() const const TimingRole * TimingRole::genericRole() const { - if (generic_role_ == NULL) + if (generic_role_ == nullptr) return this; else return generic_role_; diff --git a/liberty/TimingRole.hh b/liberty/TimingRole.hh index 8c612236..cdcf0529 100644 --- a/liberty/TimingRole.hh +++ b/liberty/TimingRole.hh @@ -87,7 +87,7 @@ private: bool is_timing_check, bool is_non_seq_check, MinMax *path_min_max, - // generic_type = NULL means type is the same as this. + // generic_type = nullptr means type is the same as this. TimingRole *generic_role, int index); DISALLOW_COPY_AND_ASSIGN(TimingRole); diff --git a/liberty/Transition.cc b/liberty/Transition.cc index 3216eb6a..d092e6e2 100644 --- a/liberty/Transition.cc +++ b/liberty/Transition.cc @@ -35,9 +35,9 @@ void TransRiseFall::destroy() { delete rise_; - rise_ = NULL; + rise_ = nullptr; delete fall_; - fall_ = NULL; + fall_ = nullptr; } TransRiseFall::TransRiseFall(const char *name, @@ -78,7 +78,7 @@ TransRiseFall::find(const char *tr_str) else if (stringEq(tr_str, fall_->name())) return fall_; else - return NULL; + return nullptr; } TransRiseFall * @@ -128,18 +128,18 @@ TransRiseFallBoth::init() { rise_ = new TransRiseFallBoth("rise", "^", 0, TransRiseFall::rise()); fall_ = new TransRiseFallBoth("fall", "v", 1, TransRiseFall::fall()); - rise_fall_ = new TransRiseFallBoth("rise_fall", "rf", 2, NULL); + rise_fall_ = new TransRiseFallBoth("rise_fall", "rf", 2, nullptr); } void TransRiseFallBoth::destroy() { delete rise_; - rise_ = NULL; + rise_ = nullptr; delete fall_; - fall_ = NULL; + fall_ = nullptr; delete rise_fall_; - rise_fall_ = NULL; + rise_fall_ = nullptr; } TransRiseFallBoth::TransRiseFallBoth(const char *name, @@ -168,7 +168,7 @@ TransRiseFallBoth::find(const char *tr_str) else if (stringEq(tr_str, rise_fall_->name())) return rise_fall_; else - return NULL; + return nullptr; } bool @@ -229,9 +229,9 @@ Transition::init() tr_X1_ = new Transition("X1", "X1", TransRiseFall::rise(), 7); tr_1X_ = new Transition("1X", "1X", TransRiseFall::fall(), 8); tr_X0_ = new Transition("X0", "X0", TransRiseFall::fall(), 9); - tr_XZ_ = new Transition("XZ", "XZ", NULL, 10); - tr_ZX_ = new Transition("ZX", "ZX", NULL, 11); - rise_fall_ = new Transition("*", "**", NULL, -1); + tr_XZ_ = new Transition("XZ", "XZ", nullptr, 10); + tr_ZX_ = new Transition("ZX", "ZX", nullptr, 11); + rise_fall_ = new Transition("*", "**", nullptr, -1); } Transition::Transition(const char *name, @@ -271,7 +271,7 @@ Transition::destroy() delete tr_ZX_; delete rise_fall_; delete transition_map_; - transition_map_ = NULL; + transition_map_ = nullptr; } } diff --git a/liberty/Units.cc b/liberty/Units.cc index ae253926..42cda577 100644 --- a/liberty/Units.cc +++ b/liberty/Units.cc @@ -130,7 +130,7 @@ Units::find(const char *unit_name) else if (stringEq(unit_name, "distance")) return &distance_unit_; else - return NULL; + return nullptr; } void diff --git a/liberty/Wireload.cc b/liberty/Wireload.cc index b088805d..80d1f6e5 100644 --- a/liberty/Wireload.cc +++ b/liberty/Wireload.cc @@ -141,9 +141,9 @@ Wireload::findWireload(float fanout, } // Scale resistance and capacitance. cap = length * capacitance_ - * library_->scaleFactor(scale_factor_wire_cap, op_cond); + * library_->scaleFactor(ScaleFactorType::wire_cap, op_cond); res = length * resistance_ - * library_->scaleFactor(scale_factor_wire_res, op_cond); + * library_->scaleFactor(ScaleFactorType::wire_res, op_cond); } //////////////////////////////////////////////////////////////// @@ -239,13 +239,13 @@ const char * wireloadTreeString(WireloadTree tree) { switch (tree) { - case wire_load_worst_case_tree: + case WireloadTree::worst_case: return "worst_case_tree"; - case wire_load_best_case_tree: + case WireloadTree::best_case: return "best_case_tree"; - case wire_load_balanced_tree: + case WireloadTree::balanced: return "balanced_tree"; - case wire_load_unknown_tree: + case WireloadTree::unknown: return "unknown"; } // Prevent warnings from lame compilers. @@ -256,26 +256,26 @@ WireloadTree stringWireloadTree(const char *wire_load_type) { if (stringEq(wire_load_type, "worst_case_tree")) - return wire_load_worst_case_tree; + return WireloadTree::worst_case; else if (stringEq(wire_load_type, "best_case_tree")) - return wire_load_best_case_tree; + return WireloadTree::best_case; else if (stringEq(wire_load_type, "balanced_tree")) - return wire_load_balanced_tree; + return WireloadTree::balanced; else - return wire_load_unknown_tree; + return WireloadTree::unknown; } const char * wireloadModeString(WireloadMode wire_load_mode) { switch (wire_load_mode) { - case wire_load_mode_top: + case WireloadMode::top: return "top"; - case wire_load_mode_enclosed: + case WireloadMode::enclosed: return "enclosed"; - case wire_load_mode_segmented: + case WireloadMode::segmented: return "segmented"; - case wire_load_mode_unknown: + case WireloadMode::unknown: return "unknown"; } // Prevent warnings from lame compilers. @@ -286,13 +286,13 @@ WireloadMode stringWireloadMode(const char *wire_load_mode) { if (stringEq(wire_load_mode, "top")) - return wire_load_mode_top; + return WireloadMode::top; else if (stringEq(wire_load_mode, "enclosed")) - return wire_load_mode_enclosed; + return WireloadMode::enclosed; else if (stringEq(wire_load_mode, "segmented")) - return wire_load_mode_segmented; + return WireloadMode::segmented; else - return wire_load_mode_unknown; + return WireloadMode::unknown; } } // namespace diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index 0c5355aa..72c6139d 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -137,7 +137,7 @@ ConcreteCell::setName(const char *name) ConcretePort * ConcreteCell::makePort(const char *name) { - ConcretePort *port = new ConcretePort(this, name, false, -1, -1, false, NULL); + ConcretePort *port = new ConcretePort(this, name, false, -1, -1, false, nullptr); addPort(port); return port; } @@ -213,7 +213,7 @@ ConcreteCell::makePort(const char *bit_name, int bit_index) { ConcretePort *port = new ConcretePort(this, bit_name, false, bit_index, - bit_index, false, NULL); + bit_index, false, nullptr); addPortBit(port); return port; } @@ -531,7 +531,7 @@ ConcretePort::findBusBit(int index) const && index <= from_index_) return (*member_ports_)[from_index_ - index]; else - return NULL; + return nullptr; } bool @@ -562,8 +562,8 @@ ConcretePort::memberIterator() const ConcreteCellPortBitIterator::ConcreteCellPortBitIterator(const ConcreteCell* cell) : port_iter_(cell->ports_), - member_iter_(NULL), - next_(NULL) + member_iter_(nullptr), + next_(nullptr) { findNext(); } @@ -571,7 +571,7 @@ ConcreteCellPortBitIterator::ConcreteCellPortBitIterator(const ConcreteCell* bool ConcreteCellPortBitIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } ConcretePort * @@ -592,7 +592,7 @@ ConcreteCellPortBitIterator::findNext() } else { delete member_iter_; - member_iter_ = NULL; + member_iter_ = nullptr; } } while (port_iter_.hasNext()) { @@ -606,9 +606,9 @@ ConcreteCellPortBitIterator::findNext() next_ = next; return; } - next_ = NULL; + next_ = nullptr; } - next_ = NULL; + next_ = nullptr; } } // namespace diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index 1311198e..6f363045 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -93,7 +93,7 @@ private: ConcreteInstanceNetIterator:: ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets): iter_(nets), - next_(NULL) + next_(nullptr) { findNext(); } @@ -101,7 +101,7 @@ ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets): bool ConcreteInstanceNetIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } // Skip nets that have been merged. @@ -110,10 +110,10 @@ ConcreteInstanceNetIterator::findNext() { while (iter_.hasNext()) { next_ = iter_.next(); - if (next_->mergedInto() == NULL) + if (next_->mergedInto() == nullptr) return; } - next_ = NULL; + next_ = nullptr; } Net * @@ -157,7 +157,7 @@ ConcreteInstancePinIterator(const ConcreteInstance *inst, bool ConcreteInstancePinIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } Pin * @@ -177,7 +177,7 @@ ConcreteInstancePinIterator::findNext() if (next_) return; } - next_ = NULL; + next_ = nullptr; } //////////////////////////////////////////////////////////////// @@ -203,7 +203,7 @@ ConcreteNetPinIterator::ConcreteNetPinIterator(const ConcreteNet *net) : bool ConcreteNetPinIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } Pin * @@ -237,7 +237,7 @@ ConcreteNetTermIterator::ConcreteNetTermIterator(const ConcreteNet *net) : bool ConcreteNetTermIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } Term * @@ -252,8 +252,8 @@ ConcreteNetTermIterator::next() ConcreteNetwork::ConcreteNetwork() : NetworkReader(), - top_instance_(NULL), - link_func_(NULL) + top_instance_(nullptr), + link_func_(nullptr) { } @@ -277,7 +277,7 @@ ConcreteNetwork::deleteTopInstance() { if (top_instance_) { deleteInstance(reinterpret_cast(top_instance_)); - top_instance_ = NULL; + top_instance_ = nullptr; } } @@ -358,7 +358,7 @@ private: ConcreteLibertyLibraryIterator:: ConcreteLibertyLibraryIterator(const ConcreteNetwork *network): iter_(network->library_seq_), - next_(NULL) + next_(nullptr) { findNext(); } @@ -370,7 +370,7 @@ ConcreteLibertyLibraryIterator::~ConcreteLibertyLibraryIterator() bool ConcreteLibertyLibraryIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } LibertyLibrary * @@ -384,7 +384,7 @@ ConcreteLibertyLibraryIterator::next() void ConcreteLibertyLibraryIterator::findNext() { - next_ = NULL; + next_ = nullptr; while (iter_.hasNext()) { ConcreteLibrary *lib = iter_.next(); LibertyLibrary *liberty = dynamic_cast(lib); @@ -406,7 +406,7 @@ ConcreteNetwork::libertyLibraryIterator() const Library * ConcreteNetwork::makeLibrary(const char *name) { - ConcreteLibrary *library = new ConcreteLibrary(name, NULL); + ConcreteLibrary *library = new ConcreteLibrary(name, nullptr); addLibrary(library); return reinterpret_cast(library); } @@ -492,7 +492,7 @@ ConcreteNetwork::findAnyCell(const char *name) if (cell) return reinterpret_cast(cell); } - return NULL; + return nullptr; } void @@ -1048,13 +1048,13 @@ ConcreteNetwork::instance(const Net *net) const bool ConcreteNetwork::isPower(const Net *net) const { - return constant_nets_[logic_one].hasKey(const_cast(net)); + return constant_nets_[int(LogicValue::one)].hasKey(const_cast(net)); } bool ConcreteNetwork::isGround(const Net *net) const { - return constant_nets_[logic_zero].hasKey(const_cast(net)); + return constant_nets_[int(LogicValue::zero)].hasKey(const_cast(net)); } NetPinIterator * @@ -1132,7 +1132,7 @@ ConcreteNetwork::makePins(Instance *inst) CellPortBitIterator *port_iterator = portBitIterator(cell(inst)); while (port_iterator->hasNext()) { Port *port = port_iterator->next(); - makePin(inst, port, NULL); + makePin(inst, port, nullptr); } delete port_iterator; } @@ -1254,7 +1254,7 @@ ConcreteNetwork::connect(Instance *inst, ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet); cnet->addTerm(cterm); cpin->term_ = cterm; - cpin->net_ = NULL; + cpin->net_ = nullptr; } else { cpin->net_ = cnet; @@ -1273,7 +1273,7 @@ ConcreteNetwork::connectNetPin(ConcreteNet *cnet, // and it is safe to incrementally update the drivers. Pin *pin = reinterpret_cast(cpin); if (isDriver(pin)) { - if (cnet->terms_ == NULL) { + if (cnet->terms_ == nullptr) { Net *net = reinterpret_cast(cnet); PinSet *drvrs = net_drvr_pin_map_.findKey(net); if (drvrs) @@ -1296,7 +1296,7 @@ ConcreteNetwork::disconnectPin(Pin *pin) cnet->deleteTerm(cterm); clearNetDrvPinrMap(); } - cpin->term_ = NULL; + cpin->term_ = nullptr; delete cterm; } } @@ -1304,7 +1304,7 @@ ConcreteNetwork::disconnectPin(Pin *pin) ConcreteNet *cnet = cpin->net(); if (cnet) disconnectNetPin(cnet, cpin); - cpin->net_ = NULL; + cpin->net_ = nullptr; } } @@ -1319,7 +1319,7 @@ ConcreteNetwork::disconnectNetPin(ConcreteNet *cnet, ConcreteNet *cnet = cpin->net(); // If there are no terminals the net does not span hierarchy levels // and it is safe to incrementally update the drivers. - if (cnet->terms_ == NULL) { + if (cnet->terms_ == nullptr) { Net *net = reinterpret_cast(cnet); PinSet *drvrs = net_drvr_pin_map_.findKey(net); if (drvrs) @@ -1363,11 +1363,11 @@ ConcreteNetwork::deleteNet(Net *net) ConcretePin *pin = reinterpret_cast(pin_iter.next()); // Do NOT use net->disconnectPin because it would be N^2 // to delete all of the pins from the net. - pin->net_ = NULL; + pin->net_ = nullptr; } - constant_nets_[logic_zero].eraseKey(net); - constant_nets_[logic_one].eraseKey(net); + constant_nets_[int(LogicValue::zero)].eraseKey(net); + constant_nets_[int(LogicValue::one)].eraseKey(net); PinSet *drvrs = net_drvr_pin_map_.findKey(net); if (drvrs) { delete drvrs; @@ -1383,22 +1383,23 @@ ConcreteNetwork::deleteNet(Net *net) void ConcreteNetwork::clearConstantNets() { - constant_nets_[logic_zero].clear(); - constant_nets_[logic_one].clear(); + constant_nets_[int(LogicValue::zero)].clear(); + constant_nets_[int(LogicValue::one)].clear(); } void ConcreteNetwork::addConstantNet(Net *net, - LogicValue const_value) + LogicValue value) { - constant_nets_[const_value].insert(net); + constant_nets_[int(value)].insert(net); } ConstantPinIterator * ConcreteNetwork::constantPinIterator() { - return new NetworkConstantPinIterator(this, constant_nets_[logic_zero], - constant_nets_[logic_one]); + return new NetworkConstantPinIterator(this, + constant_nets_[int(LogicValue::zero)], + constant_nets_[int(LogicValue::one)]); } //////////////////////////////////////////////////////////////// @@ -1447,13 +1448,13 @@ ConcreteInstance::ConcreteInstance(const char *name, name_(stringCopy(name)), cell_(cell), parent_(parent), - children_(NULL), - nets_(NULL) + children_(nullptr), + nets_(nullptr) { int pin_count = reinterpret_cast(cell)->portBitCount(); pins_ = new ConcretePin*[pin_count]; for (int i = 0; i < pin_count; i++) - pins_[i] = NULL; + pins_[i] = nullptr; } ConcreteInstance::~ConcreteInstance() @@ -1470,7 +1471,7 @@ ConcreteInstance::findChild(const char *name) const if (children_) return reinterpret_cast(children_->findKey(name)); else - return NULL; + return nullptr; } ConcretePin * @@ -1483,7 +1484,7 @@ ConcreteInstance::findPin(const char *port_name) const && !cport->isBus()) return pins_[cport->pinIndex()]; else - return NULL; + return nullptr; } ConcretePin * @@ -1496,7 +1497,7 @@ ConcreteInstance::findPin(const Port *port) const ConcreteNet * ConcreteInstance::findNet(const char *net_name) const { - ConcreteNet *net = NULL; + ConcreteNet *net = nullptr; if (nets_) { net = nets_->findKey(net_name); // Follow merge pointer to surviving net. @@ -1545,7 +1546,7 @@ ConcreteInstance::childIterator() const void ConcreteInstance::addChild(ConcreteInstance *child) { - if (children_ == NULL) + if (children_ == nullptr) children_ = new ConcreteInstanceChildMap; (*children_)[child->name()] = child; } @@ -1567,13 +1568,13 @@ void ConcreteInstance::deletePin(ConcretePin *pin) { ConcretePort *cport = reinterpret_cast(pin->port()); - pins_[cport->pinIndex()] = NULL; + pins_[cport->pinIndex()] = nullptr; } void ConcreteInstance::addNet(ConcreteNet *net) { - if (nets_ == NULL) + if (nets_ == nullptr) nets_ = new ConcreteInstanceNetMap; (*nets_)[net->name()] = net; } @@ -1582,7 +1583,7 @@ void ConcreteInstance::addNet(const char *name, ConcreteNet *net) { - if (nets_ == NULL) + if (nets_ == nullptr) nets_ = new ConcreteInstanceNetMap; (*nets_)[name] = net; } @@ -1607,9 +1608,9 @@ ConcretePin::ConcretePin(ConcreteInstance *instance, instance_(instance), port_(port), net_(net), - term_(NULL), - net_next_(NULL), - net_prev_(NULL), + term_(nullptr), + net_next_(nullptr), + net_prev_(nullptr), vertex_index_(0) { } @@ -1641,7 +1642,7 @@ ConcreteTerm::ConcreteTerm(ConcretePin *pin, ConcreteNet *net) : pin_(pin), net_(net), - net_next_(NULL) + net_next_(nullptr) { } @@ -1651,9 +1652,9 @@ ConcreteNet::ConcreteNet(const char *name, ConcreteInstance *instance) : name_(stringCopy(name)), instance_(instance), - pins_(NULL), - terms_(NULL), - merged_into_(NULL) + pins_(nullptr), + terms_(nullptr), + merged_into_(nullptr) { } @@ -1675,7 +1676,7 @@ ConcreteNet::mergeInto(ConcreteNet *net) net->addPin(cpin); cpin->net_ = net; } - pins_ = NULL; + pins_ = nullptr; ConcreteNetTermIterator term_iter(this); while (term_iter.hasNext()) { Term *term = term_iter.next(); @@ -1683,7 +1684,7 @@ ConcreteNet::mergeInto(ConcreteNet *net) net->addTerm(cterm); cterm->net_ = net; } - terms_ = NULL; + terms_ = nullptr; // Leave name map pointing to merged net because otherwise a top // level merged net has no pointer to it and it is leaked. merged_into_ = net; @@ -1695,7 +1696,7 @@ ConcreteNet::addPin(ConcretePin *pin) if (pins_) pins_->net_prev_ = pin; pin->net_next_ = pins_; - pin->net_prev_ = NULL; + pin->net_prev_ = nullptr; pins_ = pin; } @@ -1723,7 +1724,7 @@ ConcreteNet::addTerm(ConcreteTerm *term) void ConcreteNet::deleteTerm(ConcreteTerm *term) { - ConcreteTerm *net_prev_term = NULL; + ConcreteTerm *net_prev_term = nullptr; for (ConcreteTerm *net_term=terms_;net_term;net_term=net_term->net_next_) { if (net_term == term) { if (net_prev_term) @@ -1810,7 +1811,7 @@ ConcreteNetwork::linkNetwork(const char *top_cell_name, reinterpret_cast(link_func_(top_cell, make_black_boxes, report, this)); - return top_instance_ != NULL; + return top_instance_ != nullptr; } else { report->error("cell %s not found.\n", top_cell_name); @@ -1831,9 +1832,9 @@ linkReaderNetwork(Cell *top_cell, Instance *view = network->cellNetworkView(top_cell); if (view) { // Seed the recursion for expansion with the top level instance. - Instance *top_instance = network->makeInstance(top_cell, "", NULL); + Instance *top_instance = network->makeInstance(top_cell, "", nullptr); ConcreteBindingTbl bindings(network); - makeClonePins(view, top_instance, view, &bindings, NULL, NULL, network); + makeClonePins(view, top_instance, view, &bindings, nullptr, nullptr, network); InstanceChildIterator *child_iter = network->childIterator(view); while (child_iter->hasNext()) { Instance *child = child_iter->next(); @@ -1843,7 +1844,7 @@ linkReaderNetwork(Cell *top_cell, network->deleteCellNetworkViews(); return top_instance; } - return NULL; + return nullptr; } static void @@ -1856,7 +1857,7 @@ makeChildNetwork(Instance *proto, Instance *clone = network->makeInstance(proto_cell, network->name(proto), parent); if (network->isLeaf(proto_cell)) - makeClonePins(proto, clone, NULL, NULL, parent, parent_bindings, network); + makeClonePins(proto, clone, nullptr, nullptr, parent, parent_bindings, network); else { // Recurse if this isn't a leaf cell. ConcreteBindingTbl bindings(network); @@ -1888,14 +1889,14 @@ makeClonePins(Instance *proto, Pin *proto_pin = proto_pin_iter->next(); Net *proto_net = network->net(proto_pin); Port *proto_port = network->port(proto_pin); - Net *clone_net = NULL; + Net *clone_net = nullptr; if (proto_net && parent_bindings) clone_net = parent_bindings->ensureBinding(proto_net, parent); Pin *clone_pin = network->connect(clone, proto_port, clone_net); if (clone_view) { Pin *clone_proto_pin = network->findPin(clone_view, proto_port); Net *clone_proto_net = network->net(clone_proto_pin); - Net *clone_child_net = NULL; + Net *clone_child_net = nullptr; if (clone_proto_net) clone_child_net = bindings->ensureBinding(clone_proto_net, clone); network->makeTerm(clone_pin, clone_child_net); @@ -1935,7 +1936,7 @@ ConcreteBindingTbl::ensureBinding(Net *proto_net, Instance *parent) { Net *net = find(proto_net); - if (net == NULL) { + if (net == nullptr) { net = network_->makeNet(network_->name(proto_net), parent); map_[proto_net] = net; } diff --git a/network/ConcreteNetwork.hh b/network/ConcreteNetwork.hh index 7bd8c8ee..70793e1b 100644 --- a/network/ConcreteNetwork.hh +++ b/network/ConcreteNetwork.hh @@ -152,7 +152,7 @@ public: virtual ConstantPinIterator *constantPinIterator(); void addConstantNet(Net *net, - LogicValue const_value); + LogicValue value); // Edit methods. virtual Library *makeLibrary(const char *name); @@ -248,7 +248,7 @@ protected: ConcreteLibrarySeq library_seq_; ConcreteLibraryMap library_map_; ConcreteInstance *top_instance_; - NetSet constant_nets_[2]; // logic_zero/one + NetSet constant_nets_[2]; // LogicValue::zero/one LinkNetworkFunc *link_func_; CellNetworkViewMap cell_network_view_map_; diff --git a/network/HpinDrvrLoad.cc b/network/HpinDrvrLoad.cc index f5e4d412..7fcbe9e9 100644 --- a/network/HpinDrvrLoad.cc +++ b/network/HpinDrvrLoad.cc @@ -27,8 +27,8 @@ HpinDrvrLoad::HpinDrvrLoad(Pin *drvr, PinSet *hpins_to_load) : drvr_(drvr), load_(load), - hpins_from_drvr_(hpins_from_drvr ? new PinSet(*hpins_from_drvr) : NULL), - hpins_to_load_(hpins_to_load ? new PinSet(*hpins_to_load) : NULL) + hpins_from_drvr_(hpins_from_drvr ? new PinSet(*hpins_from_drvr) : nullptr), + hpins_to_load_(hpins_to_load ? new PinSet(*hpins_to_load) : nullptr) { } @@ -104,13 +104,13 @@ visitPinsAboveNet2(const Pin *hpin, Pin *above_pin = pin_iter->next(); if (above_pin != hpin) { if (network->isDriver(above_pin)) { - HpinDrvrLoad *drvr = new HpinDrvrLoad(above_pin, NULL, - hpin_path, NULL); + HpinDrvrLoad *drvr = new HpinDrvrLoad(above_pin, nullptr, + hpin_path, nullptr); above_drvrs.insert(drvr); } if (network->isLoad(above_pin)) { - HpinDrvrLoad *load = new HpinDrvrLoad(NULL, above_pin, - NULL, hpin_path); + HpinDrvrLoad *load = new HpinDrvrLoad(nullptr, above_pin, + nullptr, hpin_path); above_loads.insert(load); } Term *above_term = network->term(above_pin); @@ -145,13 +145,13 @@ visitPinsAboveNet2(const Pin *hpin, } if (network->isDriver(above_pin)) { - HpinDrvrLoad *drvr = new HpinDrvrLoad(above_pin, NULL, - hpin_path, NULL); + HpinDrvrLoad *drvr = new HpinDrvrLoad(above_pin, nullptr, + hpin_path, nullptr); above_drvrs.insert(drvr); } if (network->isLoad(above_pin)) { - HpinDrvrLoad *load = new HpinDrvrLoad(NULL, above_pin, - NULL, hpin_path); + HpinDrvrLoad *load = new HpinDrvrLoad(nullptr, above_pin, + nullptr, hpin_path); above_loads.insert(load); } } @@ -180,13 +180,13 @@ visitPinsBelowNet2(const Pin *hpin, visited, below_drvrs, below_loads, hpin_path, network); if (network->isDriver(below_pin)) { - HpinDrvrLoad *drvr = new HpinDrvrLoad(below_pin, NULL, - hpin_path, NULL); + HpinDrvrLoad *drvr = new HpinDrvrLoad(below_pin, nullptr, + hpin_path, nullptr); below_drvrs.insert(drvr); } if (network->isLoad(below_pin)) { - HpinDrvrLoad *load = new HpinDrvrLoad(NULL, below_pin, - NULL, hpin_path); + HpinDrvrLoad *load = new HpinDrvrLoad(nullptr, below_pin, + nullptr, hpin_path); below_loads.insert(load); } if (network->isHierarchical(below_pin)) { @@ -279,7 +279,7 @@ visitHpinDrvrLoads(const Pin *pin, } else { if (network->isDriver(pin)) { - HpinDrvrLoad drvr(const_cast(pin), NULL, &hpin_path, NULL); + HpinDrvrLoad drvr(const_cast(pin), nullptr, &hpin_path, nullptr); HpinDrvrLoads drvrs; drvrs.insert(&drvr); visitHpinDrvrLoads(drvrs, below_loads, visitor); @@ -287,7 +287,7 @@ visitHpinDrvrLoads(const Pin *pin, } // Bidirects are drivers and loads. if (network->isLoad(pin)) { - HpinDrvrLoad load(NULL, const_cast(pin), NULL, &hpin_path); + HpinDrvrLoad load(nullptr, const_cast(pin), nullptr, &hpin_path); HpinDrvrLoads loads; loads.insert(&load); visitHpinDrvrLoads(below_drvrs, loads, visitor); diff --git a/network/Network.cc b/network/Network.cc index 7961e279..7a9e38f6 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -25,7 +25,7 @@ namespace sta { Network::Network() : - default_liberty_(NULL), + default_liberty_(nullptr), divider_('/'), escape_('\\') { @@ -39,14 +39,14 @@ Network::~Network() void Network::clear() { - default_liberty_ = NULL; + default_liberty_ = nullptr; clearNetDrvPinrMap(); } bool Network::isLinked() const { - return topInstance() != NULL; + return topInstance() != nullptr; } LibertyLibrary * @@ -79,7 +79,7 @@ Network::findLibertyCell(const char *name) const } } delete iter; - return NULL; + return nullptr; } LibertyLibrary * @@ -107,7 +107,7 @@ Network::findLibertyFilename(const char *filename) } } delete lib_iter; - return NULL; + return nullptr; } LibertyCell * @@ -181,9 +181,9 @@ int Network::pathNameCmp(const Instance *inst1, const Instance *inst2) const { - if (inst1 == NULL && inst2) + if (inst1 == nullptr && inst2) return -1; - else if (inst1 && inst2 == NULL) + else if (inst1 && inst2 == nullptr) return 1; else if (inst1 == inst2) return 0; @@ -321,7 +321,7 @@ Network::isHierarchical(const Pin *pin) const bool Network::isTopLevelPort(const Pin *pin) const { - return (parent(instance(pin)) == NULL); + return (parent(instance(pin)) == nullptr); } bool @@ -704,7 +704,7 @@ Network::findPinRelative(const Instance *inst, } stringDelete(inst_path); stringDelete(port_name); - return NULL; + return nullptr; } else // Top level pin. @@ -724,7 +724,7 @@ Network::findPinLinear(const Instance *instance, } } delete pin_iter; - return NULL; + return nullptr; } Pin * @@ -763,7 +763,7 @@ Network::findNetRelative(const Instance *inst, } stringDelete(inst_path); stringDelete(net_name); - return NULL; + return nullptr; } else // Top level net. @@ -783,7 +783,7 @@ Network::findNetLinear(const Instance *instance, } } delete net_iter; - return NULL; + return nullptr; } void @@ -1075,7 +1075,7 @@ LeafInstanceIterator1::LeafInstanceIterator1(const Instance *inst, const Network *network) : network_(network), child_iter_(network->childIterator(inst)), - next_(NULL) + next_(nullptr) { pending_child_iters_.reserve(512); nextInst(); @@ -1092,7 +1092,7 @@ LeafInstanceIterator1::next() void LeafInstanceIterator1::nextInst() { - next_ = NULL; + next_ = nullptr; while (child_iter_) { while (child_iter_->hasNext()) { next_ = child_iter_->next(); @@ -1101,13 +1101,13 @@ LeafInstanceIterator1::nextInst() else { pending_child_iters_.push_back(child_iter_); child_iter_ = network_->childIterator(next_); - next_ = NULL; + next_ = nullptr; } } delete child_iter_; if (pending_child_iters_.empty()) - child_iter_ = NULL; + child_iter_ = nullptr; else { child_iter_ = pending_child_iters_.back(); pending_child_iters_.pop_back(); @@ -1138,7 +1138,7 @@ Network::visitConnectedPins(Pin *pin, Term *pin_term = term(pin); if (pin_net) visitConnectedPins(pin_net, visitor, visited_nets); - else if (pin_term == NULL) + else if (pin_term == nullptr) // Unconnected or internal pin. visitor(pin); @@ -1445,7 +1445,7 @@ Network::drivers(const Pin *pin) if (net) return drivers(net); else - return NULL; + return nullptr; } void @@ -1458,7 +1458,7 @@ PinSet * Network::drivers(const Net *net) { PinSet *drvrs = net_drvr_pin_map_.findKey(net); - if (drvrs == NULL) { + if (drvrs == nullptr) { drvrs = new PinSet; FindDrvrPins visitor(drvrs, this); visitConnectedPins(net, visitor); @@ -1478,7 +1478,7 @@ Network::pathNameFirst(const char *path_name, char divider = pathDivider(); const char *d = strchr(path_name, divider); // Skip escaped dividers. - while (d != NULL + while (d != nullptr && d > path_name && d[-1] == escape) d = strchr(d + 1, divider); @@ -1493,8 +1493,8 @@ Network::pathNameFirst(const char *path_name, } else { // No divider in path_name. - first = NULL; - tail = NULL; + first = nullptr; + tail = nullptr; } } @@ -1526,8 +1526,8 @@ Network::pathNameLast(const char *path_name, } else { // No divider in path_name. - head = NULL; - last = NULL; + head = nullptr; + last = nullptr; } } @@ -1554,10 +1554,10 @@ NetworkConstantPinIterator(const Network *network, ConstantPinIterator(), network_(network) { - findConstantPins(zero_nets, logic_zero); - findConstantPins(one_nets, logic_one); - value_ = logic_zero; - pin_iter_ = new PinSet::Iterator(constant_pins_[value_]); + findConstantPins(zero_nets, constant_pins_[0]); + findConstantPins(one_nets, constant_pins_[1]); + value_ = LogicValue::zero; + pin_iter_ = new PinSet::Iterator(constant_pins_[0]); } NetworkConstantPinIterator::~NetworkConstantPinIterator() @@ -1567,7 +1567,7 @@ NetworkConstantPinIterator::~NetworkConstantPinIterator() void NetworkConstantPinIterator::findConstantPins(NetSet &nets, - LogicValue const_value) + PinSet &pins) { NetSet::Iterator net_iter(nets); while (net_iter.hasNext()) { @@ -1575,7 +1575,7 @@ NetworkConstantPinIterator::findConstantPins(NetSet &nets, NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); - constant_pins_[const_value].insert(pin); + pins.insert(pin); } delete pin_iter; } @@ -1586,10 +1586,10 @@ NetworkConstantPinIterator::hasNext() { if (pin_iter_->hasNext()) return true; - else if (value_ == logic_zero) { + else if (value_ == LogicValue::zero) { delete pin_iter_; - value_ = logic_one; - pin_iter_ = new PinSet::Iterator(constant_pins_[value_]); + value_ = LogicValue::one; + pin_iter_ = new PinSet::Iterator(constant_pins_[1]); return pin_iter_->hasNext(); } else @@ -1825,7 +1825,7 @@ char logicValueString(LogicValue value) { static char str[] = "01X^v"; - return str[value]; + return str[int(value)]; } bool diff --git a/network/Network.hh b/network/Network.hh index 019edfa3..baca1135 100644 --- a/network/Network.hh +++ b/network/Network.hh @@ -34,7 +34,7 @@ class PinVisitor; typedef Set ConstNetSet; typedef Map LibertyLibraryMap; // Link network function returns top level instance. -// Return NULL if link fails. +// Return nullptr if link fails. typedef Instance *(LinkNetworkFunc)(Cell *top_cell, bool make_black_boxes, Report *report, @@ -599,7 +599,7 @@ public: private: DISALLOW_COPY_AND_ASSIGN(NetworkConstantPinIterator); void findConstantPins(NetSet &nets, - LogicValue const_value); + PinSet &pins); const Network *network_; PinSet constant_pins_[2]; diff --git a/network/NetworkClass.hh b/network/NetworkClass.hh index d63abdfe..a2ed1647 100644 --- a/network/NetworkClass.hh +++ b/network/NetworkClass.hh @@ -75,13 +75,7 @@ public: const PortPair *pair2) const; }; -typedef enum { - logic_zero, - logic_one, - logic_unknown, - logic_rise, - logic_fall -} LogicValue; +enum class LogicValue : unsigned { zero, one, unknown, rise, fall }; } // namespace #endif diff --git a/network/ParseBus.cc b/network/ParseBus.cc index 6fbb10c1..2652d037 100644 --- a/network/ParseBus.cc +++ b/network/ParseBus.cc @@ -33,7 +33,7 @@ isBusName(const char *name, size_t len_1 = strlen(name) - 1; if (name[len_1] == brkt_right) { const char *left = strrchr(name, brkt_left); - return left != NULL; + return left != nullptr; } else return false; @@ -58,7 +58,7 @@ parseBusName(const char *name, char *&bus_name, int &index) { - bus_name = NULL; + bus_name = nullptr; size_t len_1 = strlen(name) - 1; char last_ch = name[len_1]; const char *brkt_right_ptr = strchr(brkts_right, last_ch); @@ -98,7 +98,7 @@ parseBusRange(const char *name, int &from, int &to) { - bus_name = NULL; + bus_name = nullptr; size_t len_1 = strlen(name) - 1; char last_ch = name[len_1]; const char *brkt_right_ptr = strchr(brkts_right, last_ch); diff --git a/network/PortDirection.cc b/network/PortDirection.cc index 46c9abf0..1e6b4a74 100644 --- a/network/PortDirection.cc +++ b/network/PortDirection.cc @@ -45,21 +45,21 @@ void PortDirection::destroy() { delete input_; - input_ = NULL; + input_ = nullptr; delete output_; - output_ = NULL; + output_ = nullptr; delete tristate_; - tristate_ = NULL; + tristate_ = nullptr; delete bidirect_; - bidirect_ = NULL; + bidirect_ = nullptr; delete internal_; - internal_ = NULL; + internal_ = nullptr; delete ground_; - ground_ = NULL; + ground_ = nullptr; delete power_; - power_ = NULL; + power_ = nullptr; delete unknown_; - unknown_ = NULL; + unknown_ = nullptr; } PortDirection::PortDirection(const char *name, diff --git a/network/SdcNetwork.cc b/network/SdcNetwork.cc index 3e1d8009..7070a407 100644 --- a/network/SdcNetwork.cc +++ b/network/SdcNetwork.cc @@ -70,8 +70,8 @@ SdcPathParser::SdcPathParser(const char *path, network_(network), divider_(network->pathDivider()), escape_(network->pathEscape()), - inst_path_(NULL), - inst_(NULL) + inst_path_(nullptr), + inst_(nullptr) { initialScan(path); if (divider_count_ > 0) @@ -1012,7 +1012,7 @@ SdcNetwork::findPort(const Cell *cell, const char *name) const { Port *port = network_->findPort(cell, name); - if (port == NULL) { + if (port == nullptr) { // Look for matches after escaping brackets. const char *port_name_ = escapeBrackets(name, this); port = network_->findPort(cell, port_name_); @@ -1092,7 +1092,7 @@ SdcNetwork::findInstance(const char *path_name) const { SdcPathParser path_parser(path_name, this); Instance *parent = path_parser.instance(); - if (parent == NULL) + if (parent == nullptr) parent = network_->topInstance(); const char *child_name = path_parser.pathTail(); return findChild(parent, child_name); @@ -1103,7 +1103,7 @@ SdcNetwork::findChild(const Instance *parent, const char *name) const { Instance *child = network_->findChild(parent, name); - if (child == NULL) { + if (child == nullptr) { const char *escaped = escapeBrackets(name, this); child = network_->findChild(parent, escaped); } @@ -1115,7 +1115,7 @@ SdcNetwork::findNet(const char *path_name) const { SdcPathParser path_parser(path_name, this); const Instance *inst = path_parser.instance(); - if (inst == NULL) + if (inst == nullptr) inst = network_->topInstance(); const char *net_name = path_parser.pathTail(); return findNet(inst, net_name); @@ -1126,7 +1126,7 @@ SdcNetwork::findNet(const Instance *instance, const char *net_name) const { Net *net = network_->findNet(instance, net_name); - if (net == NULL) { + if (net == nullptr) { const char *net_name_ = escapeBrackets(net_name, this); net = network_->findNet(instance, net_name_); } @@ -1140,7 +1140,7 @@ SdcNetwork::findPin(const char *path_name) const { SdcPathParser path_parser(path_name, this); const Instance *inst = path_parser.instance(); - if (inst == NULL) + if (inst == nullptr) inst = network_->topInstance(); const char *port_name = path_parser.pathTail(); return findPin(inst, port_name); @@ -1151,7 +1151,7 @@ SdcNetwork::findPin(const Instance *instance, const char *port_name) const { Pin *pin = network_->findPin(instance, port_name); - if (pin == NULL) { + if (pin == nullptr) { // Look for match after escaping brackets. const char *port_name_ = escapeBrackets(port_name, this); pin = network_->findPin(instance, port_name_); diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index 46dc70d1..3a9653d2 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -20,6 +20,7 @@ #include "Report.hh" #include "Debug.hh" #include "Error.hh" +#include "Mutex.hh" #include "Set.hh" #include "MinMax.hh" #include "Network.hh" @@ -124,7 +125,7 @@ ConcreteParasitic::setElmore(const Pin *, Parasitic * ConcreteParasitic::findPoleResidue(const Pin *) const { - return NULL; + return nullptr; } void @@ -137,19 +138,19 @@ ConcreteParasitic::setPoleResidue(const Pin *, ParasiticDeviceIterator * ConcreteParasitic::deviceIterator() { - return NULL; + return nullptr; } ParasiticNodeIterator * ConcreteParasitic::nodeIterator() { - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// ConcreteElmore::ConcreteElmore() : - loads_(NULL) + loads_(nullptr) { } @@ -179,7 +180,7 @@ void ConcreteElmore::setElmore(const Pin *load_pin, float elmore) { - if (loads_ == NULL) + if (loads_ == nullptr) loads_ = new ConcreteElmoreLoadMap; (*loads_)[load_pin] = elmore; } @@ -420,7 +421,7 @@ ConcretePiPoleResidue::ConcretePiPoleResidue(float c2, float rpi, float c1) : ConcretePi(c2, rpi, c1), - load_pole_residue_(NULL) + load_pole_residue_(nullptr) { } @@ -472,7 +473,7 @@ ConcretePiPoleResidue::findPoleResidue(const Pin *load_pin) const if (load_pole_residue_) return load_pole_residue_->findKey(load_pin); else - return NULL; + return nullptr; } void @@ -480,10 +481,10 @@ ConcretePiPoleResidue::setPoleResidue(const Pin *load_pin, ComplexFloatSeq *poles, ComplexFloatSeq *residues) { - if (load_pole_residue_ == NULL) + if (load_pole_residue_ == nullptr) load_pole_residue_ = new ConcretePoleResidueMap; ConcretePoleResidue *pole_residue = load_pole_residue_->findKey(load_pin); - if (pole_residue == NULL) { + if (pole_residue == nullptr) { pole_residue = new ConcretePoleResidue(poles, residues); (*load_pole_residue_)[load_pin] = pole_residue; } @@ -592,7 +593,7 @@ ConcreteParasiticResistor::otherNode(ParasiticNode *node) const else if (node == other_node_) return node_; else - return NULL; + return nullptr; } void @@ -642,7 +643,7 @@ ConcreteCouplingCapInt::otherNode(ParasiticNode *node) const else if (node == other_node_) return node_; else - return NULL; + return nullptr; } void @@ -670,7 +671,7 @@ ConcreteCouplingCapExtNode(const char *name, ParasiticNode * ConcreteCouplingCapExtNode::otherNode(ParasiticNode *) const { - return NULL; + return nullptr; } void @@ -695,7 +696,7 @@ ConcreteCouplingCapExtPin(const char *name, ParasiticNode * ConcreteCouplingCapExtPin::otherNode(ParasiticNode *) const { - return NULL; + return nullptr; } void @@ -817,7 +818,7 @@ ConcreteParasiticNetwork::ensureParasiticNode(Net *net, { NetId net_id(net, id); ConcreteParasiticSubNode *node = sub_nodes_.findKey(&net_id); - if (node == NULL) { + if (node == nullptr) { node = new ConcreteParasiticSubNode(net, id); sub_nodes_[new NetId(net, id)] = node; max_node_id_ = max((int) max_node_id_, id); @@ -856,7 +857,7 @@ ConcreteParasiticNode * ConcreteParasiticNetwork::ensureParasiticNode(const Pin *pin) { ConcreteParasiticPinNode *node = pin_nodes_.findKey(pin); - if (node == NULL) { + if (node == nullptr) { node = new ConcreteParasiticPinNode(pin); pin_nodes_[pin] = node; } @@ -886,10 +887,10 @@ makeConcreteParasitics(StaState *sta) ConcreteParasitics::ConcreteParasitics(StaState *sta) : Parasitics(sta), - lumped_elmore_maps_(NULL), - pi_elmore_maps_(NULL), - pi_pole_residue_maps_(NULL), - parasitic_network_maps_(NULL) + lumped_elmore_maps_(nullptr), + pi_elmore_maps_(nullptr), + pi_pole_residue_maps_(nullptr), + parasitic_network_maps_(nullptr) { } @@ -901,10 +902,10 @@ ConcreteParasitics::~ConcreteParasitics() bool ConcreteParasitics::haveParasitics() { - return lumped_elmore_maps_ != NULL - || pi_elmore_maps_ != NULL - || pi_pole_residue_maps_ != NULL - || parasitic_network_maps_ != NULL; + return lumped_elmore_maps_ != nullptr + || pi_elmore_maps_ != nullptr + || pi_pole_residue_maps_ != nullptr + || parasitic_network_maps_ != nullptr; } void @@ -924,7 +925,7 @@ ConcreteParasitics::clear() } } delete lumped_elmore_maps_; - lumped_elmore_maps_ = NULL; + lumped_elmore_maps_ = nullptr; } if (pi_elmore_maps_) { @@ -939,7 +940,7 @@ ConcreteParasitics::clear() } } delete pi_elmore_maps_; - pi_elmore_maps_ = NULL; + pi_elmore_maps_ = nullptr; } if (pi_pole_residue_maps_) { @@ -954,7 +955,7 @@ ConcreteParasitics::clear() } } delete pi_pole_residue_maps_; - pi_pole_residue_maps_ = NULL; + pi_pole_residue_maps_ = nullptr; } if (parasitic_network_maps_) { @@ -969,7 +970,7 @@ ConcreteParasitics::clear() } } delete parasitic_network_maps_; - parasitic_network_maps_ = NULL; + parasitic_network_maps_ = nullptr; } } @@ -1083,7 +1084,7 @@ ConcreteParasitics::deleteParasitic(const Pin *drvr_pin, // not require an analysis pt. if (ap) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.writeLock(); + UniqueLock lock(lock_); if (cparasitic->isLumpedElmore()) (*lumped_elmore_maps_)[ap_index]->eraseKey(drvr_pin); else if (cparasitic->isPiElmore() && pi_elmore_maps_) @@ -1094,7 +1095,6 @@ ConcreteParasitics::deleteParasitic(const Pin *drvr_pin, const Net *net = network_->net(drvr_pin); (*parasitic_network_maps_)[ap_index]->eraseKey(net); } - lock_.unlock(); } delete cparasitic; } @@ -1277,9 +1277,8 @@ ConcreteParasitics::hasLumpedElmore(const Pin *drvr_pin, { if (lumped_elmore_maps_ && ap) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.readLock(); + UniqueLock lock(lock_); bool exists = (*lumped_elmore_maps_)[ap_index]->hasKey(drvr_pin); - lock_.unlock(); return exists; } else @@ -1293,13 +1292,12 @@ ConcreteParasitics::findLumpedElmore(const Pin *drvr_pin, { if (ap && lumped_elmore_maps_) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.readLock(); + UniqueLock lock(lock_); Parasitic *parasitic = (*lumped_elmore_maps_)[ap_index]->findKey(drvr_pin); - lock_.unlock(); return parasitic; } else - return NULL; + return nullptr; } Parasitic * @@ -1309,8 +1307,8 @@ ConcreteParasitics::makeLumpedElmore(const Pin *drvr_pin, const ParasiticAnalysisPt *ap) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.writeLock(); - if (lumped_elmore_maps_ == NULL) { + UniqueLock lock(lock_); + if (lumped_elmore_maps_ == nullptr) { lumped_elmore_maps_ = new ConcreteLumpedElmoreMapSeq(mapSize()); ParasiticAnalysisPtIterator ap_iter(corners_); while (ap_iter.hasNext()) { @@ -1332,7 +1330,6 @@ ConcreteParasitics::makeLumpedElmore(const Pin *drvr_pin, lumped_elmore = new ConcreteLumpedElmore(cap); (*(*lumped_elmore_maps_)[ap_index])[drvr_pin] = lumped_elmore; } - lock_.unlock(); return lumped_elmore; } @@ -1343,14 +1340,13 @@ ConcreteParasitics::deleteLumpedElmore(const Pin *drvr_pin, { if (ap && lumped_elmore_maps_) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.writeLock(); + UniqueLock lock(lock_); ConcreteLumpedElmore *lumped_elmore = (*lumped_elmore_maps_)[ap_index]->findKey(drvr_pin); if (lumped_elmore) { (*lumped_elmore_maps_)[ap_index]->eraseKey(drvr_pin); delete lumped_elmore; } - lock_.unlock(); } } @@ -1370,13 +1366,12 @@ ConcreteParasitics::hasPiElmore(const Pin *drvr_pin, { if (ap && pi_elmore_maps_) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.readLock(); + UniqueLock lock(lock_); bool exists = (*pi_elmore_maps_)[ap_index]->hasKey(drvr_pin); if (!exists && tr == TransRiseFall::fall()) { ap_index = parasiticAnalysisPtIndex(ap, TransRiseFall::rise()); exists = (*pi_elmore_maps_)[ap_index]->hasKey(drvr_pin); } - lock_.unlock(); return exists; } else @@ -1390,17 +1385,16 @@ ConcreteParasitics::findPiElmore(const Pin *drvr_pin, { if (ap && pi_elmore_maps_) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.readLock(); + UniqueLock lock(lock_); Parasitic *parasitic = (*pi_elmore_maps_)[ap_index]->findKey(drvr_pin); - if (parasitic == NULL && tr == TransRiseFall::fall()) { + if (parasitic == nullptr && tr == TransRiseFall::fall()) { ap_index = parasiticAnalysisPtIndex(ap, TransRiseFall::rise()); parasitic = (*pi_elmore_maps_)[ap_index]->findKey(drvr_pin); } - lock_.unlock(); return parasitic; } else - return NULL; + return nullptr; } Parasitic * @@ -1412,8 +1406,8 @@ ConcreteParasitics::makePiElmore(const Pin *drvr_pin, float c1) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.writeLock(); - if (pi_elmore_maps_ == NULL) { + UniqueLock lock(lock_); + if (pi_elmore_maps_ == nullptr) { pi_elmore_maps_ = new ConcretePiElmoreMapSeq(mapSize()); ParasiticAnalysisPtIterator ap_iter(corners_); while (ap_iter.hasNext()) { @@ -1434,7 +1428,6 @@ ConcreteParasitics::makePiElmore(const Pin *drvr_pin, pi_elmore = new ConcretePiElmore(c2, rpi, c1); (*(*pi_elmore_maps_)[ap_index])[drvr_pin] = pi_elmore; } - lock_.unlock(); return pi_elmore; } @@ -1445,14 +1438,13 @@ ConcreteParasitics::deletePiElmore(const Pin *drvr_pin, { if (ap && pi_elmore_maps_) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.writeLock(); + UniqueLock lock(lock_); ConcretePiElmore *pi_elmore = (*pi_elmore_maps_)[ap_index]->findKey(drvr_pin); if (pi_elmore) { (*pi_elmore_maps_)[ap_index]->eraseKey(drvr_pin); delete pi_elmore; } - lock_.unlock(); } } @@ -1522,13 +1514,12 @@ ConcreteParasitics::hasPiPoleResidue(const Pin *drvr_pin, { if (ap && pi_pole_residue_maps_) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.readLock(); + UniqueLock lock(lock_); bool exists = (*pi_pole_residue_maps_)[ap_index]->hasKey(drvr_pin); if (!exists && tr == TransRiseFall::fall()) { ap_index = parasiticAnalysisPtIndex(ap, TransRiseFall::rise()); exists = (*pi_pole_residue_maps_)[ap_index]->hasKey(drvr_pin); } - lock_.unlock(); return exists; } else @@ -1542,17 +1533,16 @@ ConcreteParasitics::findPiPoleResidue(const Pin *drvr_pin, { if (ap && pi_pole_residue_maps_) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.readLock(); + UniqueLock lock(lock_); Parasitic *parasitic = (*pi_pole_residue_maps_)[ap_index]->findKey(drvr_pin); - if (parasitic == NULL && tr == TransRiseFall::fall()) { + if (parasitic == nullptr && tr == TransRiseFall::fall()) { ap_index = parasiticAnalysisPtIndex(ap, TransRiseFall::rise()); parasitic = (*pi_pole_residue_maps_)[ap_index]->findKey(drvr_pin); } - lock_.unlock(); return parasitic; } else - return NULL; + return nullptr; } Parasitic * @@ -1564,8 +1554,8 @@ ConcreteParasitics::makePiPoleResidue(const Pin *drvr_pin, float c1) { int ap_index = parasiticAnalysisPtIndex(ap, tr); - lock_.writeLock(); - if (pi_pole_residue_maps_ == NULL) { + UniqueLock lock(lock_); + if (pi_pole_residue_maps_ == nullptr) { pi_pole_residue_maps_ = new ConcretePiPoleResidueMapSeq(mapSize()); ParasiticAnalysisPtIterator ap_iter(corners_); while (ap_iter.hasNext()) { @@ -1587,7 +1577,6 @@ ConcreteParasitics::makePiPoleResidue(const Pin *drvr_pin, pi_pole_residue = new ConcretePiPoleResidue(c2, rpi, c1); (*(*pi_pole_residue_maps_)[ap_index])[drvr_pin] = pi_pole_residue; } - lock_.unlock(); return pi_pole_residue; } @@ -1662,9 +1651,8 @@ ConcreteParasitics::hasParasiticNetwork(const Net *net, { if (ap && parasitic_network_maps_) { int ap_index = parasiticNetworkAnalysisPtIndex(ap); - lock_.readLock(); + UniqueLock lock(lock_); bool exists = (*parasitic_network_maps_)[ap_index]->hasKey(net); - lock_.unlock(); return exists; } else @@ -1678,18 +1666,17 @@ ConcreteParasitics::findParasiticNetwork(const Pin *pin, if (ap && parasitic_network_maps_) { int ap_index = parasiticNetworkAnalysisPtIndex(ap); ConcreteParasiticNetworkMap *parasitics = (*parasitic_network_maps_)[ap_index]; - lock_.readLock(); - Parasitic *parasitic = NULL; + UniqueLock lock(lock_); + Parasitic *parasitic = nullptr; if (parasitics->size()) { // Only call findParasiticNet if parasitics exist. Net *net = findParasiticNet(pin); parasitic = parasitics->findKey(net); } - lock_.unlock(); return parasitic; } else - return NULL; + return nullptr; } Parasitic * @@ -1698,8 +1685,8 @@ ConcreteParasitics::makeParasiticNetwork(Net *net, const ParasiticAnalysisPt *ap) { int ap_index = parasiticNetworkAnalysisPtIndex(ap); - lock_.writeLock(); - if (parasitic_network_maps_ == NULL) { + UniqueLock lock(lock_); + if (parasitic_network_maps_ == nullptr) { parasitic_network_maps_ = new ConcreteParasiticNetworkMapSeq(mapSize()); ParasiticAnalysisPtIterator ap_iter(corners_); while (ap_iter.hasNext()) { @@ -1715,11 +1702,10 @@ ConcreteParasitics::makeParasiticNetwork(Net *net, ConcreteParasiticNetwork *parasitic = (*parasitic_network_maps_)[ap_index]->findKey(net); - if (parasitic == NULL) { + if (parasitic == nullptr) { parasitic = new ConcreteParasiticNetwork(includes_pin_caps); (*(*parasitic_network_maps_)[ap_index])[net] = parasitic; } - lock_.unlock(); return parasitic; } @@ -1729,14 +1715,13 @@ ConcreteParasitics::deleteParasiticNetwork(const Net *net, { if (ap && parasitic_network_maps_) { int ap_index = parasiticNetworkAnalysisPtIndex(ap); - lock_.writeLock(); + UniqueLock lock(lock_); ConcreteParasiticNetwork *parasitic = (*parasitic_network_maps_)[ap_index]->findKey(net); if (parasitic) { (*parasitic_network_maps_)[ap_index]->eraseKey(net); delete parasitic; } - lock_.unlock(); } } @@ -1877,7 +1862,7 @@ ConcreteParasitics::connectionPin(const ParasiticNode *node) const return pin_node->pin(); } else - return NULL; + return nullptr; } ParasiticNode * @@ -1967,14 +1952,14 @@ ConcreteParasitics::reduceTo(Parasitic *parasitic, const ParasiticAnalysisPt *ap) { switch (reduce_to) { - case reduce_parasitics_to_pi_elmore: + case ReduceParasiticsTo::pi_elmore: reduceToPiElmore(parasitic, net, tr, op_cond, corner, cnst_min_max, ap); break; - case reduce_parasitics_to_pi_pole_residue2: + case ReduceParasiticsTo::pi_pole_residue2: reduceToPiPoleResidue2(parasitic, net, tr, op_cond, corner, cnst_min_max, ap); break; - case reduce_parasitics_to_none: + case ReduceParasiticsTo::none: break; } } diff --git a/parasitics/ConcreteParasitics.hh b/parasitics/ConcreteParasitics.hh index 106f9547..86bdc8c0 100644 --- a/parasitics/ConcreteParasitics.hh +++ b/parasitics/ConcreteParasitics.hh @@ -17,10 +17,10 @@ #ifndef STA_CONCRETE_PARASITICS_H #define STA_CONCRETE_PARASITICS_H +#include #include "Map.hh" #include "Set.hh" #include "MinMax.hh" -#include "ReadWriteLock.hh" #include "EstimateParasitics.hh" #include "Parasitics.hh" @@ -244,7 +244,7 @@ protected: ConcretePiElmoreMapSeq *pi_elmore_maps_; ConcretePiPoleResidueMapSeq *pi_pole_residue_maps_; ConcreteParasiticNetworkMapSeq *parasitic_network_maps_; - mutable ReadWriteLock lock_; + mutable std::mutex lock_; using EstimateParasitics::estimatePiElmore; friend class ConcreteLumpedElmore; diff --git a/parasitics/ConcreteParasiticsPvt.hh b/parasitics/ConcreteParasiticsPvt.hh index c6497866..99b4263a 100644 --- a/parasitics/ConcreteParasiticsPvt.hh +++ b/parasitics/ConcreteParasiticsPvt.hh @@ -343,7 +343,7 @@ public: ConcreteParasiticNode *node, float cap); virtual bool isCouplingCap() const { return true; } - virtual ConcreteParasiticNode *node2() const { return NULL; } + virtual ConcreteParasiticNode *node2() const { return nullptr; } virtual void replaceNode(ConcreteParasiticNode *from_node, ConcreteParasiticNode *to_node); }; diff --git a/parasitics/EstimateParasitics.cc b/parasitics/EstimateParasitics.cc index dbe08ae1..17e6bfdf 100644 --- a/parasitics/EstimateParasitics.cc +++ b/parasitics/EstimateParasitics.cc @@ -46,26 +46,26 @@ EstimateParasitics::estimatePiElmore(const Pin *drvr_pin, float wireload_cap, wireload_res; wireload->findWireload(fanout, op_cond, wireload_cap, wireload_res); - WireloadTree tree = wire_load_unknown_tree; + WireloadTree tree = WireloadTree::unknown; if (op_cond) tree = op_cond->wireloadTree(); switch (tree) { - case wire_load_worst_case_tree: + case WireloadTree::worst_case: estimatePiElmoreWorst(drvr_pin, wireload_cap, wireload_res, fanout, net_pin_cap, tr, op_cond, corner, min_max, sta, c2, rpi, c1, elmore_res, elmore_cap, elmore_use_load_cap); break; - case wire_load_unknown_tree: - case wire_load_balanced_tree: + case WireloadTree::balanced: + case WireloadTree::unknown: estimatePiElmoreBalanced(drvr_pin, wireload_cap, wireload_res, fanout, net_pin_cap, tr, op_cond, corner, min_max,sta, c2, rpi, c1, elmore_res, elmore_cap, elmore_use_load_cap); break; - case wire_load_best_case_tree: + case WireloadTree::best_case: estimatePiElmoreBest(drvr_pin, wireload_cap, net_pin_cap, tr, op_cond, corner, min_max, c2, rpi, c1, elmore_res, elmore_cap, diff --git a/parasitics/NullParasitics.cc b/parasitics/NullParasitics.cc index f2151b6d..1e618ca7 100644 --- a/parasitics/NullParasitics.cc +++ b/parasitics/NullParasitics.cc @@ -82,7 +82,7 @@ NullParasitics::findLumpedElmore(const Pin *, const TransRiseFall *, const ParasiticAnalysisPt *) const { - return NULL; + return nullptr; } bool @@ -97,7 +97,7 @@ NullParasitics::makeLumpedElmore(const Pin *, const TransRiseFall *, const ParasiticAnalysisPt *) { - return NULL; + return nullptr; } void @@ -120,7 +120,7 @@ NullParasitics::findPiElmore(const Pin *, const TransRiseFall *, const ParasiticAnalysisPt *) const { - return NULL; + return nullptr; } Parasitic * @@ -131,7 +131,7 @@ NullParasitics::makePiElmore(const Pin *, float, float) { - return NULL; + return nullptr; } void @@ -220,7 +220,7 @@ NullParasitics::findPiPoleResidue(const Pin *, const TransRiseFall *, const ParasiticAnalysisPt *) const { - return NULL; + return nullptr; } Parasitic * @@ -231,14 +231,14 @@ NullParasitics::makePiPoleResidue(const Pin *, float, float) { - return NULL; + return nullptr; } Parasitic * NullParasitics::findPoleResidue(const Parasitic *, const Pin *) const { - return NULL; + return nullptr; } void @@ -280,7 +280,7 @@ Parasitic * NullParasitics::findParasiticNetwork(const Pin *, const ParasiticAnalysisPt *) const { - return NULL; + return nullptr; } bool @@ -294,7 +294,7 @@ NullParasitics::makeParasiticNetwork(Net *, bool, const ParasiticAnalysisPt *) { - return NULL; + return nullptr; } bool @@ -314,14 +314,14 @@ NullParasitics::ensureParasiticNode(Parasitic *, Net *, int) { - return NULL; + return nullptr; } ParasiticNode * NullParasitics::ensureParasiticNode(Parasitic *, const Pin *) { - return NULL; + return nullptr; } void @@ -370,20 +370,20 @@ NullParasitics::makeResistor(const char *, const char * NullParasitics::name(const ParasiticNode *) { - return NULL; + return nullptr; } const Pin * NullParasitics::connectionPin(const ParasiticNode *) const { - return NULL; + return nullptr; } ParasiticNode * NullParasitics::findNode(Parasitic *, const Pin *) const { - return NULL; + return nullptr; } float @@ -414,7 +414,7 @@ NullParasitics::isCouplingCap(const ParasiticDevice *) const const char * NullParasitics::name(const ParasiticDevice *) const { - return NULL; + return nullptr; } float @@ -427,20 +427,20 @@ NullParasitics::value(const ParasiticDevice *, ParasiticNode * NullParasitics::node1(const ParasiticDevice *) const { - return NULL; + return nullptr; } ParasiticNode * NullParasitics::node2(const ParasiticDevice *) const { - return NULL; + return nullptr; } ParasiticNode * NullParasitics::otherNode(const ParasiticDevice *, ParasiticNode *) const { - return NULL; + return nullptr; } void @@ -475,7 +475,7 @@ NullParasitics::reduceToPiElmore(Parasitic *, const MinMax *, const ParasiticAnalysisPt *) { - return NULL; + return nullptr; } void @@ -497,7 +497,7 @@ NullParasitics::reduceToPiPoleResidue2(Parasitic *, const MinMax *, const ParasiticAnalysisPt *) { - return NULL; + return nullptr; } Parasitic * @@ -511,7 +511,7 @@ NullParasitics::estimatePiElmore(const Pin *, const MinMax *, const ParasiticAnalysisPt *) { - return NULL; + return nullptr; } void diff --git a/parasitics/NullParasitics.hh b/parasitics/NullParasitics.hh index 1b95795e..70610566 100644 --- a/parasitics/NullParasitics.hh +++ b/parasitics/NullParasitics.hh @@ -126,8 +126,8 @@ public: makeParasiticNetwork(Net *net, bool pin_cap_included, const ParasiticAnalysisPt *ap); - virtual ParasiticDeviceIterator *deviceIterator(Parasitic *) { return NULL; } - virtual ParasiticNodeIterator *nodeIterator(Parasitic *) { return NULL; } + virtual ParasiticDeviceIterator *deviceIterator(Parasitic *) { return nullptr; } + virtual ParasiticNodeIterator *nodeIterator(Parasitic *) { return nullptr; } virtual bool includesPinCaps(Parasitic *parasitic) const; virtual void deleteParasiticNetwork(const Net *net, const ParasiticAnalysisPt *ap); diff --git a/parasitics/Parasitics.cc b/parasitics/Parasitics.cc index 54401d2c..e5aa0fb2 100644 --- a/parasitics/Parasitics.cc +++ b/parasitics/Parasitics.cc @@ -51,17 +51,17 @@ Parasitics::findParasiticNet(const Pin *pin) const Net *net = network_->net(pin); // Pins on the top level instance may not have nets. // Use the net connected to the pin's terminal. - if (net == NULL && network_->isTopLevelPort(pin)) { + if (net == nullptr && network_->isTopLevelPort(pin)) { Term *term = network_->term(pin); if (term) return network_->net(term); else - return NULL; + return nullptr; } if (net) return network_->highestConnectedNet(net); else - return NULL; + return nullptr; } void @@ -102,20 +102,20 @@ Parasitics::makeWireloadNetwork(const Pin *drvr_pin, float wireload_cap, wireload_res; wireload->findWireload(fanout, op_cond, wireload_cap, wireload_res); - WireloadTree tree = wire_load_balanced_tree; + WireloadTree tree = WireloadTree::balanced; if (op_cond) tree = op_cond->wireloadTree(); switch (tree) { - case wire_load_worst_case_tree: + case WireloadTree::worst_case: makeWireloadNetworkWorst(parasitic, drvr_pin, wireload_cap, wireload_res, fanout, ap); break; - case wire_load_balanced_tree: + case WireloadTree::balanced: makeWireloadNetworkBalanced(parasitic, drvr_pin, wireload_cap, wireload_res, fanout, ap); break; - case wire_load_unknown_tree: - case wire_load_best_case_tree: + case WireloadTree::best_case: + case WireloadTree::unknown: makeWireloadNetworkBest(parasitic, drvr_pin, wireload_cap, wireload_res, fanout, ap); break; @@ -136,7 +136,7 @@ Parasitics::makeWireloadNetworkWorst(Parasitic *parasitic, ParasiticNode *drvr_node = ensureParasiticNode(parasitic, drvr_pin); Net *net = network_->net(drvr_pin); ParasiticNode *load_node = ensureParasiticNode(parasitic, net, 0); - makeResistor(NULL, drvr_node, load_node, wireload_res, ap); + makeResistor(nullptr, drvr_node, load_node, wireload_res, ap); parasitics_->incrCap(load_node, wireload_cap, ap); PinConnectedPinIterator *load_iter = network_->connectedPinIterator(drvr_pin); @@ -145,7 +145,7 @@ Parasitics::makeWireloadNetworkWorst(Parasitic *parasitic, if (load_pin != drvr_pin && network_->isLoad(load_pin)) { ParasiticNode *load_node1 = ensureParasiticNode(parasitic, load_pin); - makeResistor(NULL, load_node, load_node1, 0.0, ap); + makeResistor(nullptr, load_node, load_node1, 0.0, ap); } } } @@ -168,7 +168,7 @@ Parasitics::makeWireloadNetworkBest(Parasitic *parasitic, if (load_pin != drvr_pin && network_->isLoad(load_pin)) { ParasiticNode *load_node1 = ensureParasiticNode(parasitic, load_pin); - makeResistor(NULL, drvr_node, load_node1, 0.0, ap); + makeResistor(nullptr, drvr_node, load_node1, 0.0, ap); } } } @@ -193,7 +193,7 @@ Parasitics::makeWireloadNetworkBalanced(Parasitic *parasitic, if (load_pin != drvr_pin && network_->isLoad(load_pin)) { ParasiticNode *load_node1 = ensureParasiticNode(parasitic, load_pin); - makeResistor(NULL, drvr_node, load_node1, fanout_res, ap); + makeResistor(nullptr, drvr_node, load_node1, fanout_res, ap); parasitics_->incrCap(load_node1, fanout_cap, ap); } } diff --git a/parasitics/ParasiticsClass.hh b/parasitics/ParasiticsClass.hh index 38e40977..03503bf0 100644 --- a/parasitics/ParasiticsClass.hh +++ b/parasitics/ParasiticsClass.hh @@ -25,11 +25,7 @@ class ParasiticDevice; class ParasiticNode; class ParasiticAnalysisPt; -typedef enum { - reduce_parasitics_to_pi_elmore, - reduce_parasitics_to_pi_pole_residue2, - reduce_parasitics_to_none -} ReduceParasiticsTo; +enum class ReduceParasiticsTo { pi_elmore, pi_pole_residue2, none }; } // namespace #endif diff --git a/parasitics/ReduceParasitics.cc b/parasitics/ReduceParasitics.cc index 460041dd..3c376296 100644 --- a/parasitics/ReduceParasitics.cc +++ b/parasitics/ReduceParasitics.cc @@ -80,10 +80,10 @@ protected: ReduceToPi::ReduceToPi(StaState *sta) : StaState(sta), coupling_cap_multiplier_(1.0), - tr_(NULL), - op_cond_(NULL), - corner_(NULL), - cnst_min_max_(NULL) + tr_(nullptr), + op_cond_(nullptr), + corner_(nullptr), + cnst_min_max_(nullptr) { } @@ -401,7 +401,7 @@ private: ReduceToPiPoleResidue2::ReduceToPiPoleResidue2(StaState *sta) : ReduceToPi(sta), - moments_(NULL) + moments_(nullptr) { } diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 1c65a667..f5d30663 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -117,13 +117,13 @@ SpefReader::SpefReader(const char *filename, delimiter_('\0'), bus_brkt_left_('\0'), bus_brkt_right_('\0'), - net_(NULL), + net_(nullptr), report_(report), network_(network), parasitics_(parasitics), triple_index_(0), - design_flow_(NULL), - parasitic_(NULL) + design_flow_(nullptr), + parasitic_(nullptr) { ap->setCouplingCapFactor(coupling_cap_factor); } @@ -133,7 +133,7 @@ SpefReader::~SpefReader() if (design_flow_) { deleteContents(design_flow_); delete design_flow_; - design_flow_ = NULL; + design_flow_ = nullptr; } SpefNameMap::Iterator map_iter(name_map_); @@ -202,7 +202,7 @@ SpefReader::getChars(char *buf, { char *status = gzgets(stream_, buf, max_size); if (status == Z_NULL) - result = 0; // YY_NULL + result = 0; // YY_nullptr else result = static_cast(strlen(buf)); } @@ -214,7 +214,7 @@ SpefReader::getChars(char *buf, { char *status = gzgets(stream_, buf, max_size); if (status == Z_NULL) - result = 0; // YY_NULL + result = 0; // YY_nullptr else result = strlen(buf); } @@ -358,7 +358,7 @@ SpefReader::findPin(char *name) const char *port_name = delim + 1; if (inst) { pin = network_->findPin(inst, port_name); - if (pin == NULL) + if (pin == nullptr) warn("pin %s not found.\n", name); } else @@ -366,7 +366,7 @@ SpefReader::findPin(char *name) } else { pin = findPortPinRelative(name); - if (pin == NULL) + if (pin == nullptr) warn("pin %s not found.\n", name); } } @@ -380,7 +380,7 @@ SpefReader::findNet(char *name) name = nameMapLookup(name); if (name) { net = findNetRelative(name); - if (net == NULL) + if (net == nullptr) warn("net %s not found.\n", name); } return net; @@ -473,7 +473,7 @@ SpefReader::dspfFinish() // Checking "should" be done by report_annotated_parasitics. if (!quiet_) parasitics_->check(parasitic_); - if (reduce_to_ != reduce_parasitics_to_none) { + if (reduce_to_ != ReduceParasiticsTo::none) { TransRiseFallIterator tr_iter; while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); @@ -497,7 +497,7 @@ SpefReader::findParasiticNode(char *name) int ext_node_id; Pin *ext_pin; findParasiticNode(name, node, ext_net, ext_node_id, ext_pin); - if (node == NULL + if (node == nullptr && (ext_net || ext_pin)) warn("%s not connected to net %s.\n", name, network_->pathName(net_)); return node; @@ -621,8 +621,8 @@ SpefReader::makeCouplingCap(int id, char *node_name2, float cap) { - const char *name = NULL; - const char *name_tmp = NULL; + const char *name = nullptr; + const char *name_tmp = nullptr; if (keep_device_names_) // Prepend device type because OA uses one namespace for all devices. name = name_tmp = stringPrint("C%d", id); @@ -635,14 +635,14 @@ SpefReader::makeCouplingCap(int id, findParasiticNode(node_name2, node2, ext_net2, ext_node_id2, ext_pin2); if (node1 && node2) parasitics_->makeCouplingCap(name, node1, node2, cap, ap_); - if (node1 && node2 == NULL) { + if (node1 && node2 == nullptr) { if (ext_net2) parasitics_->makeCouplingCap(name, node1, ext_net2, ext_node_id2, cap, ap_); else if (ext_pin2) parasitics_->makeCouplingCap(name, node1, ext_pin2, cap, ap_); } - else if (node1 == NULL && node2) { + else if (node1 == nullptr && node2) { if (ext_net1) parasitics_->makeCouplingCap(name, node2, ext_net1, ext_node_id1, cap, ap_); @@ -662,8 +662,8 @@ SpefReader::makeResistor(int id, ParasiticNode *node2 = findParasiticNode(node_name2); if (node1 && node2) { float res1 = res->value(triple_index_) * res_scale_; - const char *name = NULL; - const char *name_tmp = NULL; + const char *name = nullptr; + const char *name_tmp = nullptr; if (keep_device_names_) // Prepend device type because OA uses one namespace for all devices. name = name_tmp = stringPrint("R%d", id); diff --git a/sdc/Clock.cc b/sdc/Clock.cc index 72564079..d28b4556 100644 --- a/sdc/Clock.cc +++ b/sdc/Clock.cc @@ -34,29 +34,29 @@ isPowerOfTwo(int i); Clock::Clock(const char *name, int index) : name_(stringCopy(name)), - pins_(NULL), + pins_(nullptr), add_to_pins_(false), - vertex_pins_(NULL), - pll_out_(NULL), - pll_fdbk_(NULL), + vertex_pins_(nullptr), + pll_out_(nullptr), + pll_fdbk_(nullptr), period_(0.0), - waveform_(NULL), + waveform_(nullptr), waveform_valid_(false), index_(index), - clk_edges_(NULL), + clk_edges_(nullptr), is_propagated_(false), - uncertainties_(NULL), + uncertainties_(nullptr), is_generated_(false), - src_pin_(NULL), - master_clk_(NULL), + src_pin_(nullptr), + master_clk_(nullptr), master_clk_infered_(false), divide_by_(0), multiply_by_(0), duty_cycle_(0), invert_(false), combinational_(false), - edges_(NULL), - edge_shifts_(NULL) + edges_(nullptr), + edge_shifts_(nullptr) { makeClkEdges(); } @@ -85,7 +85,7 @@ Clock::initClk(PinSet *pins, bool Clock::isVirtual() const { - return pins_ == NULL || pins_->empty(); + return pins_ == nullptr || pins_->empty(); } void @@ -150,10 +150,10 @@ Clock::~Clock() void Clock::addPin(Pin *pin) { - if (pins_ == NULL) + if (pins_ == nullptr) pins_ = new PinSet; pins_->insert(pin); - if (vertex_pins_ == NULL) + if (vertex_pins_ == nullptr) vertex_pins_ = new PinSet; vertex_pins_->insert(pin); } @@ -191,7 +191,7 @@ Clock::defaultPin() const if (pin_iter.hasNext()) return pin_iter.next(); else - return NULL; + return nullptr; } ClockEdge * @@ -256,7 +256,7 @@ Clock::setSlewLimit(const TransRiseFallBoth *tr, const MinMax *min_max, float slew) { - slew_limits_[clk_data].setValue(tr, min_max, slew); + slew_limits_[int(clk_data)].setValue(tr, min_max, slew); } void @@ -267,7 +267,7 @@ Clock::slewLimit(const TransRiseFall *tr, float &slew, bool &exists) const { - slew_limits_[clk_data].value(tr, min_max, slew, exists); + slew_limits_[int(clk_data)].value(tr, min_max, slew, exists); } void @@ -288,7 +288,7 @@ void Clock::setUncertainty(const SetupHoldAll *setup_hold, float uncertainty) { - if (uncertainties_ == NULL) + if (uncertainties_ == nullptr) uncertainties_ = new ClockUncertainties; uncertainties_->setValue(setup_hold, uncertainty); } @@ -297,7 +297,7 @@ void Clock::setUncertainty(const SetupHold *setup_hold, float uncertainty) { - if (uncertainties_ == NULL) + if (uncertainties_ == nullptr) uncertainties_ = new ClockUncertainties; uncertainties_->setValue(setup_hold, uncertainty); } @@ -309,7 +309,7 @@ Clock::removeUncertainty(const SetupHoldAll *setup_hold) uncertainties_->removeValue(setup_hold); if (uncertainties_->empty()) { delete uncertainties_; - uncertainties_ = NULL; + uncertainties_ = nullptr; } } } @@ -361,7 +361,7 @@ Clock::initGeneratedClk(PinSet *pins, if (edges && edges->empty()) { delete edges; - edges = NULL; + edges = nullptr; } edges_ = edges; @@ -369,7 +369,7 @@ Clock::initGeneratedClk(PinSet *pins, if (edge_shifts && edge_shifts->empty()) { delete edge_shifts; - edge_shifts = NULL; + edge_shifts = nullptr; } edge_shifts_ = edge_shifts; } @@ -400,7 +400,7 @@ Clock::isGeneratedWithPropagatedMaster() const void Clock::generate(const Clock *src_clk) { - if (waveform_ == NULL) + if (waveform_ == nullptr) waveform_ = new FloatSeq; else waveform_->clear(); @@ -587,11 +587,11 @@ int clkCmp(const Clock *clk1, const Clock *clk2) { - if (clk1 == NULL && clk2) + if (clk1 == nullptr && clk2) return -1; - else if (clk1 == NULL && clk2 == NULL) + else if (clk1 == nullptr && clk2 == nullptr) return 0; - else if (clk1 && clk2 == NULL) + else if (clk1 && clk2 == nullptr) return 1; else { int index1 = clk1->index(); @@ -609,11 +609,11 @@ int clkEdgeCmp(ClockEdge *clk_edge1, ClockEdge *clk_edge2) { - if (clk_edge1 == NULL && clk_edge2) + if (clk_edge1 == nullptr && clk_edge2) return -1; - else if (clk_edge1 == NULL && clk_edge2 == NULL) + else if (clk_edge1 == nullptr && clk_edge2 == nullptr) return 0; - else if (clk_edge1 && clk_edge2 == NULL) + else if (clk_edge1 && clk_edge2 == nullptr) return 1; else { int index1 = clk_edge1->index(); diff --git a/sdc/ClockGatingCheck.cc b/sdc/ClockGatingCheck.cc index 4f0667c0..182aa5f8 100644 --- a/sdc/ClockGatingCheck.cc +++ b/sdc/ClockGatingCheck.cc @@ -20,7 +20,7 @@ namespace sta { ClockGatingCheck::ClockGatingCheck() : - active_value_(logic_unknown) + active_value_(LogicValue::unknown) { } diff --git a/sdc/ClockGroups.cc b/sdc/ClockGroups.cc index 30474205..1cd4835e 100644 --- a/sdc/ClockGroups.cc +++ b/sdc/ClockGroups.cc @@ -20,9 +20,7 @@ namespace sta { -ClockGroup::ClockGroup(ClockGroups *clk_groups, - ClockSet *clks) : - clk_groups_(clk_groups), +ClockGroup::ClockGroup(ClockSet *clks) : clks_(clks) { } @@ -64,7 +62,7 @@ ClockGroups::~ClockGroups() ClockGroup * ClockGroups::makeClockGroup(ClockSet *clks) { - ClockGroup *group = new ClockGroup(this, clks); + ClockGroup *group = new ClockGroup(clks); groups_.insert(group); return group; } diff --git a/sdc/ClockGroups.hh b/sdc/ClockGroups.hh index b794e95b..9954d954 100644 --- a/sdc/ClockGroups.hh +++ b/sdc/ClockGroups.hh @@ -26,8 +26,7 @@ namespace sta { class ClockGroup { public: - ClockGroup(ClockGroups *clk_groups, - ClockSet *clks); + ClockGroup(ClockSet *clks); ~ClockGroup(); bool isMember(const Clock *clk); ClockSet *clks() const { return clks_; } @@ -35,7 +34,6 @@ public: private: DISALLOW_COPY_AND_ASSIGN(ClockGroup); - ClockGroups *clk_groups_; ClockSet *clks_; }; diff --git a/sdc/CycleAccting.cc b/sdc/CycleAccting.cc index af2f8153..2efa9c27 100644 --- a/sdc/CycleAccting.cc +++ b/sdc/CycleAccting.cc @@ -309,6 +309,8 @@ CycleAccting::targetTimeOffset(const TimingRole *check_role) return targetCycle(check_role) * tgt_->clock()->period(); } +//////////////////////////////////////////////////////////////// + bool CycleAcctingLess::operator()(const CycleAccting *acct1, const CycleAccting *acct2) const @@ -321,4 +323,18 @@ CycleAcctingLess::operator()(const CycleAccting *acct1, && acct1->target()->index() < acct2->target()->index()); } +Hash +CycleAcctingHash::operator()(const CycleAccting *acct) const +{ + return hashSum(acct->src()->index(), acct->target()->index()); +} + +bool +CycleAcctingEqual::operator()(const CycleAccting *acct1, + const CycleAccting *acct2) const +{ + return acct1->src() == acct2->src() + && acct1->target() == acct2->target(); +} + } // namespace diff --git a/sdc/CycleAccting.hh b/sdc/CycleAccting.hh index 5a970929..9cc5eb14 100644 --- a/sdc/CycleAccting.hh +++ b/sdc/CycleAccting.hh @@ -88,5 +88,18 @@ public: const CycleAccting *acct2) const; }; +class CycleAcctingHash +{ +public: + Hash operator()(const CycleAccting *acct) const; +}; + +class CycleAcctingEqual +{ +public: + bool operator()(const CycleAccting *acct1, + const CycleAccting *acct2) const; +}; + } // namespace #endif diff --git a/sdc/DeratingFactors.cc b/sdc/DeratingFactors.cc index 9e4419c8..a7e67e66 100644 --- a/sdc/DeratingFactors.cc +++ b/sdc/DeratingFactors.cc @@ -19,6 +19,12 @@ namespace sta { +inline int +TimingDerateIndex(TimingDerateType type) +{ + return int(type); +} + DeratingFactors::DeratingFactors() { clear(); @@ -33,7 +39,7 @@ DeratingFactors::setFactor(PathClkOrData clk_data, TransRiseFallIterator tr_iter(tr); while (tr_iter.hasNext()) { TransRiseFall *tr1 = tr_iter.next(); - factors_[clk_data].setValue(tr1, early_late, factor); + factors_[int(clk_data)].setValue(tr1, early_late, factor); } } @@ -44,14 +50,14 @@ DeratingFactors::factor(PathClkOrData clk_data, float &factor, bool &exists) const { - factors_[clk_data].value(tr, early_late, factor, exists); + factors_[int(clk_data)].value(tr, early_late, factor, exists); } void DeratingFactors::clear() { for (int clk_data = 0; clk_data < path_clk_or_data_count;clk_data++) - factors_[clk_data].clear(); + factors_[int(clk_data)].clear(); } void @@ -59,13 +65,13 @@ DeratingFactors::isOneValue(const EarlyLate *early_late, bool &is_one_value, float &value) const { - bool is_one_value1, is_one_value2; - float value1, value2; - is_one_value1 = factors_[path_clk].isOneValue(early_late, value1); - is_one_value2 = factors_[path_data].isOneValue(early_late, value2); - is_one_value = is_one_value1 - && is_one_value2 - && value1 == value2; + bool is_one_value0, is_one_value1; + float value0, value1; + is_one_value0 = factors_[0].isOneValue(early_late, value0); + is_one_value1 = factors_[1].isOneValue(early_late, value1); + is_one_value = is_one_value0 + && is_one_value1 + && value0 == value1; value = value1; } @@ -75,14 +81,14 @@ DeratingFactors::isOneValue(PathClkOrData clk_data, bool &is_one_value, float &value) const { - is_one_value = factors_[clk_data].isOneValue(early_late, value); + is_one_value = factors_[int(clk_data)].isOneValue(early_late, value); } bool DeratingFactors::hasValue() const { - return factors_[path_clk].hasValue() - || factors_[path_data].hasValue(); + return factors_[0].hasValue() + || factors_[1].hasValue(); } //////////////////////////////////////////////////////////////// @@ -99,7 +105,7 @@ DeratingFactorsGlobal::setFactor(TimingDerateType type, const EarlyLate *early_late, float factor) { - factors_[type].setFactor(clk_data, tr, early_late, factor); + factors_[TimingDerateIndex(type)].setFactor(clk_data, tr, early_late, factor); } void @@ -110,7 +116,7 @@ DeratingFactorsGlobal::factor(TimingDerateType type, float &factor, bool &exists) const { - factors_[type].factor(clk_data, tr, early_late, factor, exists); + factors_[TimingDerateIndex(type)].factor(clk_data, tr, early_late, factor, exists); } void @@ -123,7 +129,7 @@ DeratingFactorsGlobal::clear() DeratingFactors * DeratingFactorsGlobal::factors(TimingDerateType type) { - return &factors_[type]; + return &factors_[TimingDerateIndex(type)]; } //////////////////////////////////////////////////////////////// @@ -140,7 +146,7 @@ DeratingFactorsCell::setFactor(TimingDerateType type, const EarlyLate *early_late, float factor) { - factors_[type].setFactor(clk_data, tr, early_late, factor); + factors_[TimingDerateIndex(type)].setFactor(clk_data, tr, early_late, factor); } void @@ -151,7 +157,7 @@ DeratingFactorsCell::factor(TimingDerateType type, float &factor, bool &exists) const { - factors_[type].factor(clk_data, tr, early_late, factor, exists); + factors_[TimingDerateIndex(type)].factor(clk_data, tr, early_late, factor, exists); } void @@ -164,7 +170,7 @@ DeratingFactorsCell::clear() DeratingFactors * DeratingFactorsCell::factors(TimingDerateType type) { - return &factors_[type]; + return &factors_[TimingDerateIndex(type)]; } void @@ -174,8 +180,10 @@ DeratingFactorsCell::isOneValue(const EarlyLate *early_late, { bool is_one_value1, is_one_value2; float value1, value2; - factors_[timing_derate_cell_delay].isOneValue(early_late, is_one_value1, value1); - factors_[timing_derate_cell_check].isOneValue(early_late, is_one_value2, value2); + factors_[TimingDerateIndex(TimingDerateType::cell_delay)] + .isOneValue(early_late, is_one_value1, value1); + factors_[TimingDerateIndex(TimingDerateType::cell_check)] + .isOneValue(early_late, is_one_value2, value2); is_one_value = is_one_value1 && is_one_value2 && value1 == value2; diff --git a/sdc/DisabledPorts.cc b/sdc/DisabledPorts.cc index 8af79cd8..6dfa1278 100644 --- a/sdc/DisabledPorts.cc +++ b/sdc/DisabledPorts.cc @@ -26,9 +26,9 @@ namespace sta { DisabledPorts::DisabledPorts() : all_(false), - from_(NULL), - to_(NULL), - from_to_(NULL) + from_(nullptr), + to_(nullptr), + from_to_(nullptr) { } @@ -57,7 +57,7 @@ DisabledPorts::removeDisabledAll() void DisabledPorts::setDisabledFrom(LibertyPort *port) { - if (from_ == NULL) + if (from_ == nullptr) from_ = new LibertyPortSet; from_->insert(port); } @@ -72,7 +72,7 @@ DisabledPorts::removeDisabledFrom(LibertyPort *port) void DisabledPorts::setDisabledTo(LibertyPort *port) { - if (to_ == NULL) + if (to_ == nullptr) to_ = new LibertyPortSet; to_->insert(port); } @@ -87,7 +87,7 @@ DisabledPorts::removeDisabledTo(LibertyPort *port) void DisabledPorts::setDisabledFromTo(LibertyPort *from, LibertyPort *to) { - if (from_to_ == NULL) + if (from_to_ == nullptr) from_to_ = new LibertyPortPairSet; LibertyPortPair pair(from, to); if (!from_to_->hasKey(&pair)) { @@ -126,7 +126,7 @@ DisabledPorts::isDisabled(LibertyPort *from, LibertyPort *to, DisabledCellPorts::DisabledCellPorts(LibertyCell *cell) : DisabledPorts(), cell_(cell), - arc_sets_(NULL) + arc_sets_(nullptr) { } @@ -139,7 +139,7 @@ DisabledCellPorts::~DisabledCellPorts() void DisabledCellPorts::setDisabled(TimingArcSet *arc_set) { - if (arc_sets_ == NULL) + if (arc_sets_ == nullptr) arc_sets_ = new TimingArcSetSet; arc_sets_->insert(arc_set); } diff --git a/sdc/ExceptionPath.cc b/sdc/ExceptionPath.cc index 83456c55..5cf8351a 100644 --- a/sdc/ExceptionPath.cc +++ b/sdc/ExceptionPath.cc @@ -235,7 +235,7 @@ ExceptionPath::firstPt() else if (to_) return to_; else - return NULL; + return nullptr; } bool @@ -295,7 +295,7 @@ ExceptionPath::fromThruToPriority(ExceptionFrom *from, Hash ExceptionPath::hash() const { - return hash(NULL); + return hash(nullptr); } Hash @@ -317,7 +317,7 @@ bool ExceptionPath::mergeablePts(ExceptionPath *exception) const { ExceptionPt *ignore; - return mergeablePts(exception, NULL, ignore); + return mergeablePts(exception, nullptr, ignore); } bool @@ -325,14 +325,14 @@ ExceptionPath::mergeablePts(ExceptionPath *exception2, ExceptionPt *missing_pt2, ExceptionPt *&missing_pt) const { - missing_pt = NULL; + missing_pt = nullptr; ExceptionFrom *from2 = exception2->from(); if ((from_ && from2 && !(from_->transition() == from2->transition() && (from2 == missing_pt2 || from_->equal(from2)))) - || (from_ && from2 == NULL) - || (from_ == NULL && from2)) + || (from_ && from2 == nullptr) + || (from_ == nullptr && from2)) return false; if (from2 == missing_pt2) missing_pt = from_; @@ -360,8 +360,8 @@ ExceptionPath::mergeablePts(ExceptionPath *exception2, && to_->endTransition() == to2->endTransition() && (to2 == missing_pt2 || to_->equal(to2)))) - || (to_ && to2 == NULL) - || (to_ == NULL && to2)) + || (to_ && to2 == nullptr) + || (to_ == nullptr && to2)) return false; if (to2 == missing_pt2) missing_pt = to_; @@ -374,11 +374,11 @@ ExceptionPath::intersectsPts(ExceptionPath *exception) const ExceptionFrom *from2 = exception->from(); ExceptionThruSeq *thrus2 = exception->thrus(); ExceptionTo *to2 = exception->to(); - if (((from_ == NULL && from2 == NULL) + if (((from_ == nullptr && from2 == nullptr) || (from_ && from2 && from_->intersectsPts(from2))) - && ((thrus_ == NULL && thrus2 == NULL) + && ((thrus_ == nullptr && thrus2 == nullptr) || (thrus_ && thrus2 && thrus_->size() == thrus2->size())) - && ((to_ == NULL && to2 == NULL) + && ((to_ == nullptr && to2 == nullptr) || (to_ && to2 && to_->intersectsPts(to2)))) { ExceptionThruSeq::Iterator thrus_iter1(thrus_); ExceptionThruSeq::Iterator thrus_iter2(thrus2); @@ -438,14 +438,14 @@ void ExceptionPath::makeStates() { if (thrus_) { - ExceptionState *prev_state = NULL; + ExceptionState *prev_state = nullptr; ExceptionThruSeq::Iterator thru_iter(thrus_); bool first = true; int index = 0; while (thru_iter.hasNext()) { ExceptionThru *thru = thru_iter.next(); // No state for first -thru if no -from,since it kicks off the exception. - if (!(from_ == NULL && first)) { + if (!(from_ == nullptr && first)) { ExceptionState *state = new ExceptionState(this, thru, index); if (prev_state) prev_state->setNextState(state); @@ -457,14 +457,14 @@ ExceptionPath::makeStates() index++; } // Last state indicates all the thrus have been traversed. - ExceptionState *state = new ExceptionState(this, NULL, index); + ExceptionState *state = new ExceptionState(this, nullptr, index); if (prev_state) prev_state->setNextState(state); else states_ = state; } else - states_ = new ExceptionState(this, NULL, 0); + states_ = new ExceptionState(this, nullptr, 0); } bool @@ -478,33 +478,33 @@ ExceptionPath::resetMatch(ExceptionFrom *from, // exceptions that match the -from even if they are more specific. // -from return ((from && from_ - && thrus == NULL - && to == NULL + && thrus == nullptr + && to == nullptr && from_->intersectsPts(from)) // -thru - || (from == NULL + || (from == nullptr && thrus && thrus_ - && to == NULL + && to == nullptr && thrusIntersectPts(thrus_, thrus)) // -to - || (from == NULL - && thrus == NULL + || (from == nullptr + && thrus == nullptr && to && to_ && to_->intersectsPts(to)) // -from -thru || (from && from_ && thrus && thrus_ - && to == NULL + && to == nullptr && from_->intersectsPts(from) && thrusIntersectPts(thrus_, thrus)) // -from -to || (from && from_ - && thrus == NULL + && thrus == nullptr && to && to_ && from_->intersectsPts(from) && to_->intersectsPts(to)) // -thru -to - || (from == NULL + || (from == nullptr && thrus && thrus_ && to && to_ && thrusIntersectPts(thrus_, thrus) @@ -680,9 +680,9 @@ FalsePath::overrides(ExceptionPath *exception) const //////////////////////////////////////////////////////////////// LoopPath::LoopPath(ExceptionThruSeq *thrus, bool own_pts) : - FalsePath(NULL, thrus, NULL, MinMaxAll::all(), own_pts, - falsePathPriority() + fromThruToPriority(NULL, thrus, NULL), - NULL) + FalsePath(nullptr, thrus, nullptr, MinMaxAll::all(), own_pts, + falsePathPriority() + fromThruToPriority(nullptr, thrus, nullptr), + nullptr) { } @@ -810,7 +810,7 @@ FilterPath::FilterPath(ExceptionFrom *from, bool own_pts) : ExceptionPath(from, thrus, to, MinMaxAll::all(), own_pts, filterPathPriority() + fromThruToPriority(from, thrus, to), - NULL) + nullptr) { } @@ -962,17 +962,17 @@ ExceptionFromTo::ExceptionFromTo(PinSet *pins, if (pins_ && pins_->empty()) { if (own_pts) delete pins_; - pins_ = NULL; + pins_ = nullptr; } if (clks_ && clks_->empty()) { if (own_pts) delete clks_; - clks_ = NULL; + clks_ = nullptr; } if (insts_ && insts_->empty()) { if (own_pts) delete insts_; - insts_ = NULL; + insts_ = nullptr; } findHash(); } @@ -989,19 +989,19 @@ ExceptionFromTo::~ExceptionFromTo() bool ExceptionFromTo::hasPins() const { - return pins_ != NULL && !pins_->empty(); + return pins_ != nullptr && !pins_->empty(); } bool ExceptionFromTo::hasClocks() const { - return clks_ != NULL && !clks_->empty(); + return clks_ != nullptr && !clks_->empty(); } bool ExceptionFromTo::hasInstances() const { - return insts_ != NULL && !insts_->empty(); + return insts_ != nullptr && !insts_->empty(); } bool @@ -1161,7 +1161,7 @@ ExceptionFromTo::deleteObjects(ExceptionFromTo *pt) void ExceptionFromTo::addPin(Pin *pin) { - if (pins_ == NULL) + if (pins_ == nullptr) pins_ = new PinSet; if (!pins_->hasKey(pin)) { pins_->insert(pin); @@ -1173,7 +1173,7 @@ ExceptionFromTo::addPin(Pin *pin) void ExceptionFromTo::addClock(Clock *clk) { - if (clks_ == NULL) + if (clks_ == nullptr) clks_ = new ClockSet; if (!clks_->hasKey(clk)) { clks_->insert(clk); @@ -1185,7 +1185,7 @@ ExceptionFromTo::addClock(Clock *clk) void ExceptionFromTo::addInstance(Instance *inst) { - if (insts_ == NULL) + if (insts_ == nullptr) insts_ = new InstanceSet; if (!insts_->hasKey(inst)) { insts_->insert(inst); @@ -1320,13 +1320,13 @@ ExceptionFrom::findHash() ExceptionFrom * ExceptionFrom::clone() { - PinSet *pins = NULL; + PinSet *pins = nullptr; if (pins_) pins = new PinSet(*pins_); - ClockSet *clks = NULL; + ClockSet *clks = nullptr; if (clks_) clks = new ClockSet(*clks_); - InstanceSet *insts = NULL; + InstanceSet *insts = nullptr; if (insts_) insts = new InstanceSet(*insts_); return new ExceptionFrom(pins, clks, insts, tr_, true); @@ -1368,13 +1368,13 @@ ExceptionTo::ExceptionTo(PinSet *pins, ExceptionTo * ExceptionTo::clone() { - PinSet *pins = NULL; + PinSet *pins = nullptr; if (pins_) pins = new PinSet(*pins_); - ClockSet *clks = NULL; + ClockSet *clks = nullptr; if (clks_) clks = new ClockSet(*clks_); - InstanceSet *insts = NULL; + InstanceSet *insts = nullptr; if (insts_) insts = new InstanceSet(*insts_); return new ExceptionTo(pins, clks, insts, tr_, end_tr_, true); @@ -1449,9 +1449,9 @@ ExceptionTo::matches(const Pin *pin, && network->direction(pin)->isAnyInput() && tr_->matches(end_tr) && end_tr_->matches(end_tr)) - || (pins_ == NULL - && clks_ == NULL - && insts_ == NULL + || (pins_ == nullptr + && clks_ == nullptr + && insts_ == nullptr && end_tr_->matches(end_tr)); } @@ -1463,9 +1463,9 @@ ExceptionTo::matches(const Pin *pin, && pins_->hasKey(const_cast(pin)) && tr_->matches(end_tr) && end_tr_->matches(end_tr)) - || (pins_ == NULL - && clks_ == NULL - && insts_ == NULL + || (pins_ == nullptr + && clks_ == nullptr + && insts_ == nullptr && end_tr_->matches(end_tr)); } @@ -1509,7 +1509,7 @@ ExceptionThru::ExceptionThru(PinSet *pins, const Network *network) : ExceptionPt(tr, own_pts), pins_(pins), - edges_(NULL), + edges_(nullptr), nets_(nets), insts_(insts) { @@ -1517,17 +1517,17 @@ ExceptionThru::ExceptionThru(PinSet *pins, if (pins_ && pins_->empty()) { if (own_pts) delete pins_; - pins_ = NULL; + pins_ = nullptr; } if (nets_ && nets_->empty()) { if (own_pts) delete nets_; - nets_ = NULL; + nets_ = nullptr; } if (insts_ && insts_->empty()) { if (own_pts) delete insts_; - insts_ = NULL; + insts_ = nullptr; } makeAllEdges(network); findHash(); @@ -1599,7 +1599,7 @@ void ExceptionThru::makeHpinEdges(const Pin *pin, const Network *network) { - if (edges_ == NULL) + if (edges_ == nullptr) edges_ = new EdgePinsSet; // Add edges thru pin to edges_. insertPinPairsThruHierPin(pin, network, edges_); @@ -1611,7 +1611,7 @@ ExceptionThru::makeNetEdges(const Network *network) NetSet::Iterator net_iter(nets_); while (net_iter.hasNext()) { Net *net = net_iter.next(); - if (edges_ == NULL) + if (edges_ == nullptr) edges_ = new EdgePinsSet; // Add edges thru pin to edges_. insertPinPairsThruNet(net, network, edges_); @@ -1622,7 +1622,7 @@ void ExceptionThru::makeNetEdges(Net *net, const Network *network) { - if (edges_ == NULL) + if (edges_ == nullptr) edges_ = new EdgePinsSet; // Add edges thru pin to edges_. insertPinPairsThruNet(net, network, edges_); @@ -1764,19 +1764,19 @@ exceptionThrusClone(ExceptionThruSeq *thrus, return thrus_cpy; } else - return NULL; + return nullptr; } ExceptionThru * ExceptionThru::clone(const Network *network) { - PinSet *pins = NULL; + PinSet *pins = nullptr; if (pins_) pins = new PinSet(*pins_); - NetSet *nets = NULL; + NetSet *nets = nullptr; if (nets_) nets = new NetSet(*nets_); - InstanceSet *insts = NULL; + InstanceSet *insts = nullptr; if (insts_) insts = new InstanceSet(*insts_); return new ExceptionThru(pins, nets, insts, tr_, true, network); @@ -1785,16 +1785,16 @@ ExceptionThru::clone(const Network *network) bool ExceptionThru::hasObjects() const { - return (pins_ != NULL && !pins_->empty()) - || (nets_ != NULL && !nets_->empty()) - || (insts_ != NULL && !insts_->empty()); + return (pins_ != nullptr && !pins_->empty()) + || (nets_ != nullptr && !nets_->empty()) + || (insts_ != nullptr && !insts_->empty()); } void ExceptionThru::addPin(Pin *pin) { - if (pins_ == NULL) + if (pins_ == nullptr) pins_ = new PinSet; if (!pins_->hasKey(pin)) { pins_->insert(pin); @@ -1806,7 +1806,7 @@ ExceptionThru::addPin(Pin *pin) void ExceptionThru::addNet(Net *net) { - if (nets_ == NULL) + if (nets_ == nullptr) nets_ = new NetSet; if (!nets_->hasKey(net)) { nets_->insert(net); @@ -1818,7 +1818,7 @@ ExceptionThru::addNet(Net *net) void ExceptionThru::addInstance(Instance *inst) { - if (insts_ == NULL) + if (insts_ == nullptr) insts_ = new InstanceSet; if (!insts_->hasKey(inst)) { insts_->insert(inst); @@ -1830,7 +1830,7 @@ ExceptionThru::addInstance(Instance *inst) void ExceptionThru::addEdge(EdgePins *edge) { - if (edges_ == NULL) + if (edges_ == nullptr) edges_ = new EdgePinsSet; edges_->insert(edge); // Hash is unchanged because edges are derived from hierarchical pins. @@ -2216,7 +2216,7 @@ ExpandedExceptionVisitor::visitExpansions() Pin *pin = pin_iter.next(); PinSet pins; pins.insert(pin); - ExceptionFrom expanded_from(&pins, NULL, NULL, tr, false); + ExceptionFrom expanded_from(&pins, nullptr, nullptr, tr, false); expandThrus(&expanded_from); } ClockSet::Iterator clk_iter(from->clks()); @@ -2224,7 +2224,7 @@ ExpandedExceptionVisitor::visitExpansions() Clock *clk = clk_iter.next(); ClockSet clks; clks.insert(clk); - ExceptionFrom expanded_from(NULL, &clks, NULL, tr, false); + ExceptionFrom expanded_from(nullptr, &clks, nullptr, tr, false); expandThrus(&expanded_from); } InstanceSet::Iterator inst_iter(from->instances()); @@ -2232,7 +2232,7 @@ ExpandedExceptionVisitor::visitExpansions() Instance *inst = inst_iter.next(); InstanceSet insts; insts.insert(inst); - ExceptionFrom expanded_from(NULL, NULL, &insts, tr, false); + ExceptionFrom expanded_from(nullptr, nullptr, &insts, tr, false); expandThrus(&expanded_from); } } @@ -2251,7 +2251,7 @@ ExpandedExceptionVisitor::expandThrus(ExceptionFrom *expanded_from) expandThru(expanded_from, thru_iter, &expanded_thrus); } else - expandTo(expanded_from, NULL); + expandTo(expanded_from, nullptr); } void @@ -2267,7 +2267,7 @@ ExpandedExceptionVisitor::expandThru(ExceptionFrom *expanded_from, Pin *pin = pin_iter.next(); PinSet pins; pins.insert(pin); - ExceptionThru expanded_thru(&pins, NULL, NULL, tr, false, network_); + ExceptionThru expanded_thru(&pins, nullptr, nullptr, tr, false, network_); expanded_thrus->push_back(&expanded_thru); expandThru(expanded_from, thru_iter, expanded_thrus); expanded_thrus->pop_back(); @@ -2277,7 +2277,7 @@ ExpandedExceptionVisitor::expandThru(ExceptionFrom *expanded_from, Net *net = net_iter.next(); NetSet nets; nets.insert(net); - ExceptionThru expanded_thru(NULL, &nets, NULL, tr, false, network_); + ExceptionThru expanded_thru(nullptr, &nets, nullptr, tr, false, network_); expanded_thrus->push_back(&expanded_thru); expandThru(expanded_from, thru_iter, expanded_thrus); expanded_thrus->pop_back(); @@ -2287,7 +2287,7 @@ ExpandedExceptionVisitor::expandThru(ExceptionFrom *expanded_from, Instance *inst = inst_iter.next(); InstanceSet insts; insts.insert(inst); - ExceptionThru expanded_thru(NULL, NULL, &insts, tr, false, network_); + ExceptionThru expanded_thru(nullptr, nullptr, &insts, tr, false, network_); expanded_thrus->push_back(&expanded_thru); expandThru(expanded_from, thru_iter, expanded_thrus); expanded_thrus->pop_back(); @@ -2311,7 +2311,7 @@ ExpandedExceptionVisitor::expandTo(ExceptionFrom *expanded_from, Pin *pin = pin_iter.next(); PinSet pins; pins.insert(pin); - ExceptionTo expanded_to(&pins, NULL, NULL, tr, end_tr, false); + ExceptionTo expanded_to(&pins, nullptr, nullptr, tr, end_tr, false); visit(expanded_from, expanded_thrus, &expanded_to); } ClockSet::Iterator clk_iter(to->clks()); @@ -2319,7 +2319,7 @@ ExpandedExceptionVisitor::expandTo(ExceptionFrom *expanded_from, Clock *clk = clk_iter.next(); ClockSet clks; clks.insert(clk); - ExceptionTo expanded_to(NULL, &clks, NULL, tr, end_tr, false); + ExceptionTo expanded_to(nullptr, &clks, nullptr, tr, end_tr, false); visit(expanded_from, expanded_thrus, &expanded_to); } InstanceSet::Iterator inst_iter(to->instances()); @@ -2327,12 +2327,12 @@ ExpandedExceptionVisitor::expandTo(ExceptionFrom *expanded_from, Instance *inst = inst_iter.next(); InstanceSet insts; insts.insert(inst); - ExceptionTo expanded_to(NULL, NULL, &insts, tr, end_tr, false); + ExceptionTo expanded_to(nullptr, nullptr, &insts, tr, end_tr, false); visit(expanded_from, expanded_thrus, &expanded_to); } } else - visit(expanded_from, expanded_thrus, NULL); + visit(expanded_from, expanded_thrus, nullptr); } //////////////////////////////////////////////////////////////// @@ -2342,7 +2342,7 @@ ExceptionState::ExceptionState(ExceptionPath *exception, int index) : exception_(exception), next_thru_(next_thru), - next_state_(NULL), + next_state_(nullptr), index_(index) { } @@ -2369,8 +2369,8 @@ ExceptionState::matchesNextThru(const Pin *from_pin, bool ExceptionState::isComplete() const { - return next_thru_ == NULL - && exception_->to() == NULL; + return next_thru_ == nullptr + && exception_->to() == nullptr; } Hash diff --git a/sdc/ExceptionPath.hh b/sdc/ExceptionPath.hh index 6f11965a..eb7e7915 100644 --- a/sdc/ExceptionPath.hh +++ b/sdc/ExceptionPath.hh @@ -113,7 +113,7 @@ 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 NULL; } + virtual const char *name() const { return nullptr; } virtual bool isDefault() const { return false; } virtual bool ignoreClkLatency() { return false; } @@ -156,7 +156,7 @@ public: ExceptionTo *to, bool own_pts); virtual bool isFalse() const { return true; } - virtual ExceptionPathType type() const { return exception_type_false; } + virtual ExceptionPathType type() const { return ExceptionPathType::false_path; } virtual const char *typeString() const; virtual bool mergeable(ExceptionPath *exception) const; virtual bool overrides(ExceptionPath *exception) const; @@ -175,7 +175,7 @@ public: LoopPath(ExceptionThruSeq *thrus, bool own_pts); virtual bool isLoop() const { return true; } - virtual ExceptionPathType type() const { return exception_type_loop; } + virtual ExceptionPathType type() const { return ExceptionPathType::loop; } virtual const char *typeString() const; virtual bool mergeable(ExceptionPath *exception) const; @@ -200,7 +200,7 @@ public: ExceptionTo *to, bool own_pts); virtual bool isPathDelay() const { return true; } - virtual ExceptionPathType type() const { return exception_type_path_delay; } + virtual ExceptionPathType type() const { return ExceptionPathType::path_delay; } virtual const char *asString(const Network *network) const; virtual const char *typeString() const; virtual bool mergeable(ExceptionPath *exception) const; @@ -235,7 +235,7 @@ public: ExceptionTo *to, bool own_pts); virtual bool isMultiCycle() const { return true; } - virtual ExceptionPathType type() const { return exception_type_multi_cycle; } + virtual ExceptionPathType type() const { return ExceptionPathType::multi_cycle; } virtual bool matches(const MinMax *min_max, bool exactly) const; virtual const char *asString(const Network *network) const; @@ -272,7 +272,7 @@ public: ExceptionTo *to, bool own_pts); virtual bool isFilter() const { return true; } - virtual ExceptionPathType type() const { return exception_type_filter; } + virtual ExceptionPathType type() const { return ExceptionPathType::filter; } virtual const char *typeString() const; virtual bool mergeable(ExceptionPath *exception) const; virtual bool overrides(ExceptionPath *exception) const; @@ -303,7 +303,7 @@ public: ExceptionTo *to, bool own_pts); virtual bool isGroupPath() const { return true; } - virtual ExceptionPathType type() const { return exception_type_group_path; } + virtual ExceptionPathType type() const { return ExceptionPathType::group_path; } virtual const char *typeString() const; virtual bool mergeable(ExceptionPath *exception) const; virtual bool overrides(ExceptionPath *exception) const; @@ -388,8 +388,8 @@ public: bool hasClocks() const; InstanceSet *instances() { return insts_; } bool hasInstances() const; - virtual NetSet *nets() { return NULL; } - virtual EdgePinsSet *edges() { return NULL; } + virtual NetSet *nets() { return nullptr; } + virtual EdgePinsSet *edges() { return nullptr; } bool hasObjects() const; void deleteObjects(ExceptionFromTo *pt); virtual void allPins(const Network *network, @@ -509,7 +509,7 @@ public: EdgePinsSet *edges() { return edges_; } NetSet *nets() { return nets_; } InstanceSet *instances() { return insts_; } - virtual ClockSet *clks() { return NULL; } + virtual ClockSet *clks() { return nullptr; } bool hasObjects() const; void deleteObjects(ExceptionThru *pt); virtual void allPins(const Network *network, diff --git a/sdc/InputDrive.cc b/sdc/InputDrive.cc index 407d83db..1565988c 100644 --- a/sdc/InputDrive.cc +++ b/sdc/InputDrive.cc @@ -19,8 +19,7 @@ namespace sta { -InputDrive::InputDrive(Port *port) : - port_(port) +InputDrive::InputDrive() { TransRiseFallIterator tr_iter; while (tr_iter.hasNext()) { @@ -28,7 +27,7 @@ InputDrive::InputDrive(Port *port) : MinMaxIterator mm_iter; while (mm_iter.hasNext()) { MinMax *mm = mm_iter.next(); - drive_cells_[tr->index()][mm->index()] = NULL; + drive_cells_[tr->index()][mm->index()] = nullptr; } } } @@ -138,7 +137,7 @@ InputDrive::driveCell(const TransRiseFall *tr, to_port = drive->toPort(); } else - cell = NULL; + cell = nullptr; } InputDriveCell * @@ -152,7 +151,7 @@ bool InputDrive::hasDriveCell(const TransRiseFall *tr, const MinMax *min_max) { - return drive_cells_[tr->index()][min_max->index()] != NULL; + return drive_cells_[tr->index()][min_max->index()] != nullptr; } bool diff --git a/sdc/InputDrive.hh b/sdc/InputDrive.hh index 1df7e714..8861fb3b 100644 --- a/sdc/InputDrive.hh +++ b/sdc/InputDrive.hh @@ -34,7 +34,7 @@ class InputDriveCell; class InputDrive { public: - explicit InputDrive(Port *port); + explicit InputDrive(); ~InputDrive(); void setSlew(const TransRiseFallBoth *tr, const MinMaxAll *min_max, @@ -77,7 +77,6 @@ public: private: DISALLOW_COPY_AND_ASSIGN(InputDrive); - Port *port_; RiseFallMinMax slews_; RiseFallMinMax drive_resistances_; // Separate rise/fall/min/max drive cells. diff --git a/sdc/PortDelay.cc b/sdc/PortDelay.cc index 29e72654..14cc3cfa 100644 --- a/sdc/PortDelay.cc +++ b/sdc/PortDelay.cc @@ -39,7 +39,7 @@ PortDelay::clock() const if (clk_edge_) return clk_edge_->clock(); else - return NULL; + return nullptr; } bool @@ -82,7 +82,7 @@ InputDelay::InputDelay(Pin *pin, int index, Network *network) : PortDelay(pin, clk_edge, ref_pin), - next_(NULL), + next_(nullptr), index_(index) { findVertexLoadPins(pin, network, &vertex_pins_); @@ -99,7 +99,7 @@ OutputDelay::OutputDelay(Pin *pin, Pin *ref_pin, Network *network) : PortDelay(pin, clk_edge, ref_pin), - next_(NULL) + next_(nullptr) { if (network) findVertexDriverPins(pin, network, &vertex_pins_); @@ -113,15 +113,16 @@ OutputDelay::setNext(OutputDelay *next) //////////////////////////////////////////////////////////////// -PinInputDelayIterator::PinInputDelayIterator(InputDelay *input_delay) : - next_(input_delay) +PinInputDelayIterator::PinInputDelayIterator(const Pin *pin, + const Sdc *sdc) { + next_ = sdc->input_delay_map_.findKey(pin); } bool PinInputDelayIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } InputDelay * @@ -133,17 +134,25 @@ PinInputDelayIterator::next() return next; } +VertexPinInputDelayIterator::VertexPinInputDelayIterator(const Pin *vertex_pin, + const Sdc *sdc) : + PinInputDelayIterator() +{ + next_ = sdc->input_delay_vertex_map_.findKey(vertex_pin); +} + //////////////////////////////////////////////////////////////// -PinOutputDelayIterator::PinOutputDelayIterator(OutputDelay *output_delay) : - next_(output_delay) +PinOutputDelayIterator::PinOutputDelayIterator(const Pin *pin, + const Sdc *sdc) { + next_ = sdc->output_delay_map_.findKey(pin); } bool PinOutputDelayIterator::hasNext() { - return next_ != NULL; + return next_ != nullptr; } OutputDelay * @@ -155,6 +164,13 @@ PinOutputDelayIterator::next() return next; } +VertexPinOutputDelayIterator::VertexPinOutputDelayIterator(const Pin *vertex_pin, + const Sdc *sdc) : + PinOutputDelayIterator() +{ + next_ = sdc->output_delay_vertex_map_.findKey(vertex_pin); +} + //////////////////////////////////////////////////////////////// PortDelayLess::PortDelayLess(const Network *network) : diff --git a/sdc/PortDelay.hh b/sdc/PortDelay.hh index 9d8009dd..bbd0fd5c 100644 --- a/sdc/PortDelay.hh +++ b/sdc/PortDelay.hh @@ -129,31 +129,53 @@ public: class PinInputDelayIterator : public Iterator { public: + PinInputDelayIterator(const Pin *pin, + const Sdc *sdc); virtual bool hasNext(); virtual InputDelay *next(); -private: - DISALLOW_COPY_AND_ASSIGN(PinInputDelayIterator); - PinInputDelayIterator(InputDelay *input_delay); +protected: + PinInputDelayIterator() {} InputDelay *next_; - friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(PinInputDelayIterator); +}; + +class VertexPinInputDelayIterator : public PinInputDelayIterator +{ +public: + VertexPinInputDelayIterator(const Pin *vertex_pin, + const Sdc *sdc); + +private: + DISALLOW_COPY_AND_ASSIGN(VertexPinInputDelayIterator); }; class PinOutputDelayIterator : public Iterator { public: + PinOutputDelayIterator(const Pin *pin, + const Sdc *sdc); virtual bool hasNext(); virtual OutputDelay *next(); -private: - DISALLOW_COPY_AND_ASSIGN(PinOutputDelayIterator); - PinOutputDelayIterator(OutputDelay *output_delay); +protected: + PinOutputDelayIterator() {} OutputDelay *next_; - friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(PinOutputDelayIterator); +}; + +class VertexPinOutputDelayIterator : public PinOutputDelayIterator +{ +public: + VertexPinOutputDelayIterator(const Pin *vertex_pin, + const Sdc *sdc); + +private: + DISALLOW_COPY_AND_ASSIGN(VertexPinOutputDelayIterator); }; // Prediate used to sort port delays. diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 08989b54..573117f7 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -19,6 +19,7 @@ #include "DisallowCopyAssign.hh" #include "Stats.hh" #include "Debug.hh" +#include "Mutex.hh" #include "Report.hh" #include "PatternMatch.hh" #include "MinMax.hh" @@ -51,23 +52,17 @@ namespace sta { bool -ClockPairLess::operator()(const ClockPair *pair1, - const ClockPair *pair2) const +ClockPairLess::operator()(const ClockPair &pair1, + const ClockPair &pair2) const { - int first1 = pair1->first->index(); - int second1 = pair1->second->index(); - if (first1 > second1) { - int tmp = first1; - first1 = second1; - second1 = tmp; - } - int first2 = pair2->first->index(); - int second2 = pair2->second->index(); - if (first2 > second2) { - int tmp = first2; - first2 = second2; - second2 = tmp; - } + int first1 = pair1.first->index(); + int second1 = pair1.second->index(); + if (first1 > second1) + std::swap(first1, second1); + int first2 = pair2.first->index(); + int second2 = pair2.second->index(); + if (first2 > second2) + std::swap(first2, second2); return (first1 < first2) || (first1 == first2 && second1 < second2); @@ -75,7 +70,7 @@ ClockPairLess::operator()(const ClockPair *pair1, //////////////////////////////////////////////////////////////// -typedef Vector ClockPairSeq; +typedef Vector ClockPairSeq; typedef Set PvtSet; static ExceptionThruSeq * @@ -91,38 +86,38 @@ annotateGraphDisabledWireEdge(Pin *from_pin, Sdc::Sdc(StaState *sta) : StaState(sta), - derating_factors_(NULL), - net_derating_factors_(NULL), - inst_derating_factors_(NULL), - cell_derating_factors_(NULL), + derating_factors_(nullptr), + net_derating_factors_(nullptr), + inst_derating_factors_(nullptr), + cell_derating_factors_(nullptr), clk_index_(0), - clk_insertions_(NULL), - clk_group_exclusions_(NULL), - clk_group_same_(NULL), + clk_insertions_(nullptr), + clk_group_exclusions_(nullptr), + clk_group_same_(nullptr), clk_sense_map_(network_), - clk_gating_check_(NULL), + clk_gating_check_(nullptr), input_delay_index_(0), - port_cap_map_(NULL), - net_wire_cap_map_(NULL), - drvr_pin_wire_cap_map_(NULL), - first_from_pin_exceptions_(NULL), - first_from_clk_exceptions_(NULL), - first_from_inst_exceptions_(NULL), - first_thru_pin_exceptions_(NULL), - first_thru_inst_exceptions_(NULL), - first_thru_net_exceptions_(NULL), - first_to_pin_exceptions_(NULL), - first_to_clk_exceptions_(NULL), - first_to_inst_exceptions_(NULL), - first_thru_edge_exceptions_(NULL), - path_delay_internal_startpoints_(NULL), - path_delay_internal_endpoints_(NULL) + port_cap_map_(nullptr), + net_wire_cap_map_(nullptr), + drvr_pin_wire_cap_map_(nullptr), + first_from_pin_exceptions_(nullptr), + first_from_clk_exceptions_(nullptr), + first_from_inst_exceptions_(nullptr), + first_thru_pin_exceptions_(nullptr), + first_thru_inst_exceptions_(nullptr), + first_thru_net_exceptions_(nullptr), + first_to_pin_exceptions_(nullptr), + first_to_clk_exceptions_(nullptr), + first_to_inst_exceptions_(nullptr), + first_thru_edge_exceptions_(nullptr), + path_delay_internal_startpoints_(nullptr), + path_delay_internal_endpoints_(nullptr) { initVariables(); sdc_ = this; - setWireload(NULL, MinMaxAll::all()); - setWireloadSelection(NULL, MinMaxAll::all()); - setOperatingConditions(NULL, MinMaxAll::all()); + setWireload(nullptr, MinMaxAll::all()); + setWireloadSelection(nullptr, MinMaxAll::all()); + setOperatingConditions(nullptr, MinMaxAll::all()); makeDefaultArrivalClock(); initInstancePvtMaps(); } @@ -134,7 +129,7 @@ Sdc::makeDefaultArrivalClock() waveform->push_back(0.0); waveform->push_back(0.0); default_arrival_clk_ = new Clock("input port clock", clk_index_++); - default_arrival_clk_->initClk(0, false, 0.0, waveform, false, NULL, + default_arrival_clk_->initClk(0, false, 0.0, waveform, false, nullptr, network_); } @@ -211,10 +206,10 @@ Sdc::clear() min_pulse_width_.clear(); - setWireload(NULL, MinMaxAll::all()); - setWireloadSelection(NULL, MinMaxAll::all()); + setWireload(nullptr, MinMaxAll::all()); + setWireloadSelection(nullptr, MinMaxAll::all()); // Operating conditions are owned by Liberty libraries. - setOperatingConditions(NULL, MinMaxAll::all()); + setOperatingConditions(nullptr, MinMaxAll::all()); clk_index_ = 0; makeDefaultArrivalClock(); @@ -224,10 +219,10 @@ Sdc::clear() void Sdc::initVariables() { - analysis_type_ = analysis_type_on_chip_variation; + analysis_type_ = AnalysisType::ocv; use_default_arrival_clock_ = false; crpr_enabled_ = true; - crpr_mode_ = crpr_mode_same_pin; + crpr_mode_ = CrprMode::same_pin; propagate_gated_clock_enable_ = true; preset_clr_arcs_enabled_ = false; cond_default_arcs_enabled_ = true; @@ -238,7 +233,7 @@ Sdc::initVariables() clk_thru_tristate_enabled_ = false; dynamic_loop_breaking_ = false; propagate_all_clks_ = false; - wireload_mode_ = wire_load_mode_unknown; + wireload_mode_ = WireloadMode::unknown; max_area_ = 0.0; path_delays_without_to_ = false; clk_hpin_disables_valid_ = false; @@ -255,7 +250,7 @@ Sdc::deleteConstraints() if (clk_insertions_) { clk_insertions_->deleteContents(); delete clk_insertions_; - clk_insertions_ = NULL; + clk_insertions_ = nullptr; } clk_groups_name_map_.deleteContents(); @@ -264,7 +259,7 @@ Sdc::deleteConstraints() pin_clk_uncertainty_map_.deleteContents(); inter_clk_uncertainties_.deleteContents(); delete clk_gating_check_; - clk_gating_check_ = NULL; + clk_gating_check_ = nullptr; clk_gating_check_map_.deleteContents(); inst_clk_gating_check_map_.deleteContents(); pin_clk_gating_check_map_.deleteContents(); @@ -324,7 +319,7 @@ Sdc::deleteConstraints() deleteInstancePvts(); deleteDeratingFactors(); removeLoadCaps(); - deleteClkSenses(); + clk_sense_map_.clear(); } void @@ -351,10 +346,10 @@ void Sdc::removeNetLoadCaps() { delete [] net_wire_cap_map_; - net_wire_cap_map_ = NULL; + net_wire_cap_map_ = nullptr; delete [] drvr_pin_wire_cap_map_; - drvr_pin_wire_cap_map_ = NULL; + drvr_pin_wire_cap_map_ = nullptr; } void @@ -363,7 +358,7 @@ Sdc::removeLoadCaps() if (port_cap_map_) { port_cap_map_->deleteContents(); delete port_cap_map_; - port_cap_map_ = NULL; + port_cap_map_ = nullptr; } removeNetLoadCaps(); } @@ -424,7 +419,7 @@ Sdc::initInstancePvtMaps() MinMaxIterator mm_iter; while (mm_iter.hasNext()) { MinMax *mm = mm_iter.next(); - instance_pvt_maps_[mm->index()] = NULL; + instance_pvt_maps_[mm->index()] = nullptr; } } @@ -443,7 +438,7 @@ bool Sdc::isConstrained(const Pin *pin) const { Pin *pin1 = const_cast(pin); - Port *port = network_->isTopLevelPort(pin) ? network_->port(pin) : NULL; + Port *port = network_->isTopLevelPort(pin) ? network_->port(pin) : nullptr; return clock_pin_map_.hasKey(pin) || propagated_clk_pins_.hasKey(pin1) || hasClockLatency(pin) @@ -552,7 +547,7 @@ Sdc::pvt(Instance *inst, if (pvt_map) return pvt_map->findKey(inst); else - return NULL; + return nullptr; } void @@ -564,7 +559,7 @@ Sdc::setPvt(Instance *inst, const while (mm_iter.hasNext()) { int mm_index = mm_iter.next()->index(); InstancePvtMap *pvt_map = instance_pvt_maps_[mm_index]; - if (pvt_map == NULL) { + if (pvt_map == nullptr) { pvt_map = new InstancePvtMap; instance_pvt_maps_[mm_index] = pvt_map; } @@ -581,7 +576,7 @@ Sdc::setTimingDerate(TimingDerateType type, const EarlyLate *early_late, float derate) { - if (derating_factors_ == NULL) + if (derating_factors_ == nullptr) derating_factors_ = new DeratingFactorsGlobal; derating_factors_->setFactor(type, clk_data, tr, early_late, derate); } @@ -593,10 +588,10 @@ Sdc::setTimingDerate(const Net *net, const EarlyLate *early_late, float derate) { - if (net_derating_factors_ == NULL) + if (net_derating_factors_ == nullptr) net_derating_factors_ = new NetDeratingFactorsMap; DeratingFactorsNet *factors = net_derating_factors_->findKey(net); - if (factors == NULL) { + if (factors == nullptr) { factors = new DeratingFactorsNet; (*net_derating_factors_)[net] = factors; } @@ -611,10 +606,10 @@ Sdc::setTimingDerate(const Instance *inst, const EarlyLate *early_late, float derate) { - if (inst_derating_factors_ == NULL) + if (inst_derating_factors_ == nullptr) inst_derating_factors_ = new InstDeratingFactorsMap; DeratingFactorsCell *factors = inst_derating_factors_->findKey(inst); - if (factors == NULL) { + if (factors == nullptr) { factors = new DeratingFactorsCell; (*inst_derating_factors_)[inst] = factors; } @@ -629,10 +624,10 @@ Sdc::setTimingDerate(const LibertyCell *cell, const EarlyLate *early_late, float derate) { - if (cell_derating_factors_ == NULL) + if (cell_derating_factors_ == nullptr) cell_derating_factors_ = new CellDeratingFactorsMap; DeratingFactorsCell *factors = cell_derating_factors_->findKey(cell); - if (factors == NULL) { + if (factors == nullptr) { factors = new DeratingFactorsCell; (*cell_derating_factors_)[cell] = factors; } @@ -702,7 +697,7 @@ Sdc::timingDerateNet(const Pin *pin, if (derating_factors_) { float factor; bool exists; - derating_factors_->factor(timing_derate_net_delay, clk_data, tr, + derating_factors_->factor(TimingDerateType::net_delay, clk_data, tr, early_late, factor, exists); if (exists) return factor; @@ -726,7 +721,7 @@ Sdc::deleteDeratingFactors() delete factors; } delete net_derating_factors_; - net_derating_factors_ = NULL; + net_derating_factors_ = nullptr; } if (inst_derating_factors_) { @@ -736,7 +731,7 @@ Sdc::deleteDeratingFactors() delete factors; } delete inst_derating_factors_; - inst_derating_factors_ = NULL; + inst_derating_factors_ = nullptr; } if (cell_derating_factors_) { @@ -746,11 +741,11 @@ Sdc::deleteDeratingFactors() delete factors; } delete cell_derating_factors_; - cell_derating_factors_ = NULL; + cell_derating_factors_ = nullptr; } delete derating_factors_; - derating_factors_ = NULL; + derating_factors_ = nullptr; } //////////////////////////////////////////////////////////////// @@ -791,8 +786,8 @@ InputDrive * Sdc::ensureInputDrive(Port *port) { InputDrive *drive = input_drive_map_.findKey(port); - if (drive == NULL) { - drive = new InputDrive(port); + if (drive == nullptr) { + drive = new InputDrive; input_drive_map_[port] = drive; } return drive; @@ -1105,9 +1100,7 @@ Sdc::makeGeneratedClock(const char *name, void Sdc::invalidateGeneratedClks() const { - ClockSeq::ConstIterator clk_iter(&clocks_); - while (clk_iter.hasNext()) { - Clock *clk = clk_iter.next(); + for (auto clk : clocks_) { if (clk->isGenerated()) clk->waveformInvalid(); } @@ -1194,7 +1187,7 @@ Sdc::makeClkPinMappings(Clock *clk) while (pin_iter1.hasNext()) { Pin *pin = pin_iter1.next(); ClockSet *pin_clks = clock_pin_map_.findKey(pin); - if (pin_clks == NULL) { + if (pin_clks == nullptr) { pin_clks = new ClockSet; clock_pin_map_.insert(pin, pin_clks); } @@ -1205,7 +1198,7 @@ Sdc::makeClkPinMappings(Clock *clk) while (pin_iter2.hasNext()) { Pin *pin = pin_iter2.next(); ClockSet *pin_clks = clock_vertex_pin_map_.findKey(pin); - if (pin_clks == NULL) { + if (pin_clks == nullptr) { pin_clks = new ClockSet; clock_vertex_pin_map_.insert(pin, pin_clks); } @@ -1238,12 +1231,10 @@ Sdc::removeClock(Clock *clk) void Sdc::deleteMasterClkRefs(Clock *clk) { - ClockSeq::ConstIterator clk_iter(&clocks_); - while (clk_iter.hasNext()) { - Clock *gclk = clk_iter.next(); + for (auto gclk : clocks_) { if (gclk->isGenerated() && gclk->masterClk() == clk) { - gclk->setMasterClk(NULL); + gclk->setMasterClk(nullptr); } } } @@ -1320,9 +1311,7 @@ Sdc::findClocksMatching(PatternMatch *pattern, clks->push_back(clk); } else { - ClockSeq::ConstIterator iter(&clocks_); - while (iter.hasNext()) { - Clock *clk = iter.next(); + for (auto clk : clocks_) { if (pattern->match(clk->name())) clks->push_back(clk); } @@ -1330,19 +1319,16 @@ Sdc::findClocksMatching(PatternMatch *pattern, } ClockIterator * -Sdc::clockIterator() const +Sdc::clockIterator() { - return new ClockSeq::ConstIterator(&clocks_); + return new ClockIterator(clocks_); } void Sdc::sortedClocks(ClockSeq &clks) { - ClockIterator clk_iter(clocks_); - while (clk_iter.hasNext()) { - Clock *clk = clk_iter.next(); + for (auto clk : clocks_) clks.push_back(clk); - } sort(clks, ClkNameLess()); } @@ -1493,9 +1479,7 @@ Sdc::ensureClkHpinDisables() { if (!clk_hpin_disables_valid_) { clk_hpin_disables_.deleteContentsClear(); - ClockIterator clk_iter(clocks_); - while (clk_iter.hasNext()) { - Clock *clk = clk_iter.next(); + for (auto clk : clocks_) { PinSet *srcs = clk->pins(); PinSet::Iterator src_iter(srcs); while (src_iter.hasNext()) { @@ -1543,11 +1527,8 @@ void Sdc::clkHpinDisablesInvalid() { clk_hpin_disables_valid_ = false; - ClockSeq::ConstIterator clk_iter(clocks_); - while (clk_iter.hasNext()) { - Clock *clk = clk_iter.next(); + for (auto clk : clocks_) clk->makeVertexPins(network_); - } } // Check that driver/load edge goes thru clock hpin. @@ -1572,7 +1553,7 @@ void Sdc::setPropagatedClock(Clock *clk) { clk->setIsPropagated(true); - removeClockLatency(clk, NULL); + removeClockLatency(clk, nullptr); } void @@ -1585,7 +1566,7 @@ void Sdc::setPropagatedClock(Pin *pin) { propagated_clk_pins_.insert(pin); - removeClockLatency(NULL, pin); + removeClockLatency(nullptr, pin); } void @@ -1600,12 +1581,6 @@ Sdc::isPropagatedClock(const Pin *pin) return propagated_clk_pins_.hasKey(const_cast(pin)); } -bool -Sdc::isPropagatedClock(const Clock *clk) const -{ - return clk->isPropagated(); -} - void Sdc::setClockSlew(Clock *clk, const TransRiseFallBoth *tr, @@ -1630,7 +1605,7 @@ Sdc::setClockLatency(Clock *clk, { ClockLatency probe(clk, pin); ClockLatency *latency = clk_latencies_.findKey(&probe); - if (latency == NULL) { + if (latency == nullptr) { latency = new ClockLatency(clk, pin); clk_latencies_.insert(latency); } @@ -1639,7 +1614,7 @@ Sdc::setClockLatency(Clock *clk, annotateHierClkLatency(pin, latency); // set_clock_latency removes set_propagated_clock on the same object. - if (clk && pin == NULL) + if (clk && pin == nullptr) removePropagatedClock(clk); if (pin) removePropagatedClock(pin); @@ -1679,7 +1654,7 @@ Sdc::deleteClockLatenciesReferencing(Clock *clk) bool Sdc::hasClockLatency(const Pin *pin) const { - ClockLatency probe(NULL, pin); + ClockLatency probe(nullptr, pin); return clk_latencies_.hasKey(&probe); } @@ -1701,7 +1676,7 @@ Sdc::clockLatency(const Clock *clk, latencies->delay(tr, min_max, latency, exists); } if (!exists) { - ClockLatency probe(NULL, pin); + ClockLatency probe(nullptr, pin); ClockLatency *latencies = clk_latencies_.findKey(&probe); if (latencies) latencies->delay(tr, min_max, latency, exists); @@ -1718,7 +1693,7 @@ Sdc::clockLatency(const Clock *clk, { latency = 0.0; exists = false; - ClockLatency probe(clk, NULL); + ClockLatency probe(clk, nullptr); ClockLatency *latencies = clk_latencies_.findKey(&probe); if (latencies) latencies->delay(tr, min_max, latency, exists); @@ -1742,7 +1717,7 @@ Sdc::setClockUncertainty(Pin *pin, float uncertainty) { ClockUncertainties *uncertainties = pin_clk_uncertainty_map_.findKey(pin); - if (uncertainties == NULL) { + if (uncertainties == nullptr) { uncertainties = new ClockUncertainties; pin_clk_uncertainty_map_[pin] = uncertainties; } @@ -1816,7 +1791,7 @@ Sdc::setClockUncertainty(Clock *from_clk, InterClockUncertainty probe(from_clk, to_clk); InterClockUncertainty *uncertainties = inter_clk_uncertainties_.findKey(&probe); - if (uncertainties == NULL) { + if (uncertainties == nullptr) { uncertainties = new InterClockUncertainty(from_clk, to_clk); inter_clk_uncertainties_.insert(uncertainties); } @@ -1871,11 +1846,11 @@ Sdc::setClockInsertion(const Clock *clk, const EarlyLateAll *early_late, float delay) { - if (clk_insertions_ == NULL) + if (clk_insertions_ == nullptr) clk_insertions_ = new ClockInsertions; ClockInsertion probe(clk, pin); ClockInsertion *insertion = clk_insertions_->findKey(&probe); - if (insertion == NULL) { + if (insertion == nullptr) { insertion = new ClockInsertion(clk, pin); clk_insertions_->insert(insertion); } @@ -1890,11 +1865,11 @@ Sdc::setClockInsertion(const Clock *clk, const EarlyLate *early_late, float delay) { - if (clk_insertions_ == NULL) + if (clk_insertions_ == nullptr) clk_insertions_ = new ClockInsertions; ClockInsertion probe(clk, pin); ClockInsertion *insertion = clk_insertions_->findKey(&probe); - if (insertion == NULL) { + if (insertion == nullptr) { insertion = new ClockInsertion(clk, pin); clk_insertions_->insert(insertion); } @@ -1908,7 +1883,7 @@ Sdc::removeClockInsertion(const Clock *clk, if (clk_insertions_) { ClockInsertion probe(clk, pin); ClockInsertion *insertion = clk_insertions_->findKey(&probe); - if (insertion != NULL) + if (insertion != nullptr) deleteClockInsertion(insertion); } } @@ -1939,7 +1914,7 @@ Sdc::clockInsertion(const Clock *clk, { float insertion; bool exists; - clockInsertion(clk, NULL, tr, min_max, early_late, insertion, exists); + clockInsertion(clk, nullptr, tr, min_max, early_late, insertion, exists); return insertion; } @@ -1947,7 +1922,7 @@ bool Sdc::hasClockInsertion(const Pin *pin) const { if (clk_insertions_) { - ClockInsertion probe(NULL, pin); + ClockInsertion probe(nullptr, pin); return clk_insertions_->hasKey(&probe); } else @@ -1964,18 +1939,18 @@ Sdc::clockInsertion(const Clock *clk, float &insertion, bool &exists) const { - ClockInsertion *insert = NULL; + ClockInsertion *insert = nullptr; if (clk_insertions_) { if (clk && pin) { ClockInsertion probe(clk, pin); insert = clk_insertions_->findKey(&probe); } - if (insert == NULL && pin) { - ClockInsertion probe(NULL, pin); + if (insert == nullptr && pin) { + ClockInsertion probe(nullptr, pin); insert = clk_insertions_->findKey(&probe); } - if (insert == NULL && clk) { - ClockInsertion probe(clk, NULL); + if (insert == nullptr && clk) { + ClockInsertion probe(clk, nullptr); insert = clk_insertions_->findKey(&probe); } } @@ -2017,11 +1992,11 @@ ClockInsertionPinClkLess::operator()(const ClockInsertion *insert1, || (clk1 == clk2 && pin1 && pin2 && pin1 < pin2))) - || (clk1 == NULL && clk2) - || (clk1 == NULL && clk2 == NULL + || (clk1 == nullptr && clk2) + || (clk1 == nullptr && clk2 == nullptr && ((pin1 && pin2 && pin1 < pin2) - || (pin1 == NULL && pin2))); + || (pin1 == nullptr && pin2))); } //////////////////////////////////////////////////////////////// @@ -2034,8 +2009,8 @@ Sdc::makeClockGroups(const char *name, bool allow_paths, const char *comment) { - char *gen_name = NULL; - if (name == NULL + char *gen_name = nullptr; + if (name == nullptr || name[0] == '\0') name = gen_name = makeClockGroupsName(); else { @@ -2055,7 +2030,7 @@ Sdc::makeClockGroups(const char *name, char * Sdc::makeClockGroupsName() { - char *name = NULL; + char *name = nullptr; int i = 0; do { i++; @@ -2081,14 +2056,11 @@ Sdc::clockGroupIterator() void Sdc::ensureClkGroupExclusions() { - if (clk_group_exclusions_ == NULL) { + if (clk_group_exclusions_ == nullptr) { clk_group_exclusions_ = new ClockPairSet; clk_group_same_ = new ClockPairSet; - ClockGroupsNameMap::Iterator groups_iter(clk_groups_name_map_); - while (groups_iter.hasNext()) { - ClockGroups *clk_groups = groups_iter.next(); - makeClkGroupExclusions(clk_groups); - } + for (auto name_clk_groups : clk_groups_name_map_) + makeClkGroupExclusions(name_clk_groups.second); } } @@ -2113,19 +2085,12 @@ Sdc::makeClkGroupExclusions1(ClockGroupSet *groups) ClockGroupSet::Iterator group_iter1(groups); ClockGroup *group1 = group_iter1.next(); ClockSet *clks1 = group1->clks(); - ClockSet::Iterator clk_iter1(clks1); - while (clk_iter1.hasNext()) { - Clock *clk1 = clk_iter1.next(); - ClockIterator *clk_iter2 = clockIterator(); - while (clk_iter2->hasNext()) { - Clock *clk2 = clk_iter2->next(); + for (auto clk1 : *clks1) { + for (Clock *clk2 : clocks_) { if (clk2 != clk1 - && !group1->isMember(clk2)) { - ClockPair *clk_pair = new ClockPair(clk1, clk2); - clk_group_exclusions_->insert(clk_pair); - } + && !group1->isMember(clk2)) + clk_group_exclusions_->insert(ClockPair(clk1, clk2)); } - delete clk_iter2; } makeClkGroupSame(group1); } @@ -2133,25 +2098,16 @@ Sdc::makeClkGroupExclusions1(ClockGroupSet *groups) void Sdc::makeClkGroupExclusions(ClockGroupSet *groups) { - ClockGroupSet::Iterator group_iter1(groups); - while (group_iter1.hasNext()) { - ClockGroup *group1 = group_iter1.next(); + for (auto group1 : *groups) { ClockSet *clks1 = group1->clks(); - ClockGroupSet::Iterator group_iter2(groups); - while (group_iter2.hasNext()) { - ClockGroup *group2 = group_iter2.next(); + for (auto group2 : *groups) { if (group1 != group2) { ClockSet *clks2 = group2->clks(); - ClockSet::Iterator clk_iter1(clks1); - while (clk_iter1.hasNext()) { - Clock *clk1 = clk_iter1.next(); - ClockSet::Iterator clk_iter2(clks2); - while (clk_iter2.hasNext()) { - Clock *clk2 = clk_iter2.next(); + for (auto clk1 : *clks1) { + for (auto clk2 : *clks2) { // ClockPair is symmetric so only add one clk1/clk2 pair. if (clk1->index() < clk2->index()) { - ClockPair *clk_pair = new ClockPair(clk1, clk2); - clk_group_exclusions_->insert(clk_pair); + clk_group_exclusions_->insert(ClockPair(clk1, clk2)); } } } @@ -2165,17 +2121,11 @@ void Sdc::makeClkGroupSame(ClockGroup *group) { ClockSet *clks = group->clks(); - ClockSet::Iterator clk_iter1(clks); - while (clk_iter1.hasNext()) { - Clock *clk1 = clk_iter1.next(); - ClockSet::Iterator clk_iter2(clks); - while (clk_iter2.hasNext()) { - Clock *clk2 = clk_iter2.next(); + for (auto clk1 : *clks) { + for (auto clk2 : *clks) { if (clk1->index() <= clk2->index()) { - ClockPair *clk_pair = new ClockPair(clk1, clk2); - if (clk_group_same_->hasKey(clk_pair)) - delete clk_pair; - else + ClockPair clk_pair(clk1, clk2); + if (!clk_group_same_->hasKey(clk_pair)) clk_group_same_->insert(clk_pair); } } @@ -2186,12 +2136,10 @@ void Sdc::clearClkGroupExclusions() { if (clk_group_exclusions_) { - clk_group_exclusions_->deleteContents(); - clk_group_same_->deleteContents(); delete clk_group_exclusions_; delete clk_group_same_; - clk_group_exclusions_ = NULL; - clk_group_same_ = NULL; + clk_group_exclusions_ = nullptr; + clk_group_same_ = nullptr; } } @@ -2201,7 +2149,7 @@ Sdc::sameClockGroup(const Clock *clk1, { if (clk1 && clk2) { ClockPair clk_pair(clk1, clk2); - bool excluded = clk_group_exclusions_->hasKey(&clk_pair); + bool excluded = clk_group_exclusions_->hasKey(clk_pair); return !excluded; } else @@ -2213,7 +2161,7 @@ Sdc::sameClockGroupExplicit(const Clock *clk1, const Clock *clk2) { ClockPair clk_pair(clk1, clk2); - return clk_group_same_->hasKey(&clk_pair); + return clk_group_same_->hasKey(clk_pair); } void @@ -2308,7 +2256,7 @@ Sdc::setClockSense(PinSet *pins, { if (clks->empty()) { delete clks; - clks = NULL; + clks = nullptr; } PinSet::Iterator pin_iter(pins); while (pin_iter.hasNext()) { @@ -2321,7 +2269,7 @@ Sdc::setClockSense(PinSet *pins, } } else - setClockSense(pin, NULL, sense); + setClockSense(pin, nullptr, sense); } delete pins; delete clks; @@ -2333,10 +2281,10 @@ Sdc::setClockSense(const Pin *pin, ClockSense sense) { PinClockPair probe(pin, clk); - if (clk_sense_map_.hasKey(&probe)) - clk_sense_map_[&probe] = sense; + if (clk_sense_map_.hasKey(probe)) + clk_sense_map_[probe] = sense; else { - PinClockPair *pin_clk = new PinClockPair(pin, clk); + PinClockPair pin_clk(pin, clk); clk_sense_map_[pin_clk] = sense; } } @@ -2348,13 +2296,13 @@ Sdc::clkStopPropagation(const Pin *pin, PinClockPair pin_clk(pin, clk); ClockSense sense; bool exists; - clk_sense_map_.findKey(&pin_clk, sense, exists); + clk_sense_map_.findKey(pin_clk, sense, exists); if (!exists) { - PinClockPair pin_clk1(pin, NULL); - clk_sense_map_.findKey(&pin_clk1, sense, exists); + PinClockPair pin_clk1(pin, nullptr); + clk_sense_map_.findKey(pin_clk1, sense, exists); } return exists - && sense == clk_sense_stop; + && sense == ClockSense::stop; } bool @@ -2366,16 +2314,16 @@ Sdc::clkStopSense(const Pin *to_pin, PinClockPair pin_clk(to_pin, clk); ClockSense sense; bool exists; - clk_sense_map_.findKey(&pin_clk, sense, exists); + clk_sense_map_.findKey(pin_clk, sense, exists); if (!exists) { - PinClockPair pin(to_pin, NULL); - clk_sense_map_.findKey(&pin, sense, exists); + PinClockPair pin(to_pin, nullptr); + clk_sense_map_.findKey(pin, sense, exists); } return exists - && (sense == clk_sense_stop - || (sense == clk_sense_positive + && (sense == ClockSense::stop + || (sense == ClockSense::positive && from_tr != to_tr) - || (sense == clk_sense_negative + || (sense == ClockSense::negative && from_tr == to_tr)); } @@ -2390,35 +2338,22 @@ Sdc::clkStopPropagation(const Clock *clk, || clkStopSense(to_pin, clk, from_tr, to_tr); } -void -Sdc::deleteClkSenses() -{ - ClockSenseMap::Iterator sense_iter(clk_sense_map_); - while (sense_iter.hasNext()) { - PinClockPair *pin_clk; - ClockSense sense; - sense_iter.next(pin_clk, sense); - delete pin_clk; - } - clk_sense_map_.clear(); -} - PinClockPairLess::PinClockPairLess(const Network *network) : network_(network) { } bool -PinClockPairLess::operator()(const PinClockPair *pin_clk1, - const PinClockPair *pin_clk2) const +PinClockPairLess::operator()(const PinClockPair &pin_clk1, + const PinClockPair &pin_clk2) const { - const Pin *pin1 = pin_clk1->first; - const Pin *pin2 = pin_clk2->first; - const Clock *clk1 = pin_clk1->second; - const Clock *clk2 = pin_clk2->second; + const Pin *pin1 = pin_clk1.first; + const Pin *pin2 = pin_clk2.first; + const Clock *clk1 = pin_clk1.second; + const Clock *clk2 = pin_clk2.second; return pin1 < pin2 || (pin1 == pin2 - && ((clk1 == NULL && clk2) + && ((clk1 == nullptr && clk2) || (clk1 && clk2 && clk1->index() < clk2->index()))); } @@ -2430,7 +2365,7 @@ Sdc::setClockGatingCheck(const TransRiseFallBoth *tr, const SetupHold *setup_hold, float margin) { - if (clk_gating_check_ == NULL) + if (clk_gating_check_ == nullptr) clk_gating_check_ = new ClockGatingCheck; clk_gating_check_->margins()->setValue(tr, setup_hold, margin); } @@ -2442,7 +2377,7 @@ Sdc::setClockGatingCheck(Clock *clk, float margin) { ClockGatingCheck *check = clk_gating_check_map_.findKey(clk); - if (check == NULL) { + if (check == nullptr) { check = new ClockGatingCheck(); clk_gating_check_map_[clk] = check; } @@ -2457,7 +2392,7 @@ Sdc::setClockGatingCheck(Instance *inst, LogicValue active_value) { ClockGatingCheck *check = inst_clk_gating_check_map_.findKey(inst); - if (check == NULL) { + if (check == nullptr) { check = new ClockGatingCheck(); inst_clk_gating_check_map_[inst] = check; } @@ -2473,7 +2408,7 @@ Sdc::setClockGatingCheck(const Pin *pin, LogicValue active_value) { ClockGatingCheck *check = pin_clk_gating_check_map_.findKey(pin); - if (check == NULL) { + if (check == nullptr) { check = new ClockGatingCheck(); pin_clk_gating_check_map_[pin] = check; } @@ -2563,7 +2498,7 @@ Sdc::clockGatingActiveValue(const Pin *clk_pin, check = pin_clk_gating_check_map_.findKey(clk_pin); if (check) return check->activeValue(); - return logic_unknown; + return LogicValue::unknown; } //////////////////////////////////////////////////////////////// @@ -2573,21 +2508,18 @@ CycleAccting * Sdc::cycleAccting(const ClockEdge *src, const ClockEdge *tgt) { - if (src == NULL) + if (src == nullptr) src = tgt; - cycle_acctings_lock_.readLock(); CycleAccting probe(src, tgt); CycleAccting *acct = cycle_acctings_.findKey(&probe); - cycle_acctings_lock_.unlock(); - if (acct == NULL) { - cycle_acctings_lock_.writeLock(); + if (acct == nullptr) { acct = new CycleAccting(src, tgt); if (src == defaultArrivalClockEdge()) acct->findDefaultArrivalSrcDelays(); else acct->findDelays(this); + UniqueLock lock(cycle_acctings_lock_); cycle_acctings_.insert(acct); - cycle_acctings_lock_.unlock(); } return acct; } @@ -2598,34 +2530,29 @@ Sdc::reportClkToClkMaxCycleWarnings() // Find cycle acctings that exceed max cycle count. Eliminate // duplicate warnings between different src/tgt clk edges. ClockPairSet clk_warnings; - CycleAcctingSet::Iterator acct_iter(cycle_acctings_); - while (acct_iter.hasNext()) { - CycleAccting *acct = acct_iter.next(); + ClockPairSeq clk_warnings2; + for (auto acct : cycle_acctings_) { if (acct->maxCyclesExceeded()) { Clock *src = acct->src()->clock(); Clock *tgt = acct->target()->clock(); + // Canonicalize the warning wrt src/tgt. + if (src->index() > tgt->index()) + std::swap(src, tgt); ClockPair clk_pair(src, tgt); - if (!clk_warnings.hasKey(&clk_pair)) { - ClockPair *pair = new ClockPair(src, tgt); - clk_warnings.insert(pair); + if (!clk_warnings.hasKey(clk_pair)) { + clk_warnings.insert(clk_pair); + clk_warnings2.push_back(clk_pair); } } } + // Sort clk pairs so that results are stable. - ClockPairSeq clk_warnings2; - ClockPairSet::Iterator pair_iter(clk_warnings); - while (pair_iter.hasNext()) { - ClockPair *pair = pair_iter.next(); - clk_warnings2.push_back(pair); - } sort(clk_warnings2, ClockPairLess()); - ClockPairSeq::Iterator pair_iter2(clk_warnings2); - while (pair_iter2.hasNext()) { - ClockPair *pair = pair_iter2.next(); + + for (auto pair : clk_warnings2) { report_->warn("No common period was found between clocks %s and %s.\n", - pair->first->name(), - pair->second->name()); - delete pair; + pair.first->name(), + pair.second->name()); } } @@ -2646,9 +2573,9 @@ Sdc::setDataCheck(Pin *from, const SetupHold *setup_hold, float margin) { - DataCheck *check = NULL; + DataCheck *check = nullptr; DataCheckSet *checks = data_checks_from_map_.findKey(from); - if (checks == NULL) { + if (checks == nullptr) { checks = new DataCheckSet(DataCheckLess(network_)); data_checks_from_map_[from] = checks; } @@ -2656,13 +2583,13 @@ Sdc::setDataCheck(Pin *from, DataCheck probe(from, to, clk); check = checks->findKey(&probe); } - if (check == NULL) + if (check == nullptr) check = new DataCheck(from, to, clk); check->setMargin(from_tr, to_tr, setup_hold, margin); checks->insert(check); checks = data_checks_to_map_.findKey(to); - if (checks == NULL) { + if (checks == nullptr) { checks = new DataCheckSet(DataCheckLess(network_)); data_checks_to_map_[to] = checks; } @@ -2777,7 +2704,7 @@ Sdc::setMinPulseWidth(const Pin *pin, float min_width) { RiseFallValues *widths = pin_min_pulse_width_map_.findKey(pin); - if (widths == NULL) { + if (widths == nullptr) { widths = new RiseFallValues; pin_min_pulse_width_map_[pin] = widths; } @@ -2794,7 +2721,7 @@ Sdc::setMinPulseWidth(const Instance *inst, float min_width) { RiseFallValues *widths = inst_min_pulse_width_map_.findKey(inst); - if (widths == NULL) { + if (widths == nullptr) { widths = new RiseFallValues; inst_min_pulse_width_map_[inst] = widths; } @@ -2811,7 +2738,7 @@ Sdc::setMinPulseWidth(const Clock *clk, float min_width) { RiseFallValues *widths = clk_min_pulse_width_map_.findKey(clk); - if (widths == NULL) { + if (widths == nullptr) { widths = new RiseFallValues; clk_min_pulse_width_map_[clk] = widths; } @@ -2837,7 +2764,7 @@ Sdc::minPulseWidth(const Pin *pin, const Instance *inst = network_->instance(pin); widths = inst_min_pulse_width_map_.findKey(inst); } - if (widths == NULL) + if (widths == nullptr) widths = clk_min_pulse_width_map_.findKey(clk); if (widths) widths->value(hi_low, min_width, exists); @@ -2876,7 +2803,7 @@ Sdc::setInputDelay(Pin *pin, bool add, float delay) { - ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : NULL; + ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr; InputDelay *input_delay = ensureInputDelay(pin, clk_edge, ref_pin); RiseFallMinMax *delays = input_delay->delays(); if (add) @@ -2895,14 +2822,14 @@ Sdc::ensureInputDelay(Pin *pin, Pin *ref_pin) { InputDelay *input_delay = findInputDelay(pin, clk_edge, ref_pin); - if (input_delay == NULL) { + if (input_delay == nullptr) { input_delay = new InputDelay(pin, clk_edge, ref_pin, input_delay_index_++, network_); input_delay->setNext(input_delay_map_[pin]); input_delay_map_[pin] = input_delay; if (ref_pin) { InputDelaySet *ref_inputs = input_delay_ref_pin_map_.findKey(ref_pin); - if (ref_inputs == NULL) { + if (ref_inputs == nullptr) { ref_inputs = new InputDelaySet; input_delay_ref_pin_map_[ref_pin] = ref_inputs; } @@ -2914,7 +2841,7 @@ Sdc::ensureInputDelay(Pin *pin, input_delay_vertex_map_[vpin] = input_delay; if (!network_->isTopLevelPort(vpin)) { InputDelaySet *input_set = input_delay_internal_pin_map_[vpin]; - if (input_set == NULL) { + if (input_set == nullptr) { input_set = new InputDelaySet; input_delay_internal_pin_map_[vpin] = input_set; } @@ -2937,7 +2864,7 @@ Sdc::findInputDelay(const Pin *pin, && input_delay->refPin() == ref_pin) return input_delay; } - return NULL; + return nullptr; } void @@ -2947,8 +2874,8 @@ Sdc::removeInputDelay(Pin *pin, TransRiseFall *clk_tr, MinMaxAll *min_max) { - ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : NULL; - InputDelay *input_delay = findInputDelay(pin, clk_edge, NULL); + ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr; + InputDelay *input_delay = findInputDelay(pin, clk_edge, nullptr); if (input_delay) { RiseFallMinMax *delays = input_delay->delays(); delays->removeValue(tr, min_max); @@ -2965,7 +2892,7 @@ Sdc::deleteInputDelays(Pin *pin, while (input_delay) { InputDelay *next = input_delay->next(); if (input_delay == except) - input_delay->setNext(NULL); + input_delay->setNext(nullptr); else delete input_delay; input_delay = next; @@ -3005,21 +2932,20 @@ Sdc::inputDelayVertexPinsIterator() PinInputDelayIterator * Sdc::inputDelayIterator(const Pin *pin) const { - InputDelay *input_delay = input_delay_map_.findKey(pin); - return new PinInputDelayIterator(input_delay); + + return new PinInputDelayIterator(pin, this); } PinInputDelayIterator * Sdc::inputDelayVertexIterator(const Pin *vertex_pin) const { - InputDelay *input_delay = input_delay_vertex_map_.findKey(vertex_pin); - return new PinInputDelayIterator(input_delay); + return new VertexPinInputDelayIterator(vertex_pin, this); } bool Sdc::hasInputDelay(const Pin *vertex_pin) const { - return input_delay_vertex_map_.findKey(vertex_pin) != NULL; + return input_delay_vertex_map_.findKey(vertex_pin) != nullptr; } bool @@ -3093,7 +3019,7 @@ Sdc::setOutputDelay(Pin *pin, bool add, float delay) { - ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : NULL; + ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr; OutputDelay *output_delay = ensureOutputDelay(pin, clk_edge, ref_pin); RiseFallMinMax *delays = output_delay->delays(); if (add) @@ -3112,7 +3038,7 @@ Sdc::ensureOutputDelay(Pin *pin, Pin *ref_pin) { OutputDelay *output_delay = findOutputDelay(pin, clk_edge, ref_pin); - if (output_delay == NULL) { + if (output_delay == nullptr) { output_delay = new OutputDelay(pin, clk_edge, ref_pin, network_); output_delay->setNext(output_delay_map_[pin]); output_delay_map_[pin] = output_delay; @@ -3139,7 +3065,7 @@ Sdc::findOutputDelay(const Pin *pin, && output_delay->refPin() == ref_pin) return output_delay; } - return NULL; + return nullptr; } void @@ -3149,8 +3075,8 @@ Sdc::removeOutputDelay(Pin *pin, TransRiseFall *clk_tr, MinMaxAll *min_max) { - ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : NULL; - InputDelay *input_delay = findInputDelay(pin, clk_edge, NULL); + ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr; + InputDelay *input_delay = findInputDelay(pin, clk_edge, nullptr); if (input_delay) { RiseFallMinMax *delays = input_delay->delays(); delays->removeValue(tr, min_max); @@ -3165,7 +3091,7 @@ Sdc::deleteOutputDelays(Pin *pin, while (output_delay) { OutputDelay *next = output_delay->next(); if (output_delay == except) - output_delay->setNext(NULL); + output_delay->setNext(nullptr); else delete output_delay; output_delay = next; @@ -3187,15 +3113,13 @@ Sdc::outputDelayIterator() PinOutputDelayIterator * Sdc::outputDelayIterator(const Pin *pin) const { - OutputDelay *output_delay = output_delay_map_.findKey(pin); - return new PinOutputDelayIterator(output_delay); + return new PinOutputDelayIterator(pin, this); } PinOutputDelayIterator * Sdc::outputDelayVertexIterator(const Pin *vertex_pin) const { - OutputDelay *output_delay = output_delay_vertex_map_.findKey(vertex_pin); - return new PinOutputDelayIterator(output_delay); + return new VertexPinOutputDelayIterator(vertex_pin, this); } bool @@ -3288,7 +3212,7 @@ Sdc::portExtCap(Port *port) const if (port_cap_map_) return port_cap_map_->findKey(port); else - return NULL; + return nullptr; } bool @@ -3398,7 +3322,7 @@ Sdc::setNetWireCap(Net *net, delete pin_iter; } } - if (net_wire_cap_map_ == NULL) + if (net_wire_cap_map_ == nullptr) net_wire_cap_map_ = new NetWireCapMap[corners_->count()]; bool make_drvr_entry = net_wire_cap_map_[corner->index()].hasKey(net); MinMaxFloatValues &values = net_wire_cap_map_[corner->index()][net]; @@ -3410,7 +3334,7 @@ Sdc::setNetWireCap(Net *net, while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); if (network_->isDriver(pin)) { - if (drvr_pin_wire_cap_map_ == NULL) + if (drvr_pin_wire_cap_map_ == nullptr) drvr_pin_wire_cap_map_ = new PinWireCapMap[corners_->count()]; drvr_pin_wire_cap_map_[corner->index()][pin] = &values; } @@ -3603,7 +3527,7 @@ Sdc::portCapacitance(Instance *inst, const Corner *corner, const MinMax *min_max) const { - Pvt *inst_pvt = NULL; + Pvt *inst_pvt = nullptr; if (inst) inst_pvt = pvt(inst, min_max); LibertyPort *corner_port = port->cornerPort(corner->libertyIndex(min_max)); @@ -3691,10 +3615,10 @@ Sdc::portExtFanout(Port *port, PortExtCap * Sdc::ensurePortExtPinCap(Port *port) { - if (port_cap_map_ == NULL) + if (port_cap_map_ == nullptr) port_cap_map_ = new PortExtCapMap; PortExtCap *port_cap = port_cap_map_->findKey(port); - if (port_cap == NULL) { + if (port_cap == nullptr) { port_cap = new PortExtCap(port); (*port_cap_map_)[port] = port_cap; } @@ -3709,7 +3633,7 @@ Sdc::disable(LibertyCell *cell, LibertyPort *to) { DisabledCellPorts *disabled_cell = disabled_cell_ports_.findKey(cell); - if (disabled_cell == NULL) { + if (disabled_cell == nullptr) { disabled_cell = new DisabledCellPorts(cell); disabled_cell_ports_[cell] = disabled_cell; } @@ -3770,7 +3694,7 @@ Sdc::disable(TimingArcSet *arc_set) { LibertyCell *cell = arc_set->libertyCell(); DisabledCellPorts *disabled_cell = disabled_cell_ports_.findKey(cell); - if (disabled_cell == NULL) { + if (disabled_cell == nullptr) { disabled_cell = new DisabledCellPorts(cell); disabled_cell_ports_[cell] = disabled_cell; } @@ -3829,7 +3753,7 @@ Sdc::disable(Instance *inst, LibertyPort *to) { DisabledInstancePorts *disabled_inst = disabled_inst_ports_.findKey(inst); - if (disabled_inst == NULL) { + if (disabled_inst == nullptr) { disabled_inst = new DisabledInstancePorts(inst); disabled_inst_ports_[inst] = disabled_inst; } @@ -4167,7 +4091,7 @@ Sdc::makeExceptionFrom(PinSet *from_pins, || (from_insts && !from_insts->empty())) return new ExceptionFrom(from_pins, from_clks, from_insts, from_tr, true); else - return NULL; + return nullptr; } ExceptionThru * @@ -4181,7 +4105,7 @@ Sdc::makeExceptionThru(PinSet *pins, || (insts && !insts->empty())) return new ExceptionThru(pins, nets, insts, tr, true, network_); else - return NULL; + return nullptr; } ExceptionTo * @@ -4198,7 +4122,7 @@ Sdc::makeExceptionTo(PinSet *pins, || (end_tr != TransRiseFallBoth::riseFall())) return new ExceptionTo(pins, clks, insts, tr, end_tr, true); else - return NULL; + return nullptr; } // Valid endpoints include gated clock enables which are not @@ -4208,7 +4132,7 @@ Sdc::exceptionToInvalid(const Pin *pin) { Net *net = network_->net(pin); // Floating pins are invalid. - if ((net == NULL + if ((net == nullptr && !network_->isTopLevelPort(pin)) || (net // Pins connected to power/ground are invalid. @@ -4221,7 +4145,7 @@ Sdc::exceptionToInvalid(const Pin *pin) LibertyPort *port = network_->libertyPort(pin); if (port) { LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, NULL, port); + LibertyCellTimingArcSetIterator set_iter(cell, nullptr, port); while (set_iter.hasNext()) { TimingArcSet *set = set_iter.next(); TimingRole *role = set->role(); @@ -4289,7 +4213,7 @@ Sdc::recordPathDelayInternalStartpoints(ExceptionPath *exception) Pin *pin = pin_iter.next(); if (!(network_->isRegClkPin(pin) || network_->isTopLevelPort(pin))) { - if (path_delay_internal_startpoints_ == NULL) + if (path_delay_internal_startpoints_ == nullptr) path_delay_internal_startpoints_ = new PinSet; path_delay_internal_startpoints_->insert(pin); } @@ -4353,7 +4277,7 @@ Sdc::recordPathDelayInternalEndpoints(ExceptionPath *exception) Pin *pin = pin_iter.next(); if (!(hasLibertyChecks(pin) || network_->isTopLevelPort(pin))) { - if (path_delay_internal_endpoints_ == NULL) + if (path_delay_internal_endpoints_ == nullptr) path_delay_internal_endpoints_ = new PinSet; path_delay_internal_endpoints_->insert(pin); } @@ -4387,7 +4311,7 @@ Sdc::hasLibertyChecks(const Pin *pin) if (cell) { LibertyPort *port = network_->libertyPort(pin); if (port) { - LibertyCellTimingArcSetIterator timing_iter(cell, NULL, port); + LibertyCellTimingArcSetIterator timing_iter(cell, nullptr, port); while (timing_iter.hasNext()) { TimingArcSet *arc_set = timing_iter.next(); if (arc_set->role()->isTimingCheck()) @@ -4455,7 +4379,7 @@ Sdc::makeGroupPath(const char *name, addException(group_path); // A named group path can have multiple exceptions. GroupPathSet *groups = group_path_map_.findKey(name); - if (groups == NULL) { + if (groups == nullptr) { groups = new GroupPathSet; group_path_map_[stringCopy(name)] = groups; } @@ -4562,7 +4486,7 @@ Sdc::makeLoopExceptionThru(Pin *pin, debugPrint1(debug_, "levelize", 2, " %s\n", network_->pathName(pin)); PinSet *pins = new PinSet; pins->insert(pin); - ExceptionThru *thru = makeExceptionThru(pins, NULL, NULL, + ExceptionThru *thru = makeExceptionThru(pins, nullptr, nullptr, TransRiseFallBoth::riseFall()); thrus->push_back(thru); } @@ -4589,7 +4513,7 @@ Sdc::addException(ExceptionPath *exception) if (exception->isPathDelay()) { recordPathDelayInternalStartpoints(exception); recordPathDelayInternalEndpoints(exception); - if (exception->to() == NULL) + if (exception->to() == nullptr) path_delays_without_to_ = true; } @@ -4600,24 +4524,24 @@ Sdc::addException(ExceptionPath *exception) if (from && (from->hasPins() || from->hasInstances()) && from->hasClocks()) { - PinSet *pins1 = from->pins() ? new PinSet(*from->pins()) : NULL; + PinSet *pins1 = from->pins() ? new PinSet(*from->pins()) : nullptr; InstanceSet *insts1 = - from->instances() ? new InstanceSet(*from->instances()) : NULL; - ExceptionFrom *from1 = new ExceptionFrom(pins1, NULL, insts1, + from->instances() ? new InstanceSet(*from->instances()) : nullptr; + ExceptionFrom *from1 = new ExceptionFrom(pins1, nullptr, insts1, from->transition(), true); ExceptionThruSeq *thrus1 = exceptionThrusClone(exception->thrus(), network_); ExceptionTo *to = exception->to(); - ExceptionTo *to1 = to ? to->clone() : NULL; + ExceptionTo *to1 = to ? to->clone() : nullptr; ExceptionPath *exception1 = exception->clone(from1, thrus1, to1, true); debugPrint1(debug_, "exception_merge", 1, " split exception for %s\n", exception1->asString(network_)); addException1(exception1); ClockSet *clks2 = new ClockSet(*from->clks()); - ExceptionFrom *from2 = new ExceptionFrom(NULL, clks2, NULL, + ExceptionFrom *from2 = new ExceptionFrom(nullptr, clks2, nullptr, from->transition(), true); ExceptionThruSeq *thrus2 = exceptionThrusClone(exception->thrus(), network_); - ExceptionTo *to2 = to ? to->clone() : NULL; + ExceptionTo *to2 = to ? to->clone() : nullptr; ExceptionPath *exception2 = exception->clone(from2, thrus2, to2, true); debugPrint1(debug_, "exception_merge", 1, " split exception for %s\n", exception2->asString(network_)); @@ -4638,9 +4562,9 @@ Sdc::addException1(ExceptionPath *exception) && to->hasClocks()) { ExceptionFrom *from1 = exception->from()->clone(); ExceptionThruSeq *thrus1 = exceptionThrusClone(exception->thrus(), network_); - PinSet *pins1 = to->pins() ? new PinSet(*to->pins()) : NULL; - InstanceSet *insts1 = to->instances() ? new InstanceSet(*to->instances()) : NULL; - ExceptionTo *to1 = new ExceptionTo(pins1, NULL, insts1, + PinSet *pins1 = to->pins() ? new PinSet(*to->pins()) : nullptr; + InstanceSet *insts1 = to->instances() ? new InstanceSet(*to->instances()) : nullptr; + ExceptionTo *to1 = new ExceptionTo(pins1, nullptr, insts1, to->transition(), to->endTransition(), true); ExceptionPath *exception1 = exception->clone(from1, thrus1, to1, true); @@ -4651,7 +4575,7 @@ Sdc::addException1(ExceptionPath *exception) ExceptionFrom *from2 = exception->from()->clone(); ExceptionThruSeq *thrus2 = exceptionThrusClone(exception->thrus(), network_); ClockSet *clks2 = new ClockSet(*to->clks()); - ExceptionTo *to2 = new ExceptionTo(NULL, clks2, NULL, to->transition(), + ExceptionTo *to2 = new ExceptionTo(nullptr, clks2, nullptr, to->transition(), to->endTransition(), true); ExceptionPath *exception2 = exception->clone(from2, thrus2, to2, true); debugPrint1(debug_, "exception_merge", 1, " split exception for %s\n", @@ -4902,10 +4826,10 @@ Sdc::expandExceptionExcluding(ExceptionPath *exception, ExceptionFrom *from_cpy = from->clone(); from_cpy->deleteObjects(excluding->from()); if (from_cpy->hasObjects()) { - ExceptionThruSeq *thrus_cpy = NULL; + ExceptionThruSeq *thrus_cpy = nullptr; if (thrus) thrus_cpy = clone(thrus, network_); - ExceptionTo *to_cpy = NULL; + ExceptionTo *to_cpy = nullptr; if (to) to_cpy = to->clone(); ExceptionPath *expand = exception->clone(from_cpy,thrus_cpy,to_cpy,true); @@ -4924,7 +4848,7 @@ Sdc::expandExceptionExcluding(ExceptionPath *exception, ExceptionThru *thru_cpy = thru->clone(network_); thru_cpy->deleteObjects(thru2); if (thru_cpy->hasObjects()) { - ExceptionFrom *from_cpy = NULL; + ExceptionFrom *from_cpy = nullptr; if (from) from_cpy = from->clone(); ExceptionThruSeq *thrus_cpy = new ExceptionThruSeq; @@ -4938,7 +4862,7 @@ Sdc::expandExceptionExcluding(ExceptionPath *exception, thrus_cpy->push_back(thru_cpy); } } - ExceptionTo *to_cpy = NULL; + ExceptionTo *to_cpy = nullptr; if (to) to_cpy = to->clone(); ExceptionPath *expand = exception->clone(from_cpy, thrus_cpy, to_cpy, @@ -4953,10 +4877,10 @@ Sdc::expandExceptionExcluding(ExceptionPath *exception, ExceptionTo *to_cpy = to->clone(); to_cpy->deleteObjects(excluding->to()); if (to_cpy->hasObjects()) { - ExceptionFrom *from_cpy = NULL; + ExceptionFrom *from_cpy = nullptr; if (from) from_cpy = from->clone(); - ExceptionThruSeq *thrus_cpy = NULL; + ExceptionThruSeq *thrus_cpy = nullptr; if (thrus) thrus_cpy = clone(thrus, network_); ExceptionPath *expand = exception->clone(from_cpy,thrus_cpy,to_cpy,true); @@ -5011,7 +4935,7 @@ Sdc::recordMergeHash(ExceptionPath *exception, exception->asString(network_), missing_pt->asString(network_)); ExceptionPathSet *set = exception_merge_hash_.findKey(hash); - if (set == NULL) { + if (set == nullptr) { set = new ExceptionPathSet; exception_merge_hash_[hash] = set; } @@ -5075,12 +4999,12 @@ Sdc::recordExceptionClks(ExceptionPath *exception, ClockSet::Iterator clk_iter(clks); while (clk_iter.hasNext()) { Clock *clk = clk_iter.next(); - ExceptionPathSet *set = NULL; - if (exception_map == NULL) + ExceptionPathSet *set = nullptr; + if (exception_map == nullptr) exception_map = new ClockExceptionsMap; else set = exception_map->findKey(clk); - if (set == NULL) { + if (set == nullptr) { set = new ExceptionPathSet; (*exception_map)[clk] = set; } @@ -5096,12 +5020,12 @@ Sdc::recordExceptionEdges(ExceptionPath *exception, EdgePinsSet::Iterator edge_iter(edges); while (edge_iter.hasNext()) { EdgePins *edge = edge_iter.next(); - ExceptionPathSet *set = NULL; - if (exception_map == NULL) + ExceptionPathSet *set = nullptr; + if (exception_map == nullptr) exception_map = new EdgeExceptionsMap; else set = exception_map->findKey(edge); - if (set == NULL) { + if (set == nullptr) { set = new ExceptionPathSet; // Copy the EdgePins so it is owned by the map. edge = new EdgePins(*edge); @@ -5119,12 +5043,12 @@ Sdc::recordExceptionPins(ExceptionPath *exception, PinSet::Iterator pin_iter(pins); while (pin_iter.hasNext()) { const Pin *pin = pin_iter.next(); - ExceptionPathSet *set = NULL; - if (exception_map == NULL) + ExceptionPathSet *set = nullptr; + if (exception_map == nullptr) exception_map = new PinExceptionsMap; else set = exception_map->findKey(pin); - if (set == NULL) { + if (set == nullptr) { set = new ExceptionPathSet; exception_map->insert(pin, set); } @@ -5137,12 +5061,12 @@ Sdc::recordExceptionHpin(ExceptionPath *exception, Pin *pin, PinExceptionsMap *&exception_map) { - ExceptionPathSet *set = NULL; - if (exception_map == NULL) + ExceptionPathSet *set = nullptr; + if (exception_map == nullptr) exception_map = new PinExceptionsMap; else set = exception_map->findKey(pin); - if (set == NULL) { + if (set == nullptr) { set = new ExceptionPathSet; exception_map->insert(pin, set); } @@ -5157,12 +5081,12 @@ Sdc::recordExceptionInsts(ExceptionPath *exception, InstanceSet::Iterator inst_iter(insts); while (inst_iter.hasNext()) { Instance *inst = inst_iter.next(); - ExceptionPathSet *set = NULL; - if (exception_map == NULL) + ExceptionPathSet *set = nullptr; + if (exception_map == nullptr) exception_map = new InstanceExceptionsMap; else set = exception_map->findKey(inst); - if (set == NULL) { + if (set == nullptr) { set = new ExceptionPathSet; (*exception_map)[inst] = set; } @@ -5178,12 +5102,12 @@ Sdc::recordExceptionNets(ExceptionPath *exception, NetSet::Iterator net_iter(nets); while (net_iter.hasNext()) { const Net *net = net_iter.next(); - ExceptionPathSet *set = NULL; - if (exception_map == NULL) + ExceptionPathSet *set = nullptr; + if (exception_map == nullptr) exception_map = new NetExceptionsMap; else set = exception_map->findKey(net); - if (set == NULL) { + if (set == nullptr) { set = new ExceptionPathSet; (*exception_map)[net] = set; } @@ -5254,7 +5178,7 @@ Sdc::findMergeMatch(ExceptionPath *exception) } first_pt = false; } - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -5280,10 +5204,10 @@ Sdc::deleteExceptions() deleteExceptionMap(first_thru_edge_exceptions_); delete path_delay_internal_startpoints_; - path_delay_internal_startpoints_ = NULL; + path_delay_internal_startpoints_ = nullptr; delete path_delay_internal_endpoints_; - path_delay_internal_endpoints_ = NULL; + path_delay_internal_endpoints_ = nullptr; deleteExceptionPtHashMapSets(exception_merge_hash_); exception_merge_hash_.clear(); @@ -5308,7 +5232,7 @@ Sdc::deleteExceptionMap(PinExceptionsMap *&exception_map) delete set; } delete exception_map; - exception_map = NULL; + exception_map = nullptr; } void @@ -5322,7 +5246,7 @@ Sdc::deleteExceptionMap(InstanceExceptionsMap *&exception_map) delete set; } delete exception_map; - exception_map = NULL; + exception_map = nullptr; } void @@ -5336,7 +5260,7 @@ Sdc::deleteExceptionMap(NetExceptionsMap *&exception_map) delete set; } delete exception_map; - exception_map = NULL; + exception_map = nullptr; } void @@ -5350,7 +5274,7 @@ Sdc::deleteExceptionMap(ClockExceptionsMap *&exception_map) delete set; } delete exception_map; - exception_map = NULL; + exception_map = nullptr; } void @@ -5365,7 +5289,7 @@ Sdc::deleteExceptionMap(EdgeExceptionsMap *&exception_map) delete edge_pins; } delete exception_map; - exception_map = NULL; + exception_map = nullptr; } //////////////////////////////////////////////////////////////// @@ -5591,10 +5515,10 @@ ExpandException::visit(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to) { - ExceptionFrom *from_clone = NULL; + ExceptionFrom *from_clone = nullptr; if (from) from_clone = from->clone(); - ExceptionThruSeq *thrus_clone = NULL; + ExceptionThruSeq *thrus_clone = nullptr; if (thrus) { thrus_clone = new ExceptionThruSeq; ExceptionThruSeq::Iterator thru_iter(thrus); @@ -5603,7 +5527,7 @@ ExpandException::visit(ExceptionFrom *from, thrus_clone->push_back(thru->clone(network_)); } } - ExceptionTo *to_clone = NULL; + ExceptionTo *to_clone = nullptr; if (to) to_clone = to->clone(); ExceptionPath *expand = exception_->clone(from_clone, thrus_clone, @@ -5680,11 +5604,11 @@ Sdc::exceptionFromStates(const Pin *pin, if (pin) { if (srch_from && first_from_pin_exceptions_) srch_from &= exceptionFromStates(first_from_pin_exceptions_->findKey(pin), - NULL, tr, min_max, include_filter, + nullptr, tr, min_max, include_filter, states); if (srch_from && first_thru_pin_exceptions_) srch_from &= exceptionFromStates(first_thru_pin_exceptions_->findKey(pin), - NULL, tr, min_max, include_filter, + nullptr, tr, min_max, include_filter, states); if (srch_from @@ -5706,7 +5630,7 @@ Sdc::exceptionFromStates(const Pin *pin, states); if (!srch_from) { delete states; - states = NULL; + states = nullptr; } return srch_from; } @@ -5724,11 +5648,11 @@ Sdc::exceptionFromStates(const ExceptionPathSet *exceptions, while (exception_iter.hasNext()) { ExceptionPath *exception = exception_iter.next(); if (exception->matches(min_max, false) - && (exception->from() == NULL + && (exception->from() == nullptr || exception->from()->transition()->matches(tr)) && (include_filter || !exception->isFilter())) { ExceptionState *state = exception->firstState(); - if (state->matchesNextThru(NULL, pin, tr, min_max, network_)) + if (state->matchesNextThru(nullptr, pin, tr, min_max, network_)) // -from clk -thru reg/clk state = state->nextState(); // If the exception is -from and has no -to transition it is @@ -5738,7 +5662,7 @@ Sdc::exceptionFromStates(const ExceptionPathSet *exceptions, // Leave the completed false path state as a marker on the tag, // but flush all other exception states because they are lower // priority. - if (states == NULL) + if (states == nullptr) states = new ExceptionStateSet; states->clear(); states->insert(state); @@ -5746,7 +5670,7 @@ Sdc::exceptionFromStates(const ExceptionPathSet *exceptions, // pin/clock/instance. return false; } - if (states == NULL) + if (states == nullptr) states = new ExceptionStateSet; states->insert(state); } @@ -5766,7 +5690,7 @@ Sdc::exceptionFromClkStates(const Pin *pin, if (pin) { if (first_from_pin_exceptions_) exceptionFromStates(first_from_pin_exceptions_->findKey(pin), - NULL, tr, min_max, true, states); + nullptr, tr, min_max, true, states); if (first_from_inst_exceptions_) { Instance *inst = network_->instance(pin); exceptionFromStates(first_from_inst_exceptions_->findKey(inst), @@ -5795,7 +5719,7 @@ Sdc::filterRegQStates(const Pin *to_pin, if (exception->isFilter() && exception->matchesFirstPt(to_tr, min_max)) { ExceptionState *state = exception->firstState(); - if (states == NULL) + if (states == nullptr) states = new ExceptionStateSet; states->insert(state); } @@ -5841,7 +5765,7 @@ Sdc::exceptionThruStates(const ExceptionPathSet *exceptions, ExceptionPath *exception = exception_iter.next(); if (exception->matchesFirstPt(to_tr, min_max)) { ExceptionState *state = exception->firstState(); - if (states == NULL) + if (states == nullptr) states = new ExceptionStateSet; states->insert(state); } @@ -5911,12 +5835,12 @@ Sdc::exceptionTo(ExceptionPath *exception, ExceptionPath *&hi_priority_exception, int &hi_priority) const { - if ((type == exception_type_any + if ((type == ExceptionPathType::any || exception->type() == type) && exceptionMatchesTo(exception, pin, tr, clk_edge, min_max, match_min_max_exactly, false)) { int priority = exception->priority(min_max); - if (hi_priority_exception == NULL + if (hi_priority_exception == nullptr || priority > hi_priority || (priority == hi_priority && exception->tighterThan(hi_priority_exception))) { @@ -5937,7 +5861,7 @@ Sdc::exceptionMatchesTo(ExceptionPath *exception, { ExceptionTo *to = exception->to(); return exception->matches(min_max, match_min_max_exactly) - && ((to == NULL + && ((to == nullptr && !require_to_pin) || (to && to->matches(pin, clk_edge, tr, network_))); @@ -5952,7 +5876,7 @@ Sdc::isCompleteTo(ExceptionState *state, bool match_min_max_exactly, bool require_to_pin) const { - return state->nextThru() == NULL + return state->nextThru() == nullptr && exceptionMatchesTo(state->exception(), pin, tr, clk_edge, min_max, match_min_max_exactly, require_to_pin); } @@ -5963,7 +5887,7 @@ Wireload * Sdc::wireloadDefaulted(const MinMax *min_max) { Wireload *wireload1 = wireload(min_max); - if (wireload1 == NULL) { + if (wireload1 == nullptr) { LibertyLibrary *default_lib = network_->defaultLibertyLibrary(); if (default_lib) wireload1 = default_lib->defaultWireload(); @@ -6004,7 +5928,7 @@ const WireloadSelection * Sdc::wireloadSelection(const MinMax *min_max) { const WireloadSelection *sel = wireload_selection_[min_max->index()]; - if (sel == NULL) { + if (sel == nullptr) { // Look for a default. LibertyLibrary *lib = network_->defaultLibertyLibrary(); if (lib) { @@ -6058,7 +5982,7 @@ Sdc::setCrprMode(CrprMode mode) bool Sdc::crprActive() const { - return analysis_type_ == analysis_type_on_chip_variation + return analysis_type_ == AnalysisType::ocv && crpr_enabled_; } @@ -6639,6 +6563,11 @@ Sdc::clockLatency(Edge *edge, //////////////////////////////////////////////////////////////// +InputDelayVertexPinsIterator::InputDelayVertexPinsIterator(Sdc *sdc) : + InputDelayVertexPinsIterator(sdc->input_delay_map_) +{ +} + InputDelayVertexPinsIterator::InputDelayVertexPinsIterator(InputDelayMap &input_delay_map) : input_iter_(input_delay_map) @@ -6720,6 +6649,11 @@ findVertexDriverPins(Pin *pin, //////////////////////////////////////////////////////////////// +InputDelayIterator::InputDelayIterator(Sdc *sdc) : + InputDelayIterator(sdc->input_delay_map_) +{ +} + InputDelayIterator::InputDelayIterator(InputDelayMap &input_delay_map) : input_iter_(input_delay_map), next_(NULL) @@ -6752,6 +6686,11 @@ InputDelayIterator::findNext() //////////////////////////////////////////////////////////////// +OutputDelayIterator::OutputDelayIterator(Sdc *sdc) : + OutputDelayIterator(sdc->output_delay_map_) +{ +} + OutputDelayIterator::OutputDelayIterator(OutputDelayMap &output_delay_map) : output_iter_(output_delay_map), next_(NULL) @@ -6782,4 +6721,40 @@ OutputDelayIterator::findNext() next_ = output_iter_.next(); } +//////////////////////////////////////////////////////////////// + +ClockIterator::ClockIterator(Sdc *sdc) : + ClockSeq::Iterator(sdc->clocks()) +{ +} + +ClockIterator::ClockIterator(ClockSeq &clocks) : + ClockSeq::Iterator(clocks) +{ +} + +//////////////////////////////////////////////////////////////// + +ClockGroupIterator::ClockGroupIterator(Sdc *sdc) : + ClockGroupsNameMap::Iterator(sdc->clk_groups_name_map_) +{ +} + +ClockGroupIterator::ClockGroupIterator(ClockGroupsNameMap &clk_groups_name_map) : + ClockGroupsNameMap::Iterator(clk_groups_name_map) +{ +} + +//////////////////////////////////////////////////////////////// + +GroupPathIterator::GroupPathIterator(Sdc *sdc) : + GroupPathIterator(sdc->group_path_map_) +{ +} + +GroupPathIterator::GroupPathIterator(GroupPathMap &group_path_map) : + GroupPathMap::Iterator(group_path_map) +{ +} + } // namespace diff --git a/sdc/Sdc.hh b/sdc/Sdc.hh index e80d4586..66eb8865 100644 --- a/sdc/Sdc.hh +++ b/sdc/Sdc.hh @@ -17,11 +17,12 @@ #ifndef STA_SDC_H #define STA_SDC_H +#include #include "DisallowCopyAssign.hh" -#include "ReadWriteLock.hh" #include "StringUtil.hh" #include "StringSet.hh" #include "Map.hh" +#include "UnorderedSet.hh" #include "UnorderedMap.hh" #include "MinMax.hh" #include "RiseFallValues.hh" @@ -56,6 +57,11 @@ class FindNetCaps; class ClkHpinDisable; class FindClkHpinDisables; class Corner; +class ClockGroupIterator; +class GroupPathIterator; +class ClockVertexPinIterator; +class ClockPinIterator; +class ClockIterator; typedef std::pair PinClockPair; @@ -79,16 +85,16 @@ public: class ClockPairLess { public: - bool operator()(const ClockPair *pair1, - const ClockPair *pair2) const; + bool operator()(const ClockPair &pair1, + const ClockPair &pair2) const; }; class PinClockPairLess { public: PinClockPairLess(const Network *network); - bool operator()(const PinClockPair *pin_clk1, - const PinClockPair *pin_clk2) const; + bool operator()(const PinClockPair &pin_clk1, + const PinClockPair &pin_clk2) const; protected: const Network *network_; @@ -108,7 +114,7 @@ typedef Set InputDelaySet; typedef Map InputDelayRefPinMap; typedef Map InputDelayInternalPinMap; typedef Map OutputDelayMap; -typedef Set CycleAcctingSet; +typedef UnorderedSet CycleAcctingSet; typedef Set InstanceSet; typedef UnorderedMap PinExceptionsMap; typedef Map ClockExceptionsMap; @@ -155,13 +161,11 @@ typedef Map CellDeratingFactorsMap; typedef Set ClockGroupsSet; typedef Map ClockGroupsClkMap; typedef Map ClockGroupsNameMap; -typedef ClockGroupsNameMap::Iterator ClockGroupIterator; -typedef Map ClockSenseMap; +typedef Map ClockSenseMap; typedef Set ClkHpinDisables; typedef Set GroupPathSet; typedef Map GroupPathMap; -typedef GroupPathMap::Iterator GroupPathIterator; -typedef Set ClockPairSet; +typedef Set ClockPairSet; void findVertexLoadPins(Pin *pin, const @@ -386,7 +390,6 @@ public: void setPropagatedClock(Pin *pin); void removePropagatedClock(Pin *pin); bool isPropagatedClock(const Pin *pin); - bool isPropagatedClock(const Clock *clk) const __attribute__ ((deprecated)); void setClockSlew(Clock *clk, const TransRiseFallBoth *tr, const MinMaxAll *min_max, @@ -484,7 +487,7 @@ public: void makeClockGroup(ClockGroups *clk_groups, ClockSet *clks); void removeClockGroups(const char *name); - // NULL name removes all. + // nullptr name removes all. void removeClockGroupsLogicallyExclusive(const char *name); void removeClockGroupsPhysicallyExclusive(const char *name); void removeClockGroupsAsynchronous(const char *name); @@ -674,7 +677,7 @@ public: void removeDisableClockGatingCheck(Pin *pin); bool isDisableClockGatingCheck(const Pin *pin); bool isDisableClockGatingCheck(const Instance *inst); - // set_logic_zero, set_logic_one, set_logic_dc + // set_LogicValue::zero, set_LogicValue::one, set_logic_dc void setLogicValue(Pin *pin, LogicValue value); // set_case_analysis @@ -824,7 +827,7 @@ public: Pin *ref_pin); LogicValueMap *logicValues() { return &logic_value_map_; } LogicValueMap *caseLogicValues() { return &case_value_map_; } - // Returns NULL if set_operating_conditions has not been called. + // Returns nullptr if set_operating_conditions has not been called. OperatingConditions *operatingConditions(const MinMax *min_max); // Instance specific process/voltage/temperature. Pvt *pvt(Instance *inst, const MinMax *min_max) const; @@ -842,9 +845,10 @@ public: // Find the clocks defined for pin. ClockSet *findClocks(const Pin *pin) const; ClockSet *findVertexPinClocks(const Pin *pin) const; - ClockIterator *clockIterator() const; + ClockIterator *clockIterator(); void sortedClocks(ClockSeq &clks); ClockSeq *clocks() { return &clocks_; } + ClockSeq &clks() { return clocks_; } bool clkDisabledByHpinThru(const Clock *clk, const Pin *from_pin, const Pin *to_pin); @@ -909,7 +913,7 @@ public: // If the pin is hierarchical, the vertex pins are: // hierarchical input - driver pins outside the hierarchical instance. // hierarchical output - driver pins inside the hierarchical instance. - PinOutputDelayIterator *outputDelayVertexIterator(const Pin *vertex_pin)const; + PinOutputDelayIterator *outputDelayVertexIterator(const Pin *vertex_pin) const; bool hasOutputDelay(const Pin *vertex_pin) const; PortExtCap *portExtCap(Port *port) const; bool hasPortExtCap(Port *port) const; @@ -1210,7 +1214,6 @@ protected: void deleteClockLatenciesReferencing(Clock *clk); void deleteClockLatency(ClockLatency *latency); void deleteDeratingFactors(); - void deleteClkSenses(); void annotateGraphOutputDelays(bool annotate); void annotateGraphDataChecks(bool annotate); void annotateGraphConstrained(const PinSet *pins, @@ -1318,7 +1321,7 @@ protected: InstanceClockGatingCheckMap inst_clk_gating_check_map_; PinClockGatingCheckMap pin_clk_gating_check_map_; CycleAcctingSet cycle_acctings_; - ReadWriteLock cycle_acctings_lock_; + std::mutex cycle_acctings_lock_; DataChecksMap data_checks_from_map_; DataChecksMap data_checks_to_map_; InputDelayMap input_delay_map_; @@ -1386,7 +1389,7 @@ protected: // Group path exception names. GroupPathMap group_path_map_; InputDriveMap input_drive_map_; - // set_logic_one/zero/dc + // set_LogicValue::one/zero/dc LogicValueMap logic_value_map_; // set_case_analysis LogicValueMap case_value_map_; @@ -1426,30 +1429,38 @@ private: friend class InputDelayIterator; friend class OutputDelayIterator; friend class FindNetCaps; + friend class ClockGroupIterator; + friend class GroupPathIterator; + friend class InputDelayVertexPinsIterator; + friend class PinInputDelayIterator; + friend class VertexPinInputDelayIterator; + friend class PinOutputDelayIterator; + friend class VertexPinOutputDelayIterator; }; class InputDelayVertexPinsIterator : public Iterator { public: + InputDelayVertexPinsIterator(Sdc *sdc); virtual bool hasNext(); virtual const Pin *next(); private: - DISALLOW_COPY_AND_ASSIGN(InputDelayVertexPinsIterator); InputDelayVertexPinsIterator(InputDelayMap &input_delay_map); InputDelayMap::ConstIterator input_iter_; friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(InputDelayVertexPinsIterator); }; class InputDelayIterator : public Iterator { public: + InputDelayIterator(Sdc *sdc); virtual bool hasNext(); virtual InputDelay *next(); private: - DISALLOW_COPY_AND_ASSIGN(InputDelayIterator); InputDelayIterator(InputDelayMap &input_delay_map); void findNext(); @@ -1457,16 +1468,17 @@ private: InputDelay *next_; friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(InputDelayIterator); }; -class OutputDelayIterator : public Iterator +class OutputDelayIterator : public OutputDelayMap::Iterator { public: + OutputDelayIterator(Sdc *sdc); virtual bool hasNext(); virtual OutputDelay *next(); private: - DISALLOW_COPY_AND_ASSIGN(OutputDelayIterator); OutputDelayIterator(OutputDelayMap &output_delay_map); void findNext(); @@ -1474,6 +1486,42 @@ private: OutputDelay *next_; friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(OutputDelayIterator); +}; + +class ClockIterator : public ClockSeq::Iterator +{ +public: + ClockIterator(Sdc *sdc); + +private: + ClockIterator(ClockSeq &clocks); + friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(ClockIterator); +}; + +class ClockGroupIterator : public ClockGroupsNameMap::Iterator +{ +public: + ClockGroupIterator(Sdc *sdc); + +private: + ClockGroupIterator(ClockGroupsNameMap &clk_groups_name_map); + + friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(ClockGroupIterator); +}; + +class GroupPathIterator : public GroupPathMap::Iterator +{ +public: + GroupPathIterator(Sdc *sdc); + +private: + GroupPathIterator(GroupPathMap &group_path_map); + + friend class Sdc; + DISALLOW_COPY_AND_ASSIGN(GroupPathIterator); }; } // namespace diff --git a/sdc/SdcClass.hh b/sdc/SdcClass.hh index bbac89fc..bfba3b64 100644 --- a/sdc/SdcClass.hh +++ b/sdc/SdcClass.hh @@ -57,30 +57,13 @@ class ClockLatency; class ClockInsertion; class ClockGroup; class ClockGroups; -class ClockVertexPinIterator; -class ClockPinIterator; -typedef enum { - analysis_type_single, - analysis_type_bc_wc, - analysis_type_on_chip_variation -} AnalysisType; +enum class AnalysisType { single, bc_wc, ocv }; -typedef enum { - exception_type_false, - exception_type_loop, - exception_type_multi_cycle, - exception_type_path_delay, - exception_type_group_path, - exception_type_filter, - exception_type_any -} ExceptionPathType; +enum class ExceptionPathType { false_path, loop, multi_cycle, path_delay, + group_path, filter, any}; -typedef enum { - clk_sense_positive, - clk_sense_negative, - clk_sense_stop -} ClockSense; +enum class ClockSense { positive, negative, stop }; typedef std::pair ClockPair; @@ -88,7 +71,6 @@ typedef Vector FloatSeq; typedef Vector IntSeq; typedef Vector ClockSeq; typedef Set ClockSet; -typedef ClockSeq::ConstIterator ClockIterator; typedef Vector PinSetSeq; typedef MinMax SetupHold; typedef MinMaxAll SetupHoldAll; @@ -108,26 +90,15 @@ class ExceptionState; class ExceptionPath; typedef Set ExceptionStateSet; -typedef enum { - crpr_mode_same_pin, - crpr_mode_same_transition -} CrprMode; +enum class CrprMode { same_pin, same_transition }; // Constraint applies to clock or data paths. -typedef enum { - path_clk, - path_data -} PathClkOrData; +enum class PathClkOrData { clk, data }; const int path_clk_or_data_count = 2; -typedef enum { - timing_derate_cell_delay, - timing_derate_cell_check, - timing_derate_net_delay -} TimingDerateType; - -const int timing_derate_type_count = 3; +enum class TimingDerateType { cell_delay, cell_check, net_delay }; +const int timing_derate_type_count = int(TimingDerateType::net_delay) + 1 ; const int timing_derate_cell_type_count = 2; } // namespace diff --git a/sdc/SdcCmdComment.cc b/sdc/SdcCmdComment.cc index 665cd82f..b6651bbd 100644 --- a/sdc/SdcCmdComment.cc +++ b/sdc/SdcCmdComment.cc @@ -21,13 +21,13 @@ namespace sta { SdcCmdComment::SdcCmdComment() : - comment_(NULL) + comment_(nullptr) { } SdcCmdComment::SdcCmdComment(const char *comment) { - comment_ = NULL; + comment_ = nullptr; if (comment && comment[0] != '\0') comment_ = stringCopy(comment); } @@ -41,7 +41,7 @@ SdcCmdComment::setComment(const char *comment) { if (comment_) stringDelete(comment_); - comment_ = NULL; + comment_ = nullptr; if (comment && comment[0] != '\0') comment_ = stringCopy(comment); } diff --git a/sdc/WriteSdc.cc b/sdc/WriteSdc.cc index 3bc9ec72..df039e02 100644 --- a/sdc/WriteSdc.cc +++ b/sdc/WriteSdc.cc @@ -330,7 +330,7 @@ void WriteSdc::openFile(const char *filename) { stream_ = fopen(filename, "w"); - if (stream_ == NULL) + if (stream_ == nullptr) throw FileNotWritable(filename); } @@ -390,9 +390,7 @@ WriteSdc::writeClocks() const { // Write clocks in the order they were defined because generated // clocks depend on master clocks having been previously defined. - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clocks_) { if (clk->isGenerated()) writeGeneratedClock(clk); else @@ -405,7 +403,6 @@ WriteSdc::writeClocks() const fprintf(stream_, "\n"); } } - delete clk_iter; } void @@ -726,14 +723,15 @@ WriteSdc::writeInputDelays() const { // Sort arrivals by pin and clock name. PortDelaySeq delays; - InputDelayIterator *input_iter=sdc_->inputDelayIterator(); - while (input_iter->hasNext()) { - InputDelay *input_delay = input_iter->next(); + InputDelayIterator input_iter(sdc_); + while (input_iter.hasNext()) { + InputDelay *input_delay = input_iter.next(); delays.push_back(input_delay); } - delete input_iter; + PortDelayLess port_delay_less(sdc_network_); sort(delays, port_delay_less); + PortDelaySeq::Iterator delay_iter(delays); while (delay_iter.hasNext()) { PortDelay *input_delay = delay_iter.next(); @@ -746,14 +744,15 @@ WriteSdc::writeOutputDelays() const { // Sort departures by pin and clock name. PortDelaySeq delays; - OutputDelayIterator *output_iter=sdc_->outputDelayIterator(); - while (output_iter->hasNext()) { - OutputDelay *output_delay = output_iter->next(); + OutputDelayIterator output_iter(sdc_); + while (output_iter.hasNext()) { + OutputDelay *output_delay = output_iter.next(); delays.push_back(output_delay); } - delete output_iter; + PortDelayLess port_delay_less(sdc_network_); sort(delays, port_delay_less); + PortDelaySeq::Iterator delay_iter(delays); while (delay_iter.hasNext()) { PortDelay *output_delay = delay_iter.next(); @@ -862,8 +861,8 @@ class PinClockPairNameLess { public: PinClockPairNameLess(const Network *network); - bool operator()(const PinClockPair *pin_clk1, - const PinClockPair *pin_clk2) const; + bool operator()(const PinClockPair &pin_clk1, + const PinClockPair &pin_clk2) const; private: PinPathNameLess pin_less_; @@ -875,16 +874,16 @@ PinClockPairNameLess::PinClockPairNameLess(const Network *network) : } bool -PinClockPairNameLess::operator()(const PinClockPair *pin_clk1, - const PinClockPair *pin_clk2) const +PinClockPairNameLess::operator()(const PinClockPair &pin_clk1, + const PinClockPair &pin_clk2) const { - const Pin *pin1 = pin_clk1->first; - const Pin *pin2 = pin_clk2->first; - const Clock *clk1 = pin_clk1->second; - const Clock *clk2 = pin_clk2->second; + const Pin *pin1 = pin_clk1.first; + const Pin *pin2 = pin_clk2.first; + const Clock *clk1 = pin_clk1.second; + const Clock *clk2 = pin_clk2.second; return pin_less_(pin1, pin2) || (pin1 == pin2 - && ((clk1 == NULL && clk2) + && ((clk1 == nullptr && clk2) || (clk1 && clk2 && clk1->index() < clk2->index()))); } @@ -892,19 +891,14 @@ PinClockPairNameLess::operator()(const PinClockPair *pin_clk1, void WriteSdc::writeClockSenses() const { - Vector pin_clks; - ClockSenseMap::Iterator sense_iter(sdc_->clk_sense_map_); - while (sense_iter.hasNext()) { - PinClockPair *pin_clk; - ClockSense sense; - sense_iter.next(pin_clk, sense); - pin_clks.push_back(pin_clk); - } + Vector pin_clks; + for (auto iter : sdc_->clk_sense_map_) + pin_clks.push_back(iter.first); + // Sort by pin/clk pair so regressions results are stable. sort(pin_clks, PinClockPairNameLess(sdc_network_)); - Vector::Iterator pin_clk_iter(pin_clks); - while (pin_clk_iter.hasNext()) { - PinClockPair *pin_clk = pin_clk_iter.next(); + + for (auto pin_clk : pin_clks) { ClockSense sense; bool exists; sdc_->clk_sense_map_.findKey(pin_clk, sense, exists); @@ -914,24 +908,24 @@ WriteSdc::writeClockSenses() const } void -WriteSdc::writeClockSense(PinClockPair *pin_clk, +WriteSdc::writeClockSense(PinClockPair &pin_clk, ClockSense sense) const { - const char *flag = NULL; - if (sense == clk_sense_positive) + const char *flag = nullptr; + if (sense == ClockSense::positive) flag = "-positive"; - else if (sense == clk_sense_negative) + else if (sense == ClockSense::negative) flag = "-negative"; - else if (sense == clk_sense_stop) + else if (sense == ClockSense::stop) flag = "-stop_propagation"; fprintf(stream_, "set_clock_sense %s ", flag); - const Clock *clk = pin_clk->second; + const Clock *clk = pin_clk.second; if (clk) { fprintf(stream_, "-clock "); writeGetClock(clk); fprintf(stream_, " "); } - writeGetPin(pin_clk->first); + writeGetPin(pin_clk.first); fprintf(stream_, "\n"); } @@ -986,12 +980,11 @@ ClockGroupLess::operator()(const ClockGroup *clk_group1, void WriteSdc::writeClockGroups() const { - ClockGroupIterator *groups_iter = sdc_->clockGroupIterator(); - while (groups_iter->hasNext()) { - ClockGroups *clk_groups = groups_iter->next(); + ClockGroupIterator groups_iter(sdc_); + while (groups_iter.hasNext()) { + ClockGroups *clk_groups = groups_iter.next(); writeClockGroups(clk_groups); } - delete groups_iter; } void @@ -1593,7 +1586,7 @@ void WriteSdc::writeWireload() const { WireloadMode wireload_mode = sdc_->wireloadMode(); - if (wireload_mode != wire_load_mode_unknown) + if (wireload_mode != WireloadMode::unknown) fprintf(stream_, "set_wire_load_mode \"%s\"\n", wireloadModeString(wireload_mode)); } @@ -1696,12 +1689,12 @@ WriteSdc::writeDrivingCells() const && drive_rise_min->equal(drive_fall_min) && drive_rise_min->equal(drive_fall_max)) // Only write one set_driving_cell if possible. - writeDrivingCell(port, drive_rise_min, NULL, NULL); + writeDrivingCell(port, drive_rise_min, nullptr, nullptr); else { if (drive_rise_min && drive_rise_max && drive_rise_min->equal(drive_rise_max)) - writeDrivingCell(port, drive_rise_min, TransRiseFall::rise(), NULL); + writeDrivingCell(port, drive_rise_min, TransRiseFall::rise(), nullptr); else { if (drive_rise_min) writeDrivingCell(port, drive_rise_min, TransRiseFall::rise(), @@ -1713,7 +1706,7 @@ WriteSdc::writeDrivingCells() const if (drive_fall_min && drive_fall_max && drive_fall_min->equal(drive_fall_max)) - writeDrivingCell(port, drive_fall_min, TransRiseFall::fall(), NULL); + writeDrivingCell(port, drive_fall_min, TransRiseFall::fall(), nullptr); else { if (drive_fall_min) writeDrivingCell(port, drive_fall_min, TransRiseFall::fall(), @@ -1850,14 +1843,14 @@ WriteSdc::setConstantCmd(Pin *pin) const bool exists; sdc_->logicValue(pin, value, exists); switch (value) { - case logic_zero: - return "set_logic_zero"; - case logic_one: + case LogicValue::zero: + return "set_LogicValue::zero"; + case LogicValue::one: return "set_logic_one"; - case logic_unknown: + case LogicValue::unknown: return "set_logic_dc"; - case logic_rise: - case logic_fall: + case LogicValue::rise: + case LogicValue::fall: default: internalError("illegal set_logic value"); } @@ -1892,15 +1885,15 @@ WriteSdc::caseAnalysisValueStr(Pin *pin) const bool exists; sdc_->caseLogicValue(pin, value, exists); switch (value) { - case logic_zero: + case LogicValue::zero: return "0"; - case logic_one: + case LogicValue::one: return "1"; - case logic_rise: + case LogicValue::rise: return "rising"; - case logic_fall: + case LogicValue::fall: return "falling"; - case logic_unknown: + case LogicValue::unknown: default: internalError("invalid set_case_analysis value"); } @@ -1939,7 +1932,8 @@ WriteSdc::writeDeratings() const MinMaxIterator mm_iter; while (mm_iter.hasNext()) { const MinMax *early_late = mm_iter.next(); - writeDerating(factors, timing_derate_net_delay, early_late, &write_net); + writeDerating(factors, TimingDerateType::net_delay, early_late, + &write_net); } } @@ -1971,14 +1965,14 @@ WriteSdc::writeDerating(DeratingFactorsGlobal *factors) const bool delay_is_one_value, check_is_one_value, net_is_one_value; float delay_value, check_value, net_value; - factors->factors(timing_derate_cell_delay)->isOneValue(early_late, + factors->factors(TimingDerateType::cell_delay)->isOneValue(early_late, delay_is_one_value, delay_value); - factors->factors(timing_derate_net_delay)->isOneValue(early_late, - net_is_one_value, - net_value); + factors->factors(TimingDerateType::net_delay)->isOneValue(early_late, + net_is_one_value, + net_value); DeratingFactors *cell_check_factors = - factors->factors(timing_derate_cell_check); + factors->factors(TimingDerateType::cell_check); cell_check_factors->isOneValue(early_late, check_is_one_value, check_value); if (delay_is_one_value && net_is_one_value @@ -1997,7 +1991,7 @@ WriteSdc::writeDerating(DeratingFactorsGlobal *factors) const type_index++) { TimingDerateType type = static_cast(type_index); DeratingFactors *type_factors = factors->factors(type); - writeDerating(type_factors, type, early_late, NULL); + writeDerating(type_factors, type, early_late, nullptr); } } } @@ -2010,10 +2004,10 @@ WriteSdc::writeDerating(DeratingFactorsCell *factors, MinMaxIterator mm_iter; while (mm_iter.hasNext()) { const MinMax *early_late = mm_iter.next(); - DeratingFactors *delay_factors=factors->factors(timing_derate_cell_delay); - writeDerating(delay_factors, timing_derate_cell_delay, early_late, write_obj); - DeratingFactors *check_factors=factors->factors(timing_derate_cell_check); - writeDerating(check_factors, timing_derate_cell_check, early_late, write_obj); + DeratingFactors *delay_factors=factors->factors(TimingDerateType::cell_delay); + writeDerating(delay_factors, TimingDerateType::cell_delay, early_late, write_obj); + DeratingFactors *check_factors=factors->factors(TimingDerateType::cell_check); + writeDerating(check_factors, TimingDerateType::cell_check, early_late, write_obj); } } @@ -2277,13 +2271,13 @@ WriteSdc::writeClkSlewLimits() const Clock *clk = clk_iter.next(); float rise_clk_limit, fall_clk_limit, rise_data_limit, fall_data_limit; bool rise_clk_exists, fall_clk_exists, rise_data_exists, fall_data_exists; - clk->slewLimit(TransRiseFall::rise(), path_clk, min_max, + clk->slewLimit(TransRiseFall::rise(), PathClkOrData::clk, min_max, rise_clk_limit, rise_clk_exists); - clk->slewLimit(TransRiseFall::fall(), path_clk, min_max, + clk->slewLimit(TransRiseFall::fall(), PathClkOrData::clk, min_max, fall_clk_limit, fall_clk_exists); - clk->slewLimit(TransRiseFall::rise(), path_data, min_max, + clk->slewLimit(TransRiseFall::rise(), PathClkOrData::data, min_max, rise_data_limit, rise_data_exists); - clk->slewLimit(TransRiseFall::fall(), path_data, min_max, + clk->slewLimit(TransRiseFall::fall(), PathClkOrData::data, min_max, fall_data_limit, fall_data_exists); if (rise_clk_exists && fall_clk_exists && rise_data_exists && fall_data_exists @@ -2462,7 +2456,7 @@ WriteSdc::writeGetTimingArcsOfOjbects(LibertyCell *cell) const void WriteSdc::writeGetTimingArcs(Edge *edge) const { - writeGetTimingArcs(edge, NULL); + writeGetTimingArcs(edge, nullptr); } void @@ -2928,7 +2922,7 @@ transRiseFallFlag(const TransRiseFallBoth *tr) else { internalError("unknown transition"); } - return NULL; + return nullptr; } static const char * @@ -2942,7 +2936,7 @@ minMaxFlag(const MinMaxAll *min_max) return " -max"; else { internalError("unknown MinMaxAll"); - return NULL; + return nullptr; } } @@ -2955,7 +2949,7 @@ minMaxFlag(const MinMax *min_max) return " -max"; else { internalError("unknown MinMax"); - return NULL; + return nullptr; } } @@ -2968,7 +2962,7 @@ earlyLateFlag(const MinMax *early_late) return "-late"; else { internalError("unknown EarlyLate"); - return NULL; + return nullptr; } } @@ -2990,7 +2984,7 @@ setupHoldFlag(const MinMax *min_max) return " -setup"; else { internalError("unknown MinMax"); - return NULL; + return nullptr; } } diff --git a/sdc/WriteSdcPvt.hh b/sdc/WriteSdcPvt.hh index 572b9ff1..b719aa15 100644 --- a/sdc/WriteSdcPvt.hh +++ b/sdc/WriteSdcPvt.hh @@ -89,7 +89,7 @@ public: const MinMaxAll *min_max, const char *sdc_cmd) const; void writeClockSenses() const; - void writeClockSense(PinClockPair *pin_clk, + void writeClockSense(PinClockPair &pin_clk, ClockSense sense) const; void writeClockGroups() const; void writeClockGroups(ClockGroups *clk_groups) const; diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index 7f30dc31..b0fa545b 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -56,7 +56,7 @@ class SdfPortSpec public: SdfPortSpec(Transition *tr, const char *port, - const char *cond = NULL) : + const char *cond = nullptr) : tr_(tr), port_(port), cond_(cond) {} ~SdfPortSpec() { @@ -75,7 +75,7 @@ private: const char *cond_; // timing checks only }; -SdfReader *sdf_reader = NULL; +SdfReader *sdf_reader = nullptr; bool readSdfSingle(const char *filename, @@ -144,8 +144,8 @@ SdfReader::SdfReader(const char *filename, cond_use_(cond_use), line_(1), escape_('\\'), - instance_(NULL), - cell_name_(NULL), + instance_(nullptr), + cell_name_(nullptr), in_timing_check_(false), in_incremental_(false), timescale_(1.0E-9F) // default units of ns @@ -231,9 +231,9 @@ SdfReader::interconnect(const char *from_pin_name, } } else { - if (from_pin == NULL) + if (from_pin == nullptr) sdfError("pin %s not found.\n", from_pin_name); - if (to_pin == NULL) + if (to_pin == nullptr) sdfError("pin %s not found.\n", to_pin_name); } } @@ -251,7 +251,7 @@ SdfReader::port(const char *to_pin_name, Pin *to_pin = (instance_) ? network_->findPinRelative(instance_, to_pin_name) : network_->findPin(to_pin_name); - if (to_pin == NULL) + if (to_pin == nullptr) sdfError("pin %s not found.\n", to_pin_name); else { Vertex *vertex = graph_->pinLoadVertex(to_pin); @@ -282,7 +282,7 @@ SdfReader::findWireEdge(Pin *from_pin, && edge_role->sdfRole()->isWire()) return edge; } - return NULL; + return nullptr; } void @@ -325,7 +325,7 @@ SdfReader::setInstance(const char *instance_name) if (instance_name) { if (stringEq(instance_name, "*")) { notSupported("INSTANCE wildcards"); - instance_ = NULL; + instance_ = nullptr; } else { instance_ = findInstance(instance_name); @@ -342,22 +342,22 @@ SdfReader::setInstance(const char *instance_name) stringDelete(instance_name); } else - instance_ = NULL; + instance_ = nullptr; } void SdfReader::setInstanceWildcard() { notSupported("INSTANCE wildcards"); - instance_ = NULL; + instance_ = nullptr; } void SdfReader::cellFinish() { stringDelete(cell_name_); - cell_name_ = NULL; - instance_ = NULL; + cell_name_ = nullptr; + instance_ = nullptr; } void @@ -372,9 +372,9 @@ SdfReader::iopath(SdfPortSpec *from_edge, Cell *cell = network_->cell(instance_); Port *from_port = network_->findPort(cell, from_port_name); Port *to_port = network_->findPort(cell, to_port_name); - if (from_port == NULL) + if (from_port == nullptr) portNotFound(from_port_name); - if (to_port == NULL) + if (to_port == nullptr) portNotFound(to_port_name); if (from_port && to_port) { Pin *from_pin = network_->findPin(instance_, from_port_name); @@ -394,14 +394,14 @@ SdfReader::iopath(SdfPortSpec *from_edge, TimingArcSet *arc_set = edge->timingArcSet(); const char *lib_cond = arc_set->sdfCond(); const TimingRole *edge_role = arc_set->role(); - bool cond_use_flag = cond_use_ && cond && lib_cond == NULL + bool cond_use_flag = cond_use_ && cond && lib_cond == nullptr && !(!is_incremental_only_ && in_incremental_); if (edge->from(graph_)->pin() == from_pin && edge_role->sdfRole() == TimingRole::sdfIopath() && (cond_use_flag || (!condelse && condMatch(cond, lib_cond)) // condelse matches the default (unconditional) arc. - || (condelse && lib_cond == NULL))) { + || (condelse && lib_cond == nullptr))) { matched = true; TimingArcSetArcIterator arc_iter(arc_set); while (arc_iter.hasNext()) { @@ -409,7 +409,7 @@ SdfReader::iopath(SdfPortSpec *from_edge, if ((from_edge->transition() == Transition::riseFall()) || (arc->fromTrans() == from_edge->transition())) { size_t triple_index = arc->toTrans()->sdfTripleIndex(); - SdfTriple *triple = NULL; + SdfTriple *triple = nullptr; if (triple_index < triple_count) triple = (*triples)[triple_index]; if (triple_count == 1) @@ -466,9 +466,9 @@ SdfReader::timingCheck1(TimingRole *role, Cell *cell = network_->cell(instance_); Port *data_port = network_->findPort(cell, data_port_name); Port *clk_port = network_->findPort(cell, clk_port_name); - if (data_port == NULL && warn) + if (data_port == nullptr && warn) portNotFound(data_port_name); - if (clk_port == NULL && warn) + if (clk_port == nullptr && warn) portNotFound(clk_port_name); if (data_port && clk_port) { Pin *data_pin = network_->findPin(instance_, data_port_name); @@ -482,15 +482,15 @@ SdfReader::timingCheck1(TimingRole *role, float *value_max = values[triple_max_index_]; if (value_min && value_max) { switch (analysis_type_) { - case analysis_type_single: + case AnalysisType::single: break; - case analysis_type_bc_wc: + case AnalysisType::bc_wc: if (role->genericRole() == TimingRole::setup()) *value_min = *value_max; else *value_max = *value_min; break; - case analysis_type_on_chip_variation: + case AnalysisType::ocv: *value_min = *value_max; break; } @@ -576,7 +576,7 @@ SdfReader::timingCheckWidth(SdfPortSpec *edge, const char *port_name = edge->port(); Cell *cell = network_->cell(instance_); Port *port = network_->findPort(cell, port_name); - if (port == NULL) + if (port == nullptr) portNotFound(port_name); else { Pin *pin = network_->findPin(instance_, port_name); @@ -614,7 +614,7 @@ SdfReader::timingCheckPeriod(SdfPortSpec *edge, const char *port_name = edge->port(); Cell *cell = network_->cell(instance_); Port *port = network_->findPort(cell, port_name); - if (port == NULL) + if (port == nullptr) portNotFound(port_name); else { // Edge specifier is ignored for period checks. @@ -706,7 +706,7 @@ SdfReader::device(const char *to_port_name, && instance_) { Cell *cell = network_->cell(instance_); Port *to_port = network_->findPort(cell, to_port_name); - if (to_port == NULL) + if (to_port == nullptr) portNotFound(to_port_name); else { Pin *to_pin = network_->findPin(instance_, to_port_name); @@ -768,10 +768,10 @@ SdfReader::setEdgeArcDelaysCondUse(Edge *edge, SdfTriple *triple) { float **values = triple->values(); - float *value_min = NULL; + float *value_min = nullptr; if (triple_min_index_ != null_index_) value_min = values[triple_min_index_]; - float *value_max = NULL; + float *value_max = nullptr; if (triple_max_index_ != null_index_) value_max = values[triple_max_index_]; MinMax *min, *max; @@ -808,7 +808,7 @@ SdfReader::setEdgeArcDelaysCondUse(Edge *edge, delay = graph_->arcDelay(edge, arc, arc_delay_index) + *value; else if (graph_->arcDelayAnnotated(edge, arc, arc_delay_index)) { ArcDelay prev_value = graph_->arcDelay(edge, arc, arc_delay_index); - if (delayFuzzyGreater(prev_value, delay, min_max)) + if (fuzzyGreater(prev_value, delay, min_max)) delay = prev_value; } graph_->setArcDelay(edge, arc, arc_delay_index, delay); @@ -822,7 +822,7 @@ SdfReader::condMatch(const char *sdf_cond, const char *lib_cond) { // If the sdf is not conditional it matches any library condition. - if (sdf_cond == NULL) + if (sdf_cond == nullptr) return true; else if (sdf_cond && lib_cond) { // Match sdf_cond and lib_cond ignoring blanks. @@ -1000,7 +1000,7 @@ SdfReader::getChars(char *buf, { char *status = gzgets(stream_, buf, max_size); if (status == Z_NULL) - result = 0; // YY_NULL + result = 0; // YY_nullptr else result = strlen(buf); } @@ -1012,7 +1012,7 @@ SdfReader::getChars(char *buf, { char *status = gzgets(stream_, buf, max_size); if (status == Z_NULL) - result = 0; // YY_NULL + result = 0; // YY_nullptr else result = strlen(buf); } @@ -1060,7 +1060,7 @@ SdfReader::findInstance(const char *name) if (path_) stringPrint(inst_name, "%s%c%s", path_, divider_, name); Instance *inst = network_->findInstance(inst_name.c_str()); - if (inst == NULL) + if (inst == nullptr) sdfError("instance %s not found.\n", inst_name.c_str()); return inst; } diff --git a/sdf/SdfReader.hh b/sdf/SdfReader.hh index a3e667f7..f7e4ee39 100644 --- a/sdf/SdfReader.hh +++ b/sdf/SdfReader.hh @@ -40,7 +40,7 @@ class Corner; // If incremental_only is true non-incremental annoatations are ignored. // // path is a hierararchial path prefix for instances and pins in the -// sdf file. Pass 0 (NULL) to specify no path. +// sdf file. Pass 0 (nullptr) to specify no path. // // The cond_use option is used when the SDF file contains conditional // delays and the library does not have conditional delay arcs. If diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index e56f432a..75e94207 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -108,7 +108,6 @@ private: char sdf_divider_; float timescale_; - int digits_; char sdf_escape_; char network_escape_; @@ -139,7 +138,7 @@ SdfWriter::SdfWriter(StaState *sta) : StaState(sta), sdf_escape_('\\'), network_escape_(network_->pathEscape()), - delay_format_(NULL) + delay_format_(nullptr) { } @@ -158,7 +157,7 @@ SdfWriter::write(const char *filename, bool no_version) { sdf_divider_ = sdf_divider; - if (delay_format_ == NULL) + if (delay_format_ == nullptr) delay_format_ = new char[10]; sprintf(delay_format_, "%%.%df", digits); @@ -183,7 +182,7 @@ SdfWriter::write(const char *filename, writeTrailer(); gzclose(stream_); - stream_ = NULL; + stream_ = nullptr; } void @@ -213,11 +212,11 @@ SdfWriter::writeHeader(LibertyLibrary *default_lib, OperatingConditions *cond_min = sdc_->operatingConditions(MinMax::min()); - if (cond_min == NULL) + if (cond_min == nullptr) cond_min = default_lib->defaultOperatingConditions(); OperatingConditions *cond_max = sdc_->operatingConditions(MinMax::max()); - if (cond_max == NULL) + if (cond_max == nullptr) cond_max = default_lib->defaultOperatingConditions(); if (cond_min && cond_max) { gzprintf(stream_, " (VOLTAGE %.3f::%.3f)\n", @@ -231,7 +230,7 @@ SdfWriter::writeHeader(LibertyLibrary *default_lib, cond_max->temperature()); } - const char *sdf_timescale = NULL; + const char *sdf_timescale = nullptr; if (fuzzyEqual(timescale_, 1e-6)) sdf_timescale = "1us"; else if (fuzzyEqual(timescale_, 10e-6)) @@ -490,7 +489,7 @@ SdfWriter::writeTimingChecks(const Instance *inst, while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); TimingRole *role = edge->role(); - const char *sdf_check = NULL; + const char *sdf_check = nullptr; if (role == TimingRole::setup()) sdf_check = "SETUP"; else if (role == TimingRole::hold()) @@ -568,7 +567,7 @@ SdfWriter::writeCheck(Edge *edge, TimingArcSet *arc_set = edge->timingArcSet(); // Examine the arcs to see if the check requires clk or data edge specifiers. TimingArc *arcs[TransRiseFall::index_count][TransRiseFall::index_count] = - {{NULL, NULL}, {NULL, NULL}}; + {{nullptr, nullptr}, {nullptr, nullptr}}; TimingArcSetArcIterator arc_iter(arc_set); while (arc_iter.hasNext()) { TimingArc *arc = arc_iter.next(); @@ -577,11 +576,11 @@ SdfWriter::writeCheck(Edge *edge, arcs[clk_tr->index()][data_tr->index()] = arc; } - if (arcs[TransRiseFall::fallIndex()][TransRiseFall::riseIndex()] == NULL - && arcs[TransRiseFall::fallIndex()][TransRiseFall::fallIndex()] == NULL) + if (arcs[TransRiseFall::fallIndex()][TransRiseFall::riseIndex()] == nullptr + && arcs[TransRiseFall::fallIndex()][TransRiseFall::fallIndex()] == nullptr) writeEdgeCheck(edge, sdf_check, TransRiseFall::riseIndex(), arcs); - else if (arcs[TransRiseFall::riseIndex()][TransRiseFall::riseIndex()] == NULL - && arcs[TransRiseFall::riseIndex()][TransRiseFall::fallIndex()] == NULL) + else if (arcs[TransRiseFall::riseIndex()][TransRiseFall::riseIndex()] == nullptr + && arcs[TransRiseFall::riseIndex()][TransRiseFall::fallIndex()] == nullptr) writeEdgeCheck(edge, sdf_check, TransRiseFall::fallIndex(), arcs); else { // No special case; write all the checks with data and clock edge specifiers. @@ -607,13 +606,13 @@ SdfWriter::writeEdgeCheck(Edge *edge, && arcs[clk_tr_index][TransRiseFall::fallIndex()] && arcs[clk_tr_index][TransRiseFall::riseIndex()] && arcs[clk_tr_index][TransRiseFall::fallIndex()] - && delayFuzzyEqual(graph_->arcDelay(edge, + && fuzzyEqual(graph_->arcDelay(edge, arcs[clk_tr_index][TransRiseFall::riseIndex()], arc_delay_min_index_), graph_->arcDelay(edge, arcs[clk_tr_index][TransRiseFall::fallIndex()], arc_delay_min_index_)) - && delayFuzzyEqual(graph_->arcDelay(edge, + && fuzzyEqual(graph_->arcDelay(edge, arcs[clk_tr_index][TransRiseFall::riseIndex()], arc_delay_max_index_), graph_->arcDelay(edge, @@ -714,7 +713,7 @@ SdfWriter::sdfEdge(const Transition *tr) return "posedge"; else if (tr == Transition::fall()) return "negedge"; - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// diff --git a/search/Bfs.cc b/search/Bfs.cc index b0e21916..b717614c 100644 --- a/search/Bfs.cc +++ b/search/Bfs.cc @@ -18,6 +18,7 @@ #include "Machine.hh" #include "Report.hh" #include "Debug.hh" +#include "Mutex.hh" #include "ThreadForEach.hh" #include "Network.hh" #include "Graph.hh" @@ -28,66 +29,6 @@ namespace sta { -BfsList::BfsList(Vertex *vertex, - BfsList *next) : - vertex_(vertex), - next_(next) -{ -} - -void -BfsList::setVertex(Vertex *vertex) -{ - vertex_ = vertex; -} - -void -BfsList::setNext(BfsList *next) -{ - next_ = next; -} - -class BfsListIterator -{ -public: - explicit BfsListIterator(BfsList *list, - BfsIterator *bfs, - BfsIndex bfs_index); - bool hasNext() { return next_ != NULL; } - Vertex *next(); - int count() const { return count_; } - -private: - BfsIterator *bfs_; - BfsIndex bfs_index_; - BfsList *next_; - int count_; -}; - -BfsListIterator::BfsListIterator(BfsList *list, - BfsIterator *bfs, - BfsIndex bfs_index) : - bfs_(bfs), - bfs_index_(bfs_index), - next_(list), - count_(0) -{ -} - -Vertex * -BfsListIterator::next() -{ - Vertex *vertex = next_->vertex(); - BfsList *next = next_->next(); - bfs_->freeList(next_); - next_ = next; - vertex->setBfsInQueue(bfs_index_, false); - count_++; - return vertex; -} - -//////////////////////////////////////////////////////////////// - BfsIterator::BfsIterator(BfsIndex bfs_index, Level level_min, Level level_max, @@ -97,9 +38,9 @@ BfsIterator::BfsIterator(BfsIndex bfs_index, bfs_index_(bfs_index), level_min_(level_min), level_max_(level_max), - search_pred_(search_pred), - list_free_(NULL) + search_pred_(search_pred) { + init(); } void @@ -122,12 +63,6 @@ BfsIterator::ensureSize() BfsIterator::~BfsIterator() { - // Delete free list. - while (list_free_) { - BfsList *next = list_free_->next(); - delete list_free_; - list_free_ = next; - } } void @@ -135,16 +70,12 @@ BfsIterator::clear() { Level level = first_level_; while (levelLessOrEqual(level, last_level_)) { - BfsList *level_vertices = queue_[level]; - if (level_vertices) { - for (BfsList *l = level_vertices, *next; l; l = next) { - Vertex *vertex = l->vertex(); + VertexSeq &level_vertices = queue_[level]; + for (auto vertex : level_vertices) { + if (vertex) vertex->setBfsInQueue(bfs_index_, false); - next = l->next(); - freeList(l); - } - queue_[level] = NULL; } + level_vertices.clear(); incrLevel(level); } init(); @@ -155,13 +86,12 @@ BfsIterator::reportEntries(const Network *network) { Level level = first_level_; while (levelLessOrEqual(level, last_level_)) { - BfsList *level_vertices = queue_[level]; - if (level_vertices) { + VertexSeq &level_vertices = queue_[level]; + if (!level_vertices.empty()) { printf("Level %d\n", level); - for (BfsList *l = level_vertices, *next; l; l = next) { - Vertex *vertex = l->vertex(); - printf(" %s\n", vertex->name(network)); - next = l->next(); + for (auto vertex : level_vertices) { + if (vertex) + printf(" %s\n", vertex->name(network)); } } incrLevel(level); @@ -171,15 +101,12 @@ BfsIterator::reportEntries(const Network *network) void BfsIterator::deleteEntries(Level level) { - BfsList *level_vertices = queue_[level]; - if (level_vertices) { - for (BfsList *l = level_vertices, *next; l; l = next) { - Vertex *vertex = l->vertex(); + VertexSeq &level_vertices = queue_[level]; + for (auto vertex : level_vertices) { + if (vertex) vertex->setBfsInQueue(bfs_index_, false); - next = l->next(); - delete l; - } } + level_vertices.clear(); } bool @@ -215,26 +142,67 @@ BfsIterator::visit(Level to_level, int visit_count = 0; while (levelLessOrEqual(first_level_, last_level_) && levelLessOrEqual(first_level_, to_level)) { - BfsList *level_vertices = queue_[first_level_]; - if (level_vertices) { - // Remove vertices from queue. - queue_[first_level_] = NULL; - incrLevel(first_level_); - for (BfsList *l = level_vertices, *next; l; l = next) { - Vertex *vertex = l->vertex(); - vertex->setBfsInQueue(bfs_index_, false); - visitor->visit(vertex); - next = l->next(); - freeList(l); - visit_count++; + VertexSeq &level_vertices = queue_[first_level_]; + incrLevel(first_level_); + if (!level_vertices.empty()) { + for (auto vertex : level_vertices) { + if (vertex) { + vertex->setBfsInQueue(bfs_index_, false); + visitor->visit(vertex); + visit_count++; + } } + level_vertices.clear(); } - else - incrLevel(first_level_); } return visit_count; } +// VertexSeq::Iterator that filters null objects, +// and pops objects so the vector does not need to be cleared. +class QueueIterator : Iterator +{ +public: + QueueIterator(VertexSeq &vertices, + BfsIndex bfs_index); + virtual bool hasNext(); + virtual Vertex *next(); + unsigned count() { return count_; } + +private: + VertexSeq &vertices_; + BfsIndex bfs_index_; + unsigned count_; +}; + +QueueIterator::QueueIterator(VertexSeq &vertices, + BfsIndex bfs_index) : + vertices_(vertices), + bfs_index_(bfs_index), + count_(0) +{ +} + +bool +QueueIterator::hasNext() +{ + Vertex *next = nullptr; + while (!vertices_.empty() + && (next = vertices_.back()) == nullptr) + vertices_.pop_back(); + return next != nullptr; +} + +Vertex * +QueueIterator::next() +{ + Vertex *next = vertices_.back(); + next->setBfsInQueue(bfs_index_, false); + vertices_.pop_back(); + count_++; + return next; +} + int BfsIterator::visitParallel(Level to_level, VertexVisitor *visitor) @@ -244,37 +212,27 @@ BfsIterator::visitParallel(Level to_level, if (thread_count_ <= 1) visit_count = visit(to_level, visitor); else { - ForEachArg args[thread_count_]; - Thread threads[thread_count_]; - Mutex lock; - for (int i = 0; i < thread_count_; i++) { - ForEachArg &arg = args[i]; - arg.lock_ = &lock; - arg.func_ = visitor->copy(); - } - + std::mutex lock; Level level = first_level_; while (levelLessOrEqual(level, last_level_) && levelLessOrEqual(level, to_level)) { - BfsList *level_vertices = queue_[level]; - if (level_vertices) { - // Remove level vertices from queue. - queue_[level] = NULL; + VertexSeq &level_vertices = queue_[level]; + if (!level_vertices.empty()) { incrLevel(first_level_); - BfsListIterator iter(level_vertices, this, bfs_index_); + QueueIterator iter(level_vertices, bfs_index_); + std::vector threads; for (int i = 0; i < thread_count_; i++) { - ForEachArg &arg = args[i]; - // Initialize the iterator for this level's vertices. - arg.iter_ = &iter; - threads[i].beginTask(forEachBegin, - reinterpret_cast(&arg)); + ForEachArg arg(&iter, lock, + visitor->copy()); + // Missing check for null vertex. + threads.push_back(std::thread(forEachBegin, arg)); } // Wait for all threads working on this level before moving on. - for (int i = 0; i < thread_count_; i++) - threads[i].wait(); + for (auto &thread : threads) + thread.join(); visit_count += iter.count(); level = first_level_; @@ -284,11 +242,6 @@ BfsIterator::visitParallel(Level to_level, level = first_level_; } } - - for (int i = 0; i < thread_count_; i++) { - ForEachArg *arg = &args[i]; - delete arg->func_; - } } } return visit_count; @@ -305,17 +258,16 @@ BfsIterator::hasNext(Level to_level) { findNext(to_level); return levelLessOrEqual(first_level_, last_level_) - && queue_[first_level_] != NULL; + && !queue_[first_level_].empty(); } Vertex * BfsIterator::next() { - BfsList *head = queue_[first_level_]; - Vertex *vertex = head->vertex(); + VertexSeq &level_vertices = queue_[first_level_]; + Vertex *vertex = level_vertices.back(); + level_vertices.pop_back(); vertex->setBfsInQueue(bfs_index_, false); - queue_[first_level_] = head->next(); - freeList(head); return vertex; } @@ -324,7 +276,7 @@ BfsIterator::findNext(Level to_level) { while (levelLessOrEqual(first_level_, last_level_) && levelLessOrEqual(first_level_, to_level) - && queue_[first_level_] == NULL) + && queue_[first_level_].empty()) incrLevel(first_level_); } @@ -332,19 +284,18 @@ void BfsIterator::enqueue(Vertex *vertex) { debugPrint1(debug_, "bfs", 2, "enqueue %s\n", vertex->name(sdc_network_)); - Level level = vertex->level(); if (!vertex->bfsInQueue(bfs_index_)) { - queue_lock_.lock(); + Level level = vertex->level(); + UniqueLock lock(queue_lock_); if (!vertex->bfsInQueue(bfs_index_)) { vertex->setBfsInQueue(bfs_index_, true); - queue_[level] = makeList(vertex, queue_[level]); + queue_[level].push_back(vertex); if (levelLess(last_level_, level)) last_level_ = level; if (levelLess(level, first_level_)) first_level_ = level; } - queue_lock_.unlock(); } } @@ -360,8 +311,8 @@ BfsIterator::checkInQueue(Vertex *vertex) { Level level = vertex->level(); if (static_cast(queue_.size()) > level) { - for (BfsList *l = queue_[level]; l; l = l->next()) { - if (l->vertex() == vertex) { + for (auto v : queue_[level]) { + if (v == vertex) { if (vertex->bfsInQueue(bfs_index_)) return; else @@ -379,6 +330,7 @@ BfsIterator::deleteVertexBefore(Vertex *vertex) remove(vertex); } +// Remove by inserting null vertex pointer. void BfsIterator::remove(Vertex *vertex) { @@ -386,63 +338,16 @@ BfsIterator::remove(Vertex *vertex) Level level = vertex->level(); if (vertex->bfsInQueue(bfs_index_) && static_cast(queue_.size()) > level) { - BfsList *next, *prev = NULL; - for (BfsList *l = queue_[level]; l; l = next) { - next = l->next(); - if (l->vertex() == vertex) { - if (prev) - prev->setNext(next); - else - queue_[level] = next; + for (auto &v : queue_[level]) { + if (v == vertex) { + v = nullptr; vertex->setBfsInQueue(bfs_index_, false); - freeList(l); break; } - prev = l; } } } -BfsList * -BfsIterator::makeList(Vertex *vertex, - BfsList *next) -{ - BfsList *l; - list_lock_.lock(); - if (list_free_) { - l = list_free_; - list_free_ = l->next(); - list_lock_.unlock(); - l->setVertex(vertex); - l->setNext(next); - } - else { - list_lock_.unlock(); - l = new BfsList(vertex, next); - } - return l; -} - -void -BfsIterator::freeList(BfsList *l) -{ - list_lock_.lock(); - l->setNext(list_free_); - list_free_ = l; - list_lock_.unlock(); -} - -void -BfsIterator::deleteList(BfsList *list) -{ - while (list) { - BfsList *next = list->next(); - list->vertex()->setBfsInQueue(bfs_index_, false); - delete list; - list = next; - } -} - //////////////////////////////////////////////////////////////// BfsFwdIterator::BfsFwdIterator(BfsIndex bfs_index, @@ -450,7 +355,6 @@ BfsFwdIterator::BfsFwdIterator(BfsIndex bfs_index, StaState *sta) : BfsIterator(bfs_index, 0, INT_MAX, search_pred, sta) { - init(); } // clear() without saving lists to list_free_. @@ -505,7 +409,6 @@ BfsBkwdIterator::BfsBkwdIterator(BfsIndex bfs_index, StaState *sta) : BfsIterator(bfs_index, INT_MAX, 0, search_pred, sta) { - init(); } // clear() without saving lists to list_free_. diff --git a/search/Bfs.hh b/search/Bfs.hh index 7052ab02..3556cac9 100644 --- a/search/Bfs.hh +++ b/search/Bfs.hh @@ -17,10 +17,10 @@ #ifndef STA_BFS_H #define STA_BFS_H +#include #include "DisallowCopyAssign.hh" #include "Iterator.hh" #include "Set.hh" -#include "Mutex.hh" #include "StaState.hh" #include "GraphClass.hh" #include "VertexVisitor.hh" @@ -30,11 +30,9 @@ namespace sta { class SearchPred; class BfsFwdIterator; class BfsBkwdIterator; -class BfsList; -class BfsListIterator; -// LevelQueue is a vector of vertex lists indexed by logic level. -typedef Vector LevelQueue; +// LevelQueue is a vector of vertex vectors indexed by logic level. +typedef Vector LevelQueue; // Abstract base class for forward and backward breadth first search iterators. // Visit all of the vertices at a level before moving to the next. @@ -100,10 +98,6 @@ protected: Level level2) const = 0; virtual void incrLevel(Level &level) = 0; void findNext(Level to_level); - BfsList *makeList(Vertex *vertex, - BfsList *next); - void freeList(BfsList *l); - void deleteList(BfsList *list); void deleteEntries(); BfsIndex bfs_index_; @@ -111,17 +105,14 @@ protected: Level level_max_; SearchPred *search_pred_; LevelQueue queue_; - Mutex queue_lock_; + std::mutex queue_lock_; // Min (max) level of queued vertices. Level first_level_; // Max (min) level of queued vertices. Level last_level_; - BfsList *list_free_; - Mutex list_lock_; friend class BfsFwdIterator; friend class BfsBkwdIterator; - friend class BfsListIterator; private: DISALLOW_COPY_AND_ASSIGN(BfsIterator); @@ -173,21 +164,5 @@ private: DISALLOW_COPY_AND_ASSIGN(BfsBkwdIterator); }; -// Single linked list (STL list is doubly linked). -class BfsList -{ -public: - BfsList(Vertex *vertex, - BfsList *next); - Vertex *vertex() const { return vertex_; } - void setVertex(Vertex *vertex); - BfsList *next() const { return next_; } - void setNext(BfsList *next); - -protected: - Vertex *vertex_; - BfsList *next_; -}; - } // namespace #endif diff --git a/search/CheckMaxSkews.cc b/search/CheckMaxSkews.cc index 39bd6852..dcd47490 100644 --- a/search/CheckMaxSkews.cc +++ b/search/CheckMaxSkews.cc @@ -107,7 +107,7 @@ void MaxSkewViolatorsVisititor::visit(MaxSkewCheck &check, const StaState *sta) { - if (delayFuzzyLess(check.slack(sta), 0.0)) + if (fuzzyLess(check.slack(sta), 0.0)) checks_.push_back(check.copy()); } @@ -137,7 +137,7 @@ private: MaxSkewSlackVisitor::MaxSkewSlackVisitor() : MaxSkewCheckVisitor(), - min_slack_check_(NULL) + min_slack_check_(nullptr) { } @@ -146,7 +146,7 @@ MaxSkewSlackVisitor::visit(MaxSkewCheck &check, const StaState *sta) { MaxSkewSlackLess slack_less(sta); - if (min_slack_check_ == NULL) + if (min_slack_check_ == nullptr) min_slack_check_ = check.copy(); else if (slack_less(&check, min_slack_check_)) { delete min_slack_check_; @@ -288,7 +288,7 @@ MaxSkewSlackLess::operator()(const MaxSkewCheck *check1, Slack slack1 = check1->slack(sta_); Slack slack2 = check2->slack(sta_); return slack1 < slack2 - || (delayFuzzyEqual(slack1, slack2) + || (fuzzyEqual(slack1, slack2) // Break ties based on constrained pin names. && sta_->network()->pinLess(check1->clkPin(sta_),check2->clkPin(sta_))); } diff --git a/search/CheckMinPeriods.cc b/search/CheckMinPeriods.cc index edad1438..5533771b 100644 --- a/search/CheckMinPeriods.cc +++ b/search/CheckMinPeriods.cc @@ -21,7 +21,6 @@ #include "Clock.hh" #include "Sdc.hh" #include "Graph.hh" -#include "Corner.hh" #include "DcalcAnalysisPt.hh" #include "GraphDelayCalc.hh" #include "Search.hh" @@ -61,21 +60,17 @@ CheckMinPeriods::clear() class MinPeriodViolatorsVisitor : public MinPeriodCheckVisitor { public: - MinPeriodViolatorsVisitor(const Corner *corner, - MinPeriodCheckSeq &checks); + MinPeriodViolatorsVisitor(MinPeriodCheckSeq &checks); virtual void visit(MinPeriodCheck &check, StaState *sta); private: DISALLOW_COPY_AND_ASSIGN(MinPeriodViolatorsVisitor); - const Corner *corner_; MinPeriodCheckSeq &checks_; }; -MinPeriodViolatorsVisitor::MinPeriodViolatorsVisitor(const Corner *corner, - MinPeriodCheckSeq &checks): - corner_(corner), +MinPeriodViolatorsVisitor::MinPeriodViolatorsVisitor(MinPeriodCheckSeq &checks): checks_(checks) { } @@ -84,15 +79,15 @@ void MinPeriodViolatorsVisitor::visit(MinPeriodCheck &check, StaState *sta) { - if (delayFuzzyLess(check.slack(sta), 0.0)) + if (fuzzyLess(check.slack(sta), 0.0)) checks_.push_back(check.copy()); } MinPeriodCheckSeq & -CheckMinPeriods::violations(const Corner *corner) +CheckMinPeriods::violations() { clear(); - MinPeriodViolatorsVisitor visitor(corner, checks_); + MinPeriodViolatorsVisitor visitor(checks_); visitMinPeriodChecks(&visitor); sort(checks_, MinPeriodSlackLess(sta_)); return checks_; @@ -137,7 +132,7 @@ CheckMinPeriods::visitMinPeriodChecks(Vertex *vertex, class MinPeriodSlackVisitor : public MinPeriodCheckVisitor { public: - MinPeriodSlackVisitor(const Corner *corner); + MinPeriodSlackVisitor(); virtual void visit(MinPeriodCheck &check, StaState *sta); MinPeriodCheck *minSlackCheck(); @@ -145,13 +140,11 @@ public: private: DISALLOW_COPY_AND_ASSIGN(MinPeriodSlackVisitor); - const Corner *corner_; MinPeriodCheck *min_slack_check_; }; -MinPeriodSlackVisitor::MinPeriodSlackVisitor(const Corner *corner) : - corner_(corner), - min_slack_check_(NULL) +MinPeriodSlackVisitor::MinPeriodSlackVisitor() : + min_slack_check_(nullptr) { } @@ -160,7 +153,7 @@ MinPeriodSlackVisitor::visit(MinPeriodCheck &check, StaState *sta) { MinPeriodSlackLess slack_less(sta); - if (min_slack_check_ == NULL) + if (min_slack_check_ == nullptr) min_slack_check_ = check.copy(); else if (slack_less(&check, min_slack_check_)) { delete min_slack_check_; @@ -175,10 +168,10 @@ MinPeriodSlackVisitor::minSlackCheck() } MinPeriodCheck * -CheckMinPeriods::minSlackCheck(const Corner *corner) +CheckMinPeriods::minSlackCheck() { clear(); - MinPeriodSlackVisitor visitor(corner); + MinPeriodSlackVisitor visitor; visitMinPeriodChecks(&visitor); MinPeriodCheck *check = visitor.minSlackCheck(); // Save check for cleanup. @@ -238,9 +231,9 @@ MinPeriodSlackLess::operator()(const MinPeriodCheck *check1, Slack slack2 = check2->slack(sta_); const Pin *pin1 = check1->pin(); const Pin *pin2 = check2->pin(); - return delayFuzzyLess(slack1, slack2) + return fuzzyLess(slack1, slack2) // Break ties based on pin and clock names. - || (delayFuzzyEqual(slack1, slack2) + || (fuzzyEqual(slack1, slack2) && (sta_->network()->pinLess(pin1, pin2) || (pin1 == pin2 && ClockNameLess()(check1->clk(), diff --git a/search/CheckMinPeriods.hh b/search/CheckMinPeriods.hh index 8a1f683f..a1e296d0 100644 --- a/search/CheckMinPeriods.hh +++ b/search/CheckMinPeriods.hh @@ -35,12 +35,9 @@ public: explicit CheckMinPeriods(StaState *sta); ~CheckMinPeriods(); void clear(); - // All violating min period checks. - // corner=NULL checks all corners. - MinPeriodCheckSeq &violations(const Corner *corner); + MinPeriodCheckSeq &violations(); // Min period check with the least slack. - // corner=NULL checks all corners. - MinPeriodCheck *minSlackCheck(const Corner *corner); + MinPeriodCheck *minSlackCheck(); protected: void visitMinPeriodChecks(MinPeriodCheckVisitor *visitor); diff --git a/search/CheckMinPulseWidths.cc b/search/CheckMinPulseWidths.cc index 0f7a0354..df00ef43 100644 --- a/search/CheckMinPulseWidths.cc +++ b/search/CheckMinPulseWidths.cc @@ -103,7 +103,7 @@ void MinPulseWidthChecksVisitor::visit(MinPulseWidthCheck &check, const StaState *sta) { - if (corner_ == NULL + if (corner_ == nullptr || check.corner(sta) == corner_) { MinPulseWidthCheck *copy = new MinPulseWidthCheck(check.openPath()); checks_.push_back(copy); @@ -166,8 +166,8 @@ void MinPulseWidthViolatorsVisitor::visit(MinPulseWidthCheck &check, const StaState *sta) { - if (delayFuzzyLess(check.slack(sta), 0.0) - && (corner_ == NULL + if (fuzzyLess(check.slack(sta), 0.0) + && (corner_ == nullptr || check.corner(sta) == corner_)) { MinPulseWidthCheck *copy = new MinPulseWidthCheck(check.openPath()); checks_.push_back(copy); @@ -203,7 +203,7 @@ private: MinPulseWidthSlackVisitor::MinPulseWidthSlackVisitor(const Corner *corner) : corner_(corner), - min_slack_check_(NULL) + min_slack_check_(nullptr) { } @@ -212,9 +212,9 @@ MinPulseWidthSlackVisitor::visit(MinPulseWidthCheck &check, const StaState *sta) { MinPulseWidthSlackLess slack_less(sta); - if (corner_ == NULL + if (corner_ == nullptr || check.corner(sta) == corner_) { - if (min_slack_check_ == NULL) + if (min_slack_check_ == nullptr) min_slack_check_ = check.copy(); else if (slack_less(&check, min_slack_check_)) { delete min_slack_check_; @@ -334,7 +334,7 @@ MinPulseWidthCheck::closePath(const StaState *sta, open_clk_info->genClkSrc(), open_clk_info->isGenClkSrcPath(), open_clk_info->pulseClkSense(), - delay_zero, 0.0, NULL, + delay_zero, 0.0, nullptr, open_clk_info->pathAPIndex(), open_clk_info->crprClkPath(), sta); @@ -499,7 +499,7 @@ MinPulseWidthSlackLess::operator()(const MinPulseWidthCheck *check1, const Pin *pin1 = check1->pin(sta_); const Pin *pin2 = check2->pin(sta_); return slack1 < slack2 - || (delayFuzzyEqual(slack1, slack2) + || (fuzzyEqual(slack1, slack2) // Break ties for the sake of regression stability. && (sta_->network()->pinLess(pin1, pin2) || (pin1 == pin2 diff --git a/search/CheckMinPulseWidths.hh b/search/CheckMinPulseWidths.hh index 04a00254..dcae4af4 100644 --- a/search/CheckMinPulseWidths.hh +++ b/search/CheckMinPulseWidths.hh @@ -36,17 +36,17 @@ public: ~CheckMinPulseWidths(); void clear(); // Min pulse width checks for pins. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheckSeq &check(PinSeq *pins, const Corner *corner); // All min pulse width checks. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheckSeq &check(const Corner *corner); // All violating min pulse width checks. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheckSeq &violations(const Corner *corner); // Min pulse width check with the least slack. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheck *minSlackCheck(const Corner *corner); protected: diff --git a/search/CheckSlewLimits.cc b/search/CheckSlewLimits.cc index 6613e136..6ae97e25 100644 --- a/search/CheckSlewLimits.cc +++ b/search/CheckSlewLimits.cc @@ -107,8 +107,8 @@ CheckSlewLimits::checkSlews(const Pin *pin, float &limit, float &slack) const { - corner1 = NULL; - tr = NULL; + corner1 = nullptr; + tr = nullptr; slew = 0.0; limit = 0.0; slack = MinMax::min()->initValue(); @@ -189,7 +189,7 @@ CheckSlewLimits::findLimit(const Pin *pin, ClockSet::Iterator clk_iter(clks); while (clk_iter.hasNext()) { Clock *clk = clk_iter.next(); - PathClkOrData clk_data = is_clk ? path_clk : path_data; + PathClkOrData clk_data = is_clk ? PathClkOrData::clk : PathClkOrData::data; float clk_limit; bool clk_limit_exists; sdc->slewLimit(clk, tr, clk_data, min_max, @@ -281,7 +281,7 @@ CheckSlewLimits::checkSlew(Vertex *vertex, float slew2 = delayAsFloat(slew1); float slack1 = (min_max == MinMax::max()) ? limit1 - slew2 : slew2 - limit1; - if (corner == NULL + if (corner == nullptr || (slack1 < slack // Break ties for the sake of regression stability. || (fuzzyEqual(slack1, slack) diff --git a/search/CheckSlewLimits.hh b/search/CheckSlewLimits.hh index df9c2ce5..3bb4b2a0 100644 --- a/search/CheckSlewLimits.hh +++ b/search/CheckSlewLimits.hh @@ -34,21 +34,21 @@ public: CheckSlewLimits(const StaState *sta); void init(const MinMax *min_max); // Requires init(). - // corner=NULL checks all corners. + // corner=nullptr checks all corners. void checkSlews(const Pin *pin, const Corner *corner, const MinMax *min_max, // Return values. - // Corner is NULL for no slew limit. + // Corner is nullptr for no slew limit. const Corner *&corner1, const TransRiseFall *&tr, Slew &slew, float &limit, float &slack) const; - // corner=NULL checks all corners. + // corner=nullptr checks all corners. PinSeq *pinSlewLimitViolations(const Corner *corner, const MinMax *min_max); - // corner=NULL checks all corners. + // corner=nullptr checks all corners. Pin *pinMinSlewLimitSlack(const Corner *corner, const MinMax *min_max); diff --git a/search/CheckTiming.cc b/search/CheckTiming.cc index 927c4474..8bf8a8b1 100644 --- a/search/CheckTiming.cc +++ b/search/CheckTiming.cc @@ -196,7 +196,7 @@ CheckTiming::checkLoops() GraphLoop *loop = loop_iter2.next(); if (loop->isCombinational()) { EdgeSeq::Iterator edge_iter(loop->edges()); - Edge *last_edge = NULL; + Edge *last_edge = nullptr; while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); Pin *pin = edge->from(graph_)->pin(); @@ -247,15 +247,12 @@ CheckTiming::checkUnconstraintedOutputs(PinSet &unconstrained_ends) bool CheckTiming::hasClkedDepature(Pin *pin) { - PinOutputDelayIterator *delay_iter = sdc_->outputDelayIterator(pin); - while (delay_iter->hasNext()) { - OutputDelay *output_delay = delay_iter->next(); - if (output_delay->clkEdge() != NULL) { - delete delay_iter; + PinOutputDelayIterator delay_iter(pin, sdc_); + while (delay_iter.hasNext()) { + OutputDelay *output_delay = delay_iter.next(); + if (output_delay->clkEdge() != nullptr) return true; - } } - delete delay_iter; return false; } @@ -313,9 +310,7 @@ void CheckTiming::checkGeneratedClocks() { ClockSet gen_clk_errors; - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { if (clk->isGenerated()) { search_->genclks()->checkMaster(clk); bool found_clk = false; @@ -333,7 +328,6 @@ CheckTiming::checkGeneratedClocks() gen_clk_errors.insert(clk); } } - delete clk_iter; pushClkErrors("Warning: There %is %d generated clock%s that %is not connected to a clock source.", gen_clk_errors); } diff --git a/search/ClkInfo.cc b/search/ClkInfo.cc index a6b7ba81..1990fbb4 100644 --- a/search/ClkInfo.cc +++ b/search/ClkInfo.cc @@ -56,7 +56,7 @@ ClkInfo::ClkInfo(ClockEdge *clk_edge, latency_(latency), is_propagated_(is_propagated), is_gen_clk_src_path_(is_gen_clk_src_path), - is_pulse_clk_(pulse_clk_sense != NULL), + is_pulse_clk_(pulse_clk_sense != nullptr), pulse_clk_sense_(pulse_clk_sense ? pulse_clk_sense->index() : 0), path_ap_index_(path_ap_index) { @@ -149,7 +149,7 @@ ClkInfo::clock() const if (clk_edge_) return clk_edge_->clock(); else - return NULL; + return nullptr; } TransRiseFall * @@ -158,7 +158,7 @@ ClkInfo::pulseClkSense() const if (is_pulse_clk_) return TransRiseFall::find(pulse_clk_sense_); else - return NULL; + return nullptr; } const Pin * @@ -167,7 +167,7 @@ ClkInfo::crprClkPin(const StaState *sta) const if (!crpr_clk_path_.isNull()) return crpr_clk_path_.vertex(sta)->pin(); else - return NULL; + return nullptr; } bool @@ -214,8 +214,8 @@ clkInfoEqual(const ClkInfo *clk_info1, && (!crpr_on || (PathVertexRep::equal(clk_info1->crprClkPath(), clk_info2->crprClkPath()))) - && ((uncertainties1 == NULL - && uncertainties2 == NULL) + && ((uncertainties1 == nullptr + && uncertainties2 == nullptr) || (uncertainties1 && uncertainties2 && MinMaxValues::equal(uncertainties1, uncertainties2))) diff --git a/search/ClkInfo.hh b/search/ClkInfo.hh index 82162b87..a90d9f51 100644 --- a/search/ClkInfo.hh +++ b/search/ClkInfo.hh @@ -63,7 +63,7 @@ public: const Pin *crprClkPin(const StaState *sta) const; // Much faster than crprClkPin. VertexIndex crprClkVertexIndex() const; - // Much faster than crprClkPin != NULL + // Much faster than crprClkPin != nullptr bool hasCrprClkPin() const { return !crpr_clk_path_.isNull(); } bool refsFilter(const StaState *sta) const; // This clk_info/tag is used for a generated clock source path. diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index 50c56359..d6a268f0 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.cc @@ -262,7 +262,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, && src_path->minMax(this) == setup_hold && clks->hasKey(src_clk)) { Corner *src_corner = src_path->pathAnalysisPt(this)->corner(); - if (corner == NULL + if (corner == nullptr || src_corner == corner) { VertexPathIterator tgt_iter(tgt_vertex, this); while (tgt_iter.hasNext()) { @@ -283,7 +283,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, time_unit->asString(probe.tgtLatency(this)), delayAsString(probe.crpr(this), this), time_unit->asString(probe.skew())); - if (clk_skew == NULL) { + if (clk_skew == nullptr) { clk_skew = new ClkSkew(probe); skews[src_clk] = clk_skew; } @@ -326,7 +326,7 @@ ClkSkews::findFanout(Vertex *from, debugPrint1(debug_, "fanout", 1, "%s\n", from->name(sdc_network_)); FanOutSrchPred pred(this); - BfsFwdIterator fanout_iter(bfs_other, &pred, this); + BfsFwdIterator fanout_iter(BfsIndex::other, &pred, this); fanout_iter.enqueue(from); while (fanout_iter.hasNext()) { Vertex *fanout = fanout_iter.next(); diff --git a/search/Corner.cc b/search/Corner.cc index 12ce8416..1ecf5306 100644 --- a/search/Corner.cc +++ b/search/Corner.cc @@ -25,7 +25,7 @@ namespace sta { Corners::Corners(StaState *sta) : StaState(sta), - default_corner_(NULL) + default_corner_(nullptr) { } @@ -41,7 +41,7 @@ Corners::clear() corners_.deleteContentsClear(); dcalc_analysis_pts_.deleteContentsClear(); path_analysis_pts_.deleteContentsClear(); - default_corner_ = NULL; + default_corner_ = nullptr; } int @@ -95,10 +95,10 @@ Corners::makeCorners(StringSet *corner_names) StringSet::Iterator name_iter(corner_names); while (name_iter.hasNext()) { const char *name = name_iter.next(); - Corner *corner = new Corner(name, index, this); + Corner *corner = new Corner(name, index); // Use the copied name in the map. corners_[corner->name()] = corner; - if (default_corner_ == NULL) + if (default_corner_ == nullptr) default_corner_ = corner; index++; } @@ -173,19 +173,18 @@ Corners::makeDcalcAnalysisPts(Corner *corner) { DcalcAnalysisPt *min_ap, *max_ap; switch (sdc_->analysisType()) { - case analysis_type_single: - + case AnalysisType::single: corner->setDcalcAnalysisPtcount(1); makeDcalcAnalysisPt(corner, MinMax::max(), MinMax::min()); break; - case analysis_type_bc_wc: + case AnalysisType::bc_wc: corner->setDcalcAnalysisPtcount(2); min_ap = makeDcalcAnalysisPt(corner, MinMax::min(), MinMax::min()); max_ap = makeDcalcAnalysisPt(corner, MinMax::max(), MinMax::max()); min_ap->setCheckClkSlewIndex(min_ap->index()); max_ap->setCheckClkSlewIndex(max_ap->index()); break; - case analysis_type_on_chip_variation: + case AnalysisType::ocv: corner->setDcalcAnalysisPtcount(2); min_ap = makeDcalcAnalysisPt(corner, MinMax::min(), MinMax::max()); max_ap = makeDcalcAnalysisPt(corner, MinMax::max(), MinMax::min()); @@ -240,11 +239,11 @@ Corners::makePathAnalysisPts(Corner *corner) DcalcAnalysisPt *dcalc_ap_min = corner->findDcalcAnalysisPt(MinMax::min()); DcalcAnalysisPt *dcalc_ap_max = corner->findDcalcAnalysisPt(MinMax::max()); switch (sdc_->analysisType()) { - case analysis_type_single: - case analysis_type_bc_wc: + case AnalysisType::single: + case AnalysisType::bc_wc: makePathAnalysisPts(corner, false, dcalc_ap_min, dcalc_ap_max); break; - case analysis_type_on_chip_variation: + case AnalysisType::ocv: makePathAnalysisPts(corner, true, dcalc_ap_min, dcalc_ap_max); break; } @@ -341,11 +340,9 @@ Corners::findPathAnalysisPt(PathAPIndex path_index) const //////////////////////////////////////////////////////////////// Corner::Corner(const char *name, - int index, - Corners *corners) : + int index) : name_(stringCopy(name)), index_(index), - corners_(corners), path_analysis_pts_(MinMax::index_count) { } @@ -360,14 +357,14 @@ Corner::findParasiticAnalysisPt(const MinMax *min_max) const { int ap_count = parasitic_analysis_pts_.size(); if (ap_count == 0) - return NULL; + return nullptr; else if (ap_count == 1) return parasitic_analysis_pts_[0]; else if (ap_count == 2) return parasitic_analysis_pts_[min_max->index()]; else { internalError("unknown parasitic analysis point count"); - return NULL; + return nullptr; } } @@ -406,14 +403,14 @@ Corner::findDcalcAnalysisPt(const MinMax *min_max) const { int ap_count = dcalc_analysis_pts_.size(); if (ap_count == 0) - return NULL; + return nullptr; else if (ap_count == 1) return dcalc_analysis_pts_[0]; else if (ap_count == 2) return dcalc_analysis_pts_[min_max->index()]; else { internalError("unknown analysis point count"); - return NULL; + return nullptr; } } diff --git a/search/Corner.hh b/search/Corner.hh index 0b04ab68..b1607cb4 100644 --- a/search/Corner.hh +++ b/search/Corner.hh @@ -97,8 +97,7 @@ class Corner { public: Corner(const char *name, - int index, - Corners *corners); + int index); ~Corner(); const char *name() const { return name_; } int index() const { return index_; } @@ -120,7 +119,6 @@ protected: private: const char *name_; int index_; - Corners *corners_; ParasiticAnalysisPtSeq parasitic_analysis_pts_; DcalcAnalysisPtSeq dcalc_analysis_pts_; PathAnalysisPtSeq path_analysis_pts_; diff --git a/search/Crpr.cc b/search/Crpr.cc index 6e869be5..e3d9e378 100644 --- a/search/Crpr.cc +++ b/search/Crpr.cc @@ -66,7 +66,7 @@ CheckCrpr::clkPathPrev(Vertex *vertex, if (prevs) { PathVertexRep *prev = &prevs[arrival_index]; if (prev->isNull()) - return NULL; + return nullptr; else { tmp.init(graph_->vertex(prev->vertexIndex()), search_->tag(prev->tagIndex()), this); @@ -90,8 +90,10 @@ CheckCrpr::maxCrpr(ClkInfo *clk_info) if (!crpr_clk_vpath.isNull()) { Arrival other_arrival = otherMinMaxArrival(&crpr_clk_vpath); float crpr_diff = abs(delayAsFloat(crpr_clk_vpath.arrival(this), - EarlyLate::late()) - - delayAsFloat(other_arrival, EarlyLate::early())); + EarlyLate::late(), + sigma_factor_) + - delayAsFloat(other_arrival, EarlyLate::early(), + sigma_factor_)); return crpr_diff; } } @@ -134,10 +136,10 @@ CheckCrpr::checkCrpr(const Path *src_path, Pin *&crpr_pin) { crpr = 0.0; - crpr_pin = NULL; + crpr_pin = nullptr; if (sdc_->crprActive() && src_path && tgt_clk_path) { - bool same_pin = (sdc_->crprMode() == crpr_mode_same_pin); + bool same_pin = (sdc_->crprMode() == CrprMode::same_pin); checkCrpr1(src_path, tgt_clk_path, same_pin, crpr, crpr_pin); } } @@ -151,14 +153,14 @@ CheckCrpr::checkCrpr1(const Path *src_path, Pin *&crpr_pin) { crpr = 0.0; - crpr_pin = NULL; + crpr_pin = nullptr; ClkInfo *src_clk_info = src_path->tag(this)->clkInfo(); ClkInfo *tgt_clk_info = tgt_clk_path->tag(this)->clkInfo(); Clock *src_clk = src_clk_info->clock(); Clock *tgt_clk = tgt_clk_info->clock(); const PathVertex src_clk_path1(src_clk_info->crprClkPath(), this); const PathVertex *src_clk_path = - src_clk_path1.isNull() ? NULL : &src_clk_path1; + src_clk_path1.isNull() ? nullptr : &src_clk_path1; const MinMax *src_clk_min_max = src_clk_path ? src_clk_path->minMax(this) : src_path->minMax(this); if (crprPossible(src_clk, tgt_clk) @@ -166,11 +168,11 @@ CheckCrpr::checkCrpr1(const Path *src_path, // For path from latches that are borrowing the enable path // is from the opposite min/max of the data. && src_clk_min_max != tgt_clk_path->minMax(this) - && (src_clk_path != NULL + && (src_clk_path != nullptr || src_clk->isGenerated())) { // Src path from input port clk path can only be from generated clk path. PathVertex port_clk_path; - if (src_clk_path == NULL) { + if (src_clk_path == nullptr) { portClkPath(src_clk_info->clkEdge(), src_clk_info->clkSrc(), src_path->pathAnalysisPt(this), @@ -211,7 +213,7 @@ CheckCrpr::findCrpr(const PathVertex *src_clk_path, Pin *&crpr_pin) { crpr = 0.0; - crpr_pin = NULL; + crpr_pin = nullptr; const PathVertex *src_clk_path1 = src_clk_path; const PathVertex *tgt_clk_path1 = tgt_clk_path; PathVertexSeq src_gclk_paths, tgt_gclk_paths; @@ -332,11 +334,11 @@ CheckCrpr::outputDelayCrpr(const Path *src_path, Pin *&crpr_pin) { crpr = 0.0; - crpr_pin = NULL; + crpr_pin = nullptr; if (sdc_->crprActive()) { const PathAnalysisPt *path_ap = src_path->pathAnalysisPt(this); const PathAnalysisPt *tgt_path_ap = path_ap->tgtClkAnalysisPt(); - bool same_pin = (sdc_->crprMode() == crpr_mode_same_pin); + bool same_pin = (sdc_->crprMode() == CrprMode::same_pin); outputDelayCrpr1(src_path,tgt_clk_edge,tgt_path_ap, same_pin, crpr, crpr_pin); } @@ -352,7 +354,7 @@ CheckCrpr::outputDelayCrpr1(const Path *src_path, Pin *&crpr_pin) { crpr = 0.0; - crpr_pin = NULL; + crpr_pin = nullptr; Clock *tgt_clk = tgt_clk_edge->clock(); Clock *src_clk = src_path->clock(this); if (tgt_clk->isGenerated() @@ -386,8 +388,10 @@ float CheckCrpr::crprArrivalDiff(const PathVertex *path) { Arrival other_arrival = otherMinMaxArrival(path); - float crpr_diff = abs(delayAsFloat(path->arrival(this), EarlyLate::late()) - - delayAsFloat(other_arrival, EarlyLate::early())); + float crpr_diff = abs(delayAsFloat(path->arrival(this), EarlyLate::late(), + sigma_factor_) + - delayAsFloat(other_arrival, EarlyLate::early(), + sigma_factor_)); return crpr_diff; } diff --git a/search/Crpr.hh b/search/Crpr.hh index 6324ab60..ac626ba6 100644 --- a/search/Crpr.hh +++ b/search/Crpr.hh @@ -18,7 +18,6 @@ #define STA_CRPR_H #include "DisallowCopyAssign.hh" -#include "Mutex.hh" #include "SdcClass.hh" #include "SearchClass.hh" diff --git a/search/FindRegister.cc b/search/FindRegister.cc index 78dbf1dd..cf73b83a 100644 --- a/search/FindRegister.cc +++ b/search/FindRegister.cc @@ -149,14 +149,14 @@ FindRegVisitor::visitRegs(ClockSet *clks, Pin *pin = pin_iter.next(); Vertex *vertex, *bidirect_drvr_vertex; graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); - visitFanoutRegs(vertex, timing_sense_positive_unate, + visitFanoutRegs(vertex, TimingSense::positive_unate, clk_tr, edge_triggered, latches, clk_pred, visited_vertices); // Clocks defined on bidirect pins blow it out both ends. if (bidirect_drvr_vertex) visitFanoutRegs(bidirect_drvr_vertex, - timing_sense_positive_unate, + TimingSense::positive_unate, clk_tr, edge_triggered, latches, clk_pred, visited_vertices); @@ -167,7 +167,7 @@ FindRegVisitor::visitRegs(ClockSet *clks, VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices()); while (reg_clk_iter.hasNext()) { Vertex *vertex = reg_clk_iter.next(); - visitRegs(vertex->pin(), timing_sense_positive_unate, + visitRegs(vertex->pin(), TimingSense::positive_unate, TransRiseFallBoth::riseFall(), edge_triggered, latches); } @@ -259,9 +259,9 @@ FindRegVisitor::findSequential(const Pin *clk_pin, LibertyPort *port = network_->libertyPort(clk_pin); TimingSense port_sense = clk_func->portTimingSense(port); TimingSense path_sense = pathSenseThru(clk_sense, port_sense); - if ((path_sense == timing_sense_positive_unate + if ((path_sense == TimingSense::positive_unate && clk_tr == TransRiseFallBoth::rise()) - || (path_sense == timing_sense_negative_unate + || (path_sense == TimingSense::negative_unate && clk_tr == TransRiseFallBoth::fall())) { visitSequential(inst, seq); matches = true; @@ -289,9 +289,9 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell, TransRiseFall *arc_clk_tr = arc->fromTrans()->asRiseFall(); bool tr_matches = (clk_tr == TransRiseFallBoth::riseFall() || (arc_clk_tr == clk_tr1 - && clk_sense == timing_sense_positive_unate) + && clk_sense == TimingSense::positive_unate) || (arc_clk_tr == clk_tr1->opposite() - && clk_sense == timing_sense_negative_unate)); + && clk_sense == TimingSense::negative_unate)); TimingRole *role = set->role(); if (tr_matches && ((role == TimingRole::regClkToQ() @@ -340,7 +340,7 @@ private: FindRegInstances::FindRegInstances(StaState *sta) : FindRegVisitor(sta), - regs_(NULL) + regs_(nullptr) { } @@ -407,7 +407,7 @@ protected: FindRegPins::FindRegPins(StaState *sta) : FindRegVisitor(sta), - pins_(NULL) + pins_(nullptr) { } @@ -490,7 +490,7 @@ FindRegDataPins::seqExpr1(Sequential *seq) FuncExpr * FindRegDataPins::seqExpr2(Sequential *) { - return NULL; + return nullptr; } bool @@ -553,7 +553,7 @@ FindRegClkPins::matchPin(Pin *pin) { LibertyPort *port = network_->libertyPort(pin); LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, port, NULL); + LibertyCellTimingArcSetIterator set_iter(cell, port, nullptr); while (set_iter.hasNext()) { TimingArcSet *set = set_iter.next(); TimingRole *role = set->role(); @@ -573,7 +573,7 @@ FindRegClkPins::seqExpr1(Sequential *seq) FuncExpr * FindRegClkPins::seqExpr2(Sequential *) { - return NULL; + return nullptr; } PinSet * @@ -611,7 +611,7 @@ FindRegAsyncPins::matchPin(Pin *pin) { LibertyPort *port = network_->libertyPort(pin); LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, port, NULL); + LibertyCellTimingArcSetIterator set_iter(cell, port, nullptr); while (set_iter.hasNext()) { TimingArcSet *set = set_iter.next(); TimingRole *role = set->role(); @@ -661,7 +661,7 @@ FindRegOutputPins::matchPin(Pin *pin) { LibertyPort *port = network_->libertyPort(pin); LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, NULL, port); + LibertyCellTimingArcSetIterator set_iter(cell, nullptr, port); while (set_iter.hasNext()) { TimingArcSet *set = set_iter.next(); TimingRole *role = set->role(); @@ -706,13 +706,13 @@ FindRegOutputPins::visitOutput(LibertyPort *port, FuncExpr * FindRegOutputPins::seqExpr1(Sequential *) { - return NULL; + return nullptr; } FuncExpr * FindRegOutputPins::seqExpr2(Sequential *) { - return NULL; + return nullptr; } PinSet * @@ -730,70 +730,77 @@ findRegOutputPins(ClockSet *clks, static TimingSense path_sense_thru[timing_sense_count][timing_sense_count]; +static void +initPathSenseThru1(TimingSense from, + TimingSense thru, + TimingSense to) +{ + path_sense_thru[int(from)][int(thru)] = to; +} + void initPathSenseThru() { - path_sense_thru[timing_sense_positive_unate][timing_sense_positive_unate] = - timing_sense_positive_unate; - path_sense_thru[timing_sense_positive_unate][timing_sense_negative_unate] = - timing_sense_negative_unate; - path_sense_thru[timing_sense_positive_unate][timing_sense_non_unate] = - timing_sense_non_unate; - path_sense_thru[timing_sense_positive_unate][timing_sense_none] = - timing_sense_none; - path_sense_thru[timing_sense_positive_unate][timing_sense_unknown] = - timing_sense_unknown; + initPathSenseThru1(TimingSense::positive_unate, TimingSense::positive_unate, + TimingSense::positive_unate); + initPathSenseThru1(TimingSense::positive_unate, TimingSense::negative_unate, + TimingSense::negative_unate); + initPathSenseThru1(TimingSense::positive_unate, TimingSense::non_unate, + TimingSense::non_unate); + initPathSenseThru1(TimingSense::positive_unate, TimingSense::none, + TimingSense::none); + initPathSenseThru1(TimingSense::positive_unate, TimingSense::unknown, + TimingSense::unknown); + initPathSenseThru1(TimingSense::negative_unate, TimingSense::positive_unate, + TimingSense::negative_unate); + initPathSenseThru1(TimingSense::negative_unate, TimingSense::negative_unate, + TimingSense::positive_unate); + initPathSenseThru1(TimingSense::negative_unate, TimingSense::non_unate, + TimingSense::non_unate); + initPathSenseThru1(TimingSense::negative_unate, TimingSense::none, + TimingSense::none); + initPathSenseThru1(TimingSense::negative_unate, TimingSense::unknown, + TimingSense::unknown); - path_sense_thru[timing_sense_negative_unate][timing_sense_positive_unate] = - timing_sense_negative_unate; - path_sense_thru[timing_sense_negative_unate][timing_sense_negative_unate] = - timing_sense_positive_unate; - path_sense_thru[timing_sense_negative_unate][timing_sense_non_unate] = - timing_sense_non_unate; - path_sense_thru[timing_sense_negative_unate][timing_sense_none] = - timing_sense_none; - path_sense_thru[timing_sense_negative_unate][timing_sense_unknown] = - timing_sense_unknown; + initPathSenseThru1(TimingSense::non_unate, TimingSense::positive_unate, + TimingSense::non_unate); + initPathSenseThru1(TimingSense::non_unate, TimingSense::negative_unate, + TimingSense::non_unate); + initPathSenseThru1(TimingSense::non_unate, TimingSense::non_unate, + TimingSense::non_unate); + initPathSenseThru1(TimingSense::non_unate, TimingSense::none, + TimingSense::none); + initPathSenseThru1(TimingSense::non_unate, TimingSense::unknown, + TimingSense::unknown); - path_sense_thru[timing_sense_non_unate][timing_sense_positive_unate] = - timing_sense_non_unate; - path_sense_thru[timing_sense_non_unate][timing_sense_negative_unate] = - timing_sense_non_unate; - path_sense_thru[timing_sense_non_unate][timing_sense_non_unate] = - timing_sense_non_unate; - path_sense_thru[timing_sense_non_unate][timing_sense_none] = - timing_sense_none; - path_sense_thru[timing_sense_non_unate][timing_sense_unknown] = - timing_sense_unknown; + initPathSenseThru1(TimingSense::none, TimingSense::positive_unate, + TimingSense::none); + initPathSenseThru1(TimingSense::none, TimingSense::negative_unate, + TimingSense::none); + initPathSenseThru1(TimingSense::none, TimingSense::non_unate, + TimingSense::none); + initPathSenseThru1(TimingSense::none, TimingSense::none, + TimingSense::none); + initPathSenseThru1(TimingSense::none, TimingSense::unknown, + TimingSense::unknown); - path_sense_thru[timing_sense_none][timing_sense_positive_unate] = - timing_sense_none; - path_sense_thru[timing_sense_none][timing_sense_negative_unate] = - timing_sense_none; - path_sense_thru[timing_sense_none][timing_sense_non_unate] = - timing_sense_none; - path_sense_thru[timing_sense_none][timing_sense_none] = - timing_sense_none; - path_sense_thru[timing_sense_none][timing_sense_unknown] = - timing_sense_unknown; - - path_sense_thru[timing_sense_unknown][timing_sense_positive_unate] = - timing_sense_unknown; - path_sense_thru[timing_sense_unknown][timing_sense_negative_unate] = - timing_sense_unknown; - path_sense_thru[timing_sense_unknown][timing_sense_non_unate] = - timing_sense_unknown; - path_sense_thru[timing_sense_unknown][timing_sense_none] = - timing_sense_unknown; - path_sense_thru[timing_sense_unknown][timing_sense_unknown] = - timing_sense_unknown; + initPathSenseThru1(TimingSense::unknown, TimingSense::positive_unate, + TimingSense::unknown); + initPathSenseThru1(TimingSense::unknown, TimingSense::negative_unate, + TimingSense::unknown); + initPathSenseThru1(TimingSense::unknown, TimingSense::non_unate, + TimingSense::unknown); + initPathSenseThru1(TimingSense::unknown, TimingSense::none, + TimingSense::unknown); + initPathSenseThru1(TimingSense::unknown, TimingSense::unknown, + TimingSense::unknown); } static TimingSense pathSenseThru(TimingSense from_sense, TimingSense thru_sense) { - return path_sense_thru[from_sense][thru_sense]; + return path_sense_thru[int(from_sense)][int(thru_sense)]; } } // namespace diff --git a/search/GatedClk.cc b/search/GatedClk.cc index 564da07a..3fe2d917 100644 --- a/search/GatedClk.cc +++ b/search/GatedClk.cc @@ -58,8 +58,8 @@ GatedClk::isGatedClkEnable(Vertex *enable_vertex, && !sdc_->isDisableClockGatingCheck(enable_pin) && !sdc_->isDisableClockGatingCheck(inst) && eval_pred->searchFrom(enable_vertex)) { - FuncExpr *func = NULL; - Vertex *gclk_vertex = NULL; + FuncExpr *func = nullptr; + Vertex *gclk_vertex = nullptr; VertexOutEdgeIterator edge_iter(enable_vertex, graph_); while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); @@ -114,8 +114,8 @@ GatedClk::gatedClkEnables(Vertex *clk_vertex, && !sdc_->isDisableClockGatingCheck(clk_pin) && !sdc_->isDisableClockGatingCheck(inst) && eval_pred->searchFrom(clk_vertex)) { - FuncExpr *func = NULL; - Vertex *gclk_vertex = NULL; + FuncExpr *func = nullptr; + Vertex *gclk_vertex = nullptr; VertexOutEdgeIterator edge_iter(clk_vertex, graph_); while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); @@ -169,9 +169,9 @@ GatedClk::isClkGatingFunc(FuncExpr *func, while (func->op() == FuncExpr::op_not) func = func->left(); if (func->op() == FuncExpr::op_and) - logic_value = logic_one; + logic_value = LogicValue::one; else if (func->op() == FuncExpr::op_or) - logic_value = logic_zero; + logic_value = LogicValue::zero; else { is_clk_gate = false; return; @@ -189,7 +189,7 @@ GatedClk::isClkGatingFunc(FuncExpr *func, if (expr->left()->op() == FuncExpr::op_port && expr->left()->port() == clk_port) { need_gating_check = true; - logic_value = (logic_value == logic_one) ? logic_zero : logic_one; + logic_value = (logic_value == LogicValue::one) ? LogicValue::zero : LogicValue::one; } } else { @@ -236,11 +236,11 @@ GatedClk::gatedClkActiveTrans(LogicValue active_value, { TransRiseFall *leading_tr; switch (active_value) { - case logic_one: - case logic_unknown: + case LogicValue::one: + case LogicValue::unknown: leading_tr = TransRiseFall::rise(); break; - case logic_zero: + case LogicValue::zero: leading_tr = TransRiseFall::fall(); break; default: diff --git a/search/Genclks.cc b/search/Genclks.cc index dc08864d..31971da1 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -74,10 +74,10 @@ GenclkInfo::GenclkInfo(Clock *gclk, gclk_(gclk), gclk_level_(gclk_level), fanins_(fanins), - fdbk_edges_(NULL), + fdbk_edges_(nullptr), found_latch_fdbk_edges_(false), src_filter_(src_filter), - pll_filter_(NULL) + pll_filter_(nullptr) { } @@ -198,15 +198,12 @@ Genclks::ensureInsertionDelays() debugPrint0(debug_, "genclk", 1, "find generated clk insertion delays\n"); ClockSeq gclks; - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { if (clk->isGenerated()) { checkMaster(clk); gclks.push_back(clk); } } - delete clk_iter; clearSrcPaths(); @@ -288,7 +285,7 @@ void Genclks::checkMaster(Clock *gclk) { ensureMaster(gclk); - if (gclk->masterClk() == NULL) + if (gclk->masterClk() == nullptr) report_->warn("no master clock found for generated clock %s.\n", gclk->name()); } @@ -297,13 +294,13 @@ void Genclks::ensureMaster(Clock *gclk) { Clock *master_clk = gclk->masterClk(); - if (master_clk == NULL) { + if (master_clk == nullptr) { int master_clk_count = 0; bool found_master = false; if (gclk->pllOut()) { // Search backward from generated clock source pin to a clock pin. GenClkMasterSearchPred pred(this); - BfsBkwdIterator iter(bfs_other, &pred, this); + BfsBkwdIterator iter(BfsIndex::other, &pred, this); seedSrcPins(gclk, iter); while (iter.hasNext()) { Vertex *vertex = iter.next(); @@ -355,7 +352,7 @@ Genclks::ensureMaster(Clock *gclk) if (!found_master) { // Search backward from generated clock source pin to a clock pin. GenClkMasterSearchPred pred(this); - BfsBkwdIterator iter(bfs_other, &pred, this); + BfsBkwdIterator iter(BfsIndex::other, &pred, this); seedSrcPins(gclk, iter); while (iter.hasNext()) { Vertex *vertex = iter.next(); @@ -459,7 +456,7 @@ Genclks::findFanin(Clock *gclk, { // Search backward from generated clock source pin to a clock pin. GenClkFaninSrchPred srch_pred(gclk, this); - BfsBkwdIterator iter(bfs_other, &srch_pred, this); + BfsBkwdIterator iter(BfsIndex::other, &srch_pred, this); seedClkVertices(gclk, iter, fanins); while (iter.hasNext()) { Vertex *vertex = iter.next(); @@ -576,8 +573,8 @@ Genclks::findInsertionDelays(Clock *gclk) gclk->name()); GenclkInfo *genclk_info = makeGenclkInfo(gclk); FilterPath *src_filter = genclk_info->srcFilter(); - GenClkInsertionSearchPred srch_pred(gclk, NULL, genclk_info, this); - BfsFwdIterator insert_iter(bfs_other, &srch_pred, this); + GenClkInsertionSearchPred srch_pred(gclk, nullptr, genclk_info, this); + BfsFwdIterator insert_iter(BfsIndex::other, &srch_pred, this); seedSrcPins(gclk, src_filter, insert_iter); // Propagate arrivals to generated clk root pin level. findSrcArrivals(gclk, insert_iter, genclk_info); @@ -613,7 +610,7 @@ Genclks::srcFilter(Clock *gclk) if (genclk_info) return genclk_info->srcFilter(); else - return NULL; + return nullptr; } EdgeSet * @@ -645,7 +642,7 @@ Genclks::findLatchFdbkEdges(const Clock *gclk, GenclkInfo *genclk_info) { Level gclk_level = genclk_info->gclkLevel(); - EdgeSet *fdbk_edges = NULL; + EdgeSet *fdbk_edges = nullptr; ClockVertexPinIterator pin_iter(gclk->masterClk()); while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); @@ -679,7 +676,7 @@ Genclks::findLatchFdbkEdges(Vertex *from_vertex, debugPrint2(debug_, "genclk", 2, " found feedback edge %s -> %s\n", from_vertex->name(sdc_network_), to_vertex->name(sdc_network_)); - if (fdbk_edges == NULL) + if (fdbk_edges == nullptr) fdbk_edges = new EdgeSet; fdbk_edges->insert(edge); } @@ -699,17 +696,17 @@ Genclks::makeSrcFilter(Clock *gclk) ClockSet *from_clks = new ClockSet; from_clks->insert(gclk->masterClk()); const TransRiseFallBoth *rf = TransRiseFallBoth::riseFall(); - ExceptionFrom *from = sdc_->makeExceptionFrom(NULL,from_clks,NULL,rf); + ExceptionFrom *from = sdc_->makeExceptionFrom(nullptr,from_clks,nullptr,rf); PinSet *thru_pins = new PinSet; thru_pins->insert(gclk->srcPin()); - ExceptionThru *thru = sdc_->makeExceptionThru(thru_pins,NULL,NULL,rf); + ExceptionThru *thru = sdc_->makeExceptionThru(thru_pins,nullptr,nullptr,rf); ExceptionThruSeq *thrus = new ExceptionThruSeq; thrus->push_back(thru); ClockSet *to_clks = new ClockSet; to_clks->insert(gclk); - ExceptionTo *to = sdc_->makeExceptionTo(NULL, to_clks, NULL, rf, rf); + ExceptionTo *to = sdc_->makeExceptionTo(nullptr, to_clks, nullptr, rf, rf); return sdc_->makeFilterPath(from, thrus, to); } @@ -741,7 +738,7 @@ Genclks::seedSrcPins(Clock *gclk, path_ap); Arrival insert = search_->clockInsertion(master_clk, master_pin, tr, min_max, early_late, path_ap); - tag_bldr.setArrival(tag, insert, NULL); + tag_bldr.setArrival(tag, insert, nullptr); } } search_->setVertexArrivals(vertex, &tag_bldr); @@ -765,10 +762,10 @@ Genclks::makeTag(const Clock *gclk, ExceptionStateSet *states = new ExceptionStateSet; states->insert(state); ClkInfo *clk_info = search_->findClkInfo(master_clk->edge(master_tr), - master_pin, true, NULL, true, - NULL, 0.0, 0.0, NULL, - path_ap, NULL); - return search_->findTag(master_tr, path_ap, clk_info, false, NULL, false, + master_pin, true, nullptr, true, + nullptr, 0.0, 0.0, nullptr, + path_ap, nullptr); + return search_->findTag(master_tr, path_ap, clk_info, false, nullptr, false, states, true); } @@ -924,7 +921,7 @@ Genclks::copyGenClkSrcPaths(Vertex *vertex, Arrival arrival = arrivals[arrival_index]; PathVertexRep *prev_path = prev_paths ? &prev_paths[arrival_index] - : NULL; + : nullptr; tag_bldr->setArrival(tag, arrival, prev_path); } } @@ -955,7 +952,7 @@ Genclks::recordSrcPaths(Clock *gclk) bool divide_by_1 = gclk->isDivideByOneCombinational(); bool invert = gclk->invert(); - bool has_edges = gclk->edges() != NULL; + bool has_edges = gclk->edges() != nullptr; ClockVertexPinIterator gclk_pin_iter(gclk); while (gclk_pin_iter.hasNext()) { @@ -983,7 +980,7 @@ Genclks::recordSrcPaths(Clock *gclk) && (!has_edges || src_clk_tr == gclk->masterClkEdgeTr(tr)) && (src_path.isNull() - || delayFuzzyGreater(path->arrival(this), + || fuzzyGreater(path->arrival(this), src_path.arrival(this), early_late))) { debugPrint4(debug_, "genclk", 2, " %s insertion %s %s %s\n", @@ -1020,7 +1017,7 @@ Genclks::matchesSrcFilter(Path *path, ExceptionState *state = state_iter.next(); ExceptionPath *except = state->exception(); if (except->isFilter() - && state->nextThru() == NULL + && state->nextThru() == nullptr && except->to() && except->to()->matches(gclk)) return true; @@ -1131,7 +1128,7 @@ Genclks::findPllDelays(Clock *gclk) GenclkInfo *genclk_info = genclkInfo(gclk); genclk_info->setPllFilter(pll_filter); ClkTreeSearchPred srch_pred(this); - BfsFwdIterator pll_iter(bfs_other, &srch_pred, this); + BfsFwdIterator pll_iter(BfsIndex::other, &srch_pred, this); seedPllPin(gclk, pll_filter, pll_iter); // Propagate arrivals to pll feedback pin level. findPllArrivals(gclk, pll_iter); @@ -1144,13 +1141,13 @@ Genclks::makePllFilter(const Clock *gclk) PinSet *from_pins = new PinSet; from_pins->insert(gclk->pllOut()); TransRiseFallBoth *rf = TransRiseFallBoth::riseFall(); - ExceptionFrom *from = sdc_->makeExceptionFrom(from_pins,NULL,NULL,rf); + ExceptionFrom *from = sdc_->makeExceptionFrom(from_pins,nullptr,nullptr,rf); PinSet *to_pins = new PinSet; to_pins->insert(gclk->pllFdbk()); - ExceptionTo *to = sdc_->makeExceptionTo(to_pins, NULL, NULL, rf, rf); + ExceptionTo *to = sdc_->makeExceptionTo(to_pins, nullptr, nullptr, rf, rf); - return sdc_->makeFilterPath(from, NULL, to); + return sdc_->makeFilterPath(from, nullptr, to); } void @@ -1172,7 +1169,7 @@ Genclks::seedPllPin(const Clock *gclk, while (tr_iter.hasNext()) { TransRiseFall *tr = tr_iter.next(); Tag *tag = makeTag(gclk, gclk, pll_out_pin, tr, pll_filter, path_ap); - tag_bldr.setArrival(tag, 0.0, NULL); + tag_bldr.setArrival(tag, 0.0, nullptr); } } search_->setVertexArrivals(vertex, &tag_bldr); diff --git a/search/Latches.cc b/search/Latches.cc index 944e9795..16714061 100644 --- a/search/Latches.cc +++ b/search/Latches.cc @@ -207,7 +207,7 @@ Latches::latchRequired(const Path *data_path, Vertex *data_vertex = data_path->vertex(this); const TransRiseFall *data_tr = data_path->transition(this); ArcDelay setup = latchSetupMargin(data_vertex,data_tr,disable_path,path_ap); - ExceptionPath *excpt = search_->exceptionTo(exception_type_any, + ExceptionPath *excpt = search_->exceptionTo(ExceptionPathType::any, data_path, data_vertex->pin(), data_tr, enable_path->clkEdge(this), @@ -262,7 +262,7 @@ Latches::latchEnablePath(Path *q_path, TransRiseFall *en_tr; LatchEnableState state; latchDtoQEnable(d_q_edge, latch, en_vertex, en_tr, state); - if (state == latch_state_enabled) { + if (state == LatchEnableState::enabled) { VertexPathIterator path_iter(en_vertex, en_tr, tgt_clk_path_ap, this); while (path_iter.hasNext()) { PathVertex *path = path_iter.next(); @@ -298,11 +298,11 @@ Latches::latchOutArrival(Path *data_path, latchDtoQEnable(d_q_edge, inst, enable_vertex, enable_tr, state); // Latch enable may be missing if library is malformed. switch (state) { - case latch_state_closed: + case LatchEnableState::closed: // Latch is disabled by constant enable. break; - case latch_state_open: { - ExceptionPath *excpt = exceptionTo(data_path, NULL); + case LatchEnableState::open: { + ExceptionPath *excpt = exceptionTo(data_path, nullptr); if (!(excpt && excpt->isFalse())) { arc_delay = search_->deratedDelay(data_vertex, d_q_arc, d_q_edge, false, path_ap); @@ -311,7 +311,7 @@ Latches::latchOutArrival(Path *data_path, } } break; - case latch_state_enabled: { + case LatchEnableState::enabled: { const PathAnalysisPt *tgt_clk_path_ap = path_ap->tgtClkAnalysisPt(); VertexPathIterator enable_iter(enable_vertex, enable_tr, tgt_clk_path_ap, this); @@ -340,7 +340,7 @@ Latches::latchOutArrival(Path *data_path, // Tag switcheroo - data passing thru gets latch enable tag. // States and path ap come from Q, everything else from enable. PathVertex *crpr_clk_path = - sdc_->crprActive() ? enable_path : NULL; + sdc_->crprActive() ? enable_path : nullptr; ClkInfo *q_clk_info = search_->findClkInfo(en_clk_edge, en_clk_info->clkSrc(), @@ -354,11 +354,11 @@ Latches::latchOutArrival(Path *data_path, path_ap, crpr_clk_path); TransRiseFall *q_tr = d_q_arc->toTrans()->asRiseFall(); - ExceptionStateSet *states = NULL; + ExceptionStateSet *states = nullptr; // Latch data pin is a valid exception -from pin. if (sdc_->exceptionFromStates(data_path->pin(this), data_path->transition(this), - NULL, NULL, // clk below + nullptr, nullptr, // clk below MinMax::max(), states) // -from enable non-filter exceptions apply. && sdc_->exceptionFromStates(enable_vertex->pin(), @@ -367,7 +367,7 @@ Latches::latchOutArrival(Path *data_path, en_clk_edge->transition(), MinMax::max(), false, states)) q_tag = search_->findTag(q_tr, path_ap, q_clk_info, false, - NULL, false, states, true); + nullptr, false, states, true); } return; } @@ -384,7 +384,7 @@ Latches::exceptionTo(Path *data_path, ClockEdge *en_clk_edge) { // Look for exceptions -to data or -to enable clk. - return search_->exceptionTo(exception_type_any, + return search_->exceptionTo(ExceptionPathType::any, data_path, data_path->pin(this), data_path->transition(this), @@ -461,8 +461,8 @@ Latches::latchDtoQEnable(Edge *d_q_edge, TransRiseFall *&enable_tr, LatchEnableState &state) const { - enable_vertex = NULL; - state = latch_state_open; + enable_vertex = nullptr; + state = LatchEnableState::open; LibertyCell *cell = network_->libertyCell(inst); if (cell) { TimingArcSet *d_q_set = d_q_edge->timingArcSet(); @@ -474,7 +474,7 @@ Latches::latchDtoQEnable(Edge *d_q_edge, if (enable_pin) { enable_vertex = graph_->pinLoadVertex(enable_pin); if (enable_vertex->isDisabledConstraint()) - state = latch_state_open; + state = LatchEnableState::open; else { // See if constant values in the latch enable expression force // it to be continuously open or closed. @@ -482,16 +482,16 @@ Latches::latchDtoQEnable(Edge *d_q_edge, ? sim_->evalExpr(enable_func, inst) : sim_->logicValue(enable_pin); switch (enable_value) { - case logic_zero: - case logic_fall: - state = latch_state_closed; + case LogicValue::zero: + case LogicValue::fall: + state = LatchEnableState::closed; break; - case logic_one: - case logic_rise: - state = latch_state_open; + case LogicValue::one: + case LogicValue::rise: + state = LatchEnableState::open; break; - case logic_unknown: - state = latch_state_enabled; + case LogicValue::unknown: + state = LatchEnableState::enabled; break; } } @@ -519,7 +519,7 @@ bool Latches::isLatchDtoQ(Edge *edge) const { return edge->role() == TimingRole::latchDtoQ() - && latchDtoQState(edge) == latch_state_enabled; + && latchDtoQState(edge) == LatchEnableState::enabled; } } // namespace diff --git a/search/Latches.hh b/search/Latches.hh index 9784a5cb..0d204477 100644 --- a/search/Latches.hh +++ b/search/Latches.hh @@ -22,11 +22,7 @@ namespace sta { #include "GraphClass.hh" #include "SearchClass.hh" -typedef enum { - latch_state_enabled, - latch_state_open, - latch_state_closed -} LatchEnableState; +enum class LatchEnableState { enabled, open, closed }; // Latches class defines latch behavior. class Latches : public StaState diff --git a/search/Levelize.cc b/search/Levelize.cc index 4e834e23..6500a828 100644 --- a/search/Levelize.cc +++ b/search/Levelize.cc @@ -37,8 +37,8 @@ Levelize::Levelize(StaState *sta) : levels_valid_(false), max_level_(0), level_space_(10), - loops_(NULL), - observer_(NULL) + loops_(nullptr), + observer_(nullptr) { } @@ -90,7 +90,7 @@ Levelize::deleteLoops() if (loops_) { loops_->deleteContents(); delete loops_; - loops_ = NULL; + loops_ = nullptr; loop_edges_.clear(); } } @@ -147,10 +147,10 @@ Levelize::findRoots() if (hasFanout(vertex, search_pred_, graph_)) // Color roots with no fanout black so that they are // not treated as degenerate loops by levelizeCycles(). - vertex->setColor(vertex_color_black); + vertex->setColor(LevelColor::black); } else - vertex->setColor(vertex_color_white); + vertex->setColor(LevelColor::white); } } @@ -208,7 +208,7 @@ Levelize::visit(Vertex *vertex, Pin *from_pin = vertex->pin(); debugPrint2(debug_, "levelize", 3, "level %d %s\n", level, vertex->name(sdc_network_)); - vertex->setColor(vertex_color_gray); + vertex->setColor(LevelColor::gray); setLevel(vertex, level); max_level_ = max(level, max_level_); level += level_space; @@ -220,11 +220,11 @@ Levelize::visit(Vertex *vertex, Vertex *to_vertex = edge->to(graph_); if (search_pred_->searchThru(edge) && search_pred_->searchTo(to_vertex)) { - VertexColor to_color = to_vertex->color(); - if (to_color == vertex_color_gray) + LevelColor to_color = to_vertex->color(); + if (to_color == LevelColor::gray) // Back edges form feedback loops. recordLoop(edge, path); - else if (to_color == vertex_color_white + else if (to_color == LevelColor::white || to_vertex->level() < level) { path.push_back(edge); visit(to_vertex, level, level_space, path); @@ -239,12 +239,12 @@ Levelize::visit(Vertex *vertex, && !vertex->isBidirectDriver()) { Vertex *to_vertex = graph_->pinDrvrVertex(from_pin); if (search_pred_->searchTo(to_vertex) - && (to_vertex->color() == vertex_color_white + && (to_vertex->color() == LevelColor::white || to_vertex->level() < level)) visit(to_vertex, level, level_space, path); } } - vertex->setColor(vertex_color_black); + vertex->setColor(LevelColor::black); } void @@ -327,7 +327,7 @@ Levelize::levelizeCycles() VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); - if (vertex->color() == vertex_color_white + if (vertex->color() == LevelColor::white && search_pred_->searchFrom(vertex)) uncolored.push_back(vertex); } @@ -341,7 +341,7 @@ Levelize::levelizeCycles() // Only search from and assign root status to vertices that // previous searches did not visit. Otherwise "everybody is a // root". - if (vertex->color() == vertex_color_white) { + if (vertex->color() == LevelColor::white) { EdgeSeq path; roots_.insert(vertex); visit(vertex, 0, level_space_, path); diff --git a/search/Path.cc b/search/Path.cc index 0b569a10..b2508f74 100644 --- a/search/Path.cc +++ b/search/Path.cc @@ -179,7 +179,7 @@ Path::prevEdge(const TimingArc *prev_arc, return edge; } } - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -208,9 +208,9 @@ Path::cmpPinTrClk(const Path *path1, else return 1; } - else if (path1 == NULL && path2 == NULL) + else if (path1 == nullptr && path2 == nullptr) return 0; - else if (path1 == NULL) + else if (path1 == nullptr) return -1; else return 1; @@ -233,8 +233,8 @@ Path::cmpClk(const Path *path1, else return 1; } - else if (clk_edge1 == NULL - && clk_edge2 == NULL) + else if (clk_edge1 == nullptr + && clk_edge2 == nullptr) return 0; else if (clk_edge2) return -1; @@ -252,8 +252,8 @@ Path::equal(const Path *path1, && path1->vertexIndex(sta) == path2->vertexIndex(sta) // Tag equal implies transition and path ap equal. && path1->tagIndex(sta) == path2->tagIndex(sta)) - || ((path1 == NULL || path1->isNull()) - && (path2 == NULL || path2->isNull())); + || ((path1 == nullptr || path1->isNull()) + && (path2 == nullptr || path2->isNull())); } //////////////////////////////////////////////////////////////// @@ -301,10 +301,10 @@ Path::cmp(const Path *path1, else return 1; } - else if (path1 == NULL - && path2 == NULL) + else if (path1 == nullptr + && path2 == nullptr) return 0; - else if (path1 == NULL) + else if (path1 == nullptr) return -1; else return 1; diff --git a/search/Path.hh b/search/Path.hh index d41c888d..5a4d7dcb 100644 --- a/search/Path.hh +++ b/search/Path.hh @@ -39,8 +39,8 @@ public: virtual ~Path() {} virtual const char *name(const StaState *sta) const; virtual bool isNull() const = 0; - virtual Path *path() { return isNull() ? NULL : this; } - virtual const Path *path() const { return isNull() ? NULL : this; } + virtual Path *path() { return isNull() ? nullptr : this; } + virtual const Path *path() const { return isNull() ? nullptr : this; } virtual void setRef(PathRef *ref) const = 0; virtual void setRef(PathRef &ref) const { setRef(&ref); } virtual Vertex *vertex(const StaState *sta) const = 0; diff --git a/search/PathAnalysisPt.cc b/search/PathAnalysisPt.cc index 30e93ed0..45194a87 100644 --- a/search/PathAnalysisPt.cc +++ b/search/PathAnalysisPt.cc @@ -29,7 +29,7 @@ PathAnalysisPt::PathAnalysisPt(Corner *corner, corner_(corner), index_(index), path_min_max_(path_min_max), - tgt_clk_ap_(NULL), + tgt_clk_ap_(nullptr), dcalc_ap_(dcalc_ap) { } diff --git a/search/PathEnd.cc b/search/PathEnd.cc index b65a7799..d4a1ce26 100644 --- a/search/PathEnd.cc +++ b/search/PathEnd.cc @@ -133,7 +133,7 @@ PathEnd::targetClkEndTrans(const StaState *sta) const if (clk_edge) return clk_edge->transition(); else - return NULL; + return nullptr; } } @@ -158,13 +158,13 @@ PathEnd::sourceClkInsertionDelay(const StaState *) const Clock * PathEnd::targetClk(const StaState *) const { - return NULL; + return nullptr; } ClockEdge * PathEnd::targetClkEdge(const StaState *) const { - return NULL; + return nullptr; } float @@ -224,19 +224,19 @@ PathEnd::targetClkMcpAdjustment(const StaState *) const TimingRole * PathEnd::checkRole(const StaState *) const { - return NULL; + return nullptr; } PathVertex * PathEnd::targetClkPath() { - return NULL; + return nullptr; } const PathVertex * PathEnd::targetClkPath() const { - return NULL; + return nullptr; } bool @@ -248,7 +248,7 @@ PathEnd::pathDelayMarginIsExternal() const PathDelay * PathEnd::pathDelay() const { - return NULL; + return nullptr; } Arrival @@ -266,15 +266,15 @@ PathEnd::commonClkPessimism(const StaState *) const MultiCyclePath * PathEnd::multiCyclePath() const { - return NULL; + return nullptr; } int PathEnd::exceptPathCmp(const PathEnd *path_end, const StaState *) const { - PathEndType type1 = type(); - PathEndType type2 = path_end->type(); + Type type1 = type(); + Type type2 = path_end->type(); if (type1 == type2) return 0; else if (type1 < type2) @@ -401,7 +401,7 @@ PathEnd::checkNonInterClkUncertainty(const PathVertex *tgt_clk_path, const StaState *sta) { MinMax *min_max = check_role->pathMinMax(); - ClockUncertainties *uncertainties = NULL; + ClockUncertainties *uncertainties = nullptr; if (tgt_clk_path && tgt_clk_path->isClock(sta)) uncertainties = tgt_clk_path->clkInfo(sta)->uncertainties(); else if (tgt_clk_edge) @@ -516,10 +516,16 @@ PathEndUnconstrained::sourceClkOffset(const StaState *) const return 0.0; } -PathEndType +PathEnd::Type PathEndUnconstrained::type() const { - return path_end_unconstrained; + return Type::unconstrained; +} + +const char * +PathEndUnconstrained::typeName() const +{ + return "unconstrained"; } //////////////////////////////////////////////////////////////// @@ -590,7 +596,7 @@ PathVertex * PathEndClkConstrained::targetClkPath() { if (clk_path_.isNull()) - return NULL; + return nullptr; else return &clk_path_; } @@ -599,7 +605,7 @@ const PathVertex * PathEndClkConstrained::targetClkPath() const { if (clk_path_.isNull()) - return NULL; + return nullptr; else return &clk_path_; } @@ -621,7 +627,7 @@ PathEndClkConstrained::targetClkEdge(const StaState *sta) const if (!clk_path_.isNull()) return clk_path_.clkEdge(sta); else - return NULL; + return nullptr; } Clock * @@ -631,7 +637,7 @@ PathEndClkConstrained::targetClk(const StaState *sta) const if (clk_edge) return clk_edge->clock(); else - return NULL; + return nullptr; } float @@ -820,7 +826,7 @@ PathEndClkConstrainedMcp::checkMcpAdjustment(const Path *path, else { // Hold check. // Default arrival clock is a proxy for the target clock. - if (src_clk_edge == NULL) + if (src_clk_edge == nullptr) src_clk_edge = tgt_clk_edge; else if (src_clk_edge->clock() == sdc->defaultArrivalClock()) src_clk_edge = tgt_clk_edge->clock()->edge(src_clk_edge->transition()); @@ -870,7 +876,7 @@ PathEnd::checkSetupMcpAdjustment(const ClockEdge *src_clk_edge, { if (mcp) { // Default arrival clock is a proxy for the target clock. - if (src_clk_edge == NULL) + if (src_clk_edge == nullptr) src_clk_edge = tgt_clk_edge; else if (src_clk_edge->clock() == sdc->defaultArrivalClock()) src_clk_edge = tgt_clk_edge->clock()->edge(src_clk_edge->transition()); @@ -914,7 +920,7 @@ PathEndClkConstrainedMcp::findHoldMcps(const ClockEdge *tgt_clk_edge, if (mcp_min_max->matches(MinMax::min())) { hold_mcp = mcp_; setup_mcp = - dynamic_cast(search->exceptionTo(exception_type_multi_cycle, + dynamic_cast(search->exceptionTo(ExceptionPathType::multi_cycle, path_.path(), pin, tr, tgt_clk_edge, MinMax::max(), true, @@ -923,7 +929,7 @@ PathEndClkConstrainedMcp::findHoldMcps(const ClockEdge *tgt_clk_edge, else { setup_mcp = mcp_; hold_mcp = - dynamic_cast(search->exceptionTo(exception_type_multi_cycle, + dynamic_cast(search->exceptionTo(ExceptionPathType::multi_cycle, path_.path(), pin, tr, tgt_clk_edge, MinMax::min(), true, @@ -985,10 +991,16 @@ PathEndCheck::copy() &clk_path_, mcp_, crpr_, crpr_valid_); } -PathEndType +PathEnd::Type PathEndCheck::type() const { - return path_end_check; + return Type::check; +} + +const char * +PathEndCheck::typeName() const +{ + return "check"; } void @@ -1047,7 +1059,7 @@ PathEndLatchCheck::PathEndLatchCheck(Path *path, MultiCyclePath *mcp, PathDelay *path_delay, const StaState *sta) : - PathEndCheck(path, check_arc, check_edge, NULL, mcp, sta), + PathEndCheck(path, check_arc, check_edge, nullptr, mcp, sta), disable_path_(disable_path), path_delay_(path_delay), src_clk_arrival_(0.0) @@ -1089,17 +1101,23 @@ PathEndLatchCheck::copy() src_clk_arrival_, crpr_, crpr_valid_); } -PathEndType +PathEnd::Type PathEndLatchCheck::type() const { - return path_end_latch_check; + return Type::latch_check; +} + +const char * +PathEndLatchCheck::typeName() const +{ + return "latch_check"; } PathVertex * PathEndLatchCheck::latchDisable() { if (disable_path_.isNull()) - return NULL; + return nullptr; else return &disable_path_; } @@ -1108,7 +1126,7 @@ const PathVertex * PathEndLatchCheck::latchDisable() const { if (disable_path_.isNull()) - return NULL; + return nullptr; else return &disable_path_; } @@ -1285,10 +1303,16 @@ PathEndOutputDelay::copy() mcp_, crpr_, crpr_valid_); } -PathEndType +PathEnd::Type PathEndOutputDelay::type() const { - return path_end_output_delay; + return Type::output_delay; +} + +const char * +PathEndOutputDelay::typeName() const +{ + return "output_delay"; } void @@ -1488,10 +1512,16 @@ PathEndGatedClock::copy() mcp_, margin_, crpr_, crpr_valid_); } -PathEndType +PathEnd::Type PathEndGatedClock::type() const { - return path_end_gated_clk; + return Type::gated_clk; +} + +const char * +PathEndGatedClock::typeName() const +{ + return "gated_clk"; } TimingRole * @@ -1541,7 +1571,7 @@ PathEndDataCheck::PathEndDataCheck(DataCheck *check, PathVertex *data_clk_path, MultiCyclePath *mcp, const StaState *sta) : - PathEndClkConstrainedMcp(data_path, NULL, mcp), + PathEndClkConstrainedMcp(data_path, nullptr, mcp), data_clk_path_(data_clk_path), check_(check) { @@ -1568,10 +1598,16 @@ PathEndDataCheck::copy() &clk_path_, mcp_, crpr_, crpr_valid_); } -PathEndType +PathEnd::Type PathEndDataCheck::type() const { - return path_end_data_check; + return Type::data_check; +} + +const char * +PathEndDataCheck::typeName() const +{ + return "data_check"; } Arrival @@ -1652,11 +1688,11 @@ PathEndDataCheck::exceptPathCmp(const PathEnd *path_end, PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, Path *path, const StaState *sta): - PathEndClkConstrained(path, NULL), + PathEndClkConstrained(path, nullptr), path_delay_(path_delay), - check_arc_(NULL), - check_edge_(NULL), - output_delay_(NULL) + check_arc_(nullptr), + check_edge_(nullptr), + output_delay_(nullptr) { findSrcClkArrival(sta); } @@ -1665,10 +1701,10 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, Path *path, OutputDelay *output_delay, const StaState *sta): - PathEndClkConstrained(path, NULL), + PathEndClkConstrained(path, nullptr), path_delay_(path_delay), - check_arc_(NULL), - check_edge_(NULL), + check_arc_(nullptr), + check_edge_(nullptr), output_delay_(output_delay) { findSrcClkArrival(sta); @@ -1684,7 +1720,7 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, path_delay_(path_delay), check_arc_(check_arc), check_edge_(check_edge), - output_delay_(NULL) + output_delay_(nullptr) { findSrcClkArrival(sta); } @@ -1715,10 +1751,16 @@ PathEndPathDelay::copy() src_clk_arrival_, crpr_, crpr_valid_); } -PathEndType +PathEnd::Type PathEndPathDelay::type() const { - return path_end_path_delay; + return Type::path_delay; +} + +const char * +PathEndPathDelay::typeName() const +{ + return "path_delay"; } void @@ -1747,7 +1789,7 @@ PathEndPathDelay::reportShort(ReportPath *report, bool PathEndPathDelay::pathDelayMarginIsExternal() const { - return check_arc_ == NULL; + return check_arc_ == nullptr; } TimingRole * @@ -1934,22 +1976,22 @@ PathEnd::cmpSlack(const PathEnd *path_end1, { Slack slack1 = path_end1->slack(sta); Slack slack2 = path_end2->slack(sta); - if (delayFuzzyZero(slack1) - && delayFuzzyZero(slack2) + if (fuzzyZero(slack1) + && fuzzyZero(slack2) && path_end1->isLatchCheck() && path_end2->isLatchCheck()) { Arrival borrow1 = path_end1->borrow(sta); Arrival borrow2 = path_end2->borrow(sta); // Latch slack is zero if there is borrowing so break ties // based on borrow time. - if (delayFuzzyEqual(borrow1, borrow2)) + if (fuzzyEqual(borrow1, borrow2)) return 0; else if (borrow1 > borrow2) return -1; else return 1; } - else if (delayFuzzyEqual(slack1, slack2)) + else if (fuzzyEqual(slack1, slack2)) return 0; else if (slack1 < slack2) return -1; @@ -1965,9 +2007,9 @@ PathEnd::cmpArrival(const PathEnd *path_end1, Arrival arrival1 = path_end1->dataArrivalTime(sta); Arrival arrival2 = path_end2->dataArrivalTime(sta); const MinMax *min_max = path_end1->minMax(sta); - if (delayFuzzyEqual(arrival1, arrival2)) + if (fuzzyEqual(arrival1, arrival2)) return 0; - else if (delayFuzzyLess(arrival1, arrival2, min_max)) + else if (fuzzyLess(arrival1, arrival2, min_max)) return -1; else return 1; @@ -1988,28 +2030,6 @@ PathEnd::cmpNoCrpr(const PathEnd *path_end1, return cmp; } -const char * -PathEnd::typeName(PathEndType type) -{ - switch (type) { - case path_end_unconstrained: - return "unconstrained"; - case path_end_check: - return "check"; - case path_end_data_check: - return "data check"; - case path_end_latch_check: - return "latc check"; - case path_end_output_delay: - return "output delay"; - case path_end_gated_clk: - return "gated clock"; - case path_end_path_delay: - return "path delay"; - }; - return "??"; -} - //////////////////////////////////////////////////////////////// PathEndSlackLess::PathEndSlackLess(const StaState *sta) : diff --git a/search/PathEnd.hh b/search/PathEnd.hh index 306078cd..c2778e1c 100644 --- a/search/PathEnd.hh +++ b/search/PathEnd.hh @@ -36,16 +36,6 @@ class ReportPath; using std::string; -typedef enum { - path_end_unconstrained, - path_end_check, - path_end_data_check, - path_end_latch_check, - path_end_output_delay, - path_end_gated_clk, - path_end_path_delay -} PathEndType; - // PathEnds represent search endpoints that are either unconstrained // or constrained by a timing check, output delay, data check, // or path delay. @@ -65,6 +55,15 @@ typedef enum { class PathEnd { public: + enum Type { unconstrained, + check, + data_check, + latch_check, + output_delay, + gated_clk, + path_delay + }; + virtual PathEnd *copy() = 0; virtual ~PathEnd(); void deletePath(); @@ -95,7 +94,8 @@ public: virtual bool isOutputDelay() const { return false; } virtual bool isGatedClock() const { return false; } virtual bool isPathDelay() const { return false; } - virtual PathEndType type() const = 0; + virtual Type type() const = 0; + virtual const char *typeName() const = 0; virtual int exceptPathCmp(const PathEnd *path_end, const StaState *sta) const; virtual Arrival dataArrivalTime(const StaState *sta) const; @@ -140,9 +140,9 @@ public: virtual PathDelay *pathDelay() const; virtual Crpr commonClkPessimism(const StaState *sta) const; virtual MultiCyclePath *multiCyclePath() const; - virtual TimingArc *checkArc() const { return NULL; } + virtual TimingArc *checkArc() const { return nullptr; } // PathEndDataCheck data clock path. - virtual const PathVertex *dataClkPath() const { return NULL; } + virtual const PathVertex *dataClkPath() const { return nullptr; } static bool less(const PathEnd *path_end1, const PathEnd *path_end2, @@ -159,7 +159,6 @@ public: static int cmpNoCrpr(const PathEnd *path_end1, const PathEnd *path_end2, const StaState *sta); - static const char *typeName(PathEndType type); // Helper common to multiple PathEnd classes and used // externally. @@ -218,7 +217,8 @@ class PathEndUnconstrained : public PathEnd { public: explicit PathEndUnconstrained(Path *path); - virtual PathEndType type() const; + virtual Type type() const; + virtual const char *typeName() const; virtual PathEnd *copy(); virtual void reportShort(ReportPath *report, string &result) const; @@ -329,7 +329,8 @@ public: MultiCyclePath *mcp, const StaState *sta); virtual PathEnd *copy(); - virtual PathEndType type() const; + virtual Type type() const; + virtual const char *typeName() const; virtual void reportShort(ReportPath *report, string &result) const; virtual void reportFull(ReportPath *report, string &result) const; virtual bool isCheck() const { return true; } @@ -366,7 +367,8 @@ public: MultiCyclePath *mcp, PathDelay *path_delay, const StaState *sta); - virtual PathEndType type() const; + virtual Type type() const; + virtual const char *typeName() const; virtual float sourceClkOffset(const StaState *sta) const; virtual bool isCheck() const { return false; } virtual bool isLatchCheck() const { return true; } @@ -433,7 +435,8 @@ public: MultiCyclePath *mcp, const StaState *sta); virtual PathEnd *copy(); - virtual PathEndType type() const; + virtual Type type() const; + virtual const char *typeName() const; virtual void reportShort(ReportPath *report, string &result) const; virtual void reportFull(ReportPath *report, @@ -483,7 +486,8 @@ public: ArcDelay margin, const StaState *sta); virtual PathEnd *copy(); - virtual PathEndType type() const; + virtual Type type() const; + virtual const char *typeName() const; virtual void reportShort(ReportPath *report, string &result) const; virtual void reportFull(ReportPath *report, @@ -519,7 +523,8 @@ public: MultiCyclePath *mcp, const StaState *sta); virtual PathEnd *copy(); - virtual PathEndType type() const; + virtual Type type() const; + virtual const char *typeName() const; virtual void reportShort(ReportPath *report, string &result) const; virtual void reportFull(ReportPath *report, @@ -571,7 +576,8 @@ public: OutputDelay *output_delay, const StaState *sta); virtual PathEnd *copy(); - virtual PathEndType type() const; + virtual Type type() const; + virtual const char *typeName() const; virtual void reportShort(ReportPath *report, string &result) const; virtual void reportFull(ReportPath *report, @@ -605,7 +611,7 @@ protected: PathDelay *path_delay_; TimingArc *check_arc_; Edge *check_edge_; - // Output delay is NULL when there is no timing check or output + // Output delay is nullptr when there is no timing check or output // delay at the endpoint. OutputDelay *output_delay_; // Source clk arrival for set_min/max_delay -ignore_clk_latency. diff --git a/search/PathEnum.cc b/search/PathEnum.cc index a6df2cc2..4ab0bea9 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.cc @@ -69,7 +69,7 @@ Diversion::Diversion(PathEnd *path_end, // Default constructor required for DiversionQueue template. DiversionGreater::DiversionGreater() : - sta_(NULL) + sta_(nullptr) { } @@ -112,7 +112,7 @@ PathEnum::PathEnum(int group_count, div_queue_(DiversionGreater(sta)), div_count_(0), inserts_pruned_(false), - next_(NULL) + next_(nullptr) { } @@ -150,10 +150,10 @@ PathEnum::hasNext() pruneDiversionQueue(); inserts_pruned_ = true; } - if (next_ == NULL + if (next_ == nullptr && !div_queue_.empty()) findNext(); - return next_ != NULL; + return next_ != nullptr; } PathEnd * @@ -167,7 +167,7 @@ PathEnum::next() void PathEnum::findNext() { - next_ = NULL; + next_ = nullptr; // Pop the next slowest path off the queue. while (!div_queue_.empty()) { Diversion *div = div_queue_.top(); @@ -348,7 +348,7 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, // Make the diverted path end to check slack with from_path crpr. makeDivertedPathEnd(from_path, arc, div_end, after_div_copy); // Only enumerate paths with greater slack. - if (delayFuzzyGreaterEqual(div_end->slack(sta_), path_end_slack_)) { + if (fuzzyGreaterEqual(div_end->slack(sta_), path_end_slack_)) { reportDiversion(arc, from_path); path_enum_->makeDiversion(div_end, after_div_copy); } @@ -356,7 +356,7 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, delete div_end; } // Only enumerate slower/faster paths. - else if (delayFuzzyLessEqual(to_arrival, before_div_arrival_, min_max)) { + else if (fuzzyLessEqual(to_arrival, before_div_arrival_, min_max)) { PathEnd *div_end; PathEnumed *after_div_copy; makeDivertedPathEnd(from_path, arc, div_end, after_div_copy); @@ -487,7 +487,7 @@ PathEnum::divEdge(Path *before_div, if (edge->timingArcSet() == arc_set) return edge; } - return NULL; + return nullptr; } // Make diversions for all arcs that merge into path for paths @@ -533,7 +533,7 @@ PathEnum::makeDivertedPath(Path *path, PathRef p(path); bool first = true; bool is_latch_data = false; - PathEnumed *prev_copy = NULL; + PathEnumed *prev_copy = nullptr; while (!p.isNull()) { PathRef prev; TimingArc *prev_arc; @@ -541,7 +541,7 @@ PathEnum::makeDivertedPath(Path *path, PathEnumed *copy = new PathEnumed(p.vertexIndex(this), p.tagIndex(this), p.arrival(this), - NULL, // prev_path made in next pass. + nullptr, // prev_path made in next pass. prev_arc); if (prev_copy) prev_copy->setPrevPath(copy); diff --git a/search/PathEnumed.cc b/search/PathEnumed.cc index 19cc706f..646b5bc7 100644 --- a/search/PathEnumed.cc +++ b/search/PathEnumed.cc @@ -152,7 +152,7 @@ PathEnumed::prevPath(const StaState *, } else { prev_path.init(); - prev_arc = NULL; + prev_arc = nullptr; } } diff --git a/search/PathExpanded.cc b/search/PathExpanded.cc index 7b79fb37..e19a69d5 100644 --- a/search/PathExpanded.cc +++ b/search/PathExpanded.cc @@ -81,7 +81,7 @@ PathExpanded::expand(const Path *path, prev_arcs_.push_back(prev_arc); // Push latch D path. paths_.push_back(prev_path); - prev_arcs_.push_back(NULL); + prev_arcs_.push_back(nullptr); // This breaks latch loop paths. break; } @@ -152,7 +152,7 @@ PathExpanded::path(size_t index) if (index < paths_.size()) return &paths_[pathsIndex(index)]; else - return NULL; + return nullptr; } TimingArc * @@ -186,7 +186,7 @@ PathExpanded::startPrevPath() if (start1 < paths_.size()) return &paths_[start1]; else - return NULL; + return nullptr; } void @@ -219,9 +219,9 @@ PathExpanded::latchPaths(// Return values. PathRef *&q_path, Edge *&d_q_edge) { - d_path = NULL; - q_path = NULL; - d_q_edge = NULL; + d_path = nullptr; + q_path = nullptr; + d_q_edge = nullptr; PathRef *start = startPath(); TimingArc *prev_arc = startPrevArc(); if (prev_arc diff --git a/search/PathGroup.cc b/search/PathGroup.cc index 484bf7ab..af736d45 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -19,6 +19,7 @@ #include "Machine.hh" #include "Stats.hh" #include "Debug.hh" +#include "Mutex.hh" #include "Fuzzy.hh" #include "MinMax.hh" #include "ExceptionPath.hh" @@ -99,19 +100,19 @@ PathGroup::savable(PathEnd *path_end) // without crpr first because it is expensive to find. Slack slack = path_end->slackNoCrpr(sta_); if (!delayIsInitValue(slack, min_max_) - && delayFuzzyLessEqual(slack, threshold_) - && delayFuzzyLessEqual(slack, slack_max_)) { + && fuzzyLessEqual(slack, threshold_) + && fuzzyLessEqual(slack, slack_max_)) { // Now check with crpr. slack = path_end->slack(sta_); - savable = delayFuzzyLessEqual(slack, threshold_) - && delayFuzzyLessEqual(slack, slack_max_) - && delayFuzzyGreaterEqual(slack, slack_min_); + savable = fuzzyLessEqual(slack, threshold_) + && fuzzyLessEqual(slack, slack_max_) + && fuzzyGreaterEqual(slack, slack_min_); } } else { const Arrival &arrival = path_end->dataArrivalTime(sta_); savable = !delayIsInitValue(arrival, min_max_) - && delayFuzzyGreaterEqual(arrival, threshold_, min_max_); + && fuzzyGreaterEqual(arrival, threshold_, min_max_); } return savable; } @@ -119,12 +120,11 @@ PathGroup::savable(PathEnd *path_end) void PathGroup::insert(PathEnd *path_end) { - lock_.lock(); + UniqueLock lock(lock_); path_ends_.push_back(path_end); if (group_count_ != group_count_max && static_cast(path_ends_.size()) > group_count_ * 2) prune(); - lock_.unlock(); } void @@ -192,10 +192,9 @@ PathGroup::sort() void PathGroup::clear() { - lock_.lock(); + UniqueLock lock(lock_); threshold_ = min_max_->initValue(); path_ends_.clear(); - lock_.unlock(); } //////////////////////////////////////////////////////////////// @@ -258,11 +257,11 @@ PathGroups::makeGroups(int group_count, { int mm_index = min_max->index(); if (setup_hold) { - GroupPathIterator *group_path_iter = sdc_->groupPathIterator(); - while (group_path_iter->hasNext()) { + GroupPathIterator group_path_iter(sdc_); + while (group_path_iter.hasNext()) { const char *name; GroupPathSet *groups; - group_path_iter->next(name, groups); + group_path_iter.next(name, groups); if (reportGroup(name, group_names)) { PathGroup *group = PathGroup::makePathGroupSlack(name, group_count, endpoint_count, unique_pins, @@ -271,11 +270,8 @@ PathGroups::makeGroups(int group_count, named_map_[mm_index][name] = group; } } - delete group_path_iter; - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { const char *clk_name = clk->name(); if (reportGroup(clk_name, group_names)) { PathGroup *group = PathGroup::makePathGroupSlack(clk_name, group_count, @@ -285,7 +281,6 @@ PathGroups::makeGroups(int group_count, clk_map_[mm_index][clk] = group; } } - delete clk_iter; } if (setup_hold @@ -296,7 +291,7 @@ PathGroups::makeGroups(int group_count, slack_min, slack_max, this); else - path_delay_[mm_index] = NULL; + path_delay_[mm_index] = nullptr; if (gated_clk && reportGroup(gated_clk_group_name_, group_names)) @@ -306,7 +301,7 @@ PathGroups::makeGroups(int group_count, slack_min, slack_max, this); else - gated_clk_[mm_index] = NULL; + gated_clk_[mm_index] = nullptr; if (async && reportGroup(async_group_name_, group_names)) @@ -316,7 +311,7 @@ PathGroups::makeGroups(int group_count, slack_min, slack_max, this); else - async_[mm_index] = NULL; + async_[mm_index] = nullptr; if (unconstrained && reportGroup(unconstrained_group_name_, group_names)) @@ -325,7 +320,7 @@ PathGroups::makeGroups(int group_count, group_count, endpoint_count, unique_pins, min_max, this); else - unconstrained_[mm_index] = NULL; + unconstrained_[mm_index] = nullptr; } PathGroups::~PathGroups() @@ -361,7 +356,7 @@ bool PathGroups::reportGroup(const char *group_name, PathGroupNameSet *group_names) const { - return group_names == NULL + return group_names == nullptr || group_names->empty() || group_names->hasKey(group_name); } @@ -410,7 +405,7 @@ PathGroups::pathGroup(const PathEnd *path_end) const return unconstrained_[mm_index]; else { internalError("unknown path end type"); - return NULL; + return nullptr; } } @@ -420,7 +415,7 @@ PathGroups::groupPathTo(const PathEnd *path_end) const const Path *path = path_end->path(); const Pin *pin = path->pin(this); ExceptionPath *exception = - search_->exceptionTo(exception_type_group_path, path, + search_->exceptionTo(ExceptionPathType::group_path, path, pin, path->transition(this), path_end->targetClkEdge(this), path->minMax(this), false, false); @@ -434,16 +429,15 @@ PathGroups::pushGroupPathEnds(PathEndSeq *path_ends) while (mm_iter.hasNext()) { MinMax *min_max = mm_iter.next(); int mm_index = min_max->index(); - GroupPathIterator *group_path_iter = sdc_->groupPathIterator(); - while (group_path_iter->hasNext()) { + GroupPathIterator group_path_iter(sdc_); + while (group_path_iter.hasNext()) { const char *name; GroupPathSet *groups; - group_path_iter->next(name, groups); + group_path_iter.next(name, groups); PathGroup *path_group = findPathGroup(name, min_max); if (path_group) path_group->pushEnds(path_ends); } - delete group_path_iter; if (async_[mm_index]) async_[mm_index]->pushEnds(path_ends); @@ -599,7 +593,7 @@ MakePathEnds1::vertexEnd(Vertex *) if (end) { group->insert(end); // Clear ends_ for next vertex. - ends_[group] = NULL; + ends_[group] = nullptr; } } } @@ -673,7 +667,7 @@ MakePathEndsAll::visitPathEnd(PathEnd *path_end, PathGroup *group) { PathEndSeq *ends = ends_.findKey(group); - if (ends == NULL) { + if (ends == nullptr) { ends = new PathEndSeq; ends_[group] = ends; } @@ -703,7 +697,7 @@ MakePathEndsAll::vertexEnd(Vertex *) if (!unique_ends.hasKey(path_end)) { debugPrint4(debug, "path_enum", 5, "insert %s %s %s %d\n", path_end->vertex(sta_)->name(network), - PathEnd::typeName(path_end->type()), + path_end->typeName(), path_end->transition(sta_)->asString(), path_end->path()->tag(sta_)->index()); // Give the group a copy of the path end because @@ -717,7 +711,7 @@ MakePathEndsAll::vertexEnd(Vertex *) else debugPrint4(debug, "path_enum", 5, "prune %s %s %s %d\n", path_end->vertex(sta_)->name(network), - PathEnd::typeName(path_end->type()), + path_end->typeName(), path_end->transition(sta_)->asString(), path_end->path()->tag(sta_)->index()); } @@ -754,25 +748,21 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to, while (mm_iter.hasNext()) { const MinMax *path_min_max = mm_iter.next(); int mm_index = path_min_max->index(); - GroupPathIterator *group_path_iter = sdc_->groupPathIterator(); - while (group_path_iter->hasNext()) { + GroupPathIterator group_path_iter(sdc_); + while (group_path_iter.hasNext()) { const char *name; GroupPathSet *groups; - group_path_iter->next(name, groups); + group_path_iter.next(name, groups); PathGroup *group = findPathGroup(name, path_min_max); if (group) enumPathEnds(group, group_count, endpoint_count, unique_pins, true); } - delete group_path_iter; - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { PathGroup *group = findPathGroup(clk, path_min_max); if (group) enumPathEnds(group, group_count, endpoint_count, unique_pins, true); } - delete clk_iter; PathGroup *group = unconstrained_[mm_index]; if (group) @@ -851,9 +841,9 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to, static bool exceptionToEmpty(ExceptionTo *to) { - return to == NULL - || (to->pins() == NULL - && to->instances() == NULL); + return to == nullptr + || (to->pins() == nullptr + && to->instances() == nullptr); } //////////////////////////////////////////////////////////////// @@ -920,9 +910,9 @@ PathGroups::makeGroupPathEnds(VertexSet *endpoints, { VertexSet::Iterator end_iter(endpoints); MakeEndpointPathEnds make_path_ends(visitor, corner, min_max, this); - forEach2(&end_iter, - &make_path_ends, - this->threadCount()); + forEach(&end_iter, + &make_path_ends, + thread_count_); } } // namespace diff --git a/search/PathGroup.hh b/search/PathGroup.hh index 5c8b0940..120e39c9 100644 --- a/search/PathGroup.hh +++ b/search/PathGroup.hh @@ -20,7 +20,6 @@ #include "DisallowCopyAssign.hh" #include "Map.hh" #include "Vector.hh" -#include "Mutex.hh" #include "StaState.hh" #include "SearchClass.hh" @@ -91,7 +90,7 @@ protected: const MinMax *min_max_; bool compare_slack_; float threshold_; - Mutex lock_; + std::mutex lock_; const StaState *sta_; private: @@ -116,7 +115,7 @@ public: bool unconstrained, const StaState *sta); ~PathGroups(); - // Use corner NULL to make PathEnds for all corners. + // Use corner nullptr to make PathEnds for all corners. // Returned PathEndSeq is owned by the caller. // The PathEnds in the vector are owned by the PathGroups. PathEndSeq *makePathEnds(ExceptionTo *to, diff --git a/search/PathRef.cc b/search/PathRef.cc index 7c3a0a8c..cc1c7d0c 100644 --- a/search/PathRef.cc +++ b/search/PathRef.cc @@ -25,12 +25,12 @@ namespace sta { PathRef::PathRef() : - path_enumed_(NULL) + path_enumed_(nullptr) { } PathRef::PathRef(const Path *path) : - path_enumed_(NULL) + path_enumed_(nullptr) { if (path) path->setRef(this); @@ -50,7 +50,7 @@ PathRef::PathRef(const PathRef *path) : PathRef::PathRef(const PathVertex &path) : path_vertex_(&path), - path_enumed_(NULL) + path_enumed_(nullptr) { } @@ -58,7 +58,7 @@ void PathRef::init() { path_vertex_.init(); - path_enumed_ = NULL; + path_enumed_ = nullptr; } void @@ -93,7 +93,7 @@ PathRef::init(Vertex *vertex, int arrival_index) { path_vertex_.init(vertex, tag, arrival_index); - path_enumed_ = NULL; + path_enumed_ = nullptr; } void @@ -119,7 +119,7 @@ PathRef::deleteRep() bool PathRef::isNull() const { - return path_enumed_ == NULL + return path_enumed_ == nullptr && path_vertex_.isNull(); } diff --git a/search/PathRef.hh b/search/PathRef.hh index a8332426..74c80a1f 100644 --- a/search/PathRef.hh +++ b/search/PathRef.hh @@ -28,7 +28,7 @@ namespace sta { // Path reference to either a PathVertex or PathEnum. // This "could" be made smaller by using a union for // path_vertex_.vertex_ and path_enumed_ and a non-legal -// value for path_vertex_.arrival_index_ (because a NULL tag +// value for path_vertex_.arrival_index_ (because a nullptr tag // in PathVertex is valid). class PathRef : public Path { diff --git a/search/PathVertex.cc b/search/PathVertex.cc index dc76bbe4..32b3bbef 100644 --- a/search/PathVertex.cc +++ b/search/PathVertex.cc @@ -34,8 +34,8 @@ namespace sta { PathVertex::PathVertex() : - vertex_(NULL), - tag_(NULL), + vertex_(nullptr), + tag_(nullptr), arrival_index_(0) { } @@ -48,8 +48,8 @@ PathVertex::PathVertex(const PathVertex &path) : } PathVertex::PathVertex(const PathVertex *path) : - vertex_(NULL), - tag_(NULL), + vertex_(nullptr), + tag_(nullptr), arrival_index_(0) { if (path) { @@ -94,8 +94,8 @@ PathVertex::PathVertex(const PathVertexRep &path, void PathVertex::init() { - vertex_ = NULL; - tag_ = NULL; + vertex_ = nullptr; + tag_ = nullptr; arrival_index_ = 0; } @@ -104,8 +104,8 @@ PathVertex::init(Vertex *vertex, Tag *tag, const StaState *sta) { - vertex_ = NULL; - tag_ = NULL; + vertex_ = nullptr; + tag_ = nullptr; arrival_index_ = 0; const Search *search = sta->search(); TagGroup *tag_group = search->tagGroup(vertex); @@ -166,8 +166,8 @@ PathVertex::copy(const PathVertex *path) arrival_index_ = path->arrival_index_; } else { - vertex_ = NULL; - tag_ = NULL; + vertex_ = nullptr; + tag_ = nullptr; arrival_index_ = 0; } } @@ -175,7 +175,7 @@ PathVertex::copy(const PathVertex *path) bool PathVertex::isNull() const { - return tag_ == NULL; + return tag_ == nullptr; } void @@ -395,7 +395,7 @@ PrevPathVisitor::PrevPathVisitor(const Path *path, path_tr_index_(path->trIndex(sta)), path_ap_index_(path->pathAnalysisPtIndex(sta)), prev_path_(), - prev_arc_(NULL), + prev_arc_(nullptr), dcalc_tol_(sta->graphDelayCalc()->incrementalDelayTolerance()) { } @@ -427,7 +427,7 @@ PrevPathVisitor::visitFromToPath(const Pin *, && path_ap_index == path_ap_index_ && (dcalc_tol_ > 0.0 ? std::abs(delayAsFloat(to_arrival - path_arrival_)) < dcalc_tol_ - : delayFuzzyEqual(to_arrival, path_arrival_)) + : fuzzyEqual(to_arrival, path_arrival_)) && (tagMatch(to_tag, path_tag_, sta_) // If the filter exception became active searching from // from_path to to_path the tag includes the filter, but @@ -454,14 +454,14 @@ PrevPathVisitor::unfilteredTag(const Tag *tag) const { Search *search = sta_->search(); const Corners *corners = sta_->corners(); - ExceptionStateSet *unfiltered_states = NULL; + ExceptionStateSet *unfiltered_states = nullptr; const ExceptionStateSet *states = tag->states(); ExceptionStateSet::ConstIterator state_iter(states); while (state_iter.hasNext()) { ExceptionState *state = state_iter.next(); ExceptionPath *except = state->exception(); if (!except->isFilter()) { - if (unfiltered_states == NULL) + if (unfiltered_states == nullptr) unfiltered_states = new ExceptionStateSet; unfiltered_states->insert(state); } @@ -518,9 +518,9 @@ VertexPathIterator::VertexPathIterator(Vertex *vertex, const StaState *sta) : search_(sta->search()), vertex_(vertex), - tr_(NULL), - path_ap_(NULL), - min_max_(NULL) + tr_(nullptr), + path_ap_(nullptr), + min_max_(nullptr) { TagGroup *tag_group = search_->tagGroup(vertex); if (tag_group) { @@ -539,7 +539,7 @@ VertexPathIterator::VertexPathIterator(Vertex *vertex, vertex_(vertex), tr_(tr), path_ap_(path_ap), - min_max_(NULL) + min_max_(nullptr) { TagGroup *tag_group = search_->tagGroup(vertex); if (tag_group) { @@ -555,7 +555,7 @@ VertexPathIterator::VertexPathIterator(Vertex *vertex, search_(sta->search()), vertex_(vertex), tr_(tr), - path_ap_(NULL), + path_ap_(nullptr), min_max_(min_max) { TagGroup *tag_group = search_->tagGroup(vertex); @@ -582,11 +582,11 @@ VertexPathIterator::findNext() Tag *tag; int arrival_index; arrival_iter_.next(tag, arrival_index); - if ((tr_ == NULL + if ((tr_ == nullptr || tag->trIndex() == tr_->index()) - && (path_ap_ == NULL + && (path_ap_ == nullptr || tag->pathAPIndex() == path_ap_->index()) - && (min_max_ == NULL + && (min_max_ == nullptr || tag->pathAnalysisPt(search_)->pathMinMax() == min_max_)) { next_.init(vertex_, tag, arrival_index); return; diff --git a/search/PathVertex.hh b/search/PathVertex.hh index c8d1b695..80b120e7 100644 --- a/search/PathVertex.hh +++ b/search/PathVertex.hh @@ -18,7 +18,6 @@ #define STA_PATH_VERTEX_H #include "DisallowCopyAssign.hh" -#include "Mutex.hh" #include "SearchClass.hh" #include "Path.hh" diff --git a/search/PathVertexRep.cc b/search/PathVertexRep.cc index 71eeefca..46ab1d1f 100644 --- a/search/PathVertexRep.cc +++ b/search/PathVertexRep.cc @@ -93,7 +93,7 @@ void PathVertexRep::init(const PathVertex *path, const StaState *sta) { - if (path == NULL || path->isNull()) + if (path == nullptr || path->isNull()) init(); else { vertex_index_ = sta->graph()->index(path->vertex(sta)); @@ -196,10 +196,10 @@ PathVertexRep::cmp(const PathVertexRep *path1, else return 1; } - else if (path1 == NULL - && path2 == NULL) + else if (path1 == nullptr + && path2 == nullptr) return 0; - else if (path1 == NULL) + else if (path1 == nullptr) return -1; else return 1; diff --git a/search/Power.cc b/search/Power.cc index 2850a7d4..6d6a08f0 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -177,7 +177,7 @@ Power::findInternalPower(const Instance *inst, const char *related_pg_pin = pwr->relatedPgPin(); const LibertyPort *from_port = pwr->relatedPort(); if (pwr->port() == to_port) { - if (from_port == NULL) + if (from_port == nullptr) from_port = to_port; const Pin *from_pin = network_->findPin(inst, from_port); Vertex *from_vertex = graph_->pinLoadVertex(from_pin); @@ -265,11 +265,11 @@ Power::findLeakagePower(const Instance *inst, if (when) { LogicValue when_value = sim_->evalExpr(when, inst); switch (when_value) { - case logic_zero: - case logic_one: + case LogicValue::zero: + case LogicValue::one: leakage = max(leakage, leak->power()); break; - case logic_unknown: + case LogicValue::unknown: default: break; } @@ -319,7 +319,7 @@ Power::voltage(LibertyCell *cell, { // Should use cell pg_pin voltage name to voltage. const Pvt *pvt = dcalc_ap->operatingConditions(); - if (pvt == NULL) + if (pvt == nullptr) pvt = cell->libertyLibrary()->defaultOperatingConditions(); if (pvt) return pvt->voltage(); @@ -333,7 +333,7 @@ Power::findClk(const Pin *to_pin, const Clock *&clk, bool &is_clk) { - clk = NULL; + clk = nullptr; is_clk = false; Vertex *to_vertex = graph_->pinDrvrVertex(to_pin); VertexPathIterator path_iter(to_vertex, this); @@ -341,7 +341,7 @@ Power::findClk(const Pin *to_pin, PathVertex *path = path_iter.next(); const Clock *path_clk = path->clock(this); if (path_clk - && (clk == NULL + && (clk == nullptr || path_clk->period() < clk->period())) clk = path_clk; if (path->isClock(this)) diff --git a/search/Property.cc b/search/Property.cc index 6fc228f3..5d38021b 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -100,84 +100,72 @@ PropertyUnknown::what() const throw() PropertyValue::PropertyValue() : type_(type_none) { - init(); } PropertyValue::PropertyValue(const char *value) : - type_(type_string) + type_(type_string), + string_(stringCopy(value)) { - init(); - string_ = stringCopy(value); } PropertyValue::PropertyValue(std::string &value) : - type_(type_string) + type_(type_string), + string_(stringCopy(value.c_str())) { - init(); - string_ = stringCopy(value.c_str()); } PropertyValue::PropertyValue(float value) : - type_(type_float) + type_(type_float), + float_(value) { - init(); - float_ = value; } PropertyValue::PropertyValue(LibertyLibrary *value) : - type_(type_liberty_library) + type_(type_liberty_library), + liberty_library_(value) { - init(); - liberty_library_ = value; } PropertyValue::PropertyValue(LibertyCell *value) : - type_(type_liberty_cell) + type_(type_liberty_cell), + liberty_cell_(value) { - init(); - liberty_cell_ = value; } PropertyValue::PropertyValue(Library *value) : - type_(type_library) + type_(type_library), + library_(value) { - init(); - library_ = value; } PropertyValue::PropertyValue(Cell *value) : - type_(type_cell) + type_(type_cell), + cell_(value) { - init(); - cell_ = value; } PropertyValue::PropertyValue(Instance *value) : - type_(type_instance) + type_(type_instance), + inst_(value) { - init(); - inst_ = value; } PropertyValue::PropertyValue(Pin *value) : - type_(type_pin) + type_(type_pin), + pin_(value) { - init(); - pin_ = value; } PropertyValue::PropertyValue(PinSeq *value) : - type_(type_pins) + type_(type_pins), + pins_(value) { - init(); - pins_ = value; } PropertyValue::PropertyValue(PinSet *value) : - type_(type_pins) + type_(type_pins), + pins_(new PinSeq) { - init(); - pins_ = new PinSeq; PinSet::Iterator pin_iter(value); while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); @@ -186,31 +174,27 @@ PropertyValue::PropertyValue(PinSet *value) : } PropertyValue::PropertyValue(Net *value) : - type_(type_net) + type_(type_net), + net_(value) { - init(); - net_ = value; } PropertyValue::PropertyValue(Clock *value) : - type_(type_clock) + type_(type_clk), + clk_(value) { - init(); - clk_ = value; } PropertyValue::PropertyValue(ClockSeq *value) : - type_(type_clocks) + type_(type_clks), + clks_(new ClockSeq(*value)) { - init(); - clks_ = new ClockSeq(*value); } PropertyValue::PropertyValue(ClockSet *value) : - type_(type_clocks) + type_(type_clks), + clks_(new ClockSeq) { - init(); - clks_ = new ClockSeq; ClockSet::Iterator clk_iter(value); while (clk_iter.hasNext()) { Clock *clk = clk_iter.next(); @@ -219,72 +203,233 @@ PropertyValue::PropertyValue(ClockSet *value) : } PropertyValue::PropertyValue(PathRefSeq *value) : - type_(type_path_refs) + type_(type_path_refs), + path_refs_(new PathRefSeq(*value)) { - init(); - path_refs_ = new PathRefSeq(*value); } PropertyValue::PropertyValue(const PropertyValue &value) : - type_(value.type_), - string_(stringCopy(value.string_)), - float_(value.float_), - liberty_library_(value.liberty_library_), - liberty_cell_(value.liberty_cell_), - library_(value.library_), - cell_(value.cell_), - inst_(value.inst_), - pin_(value.pin_), - pins_(value.pins_ ? new PinSeq(*value.pins_) : NULL), - net_(value.net_), - clk_(value.clk_), - clks_(value.clks_ ? new ClockSeq(*value.clks_) : NULL), - path_refs_(value.path_refs_ ? new PathRefSeq(*value.path_refs_) : NULL) + type_(value.type_) { + switch (type_) { + case Type::type_none: + break; + case Type::type_string: + string_ = stringCopy(value.string_); + break; + case Type::type_float: + float_ = value.float_; + break; + case Type::type_liberty_library: + liberty_library_ = value.liberty_library_; + break; + case Type::type_liberty_cell: + liberty_cell_ = value.liberty_cell_; + break; + case Type::type_cell: + cell_ = value.cell_; + break; + case Type::type_library: + library_ = value.library_; + break; + case Type::type_instance: + inst_ = value.inst_; + break; + case Type::type_pin: + pin_ = value.pin_; + break; + case Type::type_pins: + pins_ = value.pins_ ? new PinSeq(*value.pins_) : nullptr; + break; + case Type::type_net: + net_ = value.net_; + break; + case Type::type_clk: + clk_ = value.clk_; + break; + case Type::type_clks: + clks_ = value.clks_ ? new ClockSeq(*value.clks_) : nullptr; + break; + case Type::type_path_refs: + path_refs_ = value.path_refs_ ? new PathRefSeq(*value.path_refs_) : nullptr; + break; + } } -void -PropertyValue::init() +PropertyValue::PropertyValue(PropertyValue &&value) : + type_(value.type_) { - string_ = NULL; - float_ = 0.0; - liberty_library_ = NULL; - liberty_cell_ = NULL; - cell_ = NULL; - inst_ = NULL; - pin_ = NULL; - pins_ = NULL; - net_ = NULL; - clk_ = NULL; - clks_ = NULL; - path_refs_ = NULL; + switch (type_) { + case Type::type_none: + break; + case Type::type_string: + string_ = value.string_; + value.string_ = nullptr; + break; + case Type::type_float: + float_ = value.float_; + break; + case Type::type_liberty_library: + liberty_library_ = value.liberty_library_; + break; + case Type::type_liberty_cell: + liberty_cell_ = value.liberty_cell_; + break; + case Type::type_cell: + cell_ = value.cell_; + break; + case Type::type_library: + library_ = value.library_; + break; + case Type::type_instance: + inst_ = value.inst_; + break; + case Type::type_pin: + pin_ = value.pin_; + break; + case Type::type_pins: + pins_ = value.pins_; + value.pins_ = nullptr; + break; + case Type::type_net: + net_ = value.net_; + break; + case Type::type_clk: + clk_ = value.clk_; + break; + case Type::type_clks: + clks_ = value.clks_; + value.clks_ = nullptr; + break; + case Type::type_path_refs: + path_refs_ = value.path_refs_; + value.clks_ = nullptr; + break; + } } PropertyValue::~PropertyValue() { - stringDelete(string_); - delete clks_; - delete pins_; - delete path_refs_; + switch (type_) { + case Type::type_string: + stringDelete(string_); + break; + case Type::type_clks: + delete clks_; + break; + case Type::type_pins: + delete pins_; + break; + case Type::type_path_refs: + delete path_refs_; + break; + default: + break; + } } -void +PropertyValue & PropertyValue::operator=(const PropertyValue &value) { type_ = value.type_; - string_ = stringCopy(value.string_); - float_ = value.float_; - liberty_library_ = value.liberty_library_; - liberty_cell_ = value.liberty_cell_; - library_ = value.library_; - cell_ = value.cell_; - inst_ = value.inst_; - pin_ = value.pin_; - pins_ = value.pins_ ? new PinSeq(*value.pins_) : NULL; - net_ = value.net_; - clk_ = value.clk_; - clks_ = value.clks_ ? new ClockSeq(*value.clks_) : NULL; - path_refs_ = value.path_refs_ ? new PathRefSeq(*value.path_refs_) : NULL; + switch (type_) { + case Type::type_none: + break; + case Type::type_string: + string_ = stringCopy(value.string_); + break; + case Type::type_float: + float_ = value.float_; + break; + case Type::type_liberty_library: + liberty_library_ = value.liberty_library_; + break; + case Type::type_liberty_cell: + liberty_cell_ = value.liberty_cell_; + break; + case Type::type_cell: + cell_ = value.cell_; + break; + case Type::type_library: + library_ = value.library_; + break; + case Type::type_instance: + inst_ = value.inst_; + break; + case Type::type_pin: + pin_ = value.pin_; + break; + case Type::type_pins: + pins_ = value.pins_ ? new PinSeq(*value.pins_) : nullptr; + break; + case Type::type_net: + net_ = value.net_; + break; + case Type::type_clk: + clk_ = value.clk_; + break; + case Type::type_clks: + clks_ = value.clks_ ? new ClockSeq(*value.clks_) : nullptr; + break; + case Type::type_path_refs: + path_refs_ = value.path_refs_ ? new PathRefSeq(*value.path_refs_) : nullptr; + break; + } + return *this; +} + +PropertyValue & +PropertyValue::operator=(PropertyValue &&value) +{ + type_ = value.type_; + switch (type_) { + case Type::type_none: + break; + case Type::type_string: + string_ = value.string_; + value.string_ = nullptr; + break; + case Type::type_float: + float_ = value.float_; + break; + case Type::type_liberty_library: + liberty_library_ = value.liberty_library_; + break; + case Type::type_liberty_cell: + liberty_cell_ = value.liberty_cell_; + break; + case Type::type_cell: + cell_ = value.cell_; + break; + case Type::type_library: + library_ = value.library_; + break; + case Type::type_instance: + inst_ = value.inst_; + break; + case Type::type_pin: + pin_ = value.pin_; + break; + case Type::type_pins: + pins_ = value.pins_; + value.pins_ = nullptr; + break; + case Type::type_net: + net_ = value.net_; + break; + case Type::type_clk: + clk_ = value.clk_; + break; + case Type::type_clks: + clks_ = value.clks_; + value.clks_ = nullptr; + break; + case Type::type_path_refs: + path_refs_ = value.path_refs_; + value.clks_ = nullptr; + break; + } + return *this; } //////////////////////////////////////////////////////////////// @@ -537,12 +682,12 @@ pinSlewProperty(const Pin *pin, Slew slew = min_max->initValue(); if (vertex) { Slew vertex_slew = sta->vertexSlew(vertex, tr, min_max); - if (delayFuzzyGreater(vertex_slew, slew, min_max)) + if (fuzzyGreater(vertex_slew, slew, min_max)) slew = vertex_slew; } if (bidirect_drvr_vertex) { Slew vertex_slew = sta->vertexSlew(bidirect_drvr_vertex, tr, min_max); - if (delayFuzzyGreater(vertex_slew, slew, min_max)) + if (fuzzyGreater(vertex_slew, slew, min_max)) slew = vertex_slew; } return PropertyValue(delayPropertyValue(slew, sta)); diff --git a/search/Property.hh b/search/Property.hh index 90e65601..2e906fbb 100644 --- a/search/Property.hh +++ b/search/Property.hh @@ -36,7 +36,7 @@ public: type_liberty_library, type_liberty_cell, type_library, type_cell, type_instance, type_pin, type_pins, type_net, - type_clock, type_clocks, type_path_refs }; + type_clk, type_clks, type_path_refs }; PropertyValue(); PropertyValue(const char *value); PropertyValue(string &value); @@ -56,6 +56,8 @@ public: PropertyValue(PathRefSeq *value); // Copy constructor. PropertyValue(const PropertyValue &props); + // Move constructor. + PropertyValue(PropertyValue &&props); ~PropertyValue(); Type type() const { return type_; } const char *stringValue() const { return string_; } @@ -71,25 +73,28 @@ public: Clock *clock() const { return clk_; } ClockSeq *clocks() const { return clks_; } PathRefSeq *pathRefs() const { return path_refs_; } - void operator=(const PropertyValue &); + // Copy assignment. + PropertyValue &operator=(const PropertyValue &); + // Move assignment. + PropertyValue &operator=(PropertyValue &&); private: - void init(); - Type type_; - const char *string_; - float float_; - LibertyLibrary *liberty_library_; - LibertyCell *liberty_cell_; - Library *library_; - Cell *cell_; - Instance *inst_; - Pin *pin_; - PinSeq *pins_; - Net *net_; - Clock *clk_; - ClockSeq *clks_; - PathRefSeq *path_refs_; + union { + const char *string_; + float float_; + LibertyLibrary *liberty_library_; + LibertyCell *liberty_cell_; + Library *library_; + Cell *cell_; + Instance *inst_; + Pin *pin_; + PinSeq *pins_; + Net *net_; + Clock *clk_; + ClockSeq *clks_; + PathRefSeq *path_refs_; + }; }; PropertyValue diff --git a/search/ReportPath.cc b/search/ReportPath.cc index e8daae0c..8b19c328 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -64,7 +64,7 @@ ReportField::ReportField(const char *name, left_justify_(left_justify), unit_(unit), enabled_(enabled), - blank_(NULL) + blank_(nullptr) { setWidth(width); } @@ -113,11 +113,11 @@ const float ReportPath::field_blank_ = -1.0; ReportPath::ReportPath(StaState *sta) : StaState(sta), - format_(report_path_full), + format_(ReportPathFormat::full), no_split_(false), start_end_pt_width_(80), - plus_zero_(NULL), - minus_zero_(NULL) + plus_zero_(nullptr), + minus_zero_(nullptr) { setDigits(2); makeFields(); @@ -142,7 +142,7 @@ ReportPath::~ReportPath() void ReportPath::makeFields() { - field_fanout_ = makeField("fanout", "Fanout", 5, false, NULL, true); + field_fanout_ = makeField("fanout", "Fanout", 5, false, nullptr, true); field_capacitance_ = makeField("capacitance", "Cap", 6, false, units_->capacitanceUnit(), true); field_slew_ = makeField("slew", "Slew", 6, false, units_->timeUnit(), @@ -151,10 +151,10 @@ ReportPath::makeFields() true); field_total_ = makeField("total", "Time", 6, false, units_->timeUnit(), true); - field_edge_ = makeField("edge", "", 1, false, NULL, true); - field_case_ = makeField("case", "case", 11, false, NULL, false); + field_edge_ = makeField("edge", "", 1, false, nullptr, true); + field_case_ = makeField("case", "case", 11, false, nullptr, false); field_description_ = makeField("description", "Description", 36, - true, NULL, true); + true, nullptr, true); } ReportField * @@ -180,7 +180,7 @@ ReportPath::findField(const char *name) if (stringEq(name, field->name())) return field; } - return NULL; + return nullptr; } void @@ -265,17 +265,17 @@ ReportPath::reportPathEndHeader() { string header; switch (format_) { - case report_path_full: - case report_path_full_clock: - case report_path_full_clock_expanded: - case report_path_short: - case report_path_endpoint: + case ReportPathFormat::full: + case ReportPathFormat::full_clock: + case ReportPathFormat::full_clock_expanded: + case ReportPathFormat::shorter: + case ReportPathFormat::endpoint: break; - case report_path_summary: + case ReportPathFormat::summary: reportSummaryHeader(header); report_->print(header); break; - case report_path_slack_only: + case ReportPathFormat::slack_only: reportSlackOnlyHeader(header); report_->print(header); break; @@ -290,14 +290,14 @@ ReportPath::reportPathEndFooter() { string header; switch (format_) { - case report_path_full: - case report_path_full_clock: - case report_path_full_clock_expanded: - case report_path_short: + case ReportPathFormat::full: + case ReportPathFormat::full_clock: + case ReportPathFormat::full_clock_expanded: + case ReportPathFormat::shorter: break; - case report_path_endpoint: - case report_path_summary: - case report_path_slack_only: + case ReportPathFormat::endpoint: + case ReportPathFormat::summary: + case ReportPathFormat::slack_only: report_->print("\n"); break; default: @@ -309,7 +309,7 @@ ReportPath::reportPathEndFooter() void ReportPath::reportPathEnd(PathEnd *end) { - reportPathEnd(end, NULL); + reportPathEnd(end, nullptr); } void @@ -318,28 +318,28 @@ ReportPath::reportPathEnd(PathEnd *end, { string result; switch (format_) { - case report_path_full: - case report_path_full_clock: - case report_path_full_clock_expanded: + case ReportPathFormat::full: + case ReportPathFormat::full_clock: + case ReportPathFormat::full_clock_expanded: end->reportFull(this, result); report_->print(result); report_->print("\n\n"); break; - case report_path_short: + case ReportPathFormat::shorter: end->reportShort(this, result); report_->print(result); report_->print("\n\n"); break; - case report_path_endpoint: + case ReportPathFormat::endpoint: reportEndpointHeader(end, prev_end); reportEndLine(end, result); report_->print(result); break; - case report_path_summary: + case ReportPathFormat::summary: reportSummaryLine(end, result); report_->print(result); break; - case report_path_slack_only: + case ReportPathFormat::slack_only: reportSlackOnly(end, result); report_->print(result); break; @@ -354,7 +354,7 @@ ReportPath::reportPathEnds(PathEndSeq *ends) { reportPathEndHeader(); PathEndSeq::Iterator end_iter(ends); - PathEnd *prev_end = NULL; + PathEnd *prev_end = nullptr; while (end_iter.hasNext()) { PathEnd *end = end_iter.next(); reportEndpointHeader(end, prev_end); @@ -371,7 +371,7 @@ void ReportPath::reportEndpointHeader(PathEnd *end, PathEnd *prev_end) { - PathGroup *prev_group = NULL; + PathGroup *prev_group = nullptr; if (prev_end) prev_group = search_->pathGroup(prev_end); PathGroup *group = search_->pathGroup(end); @@ -637,7 +637,7 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end, if (tgt_clk_path->clkInfo(search_)->isPropagated()) { auto width_msg = stdstrPrint("%s nominal pulse width", tgt_clk_name.c_str()); reportLineTotal(width_msg.c_str(), nom_pulse_width, early_late, result); - if (!delayFuzzyZero(latency_diff)) + if (!fuzzyZero(latency_diff)) reportLineTotalMinus("clock latency difference", latency_diff, early_late, result); } @@ -648,19 +648,19 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end, ArcDelay margin = end->margin(this); reportLineTotalMinus("library setup time", margin, early_late, result); reportDashLineTotal(result); - if (!delayFuzzyZero(crpr_diff)) + if (!fuzzyZero(crpr_diff)) reportLineTotalMinus("CRPR difference", crpr_diff, early_late, result); reportLineTotal("max time borrow", max_borrow, early_late, result); } - if (delayFuzzyGreater(borrow, delay_zero) + if (fuzzyGreater(borrow, delay_zero) && (!fuzzyZero(open_uncertainty) - || !delayFuzzyZero(open_crpr))) { + || !fuzzyZero(open_crpr))) { reportDashLineTotal(result); reportLineTotal("actual time borrow", borrow, early_late, result); if (!fuzzyZero(open_uncertainty)) reportLineTotal("open edge uncertainty", open_uncertainty, early_late, result); - if (!delayFuzzyZero(open_crpr)) + if (!fuzzyZero(open_crpr)) reportLineTotal("open edge CRPR", open_crpr, early_late, result); reportDashLineTotal(result); reportLineTotal("time given to startpoint", time_given_to_startpoint, @@ -750,7 +750,7 @@ ReportPath::reportFull(const PathEndPathDelay *end, else { Arrival tgt_clk_delay = end->targetClkDelay(this); Arrival tgt_clk_arrival = delay + tgt_clk_delay; - if (!delayFuzzyZero(tgt_clk_delay)) + if (!fuzzyZero(tgt_clk_delay)) reportLine(clkNetworkDelayIdealProp(isPropagated(tgt_clk_path)), tgt_clk_delay, tgt_clk_arrival, early_late, result); reportClkUncertainty(end, tgt_clk_arrival, result); @@ -1880,8 +1880,8 @@ ReportPath::clkRegLatchDesc(const PathEnd *end) // Goofy libraries can have registers with both rising and falling // clk->q timing arcs. Try and match the timing check transition. const TransRiseFall *check_clk_tr=end->checkArc()->fromTrans()->asRiseFall(); - TimingArcSet *clk_set = NULL; - TimingArcSet *clk_tr_set = NULL; + TimingArcSet *clk_set = nullptr; + TimingArcSet *clk_tr_set = nullptr; Vertex *tgt_clk_vertex = end->targetClkPath()->vertex(this); VertexOutEdgeIterator iter(tgt_clk_vertex, graph_); while (iter.hasNext()) { @@ -1998,7 +1998,7 @@ ReportPath::reportSrcClkAndPath(const Path *path, bool clk_used_as_data = pathFromClkPin(expanded); bool is_prop = isPropagated(path); const EarlyLate *early_late = min_max; - if (reportGenClkSrcPath(clk_path.isNull() ? NULL : &clk_path, + if (reportGenClkSrcPath(clk_path.isNull() ? nullptr : &clk_path, clk, clk_tr, min_max, early_late) && !(path_from_input && !input_has_ref_path)) { reportClkLine(clk, clk_name.c_str(), clk_end_tr, clk_time, @@ -2243,7 +2243,7 @@ ReportPath::reportGenClkSrcPath(const Path *clk_path, ? pathFromGenPropClk(clk_path, early_late) : isGenPropClk(clk, clk_tr, min_max, early_late); return from_gen_prop_clk - && format_ == report_path_full_clock_expanded; + && format_ == ReportPathFormat::full_clock_expanded; } void @@ -2595,7 +2595,7 @@ ReportPath::reportPath5(const Path *path, Pin *pin = vertex->pin(); Arrival time = path1->arrival(this) + time_offset; float incr = 0.0; - const char *line_case = NULL; + const char *line_case = nullptr; bool is_clk_start = network_->isRegClkPin(pin); bool is_clk = path1->isClock(search_); // Always show the search start point (register clk pin). @@ -2605,7 +2605,7 @@ ReportPath::reportPath5(const Path *path, || !is_clk) { const TransRiseFall *tr = path1->transition(this); Slew slew = graph_->slew(vertex, tr, ap_index); - if (prev_arc == NULL) { + if (prev_arc == nullptr) { // First path. reportInputExternalDelay(path1, time_offset, result); size_t next_index = i + 1; @@ -2619,8 +2619,8 @@ ReportPath::reportPath5(const Path *path, // from the input to the loads. Report the wire delay on the // input pin instead. Arrival next_time = next_path->arrival(this) + time_offset; - incr = delayAsFloat(next_time, min_max) - - delayAsFloat(time, min_max); + incr = delayAsFloat(next_time, min_max, sigma_factor_) + - delayAsFloat(time, min_max, sigma_factor_); time = next_time; line_case = "input_drive"; } @@ -2667,19 +2667,19 @@ ReportPath::reportPath5(const Path *path, line_case = "clk_ideal"; } else if (is_clk && !is_clk_start) { - incr = delayAsFloat(time, min_max) - - delayAsFloat(prev_time, min_max); + incr = delayAsFloat(time, min_max, sigma_factor_) + - delayAsFloat(prev_time, min_max, sigma_factor_); line_case = "clk_prop"; } else { - incr = delayAsFloat(time, min_max) - - delayAsFloat(prev_time, min_max); + incr = delayAsFloat(time, min_max, sigma_factor_) + - delayAsFloat(prev_time, min_max, sigma_factor_); line_case = "normal"; } if (report_input_pin_ || (i == path_last_index) || is_clk_start - || (prev_arc == NULL) + || (prev_arc == nullptr) // Filter wire edges from report unless reporting // input pins. || (prev_arc @@ -2711,7 +2711,7 @@ ReportPath::reportPath5(const Path *path, } float fanout = drvrFanout(vertex, min_max); reportLine(what2.c_str(), cap, field_blank_, fanout, - field_blank_, field_blank_, false, min_max, NULL, + field_blank_, field_blank_, false, min_max, nullptr, line_case, result); } else @@ -2867,7 +2867,7 @@ ReportPath::loadCap(Pin *drvr_pin, const TransRiseFall *tr, DcalcAnalysisPt *dcalc_ap) { - Parasitic *parasitic = NULL; + Parasitic *parasitic = nullptr; bool delete_parasitic; if (arc_delay_calc_) arc_delay_calc_->findParasitic(drvr_pin, tr, dcalc_ap, @@ -2909,7 +2909,7 @@ ReportPath::reportLine(const char *what, string &result) { reportLine(what, field_blank_, field_blank_, field_blank_, - field_blank_, total, false, early_late, NULL, NULL, result); + field_blank_, total, false, early_late, nullptr, nullptr, result); } // Report negative total. @@ -2920,7 +2920,7 @@ ReportPath::reportLineNegative(const char *what, string &result) { reportLine(what, field_blank_, field_blank_, field_blank_, - field_blank_, total, true, early_late, NULL, NULL, result); + field_blank_, total, true, early_late, nullptr, nullptr, result); } // Report total, and transition suffix. @@ -2932,7 +2932,7 @@ ReportPath::reportLine(const char *what, string &result) { reportLine(what, field_blank_, field_blank_, field_blank_, - field_blank_, total, false, early_late, tr, NULL, result); + field_blank_, total, false, early_late, tr, nullptr, result); } // Report increment, and total. @@ -2944,7 +2944,7 @@ ReportPath::reportLine(const char *what, string &result) { reportLine(what, field_blank_, field_blank_, field_blank_, - incr, total, false, early_late, NULL, NULL, result); + incr, total, false, early_late, nullptr, nullptr, result); } // Report increment, total, and transition suffix. @@ -2957,7 +2957,7 @@ ReportPath::reportLine(const char *what, string &result) { reportLine(what, field_blank_, field_blank_, field_blank_, - incr, total, false, early_late, tr, NULL, result); + incr, total, false, early_late, tr, nullptr, result); } // Report slew, increment, and total. @@ -2970,7 +2970,7 @@ ReportPath::reportLine(const char *what, string &result) { reportLine(what, field_blank_, slew, field_blank_, - incr, total, false, early_late, NULL, NULL, result); + incr, total, false, early_late, nullptr, nullptr, result); } void @@ -3167,7 +3167,7 @@ ReportPath::reportFieldDelayMinus(Delay value, if (delayAsFloat(value) == field_blank_) reportFieldBlank(field, result); else { - float mean_sigma = delayAsFloat(value, early_late); + float mean_sigma = delayAsFloat(value, early_late, sigma_factor_); const char *str = units_->timeUnit()->asString(-mean_sigma, digits_); if (stringEq(str, plus_zero_)) // Force leading minus sign. @@ -3259,8 +3259,8 @@ ReportPath::reportEndOfLine(string &result) bool ReportPath::reportClkPath() const { - return format_ == report_path_full_clock - || format_ == report_path_full_clock_expanded; + return format_ == ReportPathFormat::full_clock + || format_ == ReportPathFormat::full_clock_expanded; } //////////////////////////////////////////////////////////////// diff --git a/search/Search.cc b/search/Search.cc index 7656bb5b..4d0f6e5c 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -18,8 +18,8 @@ #include // abs #include "Machine.hh" #include "DisallowCopyAssign.hh" -#include "ThreadForEach.hh" #include "Mutex.hh" +#include "ThreadForEach.hh" #include "Report.hh" #include "Debug.hh" #include "Error.hh" @@ -95,7 +95,7 @@ EvalPred::searchThru(Edge *edge) && !role->isTimingCheck() && (search_thru_latches_ || role != TimingRole::latchDtoQ() - || sta_->latches()->latchDtoQState(edge) == latch_state_open); + || sta_->latches()->latchDtoQState(edge) == LatchEnableState::open); } bool @@ -149,7 +149,7 @@ DynLoopSrchPred::hasPendingLoopPaths(Edge *edge, Tag *to_tag = search->thruTag(from_tag, edge, TransRiseFall::rise(), path_ap->pathMinMax(), path_ap); if (to_tag - && (prev_tag_group == NULL + && (prev_tag_group == nullptr || !prev_tag_group->hasTag(from_tag))) return true; } @@ -188,7 +188,7 @@ SearchThru::searchThru(Edge *edge) // Only search thru latch D->Q if it is always open. // Enqueue thru latches is handled explicitly by search. && (edge->role() != TimingRole::latchDtoQ() - || sta_->latches()->latchDtoQState(edge) == latch_state_open) + || sta_->latches()->latchDtoQState(edge) == LatchEnableState::open) && loopEnabled(edge, sdc, graph, search); } @@ -229,7 +229,7 @@ Search::init(StaState *sta) { crpr_path_pruning_enabled_ = true; unconstrained_paths_ = false; - search_adj_ = new SearchThru(NULL, sta); + search_adj_ = new SearchThru(nullptr, sta); eval_pred_ = new EvalPred(sta); check_crpr_ = new CheckCrpr(sta); genclks_ = new Genclks(sta); @@ -241,9 +241,9 @@ Search::init(StaState *sta) requireds_exist_ = false; requireds_seeded_ = false; tns_exists_ = false; - worst_slacks_ = NULL; - arrival_iter_ = new BfsFwdIterator(bfs_arrival, NULL, sta); - required_iter_ = new BfsBkwdIterator(bfs_required, search_adj_, sta); + worst_slacks_ = nullptr; + arrival_iter_ = new BfsFwdIterator(BfsIndex::arrival, nullptr, sta); + required_iter_ = new BfsBkwdIterator(BfsIndex::required, search_adj_, sta); tag_capacity_ = 127; tag_set_ = new TagHashSet(tag_capacity_, false); clk_info_set_ = new ClkInfoSet(ClkInfoLess(sta)); @@ -255,12 +255,12 @@ Search::init(StaState *sta) tag_group_set_ = new TagGroupSet(tag_group_capacity_, false); visit_path_ends_ = new VisitPathEnds(this); gated_clk_ = new GatedClk(this); - path_groups_ = NULL; - endpoints_ = NULL; - invalid_endpoints_ = NULL; - filter_ = NULL; - filter_from_ = NULL; - filter_to_ = NULL; + path_groups_ = nullptr; + endpoints_ = nullptr; + invalid_endpoints_ = nullptr; + filter_ = nullptr; + filter_from_ = nullptr; + filter_to_ = nullptr; found_downstream_clk_pins_ = false; } @@ -349,16 +349,16 @@ Search::deleteFilter() { if (filter_) { sdc_->deleteException(filter_); - filter_ = NULL; - filter_from_ = NULL; + filter_ = nullptr; + filter_from_ = nullptr; } else { // Filter owns filter_from_ if it exists. delete filter_from_; - filter_from_ = NULL; + filter_from_ = nullptr; } delete filter_to_; - filter_to_ = NULL; + filter_to_ = nullptr; } void @@ -395,12 +395,13 @@ Search::deletePaths1(Vertex *vertex) { Arrival *arrivals = vertex->arrivals(); delete [] arrivals; - vertex->setArrivals(NULL); + vertex->setArrivals(nullptr); PathVertexRep *prev_paths = vertex->prevPaths(); delete [] prev_paths; - vertex->setPrevPaths(NULL); + vertex->setPrevPaths(nullptr); vertex->setTagGroupIndex(tag_group_index_max); vertex->setHasRequireds(false); + vertex->setCrprPathPruningDisabled(false); } void @@ -449,7 +450,7 @@ Search::findPathEnds(ExceptionFrom *from, && (from->pins() || from->instances())) || thrus) { - filter_ = sdc_->makeFilterPath(from, thrus, NULL); + filter_ = sdc_->makeFilterPath(from, thrus, nullptr); findFilteredArrivals(); } else @@ -516,7 +517,7 @@ Search::deleteFilterTagGroups() if (group && group->hasFilterTag()) { tag_group_set_->eraseKey(group); - tag_groups_[group->index()] = NULL; + tag_groups_[group->index()] = nullptr; delete group; } } @@ -529,7 +530,7 @@ Search::deleteFilterTags() Tag *tag = tags_[i]; if (tag && tag->isFilter()) { - tags_[i] = NULL; + tags_[i] = nullptr; tag_set_->eraseKey(tag); delete tag; } @@ -611,9 +612,7 @@ Search::seedFilterStarts() ExceptionPt *first_pt = filter_->firstPt(); PinSet first_pins; first_pt->allPins(network_, &first_pins); - PinSet::Iterator pin_iter(first_pins); - while (pin_iter.hasNext()) { - const Pin *pin = pin_iter.next(); + for (auto pin : first_pins) { if (network_->isHierarchical(pin)) { SeedFaninsThruHierPin visitor(graph_, this); visitDrvrLoadsThruHierPin(pin, network_, &visitor); @@ -697,9 +696,8 @@ Search::arrivalInvalid(Vertex *vertex) vertex->name(sdc_network_)); if (!arrival_iter_->inQueue(vertex)) { // Lock for StaDelayCalcObserver called by delay calc threads. - invalid_arrivals_lock_.lock(); + UniqueLock lock(invalid_arrivals_lock_); invalid_arrivals_.insert(vertex); - invalid_arrivals_lock_.unlock(); } tnsInvalid(vertex); } @@ -768,9 +766,8 @@ Search::requiredInvalid(Vertex *vertex) vertex->name(sdc_network_)); if (!required_iter_->inQueue(vertex)) { // Lock for StaDelayCalcObserver called by delay calc threads. - invalid_arrivals_lock_.lock(); + UniqueLock lock(invalid_arrivals_lock_); invalid_requireds_.insert(vertex); - invalid_arrivals_lock_.unlock(); } tnsInvalid(vertex); } @@ -801,9 +798,7 @@ Search::seedClkVertexArrivals() { PinSet clk_pins; findClkVertexPins(clk_pins); - PinSet::Iterator pin_iter(clk_pins); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (auto pin : clk_pins) { Vertex *vertex, *bidirect_drvr_vertex; graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); seedClkVertexArrivals(pin, vertex); @@ -858,10 +853,9 @@ Search::visitStartpoints(VertexVisitor *visitor) } delete pin_iter; - InputDelayVertexPinsIterator *arrival_iter = - sdc_->inputDelayVertexPinsIterator(); - while (arrival_iter->hasNext()) { - const Pin *pin = arrival_iter->next(); + InputDelayVertexPinsIterator arrival_iter(sdc_); + while (arrival_iter.hasNext()) { + const Pin *pin = arrival_iter.next(); // Already hit these. if (!network_->isTopLevelPort(pin)) { Vertex *vertex = graph_->pinDrvrVertex(pin); @@ -869,11 +863,8 @@ Search::visitStartpoints(VertexVisitor *visitor) visitor->visit(vertex); } } - delete arrival_iter; - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { ClockVertexPinIterator pin_iter(clk); while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); @@ -884,29 +875,24 @@ Search::visitStartpoints(VertexVisitor *visitor) } } } - delete clk_iter; // Register clk pins. - VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices()); - while (reg_clk_iter.hasNext()) { - Vertex *vertex = reg_clk_iter.next(); + for (auto vertex : *graph_->regClkVertices()) visitor->visit(vertex); - } - PinSet::Iterator path_pin_iter(sdc_->pathDelayInternalStartpoints()); - while (path_pin_iter.hasNext()) { - Pin *pin = path_pin_iter.next(); - Vertex *vertex = graph_->pinDrvrVertex(pin); - visitor->visit(vertex); + auto startpoints = sdc_->pathDelayInternalStartpoints(); + if (startpoints) { + for (auto pin : *startpoints) { + Vertex *vertex = graph_->pinDrvrVertex(pin); + visitor->visit(vertex); + } } } void Search::visitEndpoints(VertexVisitor *visitor) { - VertexSet::Iterator end_iter(endpoints()); - while (end_iter.hasNext()) { - Vertex *end = end_iter.next(); + for (auto end : *endpoints()) { Pin *pin = end->pin(); // Filter register clock pins (fails on set_max_delay -from clk_src). if (!network_->isRegClkPin(pin) @@ -950,11 +936,8 @@ Search::clearPendingLatchOutputs() void Search::enqueuePendingLatchOutputs() { - VertexSet::Iterator latch_iter(pending_latch_outputs_); - while (latch_iter.hasNext()) { - Vertex *latch_vertex = latch_iter.next(); + for (auto latch_vertex : pending_latch_outputs_) arrival_iter_->enqueue(latch_vertex); - } clearPendingLatchOutputs(); } @@ -1009,7 +992,7 @@ Search::findArrivals1() //////////////////////////////////////////////////////////////// ArrivalVisitor::ArrivalVisitor(const StaState *sta) : - PathVisitor(NULL, sta) + PathVisitor(nullptr, sta) { init0(); init(true); @@ -1037,7 +1020,7 @@ void ArrivalVisitor::init(bool always_to_endpoints) { Search *search = sta_->search(); - init(always_to_endpoints, search ? search->evalPred() : NULL); + init(always_to_endpoints, search ? search->evalPred() : nullptr); } void @@ -1097,7 +1080,6 @@ ArrivalVisitor::visit(Vertex *vertex) && !vertex->crprPathPruningDisabled() && !has_fanin_one_) pruneCrprArrivals(); - vertex->setCrprPathPruningDisabled(false); // Insert paths that originate here but if (!network->isTopLevelPort(pin) @@ -1178,9 +1160,7 @@ ArrivalVisitor::constrainedRequiredsInvalid(Vertex *vertex, // Data checks (vertex does not need to be a clk). DataCheckSet *data_checks = sdc->dataChecksFrom(pin); if (data_checks) { - DataCheckSet::Iterator check_iter(data_checks); - while (check_iter.hasNext()) { - DataCheck *data_check = check_iter.next(); + for (auto data_check : *data_checks) { Pin *to = data_check->to(); search->requiredInvalid(to); } @@ -1189,11 +1169,8 @@ ArrivalVisitor::constrainedRequiredsInvalid(Vertex *vertex, if (is_clk && sdc->gatedClkChecksEnabled()) { PinSet enable_pins; search->gatedClk()->gatedClkEnables(vertex, enable_pins); - PinSet::Iterator enable_iter(enable_pins); - while (enable_iter.hasNext()) { - const Pin *enable = enable_iter.next(); + for (auto enable : enable_pins) search->requiredInvalid(enable); - } } } } @@ -1217,7 +1194,7 @@ Search::arrivalsChanged(Vertex *vertex, bool arrival_exists2; tag_bldr->tagArrival(tag1, arrival2, arrival_exists2); if (!arrival_exists2 - || !delayFuzzyEqual(arrival1, arrival2)) + || !fuzzyEqual(arrival1, arrival2)) return true; } return false; @@ -1260,8 +1237,8 @@ ArrivalVisitor::visitFromToPath(const Pin *, int arrival_index; Tag *tag_match; tag_bldr_->tagMatchArrival(to_tag, tag_match, arrival, arrival_index); - if (tag_match == NULL - || delayFuzzyGreater(to_arrival, arrival, min_max)) { + if (tag_match == nullptr + || fuzzyGreater(to_arrival, arrival, min_max)) { debugPrint5(debug, "search", 3, " %s + %s = %s %s %s\n", delayAsString(from_path->arrival(sta_), sta_), delayAsString(arc_delay, sta_), @@ -1280,8 +1257,8 @@ ArrivalVisitor::visitFromToPath(const Pin *, && !to_is_clk) { tag_bldr_no_crpr_->tagMatchArrival(to_tag, tag_match, arrival, arrival_index); - if (tag_match == NULL - || delayFuzzyGreater(to_arrival, arrival, min_max)) { + if (tag_match == nullptr + || fuzzyGreater(to_arrival, arrival, min_max)) { tag_bldr_no_crpr_->setMatchArrival(to_tag, tag_match, to_arrival, arrival_index, &prev_path); @@ -1323,7 +1300,7 @@ ArrivalVisitor::pruneCrprArrivals() delayAsString(max_crpr, sta_), delayAsString(max_arrival_max_crpr, sta_)); Arrival arrival = tag_bldr_->arrival(arrival_index); - if (delayFuzzyGreater(max_arrival_max_crpr, arrival, min_max)) { + if (fuzzyGreater(max_arrival_max_crpr, arrival, min_max)) { debugPrint1(debug, "search", 3, " pruned %s\n", tag->asString(sta_)); tag_bldr_->deleteArrival(tag); @@ -1343,9 +1320,7 @@ ArrivalVisitor::enqueueRefPinInputDelays(const Pin *ref_pin) InputDelaySet *input_delays = sdc->refPinInputDelays(ref_pin); if (input_delays) { const Graph *graph = sta_->graph(); - InputDelaySet::Iterator input_iter(input_delays); - while (input_iter.hasNext()) { - InputDelay *input_delay = input_iter.next(); + for (auto input_delay : *input_delays) { const Pin *pin = input_delay->pin(); Vertex *vertex, *bidirect_drvr_vertex; graph->pinVertices(pin, vertex, bidirect_drvr_vertex); @@ -1380,9 +1355,8 @@ Search::enqueueLatchDataOutputs(Vertex *vertex) Edge *out_edge = out_edge_iter.next(); if (latches_->isLatchDtoQ(out_edge)) { Vertex *out_vertex = out_edge->to(graph_); - pending_latch_outputs_lock_.lock(); + UniqueLock lock(pending_latch_outputs_lock_); pending_latch_outputs_.insert(out_vertex); - pending_latch_outputs_lock_.unlock(); } } } @@ -1395,19 +1369,14 @@ Search::seedArrivals() findRootVertices(vertices); findInputDrvrVertices(vertices); - VertexSet::Iterator vertex_iter(vertices); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (auto vertex : vertices) seedArrival(vertex); - } } void Search::findClockVertices(VertexSet &vertices) { - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { ClockVertexPinIterator pin_iter(clk); while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); @@ -1418,17 +1387,13 @@ Search::findClockVertices(VertexSet &vertices) vertices.insert(bidirect_drvr_vertex); } } - delete clk_iter; } void Search::seedInvalidArrivals() { - VertexSet::Iterator vertex_iter(invalid_arrivals_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (auto vertex : invalid_arrivals_) seedArrival(vertex); - } invalid_arrivals_.clear(); } @@ -1486,16 +1451,13 @@ Search::seedArrival(Vertex *vertex) void Search::findClkVertexPins(PinSet &clk_pins) { - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { ClockVertexPinIterator pin_iter(clk); while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); clk_pins.insert(pin); } } - delete clk_iter; } void @@ -1503,9 +1465,7 @@ Search::seedClkArrivals(const Pin *pin, Vertex *vertex, TagGroupBldr *tag_bldr) { - ClockSet::Iterator clk_iter(sdc_->findVertexPinClocks(pin)); - while (clk_iter.hasNext()) { - Clock *clk = clk_iter.next(); + for (auto clk : *sdc_->findVertexPinClocks(pin)) { debugPrint2(debug_, "search", 2, "arrival seed clk %s pin %s\n", clk->name(), network_->pathName(pin)); PathAnalysisPtIterator path_ap_iter(this); @@ -1518,7 +1478,7 @@ Search::seedClkArrivals(const Pin *pin, ClockEdge *clk_edge = clk->edge(tr); const EarlyLate *early_late = min_max; if (clk->isGenerated() - && clk->masterClk() == NULL) + && clk->masterClk() == nullptr) seedClkDataArrival(pin, tr, clk, clk_edge, min_max, path_ap, 0.0, tag_bldr); else { @@ -1567,20 +1527,20 @@ Search::seedClkArrival(const Pin *pin, } ClockUncertainties *uncertainties = sdc_->clockUncertainties(pin); - if (uncertainties == NULL) + if (uncertainties == nullptr) uncertainties = clk->uncertainties(); // Propagate liberty "pulse_clock" transition to transitive fanout. LibertyPort *port = network_->libertyPort(pin); - TransRiseFall *pulse_clk_sense = (port ? port->pulseClkSense() : NULL); - ClkInfo *clk_info = findClkInfo(clk_edge, pin, is_propagated, NULL, false, + TransRiseFall *pulse_clk_sense = (port ? port->pulseClkSense() : nullptr); + ClkInfo *clk_info = findClkInfo(clk_edge, pin, is_propagated, nullptr, false, pulse_clk_sense, insertion, latency, - uncertainties, path_ap, NULL); + uncertainties, path_ap, nullptr); // Only false_paths -from apply to clock tree pins. - ExceptionStateSet *states = NULL; + ExceptionStateSet *states = nullptr; sdc_->exceptionFromClkStates(pin,tr,clk,tr,min_max,states); - Tag *tag = findTag(tr, path_ap, clk_info, true, NULL, false, states, true); + Tag *tag = findTag(tr, path_ap, clk_info, true, nullptr, false, states, true); Arrival arrival(clk_edge->time() + insertion); - tag_bldr->setArrival(tag, arrival, NULL); + tag_bldr->setArrival(tag, arrival, nullptr); } void @@ -1597,7 +1557,7 @@ Search::seedClkDataArrival(const Pin *pin, if (tag) { // Data arrivals include insertion delay. Arrival arrival(clk_edge->time() + insertion); - tag_bldr->setArrival(tag, arrival, NULL); + tag_bldr->setArrival(tag, arrival, nullptr); } } @@ -1610,16 +1570,16 @@ Search::clkDataTag(const Pin *pin, const MinMax *min_max, const PathAnalysisPt *path_ap) { - ExceptionStateSet *states = NULL; + ExceptionStateSet *states = nullptr; if (sdc_->exceptionFromStates(pin, tr, clk, tr, min_max, states)) { bool is_propagated = (clk->isPropagated() || sdc_->isPropagatedClock(pin)); ClkInfo *clk_info = findClkInfo(clk_edge, pin, is_propagated, insertion, path_ap); - return findTag(tr, path_ap, clk_info, false, NULL, false, states, true); + return findTag(tr, path_ap, clk_info, false, nullptr, false, states, true); } else - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -1641,7 +1601,7 @@ Search::makeUnclkedPaths(Vertex *vertex, Tag *tag = fromUnclkedInputTag(pin, tr, min_max, path_ap, is_segment_start); if (tag) { - tag_bldr->setArrival(tag, delay_zero, NULL); + tag_bldr->setArrival(tag, delay_zero, nullptr); search_from = true; } } @@ -1653,9 +1613,7 @@ Search::makeUnclkedPaths(Vertex *vertex, void Search::findRootVertices(VertexSet &vertices) { - VertexSet::Iterator root_iter(levelize_->roots()); - while (root_iter.hasNext()) { - Vertex *vertex = root_iter.next(); + for (auto vertex : levelize_->roots()) { const Pin *pin = vertex->pin(); if (!sdc_->isVertexPinClock(pin) && !sdc_->hasInputDelay(pin) @@ -1703,16 +1661,14 @@ Search::seedInputArrivals(ClockSet *clks) { // Input arrivals can be on internal pins, so iterate over the pins // that have input arrivals rather than the top level input pins. - InputDelayVertexPinsIterator *arrival_iter = - sdc_->inputDelayVertexPinsIterator(); - while (arrival_iter->hasNext()) { - const Pin *pin = arrival_iter->next(); + InputDelayVertexPinsIterator arrival_iter(sdc_); + while (arrival_iter.hasNext()) { + const Pin *pin = arrival_iter.next(); if (!sdc_->isVertexPinClock(pin)) { Vertex *vertex = graph_->pinDrvrVertex(pin); seedInputArrival(pin, vertex, clks); } } - delete arrival_iter; } void @@ -1722,18 +1678,18 @@ Search::seedInputArrival(const Pin *pin, { bool has_arrival = false; // There can be multiple arrivals for a pin with wrt different clocks. - PinInputDelayIterator *arrival_iter = sdc_->inputDelayVertexIterator(pin); + VertexPinInputDelayIterator arrival_iter(pin, sdc_); TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); - while (arrival_iter->hasNext()) { - InputDelay *input_delay = arrival_iter->next(); + while (arrival_iter.hasNext()) { + InputDelay *input_delay = arrival_iter.next(); Clock *input_clk = input_delay->clock(); ClockSet *pin_clks = sdc_->findVertexPinClocks(pin); if (input_clk && wrt_clks->hasKey(input_clk) // Input arrivals wrt a clock source pin is the insertion // delay (source latency), but arrivals wrt other clocks // propagate. - && (pin_clks == NULL + && (pin_clks == nullptr || !pin_clks->hasKey(input_clk))) { seedInputDelayArrival(pin, vertex, input_delay, false, &tag_bldr); has_arrival = true; @@ -1741,7 +1697,6 @@ Search::seedInputArrival(const Pin *pin, } if (has_arrival) setVertexArrivals(vertex, &tag_bldr); - delete arrival_iter; } void @@ -1753,7 +1708,7 @@ Search::seedInputArrival(const Pin *pin, seedInputArrival1(pin, vertex, false, tag_bldr); else if (!sdc_->isVertexPinClock(pin)) // Seed inputs without set_input_delays. - seedInputDelayArrival(pin, vertex, NULL, false, tag_bldr); + seedInputDelayArrival(pin, vertex, nullptr, false, tag_bldr); } void @@ -1771,20 +1726,19 @@ Search::seedInputArrival1(const Pin *pin, TagGroupBldr *tag_bldr) { // There can be multiple arrivals for a pin with wrt different clocks. - PinInputDelayIterator *arrival_iter = sdc_->inputDelayVertexIterator(pin); - while (arrival_iter->hasNext()) { - InputDelay *input_delay = arrival_iter->next(); + VertexPinInputDelayIterator arrival_iter(pin, sdc_); + while (arrival_iter.hasNext()) { + InputDelay *input_delay = arrival_iter.next(); Clock *input_clk = input_delay->clock(); ClockSet *pin_clks = sdc_->findVertexPinClocks(pin); // Input arrival wrt a clock source pin is the clock insertion // delay (source latency), but arrivals wrt other clocks // propagate. - if (pin_clks == NULL + if (pin_clks == nullptr || !pin_clks->hasKey(input_clk)) seedInputDelayArrival(pin, vertex, input_delay, is_segment_start, tag_bldr); } - delete arrival_iter; } void @@ -1799,11 +1753,11 @@ Search::seedInputDelayArrival(const Pin *pin, ? "arrival seed input arrival %s\n" : "arrival seed input %s\n", vertex->name(sdc_network_)); - ClockEdge *clk_edge = NULL; - const Pin *ref_pin = NULL; + ClockEdge *clk_edge = nullptr; + const Pin *ref_pin = nullptr; if (input_delay) { clk_edge = input_delay->clkEdge(); - if (clk_edge == NULL + if (clk_edge == nullptr && sdc_->useDefaultArrivalClock()) clk_edge = sdc_->defaultArrivalClockEdge(); ref_pin = input_delay->refPin(); @@ -1822,7 +1776,7 @@ Search::seedInputDelayArrival(const Pin *pin, while (ref_path_iter.hasNext()) { Path *ref_path = ref_path_iter.next(); if (ref_path->isClock(this) - && (clk == NULL + && (clk == nullptr || ref_path->clock(this) == clk)) { float ref_arrival, ref_insertion, ref_latency; inputDelayRefPinArrival(ref_path, ref_path->clkEdge(this), min_max, @@ -1904,7 +1858,7 @@ Search::seedInputDelayArrival(const Pin *pin, min_max, path_ap, tag_bldr); } else - seedInputDelayArrival(pin, tr, 0.0, NULL, clk_edge, + seedInputDelayArrival(pin, tr, 0.0, nullptr, clk_edge, clk_insertion, clk_latency, is_segment_start, min_max, path_ap, tag_bldr); } @@ -1926,7 +1880,7 @@ Search::seedInputDelayArrival(const Pin *pin, Tag *tag = inputDelayTag(pin, tr, clk_edge, clk_insertion, clk_latency, input_delay, is_segment_start, min_max, path_ap); if (tag) - tag_bldr->setArrival(tag, arrival, NULL); + tag_bldr->setArrival(tag, arrival, nullptr); } void @@ -1971,11 +1925,11 @@ Search::inputDelayTag(const Pin *pin, const MinMax *min_max, const PathAnalysisPt *path_ap) { - Clock *clk = NULL; - Pin *clk_pin = NULL; - TransRiseFall *clk_tr = NULL; + Clock *clk = nullptr; + Pin *clk_pin = nullptr; + TransRiseFall *clk_tr = nullptr; bool is_propagated = false; - ClockUncertainties *clk_uncertainties = NULL; + ClockUncertainties *clk_uncertainties = nullptr; if (clk_edge) { clk = clk_edge->clock(); clk_tr = clk_edge->transition(); @@ -1984,12 +1938,12 @@ Search::inputDelayTag(const Pin *pin, clk_uncertainties = clk->uncertainties(); } - ExceptionStateSet *states = NULL; - Tag *tag = NULL; + ExceptionStateSet *states = nullptr; + Tag *tag = nullptr; if (sdc_->exceptionFromStates(pin,tr,clk,clk_tr,min_max,states)) { - ClkInfo *clk_info = findClkInfo(clk_edge, clk_pin, is_propagated, NULL, - false, NULL, clk_insertion, clk_latency, - clk_uncertainties, path_ap, NULL); + ClkInfo *clk_info = findClkInfo(clk_edge, clk_pin, is_propagated, nullptr, + false, nullptr, clk_insertion, clk_latency, + clk_uncertainties, path_ap, nullptr); tag = findTag(tr, path_ap, clk_info, false, input_delay, is_segment_start, states, true); } @@ -2131,7 +2085,7 @@ Search::pathPropagatedToClkSrc(const Pin *pin, const Tag *tag = path->tag(this); if (!tag->isGenClkSrcPath() // Clock source can have input arrivals from unrelated clock. - && tag->inputDelay() == NULL + && tag->inputDelay() == nullptr && sdc_->isPathDelayInternalEndpoint(pin)) { ClockSet *clks = sdc_->findVertexPinClocks(pin); return clks @@ -2161,7 +2115,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, const TimingRole *role = edge->role(); Tag *from_tag = from_path->tag(sta_); ClkInfo *from_clk_info = from_tag->clkInfo(); - Tag *to_tag = NULL; + Tag *to_tag = nullptr; ClockEdge *clk_edge = from_clk_info->clkEdge(); Clock *clk = from_clk_info->clock(); Arrival from_arrival = from_path->arrival(sta_); @@ -2208,12 +2162,12 @@ PathVisitor::visitFromPath(const Pin *from_pin, } } else if (role->genericRole() == TimingRole::regClkToQ()) { - if (clk == NULL + if (clk == nullptr || !sdc->clkStopPropagation(from_pin, clk)) { arc_delay = search->deratedDelay(from_vertex, arc, edge, false, path_ap); // Propagate from unclocked reg/latch clk pins, which have no // clk but are distinguished with a segment_start flag. - if ((clk_edge == NULL + if ((clk_edge == nullptr && from_tag->isSegmentStart()) // Do not propagate paths from input ports with default // input arrival clk thru CLK->Q edges. @@ -2221,7 +2175,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, // Only propagate paths from clocks that have not // passed thru reg/latch D->Q edges. && from_tag->isClock())) { - const TransRiseFall *clk_tr = clk_edge ? clk_edge->transition() : NULL; + const TransRiseFall *clk_tr = clk_edge ? clk_edge->transition() : nullptr; ClkInfo *to_clk_info = from_clk_info; if (network->direction(to_pin)->isInternal()) to_clk_info = search->clkInfoWithCrprClkPath(from_clk_info, @@ -2236,7 +2190,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, to_arrival = from_arrival + arc_delay; } else - to_tag = NULL; + to_tag = nullptr; } } else if (edge->role() == TimingRole::latchDtoQ()) { @@ -2270,7 +2224,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, } else { arc_delay = search->deratedDelay(from_vertex, arc, edge, false, path_ap); - if (!delayFuzzyEqual(arc_delay, min_max->initValue())) { + if (!fuzzyEqual(arc_delay, min_max->initValue())) { to_arrival = from_arrival + arc_delay; to_tag = search->thruTag(from_tag, edge, to_tr, min_max, path_ap); } @@ -2368,7 +2322,7 @@ Search::pathClkPathArrival1(const Path *path, //////////////////////////////////////////////////////////////// // Find tag for a path starting with pin/clk_edge. -// Return NULL if a false path starts at pin/clk_edge. +// Return nullptr if a false path starts at pin/clk_edge. Tag * Search::fromUnclkedInputTag(const Pin *pin, const TransRiseFall *tr, @@ -2376,14 +2330,14 @@ Search::fromUnclkedInputTag(const Pin *pin, const PathAnalysisPt *path_ap, bool is_segment_start) { - ExceptionStateSet *states = NULL; - if (sdc_->exceptionFromStates(pin, tr, NULL, NULL, min_max, states)) { - ClkInfo *clk_info = findClkInfo(NULL, NULL, false, 0.0, path_ap); - return findTag(tr, path_ap, clk_info, false, NULL, + ExceptionStateSet *states = nullptr; + if (sdc_->exceptionFromStates(pin, tr, nullptr, nullptr, min_max, states)) { + ClkInfo *clk_info = findClkInfo(nullptr, nullptr, false, 0.0, path_ap); + return findTag(tr, path_ap, clk_info, false, nullptr, is_segment_start, states, true); } else - return NULL; + return nullptr; } Tag * @@ -2397,15 +2351,15 @@ Search::fromRegClkTag(const Pin *from_pin, const MinMax *min_max, const PathAnalysisPt *path_ap) { - ExceptionStateSet *states = NULL; + ExceptionStateSet *states = nullptr; if (sdc_->exceptionFromStates(from_pin, from_tr, clk, clk_tr, min_max, states)) { // Hack for filter -from reg/Q. sdc_->filterRegQStates(to_pin, to_tr, min_max, states); - return findTag(to_tr, path_ap, clk_info, false, NULL, false, states, true); + return findTag(to_tr, path_ap, clk_info, false, nullptr, false, states, true); } else - return NULL; + return nullptr; } // Insert from_path as ClkInfo crpr_clk_path. @@ -2430,7 +2384,7 @@ Search::clkInfoWithCrprClkPath(ClkInfo *from_clk_info, } // Find tag for a path starting with from_tag going thru edge. -// Return NULL if the result tag completes a false path. +// Return nullptr if the result tag completes a false path. Tag * Search::thruTag(Tag *from_tag, Edge *edge, @@ -2447,7 +2401,7 @@ Search::thruTag(Tag *from_tag, Tag *to_tag = mutateTag(from_tag, from_pin, from_tr, false, from_clk_info, to_pin, to_tr, false, to_is_reg_clk, false, // input delay is not propagated. - from_clk_info, NULL, min_max, path_ap); + from_clk_info, nullptr, min_max, path_ap); return to_tag; } @@ -2476,7 +2430,7 @@ Search::thruClkTag(PathVertex *from_path, edge, to_vertex, to_pin, min_max, path_ap); Tag *to_tag = mutateTag(from_tag,from_pin,from_tr,from_is_clk,from_clk_info, to_pin, to_tr, to_is_clk, to_is_reg_clk, false, - to_clk_info, NULL, min_max, path_ap); + to_clk_info, nullptr, min_max, path_ap); return to_tag; } @@ -2506,7 +2460,7 @@ Search::thruClkInfo(PathVertex *from_path, // Distinguish gen clk src path ClkInfo at generated clock roots, // so that generated clock crpr info can be (later) safely set on // the clkinfo. - const Pin *gen_clk_src = NULL; + const Pin *gen_clk_src = nullptr; if (from_clk_info->isGenClkSrcPath() && sdc_->crprActive() && sdc_->isClock(to_pin)) { @@ -2515,7 +2469,7 @@ Search::thruClkInfo(PathVertex *from_path, changed = true; } - PathVertex *to_crpr_clk_path = NULL; + PathVertex *to_crpr_clk_path = nullptr; if (sdc_->crprActive() && to_vertex->isRegClk()) { to_crpr_clk_path = from_path; @@ -2531,7 +2485,7 @@ Search::thruClkInfo(PathVertex *from_path, changed = true; } else if (from_pulse_sense && - edge->timingArcSet()->sense() == timing_sense_negative_unate) { + edge->timingArcSet()->sense() == TimingSense::negative_unate) { to_pulse_sense = from_pulse_sense->opposite(); changed = true; } @@ -2594,27 +2548,25 @@ Search::mutateTag(Tag *from_tag, const MinMax *min_max, const PathAnalysisPt *path_ap) { - ExceptionStateSet *new_states = NULL; + ExceptionStateSet *new_states = nullptr; ExceptionStateSet *from_states = from_tag->states(); if (from_states) { // Check for state changes in from_tag (but postpone copying state set). bool state_change = false; - ExceptionStateSet::ConstIterator state_iter(from_states); - while (state_iter.hasNext()) { - ExceptionState *state = state_iter.next(); + for (auto state : *from_states) { ExceptionPath *exception = state->exception(); if (state->isComplete() && exception->isFalse() && !from_is_clk) // Don't propagate a completed false path -thru unless it is a // clock (which ignores exceptions). - return NULL; + return nullptr; if (state->matchesNextThru(from_pin,to_pin,to_tr,min_max,network_)) { // Found a -thru that we've been waiting for. if (state->nextState()->isComplete() && exception->isLoop()) // to_pin/edge completes a loop path. - return NULL; + return nullptr; state_change = true; break; } @@ -2629,11 +2581,9 @@ Search::mutateTag(Tag *from_tag, if (new_states || state_change) { // Second pass to apply state changes and add updated existing // states to new states. - if (new_states == NULL) + if (new_states == nullptr) new_states = new ExceptionStateSet; - ExceptionStateSet::ConstIterator state_iter(from_states); - while (state_iter.hasNext()) { - ExceptionState *state = state_iter.next(); + for (auto state : *from_states) { ExceptionPath *exception = state->exception(); if (state->isComplete() && exception->isFalse() @@ -2642,7 +2592,7 @@ Search::mutateTag(Tag *from_tag, // clock. Clocks carry the completed false path to disable // downstream paths that use the clock as data. delete new_states; - return NULL; + return nullptr; } // One edge may traverse multiple hierarchical thru pins. while (state->matchesNextThru(from_pin,to_pin,to_tr,min_max,network_)) @@ -2653,7 +2603,7 @@ Search::mutateTag(Tag *from_tag, && exception->isLoop()) { // to_pin/edge completes a loop path. delete new_states; - return NULL; + return nullptr; } // Kill loop tags at register clock pins. @@ -2691,11 +2641,11 @@ Search::findTagGroup(TagGroupBldr *tag_bldr) { TagGroup probe(tag_bldr); TagGroup *tag_group = tag_group_set_->findKey(&probe); - if (tag_group == NULL) { + if (tag_group == nullptr) { // Recheck with lock. - tag_group_lock_.lock(); + UniqueLock lock(tag_group_lock_); tag_group = tag_group_set_->findKey(&probe); - if (tag_group == NULL) { + if (tag_group == nullptr) { tag_group = tag_bldr->makeTagGroup(tag_group_count_, this); tag_groups_[tag_group_count_++] = tag_group; tag_group_set_->insert(tag_group); @@ -2718,7 +2668,6 @@ Search::findTagGroup(TagGroupBldr *tag_bldr) if (tag_group_count_ > tag_group_index_max) internalError("max tag group index exceeded"); } - tag_group_lock_.unlock(); } return tag_group; } @@ -2744,14 +2693,14 @@ Search::setVertexArrivals(Vertex *vertex, // Requireds can only be reused if the tag group is unchanged. || tag_group == prev_tag_group)) { if (tag_bldr->hasClkTag() || tag_bldr->hasGenClkSrcTag()) { - if (prev_paths == NULL) + if (prev_paths == nullptr) prev_paths = new PathVertexRep[arrival_count]; } else { // Prev paths not required, delete stale ones. delete [] prev_paths; - prev_paths = NULL; - vertex->setPrevPaths(NULL); + prev_paths = nullptr; + vertex->setPrevPaths(nullptr); } tag_bldr->copyArrivals(tag_group, prev_arrivals, prev_paths); vertex->setTagGroupIndex(tag_group->index()); @@ -2761,7 +2710,7 @@ Search::setVertexArrivals(Vertex *vertex, delete [] prev_paths; Arrival *arrivals = new Arrival[arrival_count]; - prev_paths = NULL; + prev_paths = nullptr; if (tag_bldr->hasClkTag() || tag_bldr->hasGenClkSrcTag()) prev_paths = new PathVertexRep[arrival_count]; tag_bldr->copyArrivals(tag_group, arrivals, prev_paths); @@ -2830,7 +2779,7 @@ Search::tagGroup(const Vertex *vertex) const { TagGroupIndex index = vertex->tagGroupIndex(); if (index == tag_group_index_max) - return NULL; + return nullptr; else return tag_groups_[index]; } @@ -2913,11 +2862,11 @@ Search::findTag(const TransRiseFall *tr, Tag probe(0, tr->index(), path_ap->index(), clk_info, is_clk, input_delay, is_segment_start, states, false, this); Tag *tag = tag_set_->findKey(&probe); - if (tag == NULL) { + if (tag == nullptr) { // Recheck with lock. - tag_lock_.lock(); + UniqueLock lock(tag_lock_); tag = tag_set_->findKey(&probe); - if (tag == NULL) { + if (tag == nullptr) { ExceptionStateSet *new_states = !own_states && states ? new ExceptionStateSet(*states) : states; tag = new Tag(tag_count_, tr->index(), path_ap->index(), @@ -2946,7 +2895,6 @@ Search::findTag(const TransRiseFall *tr, if (tag_count_ > tag_index_max) internalError("max tag index exceeded"); } - tag_lock_.unlock(); } if (own_states) delete states; @@ -2973,18 +2921,13 @@ void Search::reportClkInfos() const { Vector clk_infos; - ClkInfoSet::Iterator clk_info_iter1(clk_info_set_); - while (clk_info_iter1.hasNext()) { - ClkInfo *clk_info = clk_info_iter1.next(); + // set -> vector for sorting. + for (auto clk_info : *clk_info_set_) clk_infos.push_back(clk_info); - } sort(clk_infos, ClkInfoLess(this)); - Vector::Iterator clk_info_iter2(clk_infos); - while (clk_info_iter2.hasNext()) { - ClkInfo *clk_info = clk_info_iter2.next(); + for (auto clk_info : clk_infos) report_->print("ClkInfo %s\n", clk_info->asString(this)); - } printf("%lu clk infos\n", clk_info_set_->size()); } @@ -3006,16 +2949,15 @@ Search::findClkInfo(ClockEdge *clk_edge, ClkInfo probe(clk_edge, clk_src, is_propagated, gen_clk_src, gen_clk_src_path, pulse_clk_sense, insertion, latency, uncertainties, path_ap->index(), crpr_clk_path_rep, this); - clk_info_lock_.lock(); + UniqueLock lock(clk_info_lock_); ClkInfo *clk_info = clk_info_set_->findKey(&probe); - if (clk_info == NULL) { + if (clk_info == nullptr) { clk_info = new ClkInfo(clk_edge, clk_src, is_propagated, gen_clk_src, gen_clk_src_path, pulse_clk_sense, insertion, latency, uncertainties, path_ap->index(), crpr_clk_path_rep, this); clk_info_set_->insert(clk_info); } - clk_info_lock_.unlock(); return clk_info; } @@ -3026,8 +2968,8 @@ Search::findClkInfo(ClockEdge *clk_edge, Arrival insertion, const PathAnalysisPt *path_ap) { - return findClkInfo(clk_edge, clk_src, is_propagated, NULL, false, NULL, - insertion, 0.0, NULL, path_ap, NULL); + return findClkInfo(clk_edge, clk_src, is_propagated, nullptr, false, nullptr, + insertion, 0.0, nullptr, path_ap, nullptr); } int @@ -3057,7 +2999,8 @@ Search::timingDerate(Vertex *from_vertex, bool is_clk, const PathAnalysisPt *path_ap) { - PathClkOrData derate_clk_data = is_clk ? path_clk : path_data; + PathClkOrData derate_clk_data = + is_clk ? PathClkOrData::clk : PathClkOrData::data; TimingRole *role = edge->role(); const Pin *pin = from_vertex->pin(); if (role->isWire()) { @@ -3069,11 +3012,11 @@ Search::timingDerate(Vertex *from_vertex, TimingDerateType derate_type; const TransRiseFall *tr; if (role->isTimingCheck()) { - derate_type = timing_derate_cell_check; + derate_type = TimingDerateType::cell_check; tr = arc->toTrans()->asRiseFall(); } else { - derate_type = timing_derate_cell_delay; + derate_type = TimingDerateType::cell_delay; tr = arc->fromTrans()->asRiseFall(); } return sdc_->timingDerateInstance(pin, derate_type, derate_clk_data, tr, @@ -3133,14 +3076,13 @@ Search::clocks(const Pin *pin, void Search::findRequireds() { - Stats stats(debug_); findRequireds(0); - stats.report("Find requireds"); } void Search::findRequireds(Level level) { + Stats stats(debug_); debugPrint1(debug_, "search", 1, "find requireds to level %d\n", level); RequiredVisitor req_visitor(this); if (!requireds_seeded_) @@ -3149,17 +3091,15 @@ Search::findRequireds(Level level) int required_count = required_iter_->visitParallel(level, &req_visitor); requireds_exist_ = true; debugPrint1(debug_, "search", 1, "found %d requireds\n", required_count); + stats.report("Find requireds"); } void Search::seedRequireds() { ensureDownstreamClkPins(); - VertexSet::Iterator end_iter(endpoints()); - while (end_iter.hasNext()) { - Vertex *vertex = end_iter.next(); + for (auto vertex : *endpoints()) seedRequired(vertex); - } requireds_seeded_ = true; requireds_exist_ = true; } @@ -3167,7 +3107,7 @@ Search::seedRequireds() VertexSet * Search::endpoints() { - if (endpoints_ == NULL) { + if (endpoints_ == nullptr) { endpoints_ = new VertexSet; invalid_endpoints_ = new VertexSet; VertexIterator vertex_iter(graph_); @@ -3181,9 +3121,7 @@ Search::endpoints() } } if (invalid_endpoints_) { - VertexSet::Iterator vertex_iter(invalid_endpoints_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (auto vertex : *invalid_endpoints_) { if (isEndpoint(vertex)) { debugPrint1(debug_, "endpoint", 2, "insert %s\n", vertex->name(sdc_network_)); @@ -3252,18 +3190,15 @@ Search::endpointsInvalid() { delete endpoints_; delete invalid_endpoints_; - endpoints_ = NULL; - invalid_endpoints_ = NULL; + endpoints_ = nullptr; + invalid_endpoints_ = nullptr; } void Search::seedInvalidRequireds() { - VertexSet::Iterator vertex_iter(invalid_requireds_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (auto vertex : invalid_requireds_) required_iter_->enqueue(vertex); - } invalid_requireds_.clear(); } @@ -3390,7 +3325,7 @@ RequiredCmp::requiredSet(int arrival_index, Required required, const MinMax *min_max) { - if (delayFuzzyGreater(required, requireds_[arrival_index], min_max)) { + if (fuzzyGreater(required, requireds_[arrival_index], min_max)) { requireds_[arrival_index] = required; have_requireds_ = true; } @@ -3415,7 +3350,7 @@ RequiredCmp::requiredsSave(Vertex *vertex, Required req = requireds_[arrival_index]; if (prev_reqs) { Required prev_req = path->required(sta); - if (!delayFuzzyEqual(prev_req, req)) { + if (!fuzzyEqual(prev_req, req)) { debugPrint2(debug, "search", 3, "required save %s -> %s\n", delayAsString(prev_req, sta), delayAsString(req, sta)); @@ -3552,12 +3487,10 @@ Search::ensureDownstreamClkPins() // Use backward BFS from register clk pins to mark upsteam pins // as having downstream clk pins. ClkTreeSearchPred pred(this); - BfsBkwdIterator iter(bfs_other, &pred, this); - VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices()); - while (reg_clk_iter.hasNext()) { - Vertex *vertex = reg_clk_iter.next(); + BfsBkwdIterator iter(BfsIndex::other, &pred, this); + for (auto vertex : *graph_->regClkVertices()) iter.enqueue(vertex); - } + // Enqueue PLL feedback pins. VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { @@ -3582,9 +3515,9 @@ bool Search::matchesFilter(Path *path, const ClockEdge *to_clk_edge) { - if (filter_ == NULL - && filter_from_ == NULL - && filter_to_ == NULL) + if (filter_ == nullptr + && filter_from_ == nullptr + && filter_to_ == nullptr) return true; else if (filter_) { // -from pins|inst @@ -3592,11 +3525,9 @@ Search::matchesFilter(Path *path, // Path has to be tagged by traversing the filter exception points. ExceptionStateSet *states = path->tag(this)->states(); if (states) { - ExceptionStateSet::ConstIterator state_iter(states); - while (state_iter.hasNext()) { - ExceptionState *state = state_iter.next(); + for (auto state : *states) { if (state->exception() == filter_ - && state->nextThru() == NULL + && state->nextThru() == nullptr && matchesFilterTo(path, to_clk_edge)) return true; } @@ -3604,19 +3535,19 @@ Search::matchesFilter(Path *path, return false; } else if (filter_from_ - && filter_from_->pins() == NULL - && filter_from_->instances() == NULL + && filter_from_->pins() == nullptr + && filter_from_->instances() == nullptr && filter_from_->clks()) { // -from clks ClockEdge *path_clk_edge = path->clkEdge(this); - Clock *path_clk = path_clk_edge ? path_clk_edge->clock() : NULL; + Clock *path_clk = path_clk_edge ? path_clk_edge->clock() : nullptr; TransRiseFall *path_clk_tr = - path_clk_edge ? path_clk_edge->transition() : NULL; + path_clk_edge ? path_clk_edge->transition() : nullptr; return filter_from_->clks()->hasKey(path_clk) && filter_from_->transition()->matches(path_clk_tr) && matchesFilterTo(path, to_clk_edge); } - else if (filter_from_ == NULL + else if (filter_from_ == nullptr && filter_to_) // -to return matchesFilterTo(path, to_clk_edge); @@ -3629,7 +3560,7 @@ bool Search::matchesFilterTo(Path *path, const ClockEdge *to_clk_edge) const { - return (filter_to_ == NULL + return (filter_to_ == nullptr || filter_to_->matchesFilter(path->pin(graph_), to_clk_edge, path->transition(this), network_)); } @@ -3650,19 +3581,17 @@ Search::exceptionTo(ExceptionPathType type, { // Find the highest priority exception carried by the path's tag. int hi_priority = -1; - ExceptionPath *hi_priority_exception = NULL; + ExceptionPath *hi_priority_exception = nullptr; const ExceptionStateSet *states = path->tag(this)->states(); if (states) { - ExceptionStateSet::ConstIterator state_iter(states); - while (state_iter.hasNext()) { - ExceptionState *state = state_iter.next(); + for (auto state : *states) { ExceptionPath *exception = state->exception(); int priority = exception->priority(min_max); - if ((type == exception_type_any + if ((type == ExceptionPathType::any || exception->type() == type) && sdc_->isCompleteTo(state, pin, tr, clk_edge, min_max, match_min_max_exactly, require_to_pin) - && (hi_priority_exception == NULL + && (hi_priority_exception == nullptr || priority > hi_priority || (priority == hi_priority && exception->tighterThan(hi_priority_exception)))) { @@ -3725,9 +3654,8 @@ Search::tnsInvalid(Vertex *vertex) && isEndpoint(vertex)) { debugPrint1(debug_, "tns", 2, "tns invalid %s\n", vertex->name(sdc_network_)); - tns_lock_.lock(); + UniqueLock lock(tns_lock_); invalid_tns_.insert(vertex); - tns_lock_.unlock(); } } @@ -3735,9 +3663,7 @@ void Search::updateInvalidTns() { PathAPIndex path_ap_count = corners_->pathAnalysisPtCount(); - VertexSet::Iterator vertex_iter(invalid_tns_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (auto vertex : invalid_tns_) { // Network edits can change endpointedness since tnsInvalid was called. if (isEndpoint(vertex)) { debugPrint1(debug_, "tns", 2, "update tns %s\n", @@ -3762,9 +3688,7 @@ Search::findTotalNegativeSlacks() tns_[i] = 0.0; tns_slacks_[i].clear(); } - VertexSet::Iterator end_iter(endpoints()); - while (end_iter.hasNext()) { - Vertex *vertex = end_iter.next(); + for (auto vertex : *endpoints()) { // No locking required. SlackSeq slacks(path_ap_count); wnsSlacks(vertex, slacks); @@ -3790,7 +3714,7 @@ Search::tnsIncr(Vertex *vertex, Slack slack, PathAPIndex path_ap_index) { - if (delayFuzzyLess(slack, 0.0)) { + if (fuzzyLess(slack, 0.0)) { debugPrint2(debug_, "tns", 3, "tns+ %s %s\n", delayAsString(slack, this), vertex->name(sdc_network_)); @@ -3809,7 +3733,7 @@ Search::tnsDecr(Vertex *vertex, bool found; tns_slacks_[path_ap_index].findKey(vertex, slack, found); if (found - && delayFuzzyLess(slack, 0.0)) { + && fuzzyLess(slack, 0.0)) { debugPrint2(debug_, "tns", 3, "tns- %s %s\n", delayAsString(slack, this), vertex->name(sdc_network_)); @@ -3870,9 +3794,7 @@ Search::wnsTnsPreamble() findAllArrivals(); // Required times are only needed at endpoints. if (requireds_seeded_) { - VertexSet::Iterator vertex_iter(invalid_requireds_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (Vertex *vertex : invalid_requireds_) { debugPrint1(debug_, "search", 2, "tns update required %s\n", vertex->name(sdc_network_)); if (isEndpoint(vertex)) { @@ -3884,8 +3806,8 @@ Search::wnsTnsPreamble() if (hasFanout(vertex, search_adj_, graph_)) required_iter_->enqueue(vertex); } - invalid_requireds_.eraseKey(vertex); } + invalid_requireds_.clear(); } else seedRequireds(); @@ -3897,7 +3819,7 @@ Search::clearWorstSlack() if (worst_slacks_) { // Don't maintain incremental worst slacks until there is a request. delete worst_slacks_; - worst_slacks_ = NULL; + worst_slacks_ = nullptr; } } @@ -3937,7 +3859,7 @@ FindEndSlackVisitor::visit(PathEnd *path_end) PathRef &path = path_end->pathRef(); PathAPIndex path_ap_index = path.pathAnalysisPtIndex(sta_); Slack slack = path_end->slack(sta_); - if (delayFuzzyLess(slack, slacks_[path_ap_index])) + if (fuzzyLess(slack, slacks_[path_ap_index])) slacks_[path_ap_index] = slack; } } @@ -3964,7 +3886,7 @@ Search::wnsSlacks(Vertex *vertex, PathAPIndex path_ap_index = path->pathAnalysisPtIndex(this); const Slack path_slack = path->slack(this); if (!path->tag(this)->isFilter() - && delayFuzzyLess(path_slack, slacks[path_ap_index])) + && fuzzyLess(path_slack, slacks[path_ap_index])) slacks[path_ap_index] = path_slack; } } @@ -4010,7 +3932,7 @@ void Search::deletePathGroups() { delete path_groups_; - path_groups_ = NULL; + path_groups_ = nullptr; } PathGroup * @@ -4022,7 +3944,7 @@ Search::pathGroup(const PathEnd *path_end) const bool Search::havePathGroups() const { - return path_groups_ != NULL; + return path_groups_ != nullptr; } PathGroup * @@ -4032,7 +3954,7 @@ Search::findPathGroup(const char *name, if (path_groups_) return path_groups_->findPathGroup(name, min_max); else - return NULL; + return nullptr; } PathGroup * @@ -4042,7 +3964,7 @@ Search::findPathGroup(const Clock *clk, if (path_groups_) return path_groups_->findPathGroup(clk, min_max); else - return NULL; + return nullptr; } } // namespace diff --git a/search/Search.hh b/search/Search.hh index 6ba30180..3758c739 100644 --- a/search/Search.hh +++ b/search/Search.hh @@ -17,11 +17,10 @@ #ifndef STA_SEARCH_H #define STA_SEARCH_H +#include #include "MinMax.hh" #include "StaState.hh" #include "HashSet.hh" -#include "HashMap.hh" -#include "Mutex.hh" #include "Transition.hh" #include "LibertyClass.hh" #include "NetworkClass.hh" @@ -77,7 +76,7 @@ public: void setCrprpathPruningEnabled(bool enabled); bool unconstrainedPaths() const { return unconstrained_paths_; } // from/thrus/to are owned and deleted by Search. - // Use corner NULL to report timing for all corners. + // Use corner nullptr to report timing for all corners. // Returned sequence is owned by the caller. // PathEnds are owned by Search PathGroups and deleted on next call. PathEndSeq *findPathEnds(ExceptionFrom *from, @@ -544,7 +543,7 @@ protected: bool requireds_seeded_; // Vertices with invalid arrival times to update and search from. VertexSet invalid_arrivals_; - Mutex invalid_arrivals_lock_; + std::mutex invalid_arrivals_lock_; BfsFwdIterator *arrival_iter_; // Vertices with invalid required times to update and search from. VertexSet invalid_requireds_; @@ -556,33 +555,33 @@ protected: SlackSeq tns_; // Indexed by path_ap->index(). VertexSlackMapSeq tns_slacks_; - Mutex tns_lock_; + std::mutex tns_lock_; // Indexed by path_ap->index(). WorstSlacks *worst_slacks_; // Use pointer to clk_info set so Tag.hh does not need to be included. ClkInfoSet *clk_info_set_; - Mutex clk_info_lock_; + std::mutex clk_info_lock_; // Use pointer to tag set so Tag.hh does not need to be included. TagHashSet *tag_set_; // Entries in tags_ may be missing where previous filter tags were deleted. TagIndex tag_capacity_; Tag **tags_; TagIndex tag_count_; - Mutex tag_lock_; + std::mutex tag_lock_; TagGroupSet *tag_group_set_; TagGroup **tag_groups_; TagGroupIndex tag_group_count_; // Capacity of tag_groups_. TagGroupIndex tag_group_capacity_; - Mutex tag_group_lock_; + std::mutex tag_group_lock_; // Latches data outputs to queue on the next search pass. VertexSet pending_latch_outputs_; - Mutex pending_latch_outputs_lock_; + std::mutex pending_latch_outputs_lock_; VertexSet *endpoints_; VertexSet *invalid_endpoints_; // Filter exception to tag arrivals for // report_timing -from pin|inst -through. - // -to is always NULL. + // -to is always nullptr. FilterPath *filter_; // filter_from_ is owned by filter_ if it exists. ExceptionFrom *filter_from_; diff --git a/search/SearchClass.hh b/search/SearchClass.hh index 11841e52..f9b6959f 100644 --- a/search/SearchClass.hh +++ b/search/SearchClass.hh @@ -114,15 +114,14 @@ typedef Vector SlackSeq; typedef Delay Crpr; typedef Vector PathRefSeq; -typedef enum { - report_path_full, - report_path_full_clock, - report_path_full_clock_expanded, - report_path_short, - report_path_endpoint, - report_path_summary, - report_path_slack_only -} ReportPathFormat; +enum class ReportPathFormat { full, + full_clock, + full_clock_expanded, + shorter, + endpoint, + summary, + slack_only +}; static const int tag_index_bits = 24; static const int tag_index_max = (1 << tag_index_bits) - 1; diff --git a/search/SearchPred.cc b/search/SearchPred.cc index 56d444d0..151dcf71 100644 --- a/search/SearchPred.cc +++ b/search/SearchPred.cc @@ -59,13 +59,14 @@ SearchPred0::searchThru(Edge *edge) || (role == TimingRole::regSetClr() && !sdc->presetClrArcsEnabled()) // Constants on other pins disable this edge (ie, a mux select). - || edge->simTimingSense() == timing_sense_none + || edge->simTimingSense() == TimingSense::none || (edge->isBidirectInstPath() && !sdc->bidirectInstPathsEnabled()) || (edge->isBidirectNetPath() && !sdc->bidirectNetPathsEnabled()) || (role == TimingRole::latchDtoQ() - && sta_->latches()->latchDtoQState(edge)==latch_state_closed)); + && sta_->latches()->latchDtoQState(edge) + == LatchEnableState::closed)); } bool @@ -200,9 +201,9 @@ searchThruSimEdge(const Vertex *vertex, const TransRiseFall *tr) { LogicValue sim_value = vertex->simValue(); switch (sim_value) { - case logic_rise: + case LogicValue::rise: return tr == TransRiseFall::rise(); - case logic_fall: + case LogicValue::fall: return tr == TransRiseFall::fall(); default: return true; @@ -214,15 +215,15 @@ searchThruTimingSense(const Edge *edge, const TransRiseFall *from_tr, const TransRiseFall *to_tr) { switch (edge->simTimingSense()) { - case timing_sense_unknown: + case TimingSense::unknown: return true; - case timing_sense_positive_unate: + case TimingSense::positive_unate: return from_tr == to_tr; - case timing_sense_negative_unate: + case TimingSense::negative_unate: return from_tr != to_tr; - case timing_sense_non_unate: + case TimingSense::non_unate: return true; - case timing_sense_none: + case TimingSense::none: return false; default: return true; diff --git a/search/Sim.cc b/search/Sim.cc index 1800cb85..2ec4bd97 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -17,6 +17,7 @@ #include "Machine.hh" #include "StaConfig.hh" // CUDD #include "Error.hh" +#include "Mutex.hh" #include "Debug.hh" #include "Report.hh" #include "Stats.hh" @@ -44,7 +45,7 @@ findDrvrPin(const Pin *pin, Sim::Sim(StaState *sta) : StaState(sta), - observer_(NULL), + observer_(nullptr), valid_(false), incremental_(false), const_func_pins_valid_(false), @@ -69,27 +70,29 @@ Sim::functionSense(const FuncExpr *expr, debugPrint2(debug_, "sim", 4, "find sense pin %s %s\n", network_->pathName(input_pin), expr->asString()); - cudd_lock_.lock(); - DdNode *bdd = funcBdd(expr, inst); - LibertyPort *input_port = network_->libertyPort(input_pin); - DdNode *input_node = ensureNode(input_port); - unsigned int input_index = Cudd_NodeReadIndex(input_node); - bool increasing = (Cudd_Increasing(cudd_manager_, bdd, input_index) - == Cudd_ReadOne(cudd_manager_)); - bool decreasing = (Cudd_Decreasing(cudd_manager_, bdd, input_index) - == Cudd_ReadOne(cudd_manager_)); - Cudd_RecursiveDeref(cudd_manager_, bdd); - clearSymtab(); - cudd_lock_.unlock(); + bool increasing, decreasing; + { + UniqueLock lock(cudd_lock_); + DdNode *bdd = funcBdd(expr, inst); + LibertyPort *input_port = network_->libertyPort(input_pin); + DdNode *input_node = ensureNode(input_port); + unsigned int input_index = Cudd_NodeReadIndex(input_node); + increasing = (Cudd_Increasing(cudd_manager_, bdd, input_index) + == Cudd_ReadOne(cudd_manager_)); + decreasing = (Cudd_Decreasing(cudd_manager_, bdd, input_index) + == Cudd_ReadOne(cudd_manager_)); + Cudd_RecursiveDeref(cudd_manager_, bdd); + clearSymtab(); + } TimingSense sense; if (increasing && decreasing) - sense = timing_sense_none; + sense = TimingSense::none; else if (increasing) - sense = timing_sense_positive_unate; + sense = TimingSense::positive_unate; else if (decreasing) - sense = timing_sense_negative_unate; + sense = TimingSense::negative_unate; else - sense = timing_sense_non_unate; + sense = TimingSense::non_unate; debugPrint1(debug_, "sim", 4, " %s\n", timingSenseString(sense)); return sense; } @@ -109,29 +112,28 @@ LogicValue Sim::evalExpr(const FuncExpr *expr, const Instance *inst) const { - cudd_lock_.lock(); + UniqueLock lock(cudd_lock_); DdNode *bdd = funcBdd(expr, inst); - LogicValue value = logic_unknown; + LogicValue value = LogicValue::unknown; if (bdd == Cudd_ReadLogicZero(cudd_manager_)) - value = logic_zero; + value = LogicValue::zero; else if (bdd == Cudd_ReadOne(cudd_manager_)) - value = logic_one; + value = LogicValue::one; if (bdd) { Cudd_RecursiveDeref(cudd_manager_, bdd); clearSymtab(); } - cudd_lock_.unlock(); return value; } -// Returns NULL if the expression simply references an internal port. +// Returns nullptr if the expression simply references an internal port. DdNode * Sim::funcBdd(const FuncExpr *expr, const Instance *inst) const { - DdNode *left = NULL; - DdNode *right = NULL; - DdNode *result = NULL; + DdNode *left = nullptr; + DdNode *right = nullptr; + DdNode *result = nullptr; switch (expr->op()) { case FuncExpr::op_port: { LibertyPort *port = expr->port(); @@ -140,10 +142,10 @@ Sim::funcBdd(const FuncExpr *expr, if (pin) { LogicValue value = logicValue(pin); switch (value) { - case logic_zero: + case LogicValue::zero: result = Cudd_ReadLogicZero(cudd_manager_); break; - case logic_one: + case LogicValue::one: result = Cudd_ReadOne(cudd_manager_); break; default: @@ -211,7 +213,7 @@ Sim::ensureNode(LibertyPort *port) const { const char *port_name = port->name(); DdNode *node = symtab_.findKey(port_name); - if (node == NULL) { + if (node == nullptr) { node = Cudd_bddNewVar(cudd_manager_); symtab_[port_name] = node; Cudd_Ref(node); @@ -219,32 +221,107 @@ Sim::ensureNode(LibertyPort *port) const return node; } -#else // CUDD +#else +// No CUDD. -static LogicValue not_logic[5] = - {logic_one, logic_zero, logic_unknown, logic_unknown, logic_unknown}; -static LogicValue or_logic[5][5] = - {{logic_zero, logic_one, logic_unknown, logic_unknown, logic_unknown}, - {logic_one, logic_one, logic_one, logic_one, logic_one}, - {logic_unknown,logic_one, logic_unknown, logic_unknown, logic_unknown}, - {logic_unknown,logic_one, logic_unknown, logic_unknown, logic_unknown}, - {logic_unknown,logic_one, logic_unknown, logic_unknown, logic_unknown}}; -static LogicValue and_logic[5][5] = - {{logic_zero,logic_zero, logic_zero, logic_zero, logic_zero}, - {logic_zero,logic_one, logic_unknown,logic_unknown, logic_unknown}, - {logic_zero,logic_unknown,logic_unknown,logic_unknown, logic_unknown}, - {logic_zero,logic_unknown,logic_unknown,logic_unknown, logic_unknown}, - {logic_zero,logic_unknown,logic_unknown,logic_unknown, logic_unknown}}; -static LogicValue xor_logic[5][5]= - {{logic_zero, logic_one, logic_unknown,logic_unknown, logic_unknown}, - {logic_one, logic_zero, logic_unknown,logic_unknown, logic_unknown}, - {logic_unknown,logic_unknown,logic_unknown,logic_unknown, logic_unknown}, - {logic_unknown,logic_unknown,logic_unknown,logic_unknown, logic_unknown}, - {logic_unknown,logic_unknown,logic_unknown,logic_unknown, logic_unknown}}; +static LogicValue +logicNot(LogicValue value) +{ + static LogicValue logic_not[5] = {LogicValue::one, LogicValue::zero, + LogicValue::unknown, LogicValue::unknown, + LogicValue::unknown}; + return logic_not[int(value)]; +} + +static LogicValue +logicOr(LogicValue value1, + LogicValue value2) +{ + static LogicValue logic_or[5][5] = + {{LogicValue::zero, LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown}, + {LogicValue::one, LogicValue::one, LogicValue::one, LogicValue::one, LogicValue::one}, + {LogicValue::unknown,LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown}, + {LogicValue::unknown,LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown}, + {LogicValue::unknown,LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown}}; + return logic_or[int(value1)][int(value2)]; +} + +static LogicValue +logicAnd(LogicValue value1, + LogicValue value2) +{ + static LogicValue logic_and[5][5] = + {{LogicValue::zero,LogicValue::zero, LogicValue::zero, LogicValue::zero, LogicValue::zero}, + {LogicValue::zero,LogicValue::one, LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}, + {LogicValue::zero,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}, + {LogicValue::zero,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}, + {LogicValue::zero,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}}; + return logic_and[int(value1)][int(value2)]; +} + +static LogicValue +logicXor(LogicValue value1, + LogicValue value2) +{ + static LogicValue logic_xor[5][5]= + {{LogicValue::zero, LogicValue::one, LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}, + {LogicValue::one, LogicValue::zero, LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}, + {LogicValue::unknown,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}, + {LogicValue::unknown,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}, + {LogicValue::unknown,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}}; + return logic_xor[int(value1)][int(value2)]; +} + +static TimingSense +senseNot(TimingSense sense) +{ + static TimingSense sense_not[5] = {TimingSense::negative_unate, + TimingSense::positive_unate, + TimingSense::non_unate, + TimingSense::none, + TimingSense::unknown}; + return sense_not[int(sense)]; +} + +static TimingSense +senseAndOr(TimingSense sense1, + TimingSense sense2) +{ + static TimingSense sense_and_or[5][5] = + {{TimingSense::positive_unate, TimingSense::non_unate, + TimingSense::non_unate, TimingSense::positive_unate, TimingSense::unknown}, + {TimingSense::non_unate, TimingSense::negative_unate, + TimingSense::non_unate, TimingSense::negative_unate, TimingSense::unknown}, + {TimingSense::non_unate, TimingSense::non_unate, TimingSense::non_unate, + TimingSense::non_unate, TimingSense::unknown}, + {TimingSense::positive_unate, TimingSense::negative_unate, + TimingSense::non_unate, TimingSense::none, TimingSense::unknown}, + {TimingSense::unknown, TimingSense::unknown, + TimingSense::unknown, TimingSense::non_unate, TimingSense::unknown}}; + return sense_and_or[int(sense1)][int(sense2)]; +} + +static TimingSense +senseXor(TimingSense sense1, + TimingSense sense2) +{ + static TimingSense xor_sense[5][5] = + {{TimingSense::non_unate, TimingSense::non_unate, + TimingSense::non_unate, TimingSense::non_unate, TimingSense::unknown}, + {TimingSense::non_unate, TimingSense::non_unate, + TimingSense::non_unate, TimingSense::non_unate, TimingSense::unknown}, + {TimingSense::non_unate, TimingSense::non_unate, + TimingSense::non_unate, TimingSense::non_unate, TimingSense::unknown}, + {TimingSense::non_unate, TimingSense::non_unate, + TimingSense::non_unate, TimingSense::none, TimingSense::unknown}, + {TimingSense::unknown, TimingSense::unknown, + TimingSense::unknown, TimingSense::unknown, TimingSense::unknown}}; + return xor_sense[int(sense1)][int(sense2)]; +} Sim::Sim(StaState *sta) : StaState(sta), - observer_(NULL), + observer_(nullptr), valid_(false), incremental_(false), const_func_pins_valid_(false) @@ -256,34 +333,6 @@ Sim::~Sim() delete observer_; } -static TimingSense not_sense[5] = {timing_sense_negative_unate, - timing_sense_positive_unate, - timing_sense_non_unate, - timing_sense_none, - timing_sense_unknown}; -static TimingSense and_or_sense[5][5] = - {{timing_sense_positive_unate, timing_sense_non_unate, - timing_sense_non_unate, timing_sense_positive_unate, timing_sense_unknown}, - {timing_sense_non_unate, timing_sense_negative_unate, - timing_sense_non_unate, timing_sense_negative_unate, timing_sense_unknown}, - {timing_sense_non_unate, timing_sense_non_unate, timing_sense_non_unate, - timing_sense_non_unate, timing_sense_unknown}, - {timing_sense_positive_unate, timing_sense_negative_unate, - timing_sense_non_unate, timing_sense_none, timing_sense_unknown}, - {timing_sense_unknown, timing_sense_unknown, - timing_sense_unknown, timing_sense_non_unate, timing_sense_unknown}}; -static TimingSense xor_sense[5][5] = - {{timing_sense_non_unate, timing_sense_non_unate, - timing_sense_non_unate, timing_sense_non_unate, timing_sense_unknown}, - {timing_sense_non_unate, timing_sense_non_unate, - timing_sense_non_unate, timing_sense_non_unate, timing_sense_unknown}, - {timing_sense_non_unate, timing_sense_non_unate, - timing_sense_non_unate, timing_sense_non_unate, timing_sense_unknown}, - {timing_sense_non_unate, timing_sense_non_unate, - timing_sense_non_unate, timing_sense_none, timing_sense_unknown}, - {timing_sense_unknown, timing_sense_unknown, - timing_sense_unknown, timing_sense_unknown, timing_sense_unknown}}; - TimingSense Sim::functionSense(const FuncExpr *expr, const Pin *input_pin, @@ -308,14 +357,14 @@ Sim::functionSense(const FuncExpr *expr, Pin *pin = network_->findPin(inst, expr->port()); if (pin) { if (pin == input_pin) - sense = timing_sense_positive_unate; + sense = TimingSense::positive_unate; else - sense = timing_sense_none; + sense = TimingSense::none; value = logicValue(pin); } else { - sense = timing_sense_none; - value = logic_unknown; + sense = TimingSense::none; + value = LogicValue::unknown; } break; } @@ -323,17 +372,17 @@ Sim::functionSense(const FuncExpr *expr, TimingSense sense1; LogicValue value1; functionSense(expr->left(), input_pin, inst, sense1, value1); - if (value1 == logic_zero) { - sense = timing_sense_none; - value = logic_one; + if (value1 == LogicValue::zero) { + sense = TimingSense::none; + value = LogicValue::one; } - else if (value1 == logic_one) { - sense = timing_sense_none; - value = logic_zero; + else if (value1 == LogicValue::one) { + sense = TimingSense::none; + value = LogicValue::zero; } else { - sense = not_sense[sense1]; - value = logic_unknown; + sense = senseNot(sense1); + value = LogicValue::unknown; } break; } @@ -342,21 +391,21 @@ Sim::functionSense(const FuncExpr *expr, LogicValue value1, value2; functionSense(expr->left(), input_pin, inst, sense1, value1); functionSense(expr->right(), input_pin, inst, sense2, value2); - if (value1 == logic_one || value2 == logic_one) { - sense = timing_sense_none; - value = logic_one; + if (value1 == LogicValue::one || value2 == LogicValue::one) { + sense = TimingSense::none; + value = LogicValue::one; } - else if (value1 == logic_zero) { + else if (value1 == LogicValue::zero) { sense = sense2; value = value2; } - else if (value2 == logic_zero) { + else if (value2 == LogicValue::zero) { sense = sense1; value = value1; } else { - sense = and_or_sense[sense1][sense2]; - value = logic_unknown; + sense = senseAndOr(sense1, sense2); + value = LogicValue::unknown; } break; } @@ -365,21 +414,21 @@ Sim::functionSense(const FuncExpr *expr, LogicValue value1, value2; functionSense(expr->left(), input_pin, inst, sense1, value1); functionSense(expr->right(), input_pin, inst, sense2, value2); - if (value1 == logic_zero || value2 == logic_zero) { - sense = timing_sense_none; - value = logic_zero; + if (value1 == LogicValue::zero || value2 == LogicValue::zero) { + sense = TimingSense::none; + value = LogicValue::zero; } - else if (value1 == logic_one) { + else if (value1 == LogicValue::one) { sense = sense2; value = value2; } - else if (value2 == logic_one) { + else if (value2 == LogicValue::one) { sense = sense1; value = value1; } else { - sense = and_or_sense[sense1][sense2]; - value = logic_unknown; + sense = senseAndOr(sense1, sense2); + value = LogicValue::unknown; } break; } @@ -388,45 +437,45 @@ Sim::functionSense(const FuncExpr *expr, LogicValue value1, value2; functionSense(expr->left(), input_pin, inst, sense1, value1); functionSense(expr->right(), input_pin, inst, sense2, value2); - if ((value1 == logic_zero && value2 == logic_zero) - || (value1 == logic_one && value2 == logic_one)) { - sense = timing_sense_none; - value = logic_zero; + if ((value1 == LogicValue::zero && value2 == LogicValue::zero) + || (value1 == LogicValue::one && value2 == LogicValue::one)) { + sense = TimingSense::none; + value = LogicValue::zero; } - else if ((value1 == logic_zero && value2 == logic_one) - || (value1 == logic_one && value2 == logic_zero)) { - sense = timing_sense_none; - value = logic_one; + else if ((value1 == LogicValue::zero && value2 == LogicValue::one) + || (value1 == LogicValue::one && value2 == LogicValue::zero)) { + sense = TimingSense::none; + value = LogicValue::one; } - else if (value1 == logic_zero) { + else if (value1 == LogicValue::zero) { sense = sense2; value = value2; } - else if (value1 == logic_one) { - sense = not_sense[sense2]; - value = not_logic[value2]; + else if (value1 == LogicValue::one) { + sense = senseNot(sense2); + value = logicNot(value2); } - else if (value2 == logic_zero) { + else if (value2 == LogicValue::zero) { sense = sense1; value = value1; } - else if (value2 == logic_one) { - sense = not_sense[sense1]; - value = not_logic[value1]; + else if (value2 == LogicValue::one) { + sense = senseNot(sense1); + value = logicNot(value1); } else { - sense = xor_sense[sense1][sense2]; - value = xor_logic[value1][value2]; + sense = senseXor(sense1, sense2); + value = logicXor(value1, value2); } break; } case FuncExpr::op_one: - sense = timing_sense_none; - value = logic_one; + sense = TimingSense::none; + value = LogicValue::one; break; case FuncExpr::op_zero: - sense = timing_sense_none; - value = logic_zero; + sense = TimingSense::none; + value = LogicValue::zero; break; } } @@ -442,26 +491,26 @@ Sim::evalExpr(const FuncExpr *expr, return logicValue(pin); else // Internal ports don't have instance pins. - return logic_unknown; + return LogicValue::unknown; } case FuncExpr::op_not: - return not_logic[evalExpr(expr->left(), inst)]; + return logicNot(evalExpr(expr->left(), inst)); case FuncExpr::op_or: - return or_logic[evalExpr(expr->left(),inst)] - [evalExpr(expr->right(),inst)]; + return logicOr(evalExpr(expr->left(),inst), + evalExpr(expr->right(),inst)); case FuncExpr::op_and: - return and_logic[evalExpr(expr->left(),inst)] - [evalExpr(expr->right(),inst)]; + return logicAnd(evalExpr(expr->left(),inst), + evalExpr(expr->right(),inst)); case FuncExpr::op_xor: - return xor_logic[evalExpr(expr->left(),inst)] - [evalExpr(expr->right(),inst)]; + return logicXor(evalExpr(expr->left(),inst), + evalExpr(expr->right(),inst)); case FuncExpr::op_one: - return logic_one; + return LogicValue::one; case FuncExpr::op_zero: - return logic_zero; + return LogicValue::zero; } // Prevent warnings from lame compilers. - return logic_zero; + return LogicValue::zero; } #endif // CUDD @@ -531,9 +580,9 @@ Sim::propagateToInvalidLoads() Pin *load_pin = load_iter.next(); Net *net = network_->net(load_pin); if (network_->isGround(net)) - setPinValue(load_pin, logic_zero, true); + setPinValue(load_pin, LogicValue::zero, true); else if (network_->isPower(net)) - setPinValue(load_pin, logic_one, true); + setPinValue(load_pin, LogicValue::one, true); else { Pin *drvr_pin = findDrvrPin(load_pin, network_); if (drvr_pin) @@ -604,7 +653,7 @@ Sim::recordConstPinFunc(Pin *pin) FuncExpr *expr = port->function(); if (expr // Tristate outputs do not force the output to be constant. - && port->tristateEnable() == NULL + && port->tristateEnable() == nullptr && (expr->op() == FuncExpr::op_zero || expr->op() == FuncExpr::op_one)) const_func_pins_.insert(pin); @@ -676,7 +725,7 @@ Sim::seedConstants() { // Propagate constants from inputs tied hi/low in the network. enqueueConstantPinInputs(true); - // Propagate set_logic_zero, set_logic_one, set_logic_dc constants. + // Propagate set_LogicValue::zero, set_LogicValue::one, set_logic_dc constants. setConstraintConstPins(sdc_->logicValues(), true); // Propagate set_case_analysis constants. setConstraintConstPins(sdc_->caseLogicValues(), true); @@ -739,12 +788,12 @@ Sim::setConstFuncPins(bool propagate) if (expr->op() == FuncExpr::op_zero) { debugPrint1(debug_, "sim", 2, "func pin %s = 0\n", network_->pathName(pin)); - setPinValue(pin, logic_zero, propagate); + setPinValue(pin, LogicValue::zero, propagate); } else if (expr->op() == FuncExpr::op_one) { debugPrint1(debug_, "sim", 2, "func pin %s = 1\n", network_->pathName(pin)); - setPinValue(pin, logic_one, propagate); + setPinValue(pin, LogicValue::one, propagate); } } } @@ -783,7 +832,7 @@ Sim::removePropagatedValue(const Pin *pin) debugPrint1(debug_, "sim", 2, "pin %s remove prop constant\n", network_->pathName(pin)); Vertex *vertex = graph_->pinLoadVertex(pin); - setSimValue(vertex, logic_unknown); + setSimValue(vertex, LogicValue::unknown); } } } @@ -801,7 +850,7 @@ Sim::setPinValue(const Pin *pin, sdc_->logicValue(pin, constraint_value, exists); if (exists && value != constraint_value) { - if (value != logic_unknown) + if (value != LogicValue::unknown) report_->warn("propagated logic value %c differs from constraint value of %c on pin %s.\n", logicValueString(value), logicValueString(constraint_value), @@ -859,8 +908,8 @@ Sim::evalInstance(const Instance *inst) if (expr) { LogicValue value = evalExpr(expr, inst); FuncExpr *tri_en_expr = port->tristateEnable(); - if (tri_en_expr == NULL - || evalExpr(tri_en_expr, inst) == logic_one) { + if (tri_en_expr == nullptr + || evalExpr(tri_en_expr, inst) == LogicValue::one) { debugPrint3(debug_, "sim", 2, " %s %s = %c\n", port->name(), expr->asString(), @@ -892,7 +941,7 @@ Sim::functionSense(const Instance *inst, const Pin *to_pin) { if (logicZeroOne(from_pin)) - return timing_sense_none; + return TimingSense::none; else { LibertyPort *from_port = network_->libertyPort(from_pin); LibertyPort *to_port = network_->libertyPort(to_pin); @@ -906,9 +955,9 @@ Sim::functionSense(const Instance *inst, if (func->hasPort(from_port)) { // from_pin is an input to the to_pin function. LogicValue tri_enable = evalExpr(tri_func, inst); - if (tri_enable == logic_zero) + if (tri_enable == LogicValue::zero) // Tristate is disabled. - return timing_sense_none; + return TimingSense::none; else return functionSense(func, from_pin, inst); } @@ -927,7 +976,7 @@ Sim::functionSense(const Instance *inst, } } } - return timing_sense_unknown; + return TimingSense::unknown; } } @@ -943,7 +992,7 @@ Sim::logicValue(const Pin *pin) const if (drvr_pin) return logicValue(drvr_pin); } - return logic_unknown; + return LogicValue::unknown; } } @@ -957,13 +1006,13 @@ findDrvrPin(const Pin *pin, if (drvr_iter.hasNext()) return drvr_iter.next(); } - return NULL; + return nullptr; } bool logicValueZeroOne(LogicValue value) { - return value == logic_zero || value == logic_one; + return value == LogicValue::zero || value == LogicValue::one; } bool @@ -996,9 +1045,9 @@ Sim::clearInstSimValues(const Instance *inst) Vertex *vertex, *bidirect_drvr_vertex; graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); if (vertex) - setSimValue(vertex, logic_unknown); + setSimValue(vertex, LogicValue::unknown); if (bidirect_drvr_vertex) - setSimValue(bidirect_drvr_vertex, logic_unknown); + setSimValue(bidirect_drvr_vertex, LogicValue::unknown); } delete pin_iter; } @@ -1047,16 +1096,16 @@ Sim::annotateVertexEdges(const Instance *inst, if (!edge->role()->isWire()) { Vertex *from_vertex = edge->from(graph_); Pin *from_pin = from_vertex->pin(); - TimingSense sense = timing_sense_unknown; + TimingSense sense = TimingSense::unknown; bool is_disabled_cond = false; if (annotate) { // Set timing sense on edges in instances that have constant pins. if (logicZeroOne(from_pin)) - sense = timing_sense_none; + sense = TimingSense::none; else sense = functionSense(inst, from_pin, pin); - if (sense != timing_sense_none) + if (sense != TimingSense::none) // Disable conditional timing edges based on constant pins. is_disabled_cond = isCondDisabled(edge, inst, from_pin, pin, network_,sim_) @@ -1115,7 +1164,7 @@ isCondDisabled(Edge *edge, if (cond) { LogicValue cond_value = sim->evalExpr(cond, inst); disable_cond = cond; - is_disabled = (cond_value == logic_zero); + is_disabled = (cond_value == LogicValue::zero); } else { // Unconditional "default" arc set is disabled if another @@ -1129,7 +1178,7 @@ isCondDisabled(Edge *edge, while (cond_iter.hasNext()) { TimingArcSet *cond_set = cond_iter.next(); FuncExpr *cond = cond_set->cond(); - if (cond && sim->evalExpr(cond, inst) == logic_one) { + if (cond && sim->evalExpr(cond, inst) == LogicValue::one) { disable_cond = cond; is_disabled = true; break; @@ -1174,7 +1223,7 @@ isModeDisabled(Edge *edge, FuncExpr *cond = value_def->cond(); if (cond) { LogicValue cond_value = sim->evalExpr(cond, inst); - if (cond_value == logic_zero) { + if (cond_value == LogicValue::zero) { // For a mode value to be disabled by having a value of // logic zero one mode value must logic one. ModeValueMap::Iterator iter(mode_def->values()); @@ -1184,7 +1233,7 @@ isModeDisabled(Edge *edge, FuncExpr *cond1 = value_def1->cond(); if (cond1) { LogicValue cond_value1 = sim->evalExpr(cond1, inst); - if (cond_value1 == logic_one) { + if (cond_value1 == LogicValue::one) { disable_cond = cond; is_disabled = true; break; @@ -1240,10 +1289,10 @@ isTestDisabled(const Instance *inst, scan_enable = network->findPin(inst, scan_enable_port); if (scan_enable) { LogicValue scan_enable_value = sim->logicValue(scan_enable); - is_disabled = ((scan_enable_value == logic_zero + is_disabled = ((scan_enable_value == LogicValue::zero && (from_port == scan_in_port || to_port == scan_in_port)) - || (scan_enable_value == logic_one + || (scan_enable_value == LogicValue::one && (from_port == data_in_port || to_port == data_in_port))); } diff --git a/search/Sim.hh b/search/Sim.hh index c4203b70..2d6e82d2 100644 --- a/search/Sim.hh +++ b/search/Sim.hh @@ -18,10 +18,10 @@ #define STA_SIM_H #include +#include #include "StaConfig.hh" // CUDD #include "DisallowCopyAssign.hh" #include "Map.hh" -#include "Mutex.hh" #include "StaState.hh" #include "NetworkClass.hh" #include "GraphClass.hh" @@ -135,7 +135,7 @@ protected: DdManager *cudd_manager_; mutable BddSymbolTable symtab_; - mutable Mutex cudd_lock_; + mutable std::mutex cudd_lock_; #endif // CUDD private: diff --git a/search/Sta.cc b/search/Sta.cc index 34337707..5209128d 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -244,7 +244,7 @@ deleteAllMemory() Sta *sta = Sta::sta(); if (sta) { delete sta; - Sta::setSta(NULL); + Sta::setSta(nullptr); } deleteDelayCalcs(); deleteTmpStrings(); @@ -266,15 +266,15 @@ Sta *Sta::sta_; Sta::Sta() : StaState(), - current_instance_(NULL), - check_timing_(NULL), - check_slew_limits_(NULL), - check_min_pulse_widths_(NULL), - check_min_periods_(NULL), - check_max_skews_(NULL), - clk_skews_(NULL), - report_path_(NULL), - power_(NULL), + current_instance_(nullptr), + check_timing_(nullptr), + check_slew_limits_(nullptr), + check_min_pulse_widths_(nullptr), + check_min_periods_(nullptr), + check_max_skews_(nullptr), + clk_skews_(nullptr), + report_path_(nullptr), + power_(nullptr), link_make_black_boxes_(true), update_genclks_(false) { @@ -432,7 +432,7 @@ Sta::makeCmdNetwork() { sdc_network_ = makeSdcNetwork(network_); cmd_network_ = sdc_network_; - cmd_namespace_ = cmd_namespace_sdc; + cmd_namespace_ = CmdNamespace::sdc; } void @@ -536,8 +536,8 @@ Sta::clear() if (check_min_periods_) check_min_periods_->clear(); delete graph_; - graph_ = NULL; - current_instance_ = NULL; + graph_ = nullptr; + current_instance_ = nullptr; // Notify components that graph is toast. updateComponentsState(); } @@ -566,10 +566,10 @@ Sta::setCmdNamespace(CmdNamespace namespc) { cmd_namespace_ = namespc; switch (cmd_namespace_) { - case cmd_namespace_sta: + case CmdNamespace::sta: cmd_network_ = network_; break; - case cmd_namespace_sdc: + case CmdNamespace::sdc: cmd_network_ = sdc_network_; break; } @@ -579,7 +579,7 @@ Sta::setCmdNamespace(CmdNamespace namespc) Instance * Sta::currentInstance() const { - if (current_instance_ == NULL) + if (current_instance_ == nullptr) return network_->topInstance(); else return current_instance_; @@ -606,7 +606,7 @@ Sta::readLiberty(const char *filename, if (library // The default library is the first library read. // This corresponds to a link_path of '*'. - && network_->defaultLibertyLibrary() == NULL) { + && network_->defaultLibertyLibrary() == nullptr) { network_->setDefaultLibertyLibrary(library); // Set units from default (first) library. units_->copy(library->units()); @@ -671,7 +671,7 @@ Sta::setMinLibrary(const char *min_filename, corners_->defaultCorner(), MinMaxAll::min(), false, report_, debug_, network_); - return min_lib != NULL; + return min_lib != nullptr; } else return false; @@ -1100,7 +1100,7 @@ Sta::findClocksMatching(PatternMatch *pattern, ClockIterator * Sta::clockIterator() const { - return sdc_->clockIterator(); + return new ClockIterator(sdc_); } bool @@ -1434,7 +1434,7 @@ Sta::disable(Instance *inst, Pin *to_pin = network_->findPin(inst, to); graph_delay_calc_->delayInvalid(to_pin); } - if (from == NULL && to == NULL) { + if (from == nullptr && to == nullptr) { InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); @@ -1462,7 +1462,7 @@ Sta::removeDisable(Instance *inst, Pin *to_pin = network_->findPin(inst, to); graph_delay_calc_->delayInvalid(to_pin); } - if (from == NULL && to == NULL) { + if (from == nullptr && to == nullptr) { InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); @@ -1709,7 +1709,7 @@ Sta::exprConstantPins(FuncExpr *expr, Instance *inst, PinSet *pins) Pin *pin = network_->findPin(inst, port); if (pin) { LogicValue value = sim_->logicValue(pin); - if (value != logic_unknown) + if (value != LogicValue::unknown) pins->insert(pin); } } @@ -1983,7 +1983,7 @@ Sta::exceptionFromInvalid(const Pin *pin) const { Net *net = network_->net(pin); // Floating pins are invalid. - return (net == NULL + return (net == nullptr && !network_->isTopLevelPort(pin)) || (net // Pins connected to power/ground are invalid. @@ -2102,7 +2102,7 @@ Sta::checkTiming(bool no_input_delay, search_->findAllArrivals(); else search_->findClkArrivals(); - if (check_timing_ == NULL) + if (check_timing_ == nullptr) makeCheckTiming(); return check_timing_->check(no_input_delay, no_output_delay, reg_multiple_clks, reg_no_clks, @@ -2120,7 +2120,7 @@ void Sta::setCrprEnabled(bool enabled) { // Pessimism is only relevant for on_chip_variation analysis. - if (sdc_->analysisType() == analysis_type_on_chip_variation + if (sdc_->analysisType() == AnalysisType::ocv && enabled != sdc_->crprEnabled()) search_->arrivalsInvalid(); sdc_->setCrprEnabled(enabled); @@ -2136,7 +2136,7 @@ void Sta::setCrprMode(CrprMode mode) { // Pessimism is only relevant for on_chip_variation analysis. - if (sdc_->analysisType() == analysis_type_on_chip_variation + if (sdc_->analysisType() == AnalysisType::ocv && sdc_->crprEnabled() && sdc_->crprMode() != mode) search_->arrivalsInvalid(); @@ -2160,6 +2160,16 @@ Sta::setPocvEnabled(bool enabled) updateComponentsState(); } +void +Sta::setSigmaFactor(float factor) +{ + if (!fuzzyEqual(factor, sigma_factor_)) { + sigma_factor_ = factor; + search_->arrivalsInvalid(); + updateComponentsState(); + } +} + bool Sta::propagateGatedClockEnable() const { @@ -2520,7 +2530,7 @@ Sta::reportClkSkew(ClockSet *clks, int digits) { ensureClkArrivals(); - if (clk_skews_ == NULL) + if (clk_skews_ == nullptr) clk_skews_ = new ClkSkews(this); clk_skews_->reportClkSkew(clks, corner, setup_hold, digits); } @@ -2561,14 +2571,14 @@ Sta::findGroupPathPins(const char *group_path_name) { if (!search_->havePathGroups()) { PathEndSeq *path_ends = findPathEnds(// from, thrus, to, unconstrained - NULL, NULL, NULL, false, + nullptr, nullptr, nullptr, false, // corner, min_max, - NULL, MinMaxAll::max(), + nullptr, MinMaxAll::max(), // group_count, endpoint_count, unique_pins 1, 1, false, -INF, INF, // slack_min, slack_max, false, // sort_by_slack - NULL, // group_names + nullptr, // group_names // setup, hold, recovery, removal, true, true, true, true, // clk_gating_setup, clk_gating_hold @@ -2626,7 +2636,7 @@ Sta::vertexWorstArrivalPath(Vertex *vertex, PathVertex *path = path_iter.next(); Arrival arrival = path->arrival(this); if (!path->tag(this)->isGenClkSrcPath() - && delayFuzzyGreater(arrival, worst_arrival, min_max)) { + && fuzzyGreater(arrival, worst_arrival, min_max)) { worst_arrival = arrival; worst_path.init(path); } @@ -2646,7 +2656,7 @@ Sta::vertexWorstArrivalPath(Vertex *vertex, Arrival arrival = path->arrival(this); if (path->minMax(this) == min_max && !path->tag(this)->isGenClkSrcPath() - && delayFuzzyGreater(arrival, worst_arrival, min_max)) { + && fuzzyGreater(arrival, worst_arrival, min_max)) { worst_arrival = arrival; worst_path.init(path); } @@ -2687,7 +2697,7 @@ Sta::vertexWorstSlackPath(Vertex *vertex, if (path->minMax(this) == min_max && !path->tag(this)->isGenClkSrcPath()) { Slack slack = path->slack(this); - if (delayFuzzyLess(slack, min_slack)) { + if (fuzzyLess(slack, min_slack)) { min_slack = slack; worst_path.init(path); } @@ -2721,7 +2731,7 @@ Sta::vertexArrival(Vertex *vertex, if ((clk_edge == clk_edge_wildcard || clk_info->clkEdge() == clk_edge) && !clk_info->isGenClkSrcPath() - && delayFuzzyGreater(path->arrival(this), arrival, min_max)) + && fuzzyGreater(path->arrival(this), arrival, min_max)) arrival = path_arrival; } return arrival; @@ -2750,7 +2760,7 @@ Sta::vertexRequired(Vertex *vertex, const Required path_required = path->required(this); if ((clk_edge == clk_edge_wildcard || path->clkEdge(search_) == clk_edge) - && delayFuzzyGreater(path_required, required, min_max)) + && fuzzyGreater(path_required, required, min_max)) required = path_required; } return required; @@ -2869,23 +2879,26 @@ Sta::findRequired(Vertex *vertex) search_->findAllArrivals(); search_->findRequireds(vertex->level()); if (sdc_->crprEnabled() + && search_->crprPathPruningEnabled() + // Clocks invariably have requireds that are pruned but isn't + // worth finding arrivals and requireds all over again for + // the entire fanout of the clock. + && !search_->isClock(vertex) && vertex->requiredsPruned()) { - debugPrint1(debug_, "search", 2, "resurrect pruned required %s\n", - vertex->name(sdc_network_)); - // printf("resurrect pruned required %s\n", vertex->name(sdc_network_)); // Invalidate arrivals and requireds and disable // path pruning on fanout vertices. int fanout = 0; disableFanoutCrprPruning(vertex, fanout); - // if (fanout > 100) - // printf("fanout %s %d\n", vertex->name(network_), fanout); + debugPrint2(debug_, "search", 1, "resurrect pruned required %s fanout %d\n", + vertex->name(sdc_network_), + fanout); // Find fanout arrivals and requireds with pruning disabled. search_->findArrivals(); search_->findRequireds(vertex->level()); } } -// DFS to invalidate arrivals and requireds to +// DFS to invalidate fanout arrivals and requireds to // find arrivals with pruning disabled. void Sta::disableFanoutCrprPruning(Vertex *vertex, @@ -3052,7 +3065,7 @@ Sta::vertexSlew(Vertex *vertex, while (dcalc_ap_iter.hasNext()) { DcalcAnalysisPt *dcalc_ap = dcalc_ap_iter.next(); Slew slew = graph_->slew(vertex, tr, dcalc_ap->index()); - if (delayFuzzyGreater(slew, mm_slew, min_max)) + if (fuzzyGreater(slew, mm_slew, min_max)) mm_slew = slew; } return mm_slew; @@ -3063,7 +3076,7 @@ Sta::vertexSlew(Vertex *vertex, Graph * Sta::ensureGraph() { - if (graph_ == NULL && network_) { + if (graph_ == nullptr && network_) { makeGraph(); // Update pointers to graph. updateComponentsState(); @@ -3097,9 +3110,7 @@ Sta::updateGeneratedClks() bool gen_clk_changed = true; while (gen_clk_changed) { gen_clk_changed = false; - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); + for (auto clk : sdc_->clks()) { if (clk->isGenerated() && !clk->waveformValid()) { search_->genclks()->ensureMaster(clk); Clock *master_clk = clk->masterClk(); @@ -3109,7 +3120,6 @@ Sta::updateGeneratedClks() } } } - delete clk_iter; } } update_genclks_ = false; @@ -3144,7 +3154,7 @@ Sta::pathDcalcAnalysisPt(Path *path) Vertex * Sta::maxPathCountVertex() const { - Vertex *max_vertex = NULL; + Vertex *max_vertex = nullptr; VertexIndex max_count = 0; VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { @@ -3438,7 +3448,7 @@ Sta::connectedCap(Net *net, Pin * Sta::findNetParasiticDrvrPin(Net *net) const { - Pin *load_pin = NULL; + Pin *load_pin = nullptr; NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); @@ -3810,15 +3820,10 @@ Sta::instanceSetCellPinInvalidate(LibertyPort *from_port, bool Sta::idealClockMode() { - ClockIterator *clk_iter = sdc_->clockIterator(); - while (clk_iter->hasNext()) { - Clock *clk = clk_iter->next(); - if (clk->isPropagated()) { - delete clk_iter; + for (auto clk : sdc_->clks()) { + if (clk->isPropagated()) return false; - } } - delete clk_iter; return true; } @@ -4364,7 +4369,7 @@ FanInOutSrchPred::searchThru(Edge *edge) || edge->isDisabledCond() || sdc->isDisabledCondDefault(edge))) && (thru_constants_ - || edge->simTimingSense() != timing_sense_none); + || edge->simTimingSense() != TimingSense::none); } bool @@ -4760,7 +4765,7 @@ Sta::checkSlewLimitPreamble() updateTiming(false); else findDelays(); - if (check_slew_limits_ == NULL) + if (check_slew_limits_ == nullptr) makeCheckSlewLimits(); } @@ -4838,7 +4843,7 @@ void Sta::minPulseWidthPreamble() { ensureClkArrivals(); - if (check_min_pulse_widths_ == NULL) + if (check_min_pulse_widths_ == nullptr) makeCheckMinPulseWidths(); } @@ -4888,17 +4893,17 @@ Sta::reportMpwCheck(MinPulseWidthCheck *check, //////////////////////////////////////////////////////////////// MinPeriodCheckSeq & -Sta::minPeriodViolations(const Corner *corner) +Sta::minPeriodViolations() { minPeriodPreamble(); - return check_min_periods_->violations(corner); + return check_min_periods_->violations(); } MinPeriodCheck * -Sta::minPeriodSlack(const Corner *corner) +Sta::minPeriodSlack() { minPeriodPreamble(); - return check_min_periods_->minSlackCheck(corner); + return check_min_periods_->minSlackCheck(); } void @@ -4906,7 +4911,7 @@ Sta::minPeriodPreamble() { // Need clk arrivals to know what clks arrive at the clk tree endpoints. ensureClkArrivals(); - if (check_min_periods_ == NULL) + if (check_min_periods_ == nullptr) makeCheckMinPeriods(); } @@ -4944,7 +4949,7 @@ void Sta::maxSkewPreamble() { ensureClkArrivals(); - if (check_max_skews_ == NULL) + if (check_max_skews_ == nullptr) makeCheckMaxSkews(); } @@ -4970,7 +4975,7 @@ Sta::powerPreamble() // Use arrivals to find clocking info. searchPreamble(); search_->findAllArrivals(); - if (power_ == NULL) + if (power_ == nullptr) makePower(); } diff --git a/search/Sta.hh b/search/Sta.hh index e661f0a5..125c96ef 100644 --- a/search/Sta.hh +++ b/search/Sta.hh @@ -57,15 +57,13 @@ class ClkSkews; class ReportField; class Power; class PowerResult; +class ClockIterator; typedef InstanceSeq::Iterator SlowDrvrIterator; typedef Vector CheckError; typedef Vector CheckErrorSeq; -typedef enum { - cmd_namespace_sta, - cmd_namespace_sdc -} CmdNamespace; +enum class CmdNamespace { sta, sdc }; // Initialize sta functions that are not part of the Sta class. void initSta(); @@ -294,14 +292,17 @@ public: void removeClock(Clock *clk); // Update period/waveform for generated clocks from source pin clock. void updateGeneratedClks(); - Clock *findClock(const char *name) const; + // Use Sdc::findClock + Clock *findClock(const char *name) const __attribute__ ((deprecated)); + // Use findClocksMatching. void findClocksMatching(PatternMatch *pattern, - ClockSeq *clks) const; - ClockIterator *clockIterator() const; + ClockSeq *clks) const __attribute__ ((deprecated)); + // Use Sdc::clockIterator. + ClockIterator *clockIterator() const __attribute__ ((deprecated)); // True if pin is defined as a clock source (pin may be hierarchical). bool isClockSrc(const Pin *pin) const; - // Clock used for inputs without defined arrivals. - Clock *defaultArrivalClock() const; + // Use Sdc::defaultArrivalClock. + Clock *defaultArrivalClock() const __attribute__ ((deprecated)); // Propagated (non-ideal) clocks. void setPropagatedClock(Clock *clk); void removePropagatedClock(Clock *clk); @@ -359,7 +360,7 @@ public: bool asynchronous, bool allow_paths, const char *comment); - // NULL name removes all. + // nullptr name removes all. void removeClockGroupsLogicallyExclusive(const char *name); void removeClockGroupsPhysicallyExclusive(const char *name); void removeClockGroupsAsynchronous(const char *name); @@ -611,11 +612,11 @@ public: ClockSet &clks); // Return the pin with the min/max slew limit slack. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. Pin *pinMinSlewLimitSlack(const Corner *corner, const MinMax *min_max); // Return all pins with min/max slew violations. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. PinSeq *pinSlewLimitViolations(const Corner *corner, const MinMax *min_max); void reportSlewLimitShortHeader(); @@ -635,17 +636,17 @@ public: float &limit, float &slack); // Min pulse width check with the least slack. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheck *minPulseWidthSlack(const Corner *corner); // All violating min pulse width checks. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheckSeq &minPulseWidthViolations(const Corner *corner); // Min pulse width checks for pins. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheckSeq &minPulseWidthChecks(PinSeq *pins, const Corner *corner); // All min pulse width checks. - // corner=NULL checks all corners. + // corner=nullptr checks all corners. MinPulseWidthCheckSeq &minPulseWidthChecks(const Corner *corner); void reportMpwChecks(MinPulseWidthCheckSeq *checks, bool verbose); @@ -653,11 +654,9 @@ public: bool verbose); // Min period check with the least slack. - // corner=NULL checks all corners. - MinPeriodCheck *minPeriodSlack(const Corner *corner); + MinPeriodCheck *minPeriodSlack(); // All violating min period checks. - // corner=NULL checks all corners. - MinPeriodCheckSeq &minPeriodViolations(const Corner *corner); + MinPeriodCheckSeq &minPeriodViolations(); void reportChecks(MinPeriodCheckSeq *checks, bool verbose); void reportCheck(MinPeriodCheck *check, @@ -735,6 +734,8 @@ public: // Parametric on chip variation (statisical sta). bool pocvEnabled() const; void setPocvEnabled(bool enabled); + // Number of std deviations from mean to use for normal distributions. + void setSigmaFactor(float factor); // TCL variable sta_propagate_gated_clock_enable. // Propagate gated clock enable arrivals. bool propagateGatedClockEnable() const; @@ -790,7 +791,7 @@ public: ExceptionThruSeq *thrus, ExceptionTo *to, bool unconstrained, - // Use corner NULL to report timing + // Use corner nullptr to report timing // for all corners. const Corner *corner, // max for setup checks. @@ -826,7 +827,7 @@ public: PathEndSeq *reportTiming(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, - // Use corner NULL to report timing + // Use corner nullptr to report timing // for all corners. const Corner *corner, // max for setup checks. @@ -1031,7 +1032,7 @@ public: LogicValue simLogicValue(const Pin *pin); // Iterator for instances sorted by max driver pin slew. - // Call owns iterator and iterator->container(). + // Caller owns iterator and iterator->container(). SlowDrvrIterator *slowDrvrIterator(); // Annotate hierarchical "instance" with parasitics. diff --git a/search/StaState.cc b/search/StaState.cc index 7e6e4cf0..343742c8 100644 --- a/search/StaState.cc +++ b/search/StaState.cc @@ -22,22 +22,23 @@ namespace sta { StaState::StaState() : - report_(NULL), - debug_(NULL), - units_(NULL), - network_(NULL), - sdc_(NULL), - corners_(NULL), - graph_(NULL), - levelize_(NULL), - parasitics_(NULL), - arc_delay_calc_(NULL), - graph_delay_calc_(NULL), - sim_(NULL), - search_(NULL), - latches_(NULL), + report_(nullptr), + debug_(nullptr), + units_(nullptr), + network_(nullptr), + sdc_(nullptr), + corners_(nullptr), + graph_(nullptr), + levelize_(nullptr), + parasitics_(nullptr), + arc_delay_calc_(nullptr), + graph_delay_calc_(nullptr), + sim_(nullptr), + search_(nullptr), + latches_(nullptr), thread_count_(1), - pocv_enabled_(false) + pocv_enabled_(false), + sigma_factor_(1.0) { } @@ -84,6 +85,7 @@ StaState::copyState(const StaState *sta) latches_ = sta->latches_; thread_count_ = sta->thread_count_; pocv_enabled_ = sta->pocv_enabled_; + sigma_factor_ = sta->sigma_factor_; } NetworkEdit * diff --git a/search/StaState.hh b/search/StaState.hh index 316e514e..d74cdde5 100644 --- a/search/StaState.hh +++ b/search/StaState.hh @@ -91,6 +91,7 @@ public: Latches *latches() const { return latches_; } unsigned threadCount() const { return thread_count_; } bool pocvEnabled() const { return pocv_enabled_; } + float sigmaFactor() const { return sigma_factor_; } protected: Report *report_; @@ -112,6 +113,7 @@ protected: Latches *latches_; int thread_count_; bool pocv_enabled_; + float sigma_factor_; private: DISALLOW_COPY_AND_ASSIGN(StaState); diff --git a/search/Tag.cc b/search/Tag.cc index 14226340..a9edbb8c 100644 --- a/search/Tag.cc +++ b/search/Tag.cc @@ -163,7 +163,7 @@ Tag::asString(bool report_index, str += ")"; } else { - if (exception->thrus() != NULL) + if (exception->thrus() != nullptr) str += " (thrus complete)"; } } @@ -241,7 +241,7 @@ Tag::genClkSrcPathClk(const StaState *sta) const } } } - return NULL; + return nullptr; } void @@ -541,8 +541,8 @@ tagStateCmp(const Tag *tag1, { ExceptionStateSet *states1 = tag1->states(); ExceptionStateSet *states2 = tag2->states(); - bool states_null1 = (states1 == NULL || states1->empty()); - bool states_null2 = (states2 == NULL || states2->empty()); + bool states_null1 = (states1 == nullptr || states1->empty()); + bool states_null2 = (states2 == nullptr || states2->empty()); if (states_null1 && states_null2) return 0; @@ -585,8 +585,8 @@ static bool tagStateEqual(ExceptionStateSet *states1, ExceptionStateSet *states2) { - bool states_null1 = (states1 == NULL || states1->empty()); - bool states_null2 = (states2 == NULL || states2->empty()); + bool states_null1 = (states1 == nullptr || states1->empty()); + bool states_null2 = (states2 == nullptr || states2->empty()); if (states_null1 && states_null2) return true; else if (states_null1 != states_null2) @@ -621,7 +621,7 @@ tagStateEqualCrpr(const Tag *tag1, ExceptionStateSet::Iterator state_iter2(states2); ExceptionState *state1, *state2; do { - state1 = NULL; + state1 = nullptr; while (state_iter1.hasNext()) { state1 = state_iter1.next(); ExceptionPath *exception1 = state1->exception(); @@ -629,9 +629,9 @@ tagStateEqualCrpr(const Tag *tag1, || exception1->isLoop()) break; else - state1 = NULL; + state1 = nullptr; } - state2 = NULL; + state2 = nullptr; while (state_iter2.hasNext()) { state2 = state_iter2.next(); ExceptionPath *exception2 = state2->exception(); @@ -639,13 +639,13 @@ tagStateEqualCrpr(const Tag *tag1, || exception2->isLoop()) break; else - state2 = NULL; + state2 = nullptr; } if (state1 != state2) return false; } while (state1 && state2); - return state1 == NULL - && state2 == NULL; + return state1 == nullptr + && state2 == nullptr; } //////////////////////////////////////////////////////////////// diff --git a/search/TagGroup.cc b/search/TagGroup.cc index 0f681e7e..cfb770ac 100644 --- a/search/TagGroup.cc +++ b/search/TagGroup.cc @@ -217,7 +217,7 @@ TagGroupBldr::tagMatchArrival(Tag *tag, if (exists) arrival = arrivals_[arrival_index]; else { - tag_match = NULL; + tag_match = nullptr; arrival = -1.0; arrival_index = -1; } diff --git a/search/VertexVisitor.cc b/search/VertexVisitor.cc index e4bb80a2..e82e14b9 100644 --- a/search/VertexVisitor.cc +++ b/search/VertexVisitor.cc @@ -30,7 +30,7 @@ VertexVisitor * VertexPinCollector::copy() { internalError("VertexPinCollector::copy not supported."); - return NULL; + return nullptr; } void diff --git a/search/VisitPathEnds.cc b/search/VisitPathEnds.cc index 6a3f4f15..0a64bd4b 100644 --- a/search/VisitPathEnds.cc +++ b/search/VisitPathEnds.cc @@ -43,7 +43,7 @@ void VisitPathEnds::visitPathEnds(Vertex *vertex, PathEndVisitor *visitor) { - visitPathEnds(vertex, NULL, MinMaxAll::all(), false, visitor); + visitPathEnds(vertex, nullptr, MinMaxAll::all(), false, visitor); } void @@ -88,7 +88,7 @@ VisitPathEnds::visitClkedPathEnds(const Pin *pin, const MinMax *path_min_max = path_ap->pathMinMax(); const TransRiseFall *end_tr = path->transition(this); Tag *tag = path->tag(this); - if ((corner == NULL + if ((corner == nullptr || path_ap->corner() == corner) && min_max->matches(path_min_max) // Ignore generated clock source paths. @@ -106,7 +106,7 @@ VisitPathEnds::visitClkedPathEnds(const Pin *pin, is_constrained); else if (!sdc_->exceptionToInvalid(pin) && (!filtered - || search_->matchesFilter(path, NULL))) { + || search_->matchesFilter(path, nullptr))) { PathDelay *path_delay = pathDelayTo(path, pin, end_tr, path_min_max); if (path_delay) { PathEndPathDelay path_end(path_delay, path, this); @@ -178,7 +178,7 @@ VisitPathEnds::visitCheckEnd(const Pin *pin, != sdc_->defaultArrivalClockEdge()) // False paths and path delays override // paths. - && (exception == NULL + && (exception == nullptr || exception->isFilter() || exception->isGroupPath() || exception->isMultiCycle())) { @@ -186,7 +186,7 @@ VisitPathEnds::visitCheckEnd(const Pin *pin, if (network_->isLatchData(pin) && check_role == TimingRole::setup()) { PathEndLatchCheck path_end(path, check_arc, edge, - tgt_clk_path, mcp, NULL, + tgt_clk_path, mcp, nullptr, this); visitor->visit(&path_end); is_constrained = true; @@ -200,14 +200,14 @@ VisitPathEnds::visitCheckEnd(const Pin *pin, } else if (exception && exception->isPathDelay() - && (src_clk == NULL + && (src_clk == nullptr || sdc_->sameClockGroup(src_clk, tgt_clk))) { PathDelay *path_delay = dynamic_cast(exception); if (network_->isLatchData(pin) && check_role == TimingRole::setup()) { PathEndLatchCheck path_end(path, check_arc, edge, - tgt_clk_path, NULL, + tgt_clk_path, nullptr, path_delay, this); visitor->visit(&path_end); } @@ -257,14 +257,14 @@ VisitPathEnds::visitCheckEndUnclked(const Pin *pin, if (check_arc->toTrans()->asRiseFall() == end_tr && clk_tr && (!filtered - || search_->matchesFilter(path, NULL))) { + || search_->matchesFilter(path, nullptr))) { ExceptionPath *exception = exceptionTo(path, pin, end_tr, - NULL, min_max); + nullptr, min_max); // False paths and path delays override multicycle paths. if (exception && exception->isPathDelay()) { PathDelay *path_delay = dynamic_cast(exception); - PathEndPathDelay path_end(path_delay, path, NULL, + PathEndPathDelay path_end(path_delay, path, nullptr, check_arc, edge, this); visitor->visit(&path_end); is_constrained = true; @@ -299,10 +299,9 @@ VisitPathEnds::visitOutputDelayEnd(const Pin *pin, bool &is_constrained) { const MinMax *min_max = path_ap->pathMinMax(); - PinOutputDelayIterator *delay_iter = - sdc_->outputDelayVertexIterator(pin); - while (delay_iter->hasNext()) { - OutputDelay *output_delay = delay_iter->next(); + VertexPinOutputDelayIterator delay_iter(pin, sdc_); + while (delay_iter.hasNext()) { + OutputDelay *output_delay = delay_iter.next(); float margin; bool exists; output_delay->delays()->value(end_tr, min_max, margin, exists); @@ -319,7 +318,7 @@ VisitPathEnds::visitOutputDelayEnd(const Pin *pin, while (ref_path_iter.hasNext()) { PathVertex *ref_path = ref_path_iter.next(); if (ref_path->isClock(this) - && (tgt_clk == NULL + && (tgt_clk == nullptr || ref_path->clock(this) == tgt_clk)) visitOutputDelayEnd1(output_delay, pin, path, end_tr, ref_path->clkEdge(this), ref_path, min_max, @@ -328,12 +327,11 @@ VisitPathEnds::visitOutputDelayEnd(const Pin *pin, } else visitOutputDelayEnd1(output_delay, pin, path, end_tr, - tgt_clk_edge, NULL, min_max, + tgt_clk_edge, nullptr, min_max, visitor, is_constrained); } } } - delete delay_iter; } void @@ -361,7 +359,7 @@ VisitPathEnds::visitOutputDelayEnd1(OutputDelay *output_delay, else if (tgt_clk_edge && sdc_->sameClockGroup(path->clock(this), tgt_clk_edge->clock()) // False paths and path delays override. - && (exception == NULL + && (exception == nullptr || exception->isFilter() || exception->isGroupPath() || exception->isMultiCycle())) { @@ -403,14 +401,14 @@ VisitPathEnds::visitGatedClkEnd(const Pin *pin, TransRiseFall *clk_tr = // Clock active value specified by set_clock_gating_check // overrides the library cell function active value. - gated_clk->gatedClkActiveTrans((active_value == logic_unknown) ? + gated_clk->gatedClkActiveTrans((active_value == LogicValue::unknown) ? logic_active_value : active_value, min_max); VertexPathIterator clk_path_iter(clk_vertex, clk_tr, clk_path_ap, this); while (clk_path_iter.hasNext()) { PathVertex *clk_path = clk_path_iter.next(); const ClockEdge *clk_edge = clk_path->clkEdge(this); - const Clock *clk = clk_edge ? clk_edge->clock() : NULL; + const Clock *clk = clk_edge ? clk_edge->clock() : nullptr; if (clk_path->isClock(this) // Ignore unclocked paths (from path delay constraints). && clk_edge @@ -429,7 +427,7 @@ VisitPathEnds::visitGatedClkEnd(const Pin *pin, clk_edge, min_max); if (sdc_->sameClockGroup(src_clk, clk) // False paths and path delays override. - && (exception == NULL + && (exception == nullptr || exception->isFilter() || exception->isGroupPath() || exception->isMultiCycle()) @@ -543,7 +541,7 @@ VisitPathEnds::visitDataCheckEnd1(DataCheck *check, while (tgt_clk_path_iter.hasNext()) { PathVertex *tgt_clk_path = tgt_clk_path_iter.next(); const ClockEdge *tgt_clk_edge = tgt_clk_path->clkEdge(this); - const Clock *tgt_clk = tgt_clk_edge ? tgt_clk_edge->clock() : NULL; + const Clock *tgt_clk = tgt_clk_edge ? tgt_clk_edge->clock() : nullptr; ExceptionPath *exception = exceptionTo(path, pin, end_tr, tgt_clk_edge, min_max); // Ignore generated clock source paths. @@ -560,7 +558,7 @@ VisitPathEnds::visitDataCheckEnd1(DataCheck *check, && (!filtered || search_->matchesFilter(path, tgt_clk_edge))) { // No mcp for data checks. - PathEndDataCheck path_end(check, path, tgt_clk_path, NULL, this); + PathEndDataCheck path_end(check, path, tgt_clk_path, nullptr, this); visitor->visit(&path_end); is_constrained = true; } @@ -584,14 +582,14 @@ VisitPathEnds::visitUnconstrainedPathEnds(const Pin *pin, PathVertex *path = path_iter.next(); PathAnalysisPt *path_ap = path->pathAnalysisPt(this); const MinMax *path_min_max = path_ap->pathMinMax(); - if ((corner == NULL + if ((corner == nullptr || path_ap->corner() == corner) && min_max->matches(path_min_max) // Ignore generated clock source paths. && !path->clkInfo(this)->isGenClkSrcPath() && !search_->pathPropagatedToClkSrc(pin, path) && (!filtered - || search_->matchesFilter(path, NULL)) + || search_->matchesFilter(path, nullptr)) && !falsePathTo(path, pin, path->transition(this), path->minMax(this))) { PathEndUnconstrained path_end(path); @@ -608,10 +606,10 @@ VisitPathEnds::falsePathTo(Path *path, const TransRiseFall *tr, const MinMax *min_max) { - ExceptionPath *exception = search_->exceptionTo(exception_type_false, path, - pin, tr, NULL, min_max, + ExceptionPath *exception = search_->exceptionTo(ExceptionPathType::false_path, path, + pin, tr, nullptr, min_max, false, false); - return exception != NULL; + return exception != nullptr; } PathDelay * @@ -620,8 +618,8 @@ VisitPathEnds::pathDelayTo(Path *path, const TransRiseFall *tr, const MinMax *min_max) { - ExceptionPath *exception = search_->exceptionTo(exception_type_path_delay, - path, pin, tr, NULL, + ExceptionPath *exception = search_->exceptionTo(ExceptionPathType::path_delay, + path, pin, tr, nullptr, min_max, false, // Register clk pins only // match with -to pin. @@ -636,7 +634,7 @@ VisitPathEnds::exceptionTo(const Path *path, const ClockEdge *clk_edge, const MinMax *min_max) const { - return search_->exceptionTo(exception_type_any, path, pin, tr, clk_edge, + return search_->exceptionTo(ExceptionPathType::any, path, pin, tr, clk_edge, min_max, false, false); } diff --git a/search/VisitPathEnds.hh b/search/VisitPathEnds.hh index 83a9699d..9a9cb7b8 100644 --- a/search/VisitPathEnds.hh +++ b/search/VisitPathEnds.hh @@ -33,7 +33,7 @@ public: // All corners, unfiltered. void visitPathEnds(Vertex *vertex, PathEndVisitor *visitor); - // Use corner NULL to visit PathEnds for all corners. + // Use corner nullptr to visit PathEnds for all corners. void visitPathEnds(Vertex *vertex, const Corner *corner, const MinMaxAll *min_max, diff --git a/search/VisitPathGroupVertices.cc b/search/VisitPathGroupVertices.cc index 2748b3a4..fae65a7b 100644 --- a/search/VisitPathGroupVertices.cc +++ b/search/VisitPathGroupVertices.cc @@ -114,7 +114,7 @@ visitPathGroupVertices(PathGroup *path_group, VertexPathSetMap matching_path_map; // Do not visit clock network. SearchPredNonReg2 srch_non_reg(sta); - BfsBkwdIterator bkwd_iter(bfs_other, &srch_non_reg, sta); + BfsBkwdIterator bkwd_iter(BfsIndex::other, &srch_non_reg, sta); // Visit the path ends and filter by path_group to seed the backward search. VisitPathGroupEnds end_visitor(path_group, visitor, &matching_path_map, &bkwd_iter, sta); @@ -197,7 +197,7 @@ vertexPathSetMapInsertPath(VertexPathSetMap *matching_path_map, const StaState *sta) { PathVertexSet *matching_paths = matching_path_map->findKey(vertex); - if (matching_paths == NULL) { + if (matching_paths == nullptr) { PathLess path_less(sta); matching_paths = new PathVertexSet(path_less); (*matching_path_map)[vertex] = matching_paths; diff --git a/search/WorstSlack.cc b/search/WorstSlack.cc index 4ab95659..5dcf2aaa 100644 --- a/search/WorstSlack.cc +++ b/search/WorstSlack.cc @@ -41,7 +41,7 @@ WorstSlacks::worstSlack(const MinMax *min_max, Vertex *&worst_vertex) { worst_slack = MinMax::min()->initValue(); - worst_vertex = NULL; + worst_vertex = nullptr; CornerIterator corner_iter(sta_); while (corner_iter.hasNext()) { Corner *corner = corner_iter.next(); @@ -50,7 +50,7 @@ WorstSlacks::worstSlack(const MinMax *min_max, Vertex *worst_vertex1; worst_slacks_[path_ap_index].worstSlack(path_ap_index, sta_, worst_slack1, worst_vertex1); - if (delayFuzzyLess(worst_slack1, worst_slack)) { + if (fuzzyLess(worst_slack1, worst_slack)) { worst_slack = worst_slack1; worst_vertex = worst_vertex1; } @@ -92,7 +92,7 @@ WorstSlacks::worstSlackNotifyBefore(Vertex *vertex) WorstSlack::WorstSlack() : slack_init_(MinMax::min()->initValue()), - worst_vertex_(NULL), + worst_vertex_(nullptr), worst_slack_(slack_init_), slack_threshold_(slack_init_), min_queue_size_(10), @@ -102,7 +102,7 @@ WorstSlack::WorstSlack() : WorstSlack::WorstSlack(const WorstSlack &) : slack_init_(MinMax::min()->initValue()), - worst_vertex_(NULL), + worst_vertex_(nullptr), worst_slack_(slack_init_), slack_threshold_(slack_init_), min_queue_size_(10), @@ -113,13 +113,12 @@ WorstSlack::WorstSlack(const WorstSlack &) : void WorstSlack::deleteVertexBefore(Vertex *vertex) { - lock_.lock(); + UniqueLock lock(lock_); if (vertex == worst_vertex_) { - worst_vertex_ = NULL; + worst_vertex_ = nullptr; worst_slack_ = slack_init_; } queue_.eraseKey(vertex); - lock_.unlock(); } void @@ -138,7 +137,7 @@ void WorstSlack::findWorstSlack(PathAPIndex path_ap_index, const StaState *sta) { - if (worst_vertex_ == NULL) { + if (worst_vertex_ == nullptr) { if (queue_.empty()) initQueue(path_ap_index, sta); else @@ -155,17 +154,17 @@ WorstSlack::initQueue(PathAPIndex path_ap_index, debugPrint0(debug, "wns", 3, "init queue\n"); queue_.clear(); - worst_vertex_ = NULL; + worst_vertex_ = nullptr; worst_slack_ = slack_init_; slack_threshold_ = slack_init_; VertexSet::Iterator end_iter(search->endpoints()); while (end_iter.hasNext()) { Vertex *vertex = end_iter.next(); Slack slack = search->wnsSlack(vertex, path_ap_index); - if (!delayFuzzyEqual(slack, slack_init_)) { - if (delayFuzzyLess(slack, worst_slack_)) + if (!fuzzyEqual(slack, slack_init_)) { + if (fuzzyLess(slack, worst_slack_)) setWorstSlack(vertex, slack, sta); - if (delayFuzzyLessEqual(slack, slack_threshold_)) + if (fuzzyLessEqual(slack, slack_threshold_)) queue_.insert(vertex); int queue_size = queue_.size(); if (queue_size >= max_queue_size_) @@ -208,7 +207,7 @@ WorstSlack::sortQueue(PathAPIndex path_ap_index, while (queue_iter2.hasNext()) { Vertex *vertex = queue_iter2.next(); Slack slack = search->wnsSlack(vertex, path_ap_index); - if (delayFuzzyGreater(slack, slack_threshold_)) + if (fuzzyGreater(slack, slack_threshold_)) break; queue_.insert(vertex); } @@ -226,7 +225,7 @@ WorstSlack::findWorstInQueue(PathAPIndex path_ap_index, const Debug *debug = sta->debug(); debugPrint0(debug, "wns", 3, "find worst in queue\n"); - worst_vertex_ = NULL; + worst_vertex_ = nullptr; worst_slack_ = slack_init_; VertexSet::Iterator queue_iter(queue_); while (queue_iter.hasNext()) { @@ -249,7 +248,7 @@ WorstSlack::checkQueue(PathAPIndex path_ap_index, VertexSet::Iterator end_iter(search->endpoints()); while (end_iter.hasNext()) { Vertex *end = end_iter.next(); - if (delayFuzzyLessEqual(search->wnsSlack(end, path_ap_index), + if (fuzzyLessEqual(search->wnsSlack(end, path_ap_index), slack_threshold_)) ends.push_back(end); } @@ -262,7 +261,7 @@ WorstSlack::checkQueue(PathAPIndex path_ap_index, Vertex *end = end_iter2.next(); end_set.insert(end); if (!queue_.hasKey(end) - && delayFuzzyLessEqual(search->wnsSlack(end, path_ap_index), + && fuzzyLessEqual(search->wnsSlack(end, path_ap_index), slack_threshold_)) report->print("WorstSlack queue missing %s %s < %s\n", end->name(network), @@ -293,16 +292,16 @@ WorstSlack::updateWorstSlack(Vertex *vertex, // Locking is required because ArrivalVisitor is called by multiple // threads. - lock_.lock(); + UniqueLock lock(lock_); if (worst_vertex_ - && delayFuzzyLess(slack, worst_slack_)) + && fuzzyLess(slack, worst_slack_)) setWorstSlack(vertex, slack, sta); else if (vertex == worst_vertex_) // Mark worst slack as unknown (updated by findWorstSlack(). - worst_vertex_ = NULL; + worst_vertex_ = nullptr; - if (!delayFuzzyEqual(slack, slack_init_) - && delayFuzzyLessEqual(slack, slack_threshold_)) { + if (!fuzzyEqual(slack, slack_init_) + && fuzzyLessEqual(slack, slack_threshold_)) { debugPrint2(debug, "wns", 3, "insert %s %s\n", vertex->name(network), delayAsString(slack, sta)); @@ -314,7 +313,6 @@ WorstSlack::updateWorstSlack(Vertex *vertex, delayAsString(slack, sta)); queue_.eraseKey(vertex); } - lock_.unlock(); // checkQueue(); } @@ -343,7 +341,7 @@ bool WnsSlackLess::operator()(Vertex *vertex1, Vertex *vertex2) { - return delayFuzzyLess(search_->wnsSlack(vertex1, path_ap_index_), + return fuzzyLess(search_->wnsSlack(vertex1, path_ap_index_), search_->wnsSlack(vertex2, path_ap_index_)); } diff --git a/search/WorstSlack.hh b/search/WorstSlack.hh index 92bdd6b5..e36a3a73 100644 --- a/search/WorstSlack.hh +++ b/search/WorstSlack.hh @@ -19,6 +19,7 @@ namespace sta { +#include #include "MinMax.hh" #include "Vector.hh" #include "GraphClass.hh" @@ -98,7 +99,7 @@ protected: Slack slack_init_; // Vertex with the worst slack. - // When NULL the worst slack is unknown but in the queue. + // When nullptr the worst slack is unknown but in the queue. Vertex *worst_vertex_; Slack worst_slack_; Slack slack_threshold_; @@ -108,7 +109,7 @@ protected: // reaches max_queue_size_. int min_queue_size_; int max_queue_size_; - Mutex lock_; + std::mutex lock_; }; } // namespace diff --git a/search/WritePathSpice.cc b/search/WritePathSpice.cc index f440100c..e892ba08 100644 --- a/search/WritePathSpice.cc +++ b/search/WritePathSpice.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include "Machine.hh" #include "Debug.hh" #include "Error.hh" @@ -290,13 +289,18 @@ WritePathSpice::WritePathSpice(Path *path, power_name_(power_name), gnd_name_(gnd_name), path_expanded_(sta), - net_name_(NULL), + net_name_(nullptr), default_library_(network_->defaultLibertyLibrary()), short_ckt_resistance_(.0001), clk_cycle_count_(3) { - power_voltage_ = default_library_->supplyVoltage(power_name_); - gnd_voltage_ = default_library_->supplyVoltage(gnd_name_); + bool exists; + default_library_->supplyVoltage(power_name_, power_voltage_, exists); + if (!exists) + report_->error("supply %s voltage not found,\n", power_name_); + default_library_->supplyVoltage(gnd_name_, gnd_voltage_, exists); + if (!exists) + report_->error("supply %s voltage not found,\n", gnd_name_); } WritePathSpice::~WritePathSpice() @@ -330,7 +334,7 @@ WritePathSpice::writeHeader() { auto min_max = path_->minMax(this); auto pvt = sdc_->operatingConditions(min_max); - if (pvt == NULL) + if (pvt == nullptr) pvt = default_library_->defaultOperatingConditions(); Path *start_path = path_expanded_.startPath(); streamPrint(spice_stream_, "* Path from %s %s to %s %s\n", @@ -413,7 +417,12 @@ WritePathSpice::pgPortVoltage(LibertyPgPort *pg_port) auto cell = pg_port->cell(); auto voltage_name = pg_port->voltageName(); auto lib = cell->libertyLibrary(); - auto voltage = lib->supplyVoltage(voltage_name); + float voltage; + bool exists; + lib->supplyVoltage(voltage_name, voltage, exists); + if (!exists) + report_->error("pg_port %s voltage %s not found,\n", + pg_port->name(), voltage_name); return voltage; } @@ -523,7 +532,7 @@ WritePathSpice::findSlew(Path *path) auto vertex = path->vertex(this); auto dcalc_ap_index = path->dcalcAnalysisPt(this)->index(); auto tr = path->transition(this); - return findSlew(vertex, tr, NULL, dcalc_ap_index); + return findSlew(vertex, tr, nullptr, dcalc_ap_index); } float @@ -561,20 +570,20 @@ WritePathSpice::slewAxisMinValue(TimingArc *arc) TableAxisVariable var; axis = model->axis1(); var = axis->variable(); - if (var == table_axis_input_transition_time - || var == table_axis_input_net_transition) + if (var == TableAxisVariable::input_transition_time + || var == TableAxisVariable::input_net_transition) return axis->axisValue(0); axis = model->axis2(); var = axis->variable(); - if (var == table_axis_input_transition_time - || var == table_axis_input_net_transition) + if (var == TableAxisVariable::input_transition_time + || var == TableAxisVariable::input_net_transition) return axis->axisValue(0); axis = model->axis3(); var = axis->variable(); - if (var == table_axis_input_transition_time - || var == table_axis_input_net_transition) + if (var == TableAxisVariable::input_transition_time + || var == TableAxisVariable::input_net_transition) return axis->axisValue(0); } return 0.0; @@ -779,7 +788,7 @@ WritePathSpice::writeGateStage(Stage stage) && !network_->isTopLevelPort(pin)) { streamPrint(spice_stream_, "* Side load %s\n", network_->pathName(pin)); writeSubcktInst(pin); - writeSubcktInstVoltSrcs(stage, pin, volt_index, port_values, NULL, 0); + writeSubcktInstVoltSrcs(stage, pin, volt_index, port_values, nullptr, 0); streamPrint(spice_stream_, "\n"); } } @@ -798,18 +807,17 @@ WritePathSpice::writeSubcktInst(const Pin *input_pin) auto cell_name = cell->name(); auto spice_port_names = cell_spice_port_names_[cell_name]; streamPrint(spice_stream_, "x%s", inst_name); - StringVector::Iterator port_iter(spice_port_names); - while (port_iter.hasNext()) { - auto subckt_port_name = port_iter.next().c_str(); - auto pin = network_->findPin(inst, subckt_port_name); - auto pg_port = cell->findPgPort(subckt_port_name); + for (auto subckt_port_name : *spice_port_names) { + auto subckt_port_cname = subckt_port_name.c_str(); + auto pin = network_->findPin(inst, subckt_port_cname); + auto pg_port = cell->findPgPort(subckt_port_cname); const char *pin_name; if (pin) { pin_name = network_->pathName(pin); streamPrint(spice_stream_, " %s", pin_name); } else if (pg_port) - streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_name); + streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_cname); } streamPrint(spice_stream_, " %s\n", cell_name); } @@ -837,9 +845,8 @@ WritePathSpice::writeSubcktInstVoltSrcs(Stage stage, auto inst_name = network_->pathName(inst); debugPrint1(debug_, "write_spice", 2, "subckt %s\n", cell->name()); - StringVector::Iterator port_iter(spice_port_names); - while (port_iter.hasNext()) { - auto subckt_port_name = port_iter.next().c_str(); + for (auto subckt_port_sname : *spice_port_names) { + auto subckt_port_name = subckt_port_sname.c_str(); auto pg_port = cell->findPgPort(subckt_port_name); debugPrint2(debug_, "write_spice", 2, " port %s%s\n", subckt_port_name, @@ -860,7 +867,7 @@ WritePathSpice::writeSubcktInstVoltSrcs(Stage stage, const Pin *pin = network_->findPin(inst, port); // Look for tie high/low or propagated constant values. LogicValue port_value = sim_->logicValue(pin); - if (port_value == logic_unknown) { + if (port_value == LogicValue::unknown) { bool has_value; LogicValue value; port_values.findKey(port, value, has_value); @@ -868,22 +875,22 @@ WritePathSpice::writeSubcktInstVoltSrcs(Stage stage, port_value = value; } switch (port_value) { - case logic_zero: - case logic_unknown: + case LogicValue::zero: + case LogicValue::unknown: writeVoltageSource(cell, inst_name, subckt_port_name, port->relatedGroundPin(), volt_index); break; - case logic_one: + case LogicValue::one: writeVoltageSource(cell, inst_name, subckt_port_name, port->relatedPowerPin(), volt_index); break; - case logic_rise: + case LogicValue::rise: writeClkedStepSource(pin, TransRiseFall::rise(), clk, dcalc_ap_index, volt_index); break; - case logic_fall: + case LogicValue::fall: writeClkedStepSource(pin, TransRiseFall::fall(), clk, dcalc_ap_index, volt_index); break; @@ -902,7 +909,7 @@ WritePathSpice::writeClkedStepSource(const Pin *pin, int &volt_index) { auto vertex = graph_->pinLoadVertex(pin); - auto slew = findSlew(vertex, tr, NULL, dcalc_ap_index); + auto slew = findSlew(vertex, tr, nullptr, dcalc_ap_index); auto time = clkWaveformTImeOffset(clk) + clk->period() / 2.0; writeStepVoltSource(pin, tr, slew, time, volt_index); } @@ -918,7 +925,12 @@ WritePathSpice::writeVoltageSource(LibertyCell *cell, if (pg_port) { auto voltage_name = pg_port->voltageName(); if (voltage_name) { - float voltage = cell->libertyLibrary()->supplyVoltage(voltage_name); + float voltage; + bool exists; + cell->libertyLibrary()->supplyVoltage(voltage_name, voltage, exists); + if (!exists) + report_->error("pg_port %s voltage %s not found,\n", + pg_port_name, voltage_name); streamPrint(spice_stream_, "v%d %s/%s 0 %.3f\n", volt_index, inst_name, subckt_port_name, @@ -944,7 +956,7 @@ WritePathSpice::gatePortValues(Stage stage, const Clock *&clk, DcalcAPIndex &dcalc_ap_index) { - clk = NULL; + clk = nullptr; dcalc_ap_index = 0; auto gate_edge = stageGateEdge(stage); @@ -1009,20 +1021,20 @@ WritePathSpice::gatePortValues(const Instance *inst, case FuncExpr::op_or: if (left->hasPort(input_port) && right->op() == FuncExpr::op_port) - port_values[right->port()] = logic_zero; + port_values[right->port()] = LogicValue::zero; else if (left->hasPort(input_port) && right->op() == FuncExpr::op_not && right->left()->op() == FuncExpr::op_port) // input_port + !right_port - port_values[right->left()->port()] = logic_one; + port_values[right->left()->port()] = LogicValue::one; else if (right->hasPort(input_port) && left->op() == FuncExpr::op_port) - port_values[left->port()] = logic_zero; + port_values[left->port()] = LogicValue::zero; else if (right->hasPort(input_port) && left->op() == FuncExpr::op_not && left->left()->op() == FuncExpr::op_port) // input_port + !left_port - port_values[left->left()->port()] = logic_one; + port_values[left->left()->port()] = LogicValue::one; else { gatePortValues(inst, left, input_port, port_values); gatePortValues(inst, right, input_port, port_values); @@ -1031,20 +1043,20 @@ WritePathSpice::gatePortValues(const Instance *inst, case FuncExpr::op_and: if (left->hasPort(input_port) && right->op() == FuncExpr::op_port) - port_values[right->port()] = logic_one; + port_values[right->port()] = LogicValue::one; else if (left->hasPort(input_port) && right->op() == FuncExpr::op_not && right->left()->op() == FuncExpr::op_port) // input_port * !right_port - port_values[right->left()->port()] = logic_zero; + port_values[right->left()->port()] = LogicValue::zero; else if (right->hasPort(input_port) && left->op() == FuncExpr::op_port) - port_values[left->port()] = logic_one; + port_values[left->port()] = LogicValue::one; else if (right->hasPort(input_port) && left->op() == FuncExpr::op_not && left->left()->op() == FuncExpr::op_port) // input_port * !left_port - port_values[left->left()->port()] = logic_zero; + port_values[left->left()->port()] = LogicValue::zero; else { gatePortValues(inst, left, input_port, port_values); gatePortValues(inst, right, input_port, port_values); @@ -1054,10 +1066,10 @@ WritePathSpice::gatePortValues(const Instance *inst, // Need to know timing arc sense to get this right. if (left->port() == input_port && right->op() == FuncExpr::op_port) - port_values[right->port()] = logic_zero; + port_values[right->port()] = LogicValue::zero; else if (right->port() == input_port && left->op() == FuncExpr::op_port) - port_values[left->port()] = logic_zero; + port_values[left->port()] = LogicValue::zero; else { gatePortValues(inst, left, input_port, port_values); gatePortValues(inst, right, input_port, port_values); @@ -1080,21 +1092,21 @@ WritePathSpice::seqPortValues(Sequential *seq, if (port) { auto sense = data->portTimingSense(port); switch (sense) { - case timing_sense_positive_unate: + case TimingSense::positive_unate: if (tr == TransRiseFall::rise()) - port_values[port] = logic_rise; + port_values[port] = LogicValue::rise; else - port_values[port] = logic_fall; + port_values[port] = LogicValue::fall; break; - case timing_sense_negative_unate: + case TimingSense::negative_unate: if (tr == TransRiseFall::rise()) - port_values[port] = logic_fall; + port_values[port] = LogicValue::fall; else - port_values[port] = logic_rise; + port_values[port] = LogicValue::rise; break; - case timing_sense_non_unate: - case timing_sense_none: - case timing_sense_unknown: + case TimingSense::non_unate: + case TimingSense::none: + case TimingSense::unknown: default: break; } @@ -1117,16 +1129,64 @@ WritePathSpice::onePort(FuncExpr *expr) case FuncExpr::op_and: case FuncExpr::op_xor: port = onePort(left); - if (port == NULL) + if (port == nullptr) port = onePort(right); return port; case FuncExpr::op_one: case FuncExpr::op_zero: default: - return NULL; + return nullptr; } } +// Sort predicate for ParasiticDevices. +class ParasiticDeviceLess +{ +public: + ParasiticDeviceLess(Parasitics *parasitics) : + parasitics_(parasitics) + { + } + bool operator()(const ParasiticDevice *device1, + const ParasiticDevice *device2) const + { + auto node1 = parasitics_->node1(device1); + auto node2 = parasitics_->node1(device2); + auto name1 = parasitics_->name(node1); + auto name2 = parasitics_->name(node2); + if (stringEq(name1, name2)) { + auto node12 = parasitics_->node2(device1); + auto node22 = parasitics_->node2(device2); + auto name12 = parasitics_->name(node12); + auto name22 = parasitics_->name(node22); + return stringLess(name12, name22); + } + else + return stringLess(name1, name2); + } +private: + Parasitics *parasitics_; +}; + +// Sort predicate for ParasiticDevices. +class ParasiticNodeLess +{ +public: + ParasiticNodeLess(Parasitics *parasitics) : + parasitics_(parasitics) + { + } + bool operator()(const ParasiticNode *node1, + const ParasiticNode *node2) const + { + auto name1 = parasitics_->name(node1); + auto name2 = parasitics_->name(node2); + return stringLess(name1, name2); + } +private: + Parasitics *parasitics_; +}; + void WritePathSpice::writeStageParasitics(Stage stage) { @@ -1143,9 +1203,19 @@ WritePathSpice::writeStageParasitics(Stage stage) auto net_name = net ? network_->pathName(net) : network_->pathName(drvr_pin); initNodeMap(net_name); streamPrint(spice_stream_, "* Net %s\n", net_name); - ParasiticDeviceIterator *device_iter = parasitics_->deviceIterator(parasitic); - while (device_iter->hasNext()) { - auto device = device_iter->next(); + + // Sort devices for consistent regression results. + Vector devices; + ParasiticDeviceIterator *device_iter1 = parasitics_->deviceIterator(parasitic); + while (device_iter1->hasNext()) { + auto device = device_iter1->next(); + devices.push_back(device); + } + delete device_iter1; + + sort(devices, ParasiticDeviceLess(parasitics_)); + + for (auto device : devices) { auto resistance = parasitics_->value(device, parasitic_ap); if (parasitics_->isResistor(device)) { auto node1 = parasitics_->node1(device); @@ -1173,7 +1243,6 @@ WritePathSpice::writeStageParasitics(Stage stage) cap_index++; } } - delete device_iter; } else streamPrint(spice_stream_, "* No parasitics found for this net.\n"); @@ -1197,9 +1266,17 @@ WritePathSpice::writeStageParasitics(Stage stage) delete pin_iter; if (parasitic) { + // Sort node capacitors for consistent regression results. + Vector nodes; ParasiticNodeIterator *node_iter = parasitics_->nodeIterator(parasitic); while (node_iter->hasNext()) { auto node = node_iter->next(); + nodes.push_back(node); + } + + sort(nodes, ParasiticNodeLess(parasitics_)); + + for (auto node : nodes) { auto cap = parasitics_->nodeGndCap(node, parasitic_ap); // Spice has a cow over zero value caps. if (cap > 0.0) { @@ -1285,13 +1362,10 @@ WritePathSpice::writeSubckts() lib_subckts_stream.close(); if (!path_cell_names.empty()) { - StringSet::Iterator cell_iter(path_cell_names); report_->error("The following subkcts are missing from %s\n", lib_subckt_filename_); - while (cell_iter.hasNext()) { - auto cell_name = cell_iter.next(); + for (auto cell_name : path_cell_names) report_->printError(" %s\n", cell_name); - } } } else { @@ -1342,7 +1416,7 @@ WritePathSpice::recordSpicePortNames(const char *cell_name, auto port_name = tokens[i].c_str(); auto port = cell->findLibertyPort(port_name); auto pg_port = cell->findPgPort(port_name); - if (port == NULL && pg_port == NULL) + if (port == nullptr && pg_port == nullptr) report_->error("subckt %s port %s has no corresponding liberty port or pg_port.\n", cell_name, port_name); spice_port_names->push_back(port_name); @@ -1419,7 +1493,7 @@ WritePathSpice::stageGateArc(Stage stage) if (path_index >= 0) return path_expanded_.prevArc(path_index); else - return NULL; + return nullptr; } TimingArc * diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl index 718b903b..63617579 100644 --- a/tcl/Sta.tcl +++ b/tcl/Sta.tcl @@ -455,10 +455,10 @@ proc_redirect report_check_types { } if { $min_period } { if { $all_violators } { - set checks [min_period_violations $corner] + set checks [min_period_violations] report_min_period_checks $checks $verbose } else { - set check [min_period_check_slack $corner] + set check [min_period_check_slack] if { $check != "NULL" } { report_min_period_check $check $verbose } @@ -1032,5 +1032,7 @@ proc with_output_to_variable { var_name args } { return $ret } +define_sta_cmd_args "set_pocv_sigma_factor" { factor } + # sta namespace end. } diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 3177a7a5..e51fcc14 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -139,7 +139,7 @@ cmdLinkedNetwork() return network; else { throw CmdErrorNetworkNotLinked(); - return NULL; + return nullptr; } } @@ -152,7 +152,7 @@ cmdEditNetwork() return dynamic_cast(network); else { throw CmdErrorNetworkNotEditable(); - return NULL; + return nullptr; } } @@ -189,7 +189,7 @@ TclListSeqPort(Tcl_Obj * const source, return seq; } else - return NULL; + return nullptr; } PinSeq * @@ -210,7 +210,7 @@ TclListSeqPin(Tcl_Obj * const source, return seq; } else - return NULL; + return nullptr; } InstanceSeq * @@ -231,7 +231,7 @@ TclListSeqInstance(Tcl_Obj * const source, return seq; } else - return NULL; + return nullptr; } ExceptionThruSeq * @@ -253,7 +253,7 @@ TclListSeqExceptionThru(Tcl_Obj *const source, return seq; } else - return NULL; + return nullptr; } PortSet * @@ -274,7 +274,7 @@ TclListSetPort(Tcl_Obj *const source, return set; } else - return NULL; + return nullptr; } PinSet * @@ -295,7 +295,7 @@ TclListSetPin(Tcl_Obj *const source, return set; } else - return NULL; + return nullptr; } ClockSet * @@ -316,7 +316,7 @@ TclListSetClock(Tcl_Obj *const source, return set; } else - return NULL; + return nullptr; } InstanceSet * @@ -337,7 +337,7 @@ TclListSetInstance(Tcl_Obj *const source, return set; } else - return NULL; + return nullptr; } NetSet * @@ -358,7 +358,7 @@ TclListSetNet(Tcl_Obj *const source, return set; } else - return NULL; + return nullptr; } StringSet * @@ -378,7 +378,7 @@ TclListSetConstChar(Tcl_Obj *const source, return set; } else - return NULL; + return nullptr; } StringSeq * @@ -398,7 +398,7 @@ TclListSeqConstChar(Tcl_Obj *const source, return seq; } else - return NULL; + return nullptr; } EdgeSeq * @@ -418,7 +418,7 @@ TclListSeqEdge(Tcl_Obj * const source, Tcl_Interp *interp) return seq; } else - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -472,7 +472,7 @@ objectListNext(const char *list, { // Default return values (failure). type_match = false; - next = NULL; + next = nullptr; // _hexaddress_p_type const char *s = list; char ch = *s++; @@ -494,7 +494,7 @@ objectListNext(const char *list, if (*s) next = s + 1; else - next = NULL; + next = nullptr; } } } @@ -520,7 +520,7 @@ using namespace sta; delete str; } else - Tcl_SetResult(interp, NULL, TCL_STATIC); + Tcl_SetResult(interp, nullptr, TCL_STATIC); } %typemap(in) StringSeq* { @@ -529,7 +529,7 @@ using namespace sta; %typemap(out) StringSeq* { StringSeq *strs = $1; - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); StringSeq::Iterator str_iter(strs); while (str_iter.hasNext()) { const char *str = str_iter.next(); @@ -541,7 +541,7 @@ using namespace sta; %typemap(out) TmpStringSeq* { StringSeq *strs = $1; - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); StringSeq::Iterator str_iter(strs); while (str_iter.hasNext()) { const char *str = str_iter.next(); @@ -573,7 +573,7 @@ using namespace sta; } %typemap(out) CellSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); CellSeq *cells = $1; CellSeq::Iterator cell_iter(cells); while (cell_iter.hasNext()) { @@ -585,7 +585,7 @@ using namespace sta; } %typemap(out) TmpCellSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); CellSeq *cells = $1; CellSeq::Iterator cell_iter(cells); while (cell_iter.hasNext()) { @@ -598,7 +598,7 @@ using namespace sta; } %typemap(out) LibertyCellSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); LibertyCellSeq *cells = $1; LibertyCellSeq::Iterator cell_iter(cells); while (cell_iter.hasNext()) { @@ -611,7 +611,7 @@ using namespace sta; } %typemap(out) TmpLibertyCellSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); LibertyCellSeq *cells = $1; LibertyCellSeq::Iterator cell_iter(cells); while (cell_iter.hasNext()) { @@ -648,7 +648,7 @@ using namespace sta; } %typemap(out) TmpPortSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); TmpPortSeq *ports = $1; TmpPortSeq::Iterator port_iter(ports); while (port_iter.hasNext()) { @@ -661,7 +661,7 @@ using namespace sta; } %typemap(out) TmpLibertyPortSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); TmpLibertyPortSeq *ports = $1; TmpLibertyPortSeq::Iterator port_iter(ports); while (port_iter.hasNext()) { @@ -675,7 +675,7 @@ using namespace sta; } %typemap(out) TmpPinSet* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); PinSet *pins = $1; PinSet::Iterator pin_iter(pins); while (pin_iter.hasNext()) { @@ -688,7 +688,7 @@ using namespace sta; } %typemap(out) TmpPinSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); PinSeq *pins = $1; PinSeq::Iterator pin_iter(pins); while (pin_iter.hasNext()) { @@ -741,7 +741,7 @@ using namespace sta; int length; const char *arg = Tcl_GetStringFromObj($input, &length); Transition *tr = Transition::find(arg); - if (tr == NULL) { + if (tr == nullptr) { Tcl_SetResult(interp,const_cast("Error: transition not found."), TCL_STATIC); return TCL_ERROR; @@ -762,7 +762,7 @@ using namespace sta; int length; const char *arg = Tcl_GetStringFromObj($input, &length); TransRiseFall *tr = TransRiseFall::find(arg); - if (tr == NULL) { + if (tr == nullptr) { Tcl_SetResult(interp,const_cast("Error: unknown transition name."), TCL_STATIC); return TCL_ERROR; @@ -782,7 +782,7 @@ using namespace sta; int length; const char *arg = Tcl_GetStringFromObj($input, &length); TransRiseFallBoth *tr = TransRiseFallBoth::find(arg); - if (tr == NULL) { + if (tr == nullptr) { Tcl_SetResult(interp,const_cast("Error: unknown transition name."), TCL_STATIC); return TCL_ERROR; @@ -819,15 +819,15 @@ using namespace sta; int length; const char *arg = Tcl_GetStringFromObj($input, &length); if (stringEq(arg, "0") || stringEq(arg, "zero")) - $1 = logic_zero; + $1 = LogicValue::zero; else if (stringEq(arg, "1") || stringEq(arg, "one")) - $1 = logic_one; + $1 = LogicValue::one; else if (stringEq(arg, "X")) - $1 = logic_unknown; + $1 = LogicValue::unknown; else if (stringEq(arg, "rise") || stringEq(arg, "rising")) - $1 = logic_rise; + $1 = LogicValue::rise; else if (stringEq(arg, "fall") || stringEq(arg, "falling")) - $1 = logic_fall; + $1 = LogicValue::fall; else { Tcl_SetResult(interp,const_cast("Error: unknown logic value."), TCL_STATIC); @@ -839,11 +839,11 @@ using namespace sta; int length; const char *arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "single")) - $1 = analysis_type_single; + $1 = AnalysisType::single; else if (stringEqual(arg, "bc_wc")) - $1 = analysis_type_bc_wc; + $1 = AnalysisType::bc_wc; else if (stringEq(arg, "on_chip_variation")) - $1 = analysis_type_on_chip_variation; + $1 = AnalysisType::ocv; else { Tcl_SetResult(interp,const_cast("Error: unknown analysis type."), TCL_STATIC); @@ -862,7 +862,7 @@ using namespace sta; } %typemap(out) TmpInstanceSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); TmpInstanceSeq *insts = $1; TmpInstanceSeq::Iterator inst_iter(insts); while (inst_iter.hasNext()) { @@ -900,7 +900,7 @@ using namespace sta; } %typemap(out) PinSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); PinSeq *pins = $1; PinSeq::Iterator pin_iter(pins); while (pin_iter.hasNext()) { @@ -918,7 +918,7 @@ using namespace sta; } %typemap(out) NetSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); NetSeq *nets = $1; NetSeq::Iterator net_iter(nets); while (net_iter.hasNext()) { @@ -956,7 +956,7 @@ using namespace sta; } %typemap(out) ClockSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); ClockSeq *clks = $1; ClockSeq::Iterator clk_iter(clks); while (clk_iter.hasNext()) { @@ -986,7 +986,7 @@ using namespace sta; %typemap(in) FloatSeq* { int argc; Tcl_Obj **argv; - FloatSeq *floats = NULL; + FloatSeq *floats = nullptr; if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) { if (argc) @@ -1008,7 +1008,7 @@ using namespace sta; %typemap(out) FloatSeq* { FloatSeq *floats = $1; - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); if (floats) { for (unsigned i = 0; i < floats->size(); i++) { Tcl_Obj *obj = Tcl_NewDoubleObj((*floats)[i]); @@ -1020,7 +1020,7 @@ using namespace sta; %typemap(out) TmpFloatSeq* { FloatSeq *floats = $1; - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); if (floats) { for (unsigned i = 0; i < floats->size(); i++) { Tcl_Obj *obj = Tcl_NewDoubleObj((*floats)[i]); @@ -1034,7 +1034,7 @@ using namespace sta; %typemap(in) IntSeq* { int argc; Tcl_Obj **argv; - IntSeq *ints = NULL; + IntSeq *ints = nullptr; if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) { if (argc) @@ -1090,7 +1090,7 @@ using namespace sta; int length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "NULL")) - $1 = NULL; + $1 = nullptr; else { MinMaxAll *min_max = MinMaxAll::find(arg); if (min_max) @@ -1165,11 +1165,11 @@ using namespace sta; int length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEq(arg, "net_delay")) - $1 = timing_derate_net_delay; + $1 = TimingDerateType::net_delay; else if (stringEq(arg, "cell_delay")) - $1 = timing_derate_cell_delay; + $1 = TimingDerateType::cell_delay; else if (stringEq(arg, "cell_check")) - $1 = timing_derate_cell_check; + $1 = TimingDerateType::cell_check; else { tclError(interp, "Error: %s not clk or data.", arg); return TCL_ERROR; @@ -1180,9 +1180,9 @@ using namespace sta; int length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEq(arg, "clk")) - $1 = path_clk; + $1 = PathClkOrData::clk; else if (stringEq(arg, "data")) - $1 = path_data; + $1 = PathClkOrData::data; else { tclError(interp, "Error: %s not clk or data.", arg); return TCL_ERROR; @@ -1206,19 +1206,19 @@ using namespace sta; int length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEq(arg, "full")) - $1 = report_path_full; + $1 = ReportPathFormat::full; else if (stringEq(arg, "full_clock")) - $1 = report_path_full_clock; + $1 = ReportPathFormat::full_clock; else if (stringEq(arg, "full_clock_expanded")) - $1 = report_path_full_clock_expanded; + $1 = ReportPathFormat::full_clock_expanded; else if (stringEq(arg, "short")) - $1 = report_path_short; + $1 = ReportPathFormat::shorter; else if (stringEq(arg, "end")) - $1 = report_path_endpoint; + $1 = ReportPathFormat::endpoint; else if (stringEq(arg, "summary")) - $1 = report_path_summary; + $1 = ReportPathFormat::summary; else if (stringEq(arg, "slack_only")) - $1 = report_path_slack_only; + $1 = ReportPathFormat::slack_only; else { tclError(interp, "Error: unknown path type %s.", arg); return TCL_ERROR; @@ -1234,7 +1234,7 @@ using namespace sta; } %typemap(out) PinSet* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); const PinSet *pins = $1; if (pins) { PinSet::ConstIterator pin_iter(pins); @@ -1252,7 +1252,7 @@ using namespace sta; } %typemap(out) ClockSet* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); const ClockSet *clks = $1; if (clks) { ClockSet::ConstIterator clk_iter(clks); @@ -1266,7 +1266,7 @@ using namespace sta; } %typemap(out) TmpClockSet* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); const ClockSet *clks = $1; if (clks) { ClockSet::ConstIterator clk_iter(clks); @@ -1285,7 +1285,7 @@ using namespace sta; } %typemap(out) TmpInstanceSet* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); InstanceSet *insts = $1; InstanceSet::Iterator inst_iter(insts); while (inst_iter.hasNext()) { @@ -1313,7 +1313,7 @@ using namespace sta; %typemap(out) Vertex** { int i = 0; Tcl_ResetResult(interp); - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); while ($1[i]) { Tcl_Obj *obj = SWIG_NewInstanceObj($1[i], SWIGTYPE_p_Vertex,false); Tcl_ListObjAppendElement(interp, list, obj); @@ -1332,7 +1332,7 @@ using namespace sta; } %typemap(out) EdgeSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); EdgeSeq *edges = $1; EdgeSeq::Iterator edge_iter(edges); while (edge_iter.hasNext()) { @@ -1370,12 +1370,12 @@ using namespace sta; } %typemap(out) CheckErrorSeq & { - Tcl_Obj *error_list = Tcl_NewListObj(0, NULL); + Tcl_Obj *error_list = Tcl_NewListObj(0, nullptr); CheckErrorSeq *check_errors = $1; CheckErrorSeq::Iterator check_iter(check_errors); while (check_iter.hasNext()) { CheckError *error = check_iter.next(); - Tcl_Obj *string_list = Tcl_NewListObj(0, NULL); + Tcl_Obj *string_list = Tcl_NewListObj(0, nullptr); CheckError::Iterator string_iter(error); while (string_iter.hasNext()) { const char *str = string_iter.next(); @@ -1395,7 +1395,7 @@ using namespace sta; } %typemap(out) PathEndSeq* { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); const PathEndSeq *path_ends = $1; PathEndSeq::ConstIterator end_iter(path_ends); while (end_iter.hasNext()) { @@ -1417,7 +1417,7 @@ using namespace sta; Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false); Tcl_SetObjResult(interp, obj); - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); PathRefSeq *paths = $1; PathRefSeq::Iterator path_iter(paths); while (path_iter.hasNext()) { @@ -1478,11 +1478,11 @@ using namespace sta; int length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEq(arg, "pi_elmore")) - $1 = reduce_parasitics_to_pi_elmore; + $1 = ReduceParasiticsTo::pi_elmore; else if (stringEq(arg, "pi_pole_residue2")) - $1 = reduce_parasitics_to_pi_pole_residue2; + $1 = ReduceParasiticsTo::pi_pole_residue2; else if (stringEq(arg, "none")) - $1 = reduce_parasitics_to_none; + $1 = ReduceParasiticsTo::none; else { tclError(interp, "Error: %s pi_elmore, pi_pole_residue2, or none.", arg); return TCL_ERROR; @@ -1549,7 +1549,7 @@ using namespace sta; } break; case PropertyValue::Type::type_pins: { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); PinSeq *pins = value.pins(); PinSeq::Iterator pin_iter(pins); while (pin_iter.hasNext()) { @@ -1590,14 +1590,14 @@ using namespace sta; Tcl_SetObjResult(interp, obj); } break; - case PropertyValue::Type::type_clock: { + case PropertyValue::Type::type_clk: { Tcl_Obj *obj = SWIG_NewInstanceObj(value.clock(), SWIGTYPE_p_Clock, false); Tcl_SetObjResult(interp, obj); } break; - case PropertyValue::Type::type_clocks: { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + case PropertyValue::Type::type_clks: { + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); ClockSeq *clks = value.clocks(); ClockSeq::Iterator clk_iter(clks); while (clk_iter.hasNext()) { @@ -1609,7 +1609,7 @@ using namespace sta; } break; case PropertyValue::Type::type_path_refs: { - Tcl_Obj *list = Tcl_NewListObj(0, NULL); + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); PathRefSeq *paths = value.pathRefs(); PathRefSeq::Iterator path_iter(paths); while (path_iter.hasNext()) { @@ -2182,7 +2182,7 @@ read_liberty_cmd(char *filename, { LibertyLibrary *lib = Sta::sta()->readLiberty(filename, corner, min_max, infer_latches); - return (lib != NULL); + return (lib != nullptr); } bool @@ -2257,9 +2257,9 @@ void set_cmd_namespace_cmd(const char *namespc) { if (stringEq(namespc, "sdc")) - Sta::sta()->setCmdNamespace(cmd_namespace_sdc); + Sta::sta()->setCmdNamespace(CmdNamespace::sdc); else if (stringEq(namespc, "sta")) - Sta::sta()->setCmdNamespace(cmd_namespace_sta); + Sta::sta()->setCmdNamespace(CmdNamespace::sta); else internalError("unknown namespace"); } @@ -2760,14 +2760,14 @@ set_analysis_type_cmd(const char *analysis_type) { AnalysisType type; if (stringEq(analysis_type, "single")) - type = analysis_type_single; + type = AnalysisType::single; else if (stringEq(analysis_type, "bc_wc")) - type = analysis_type_bc_wc; + type = AnalysisType::bc_wc; else if (stringEq(analysis_type, "on_chip_variation")) - type = analysis_type_on_chip_variation; + type = AnalysisType::ocv; else { internalError("unknown analysis type"); - type = analysis_type_single; + type = AnalysisType::single; } Sta::sta()->setAnalysisType(type); } @@ -2812,11 +2812,11 @@ const char * operating_condition_analysis_type() { switch (Sta::sta()->sdc()->analysisType()){ - case analysis_type_single: + case AnalysisType::single: return "single"; - case analysis_type_bc_wc: + case AnalysisType::bc_wc: return "bc_wc"; - case analysis_type_on_chip_variation: + case AnalysisType::ocv: return "on_chip_variation"; } // Prevent warnings from lame compilers. @@ -2902,7 +2902,7 @@ void set_wire_load_mode_cmd(const char *mode_name) { WireloadMode mode = stringWireloadMode(mode_name); - if (mode == wire_load_mode_unknown) + if (mode == WireloadMode::unknown) internalError("unknown wire load mode"); else Sta::sta()->setWireloadMode(mode); @@ -3430,7 +3430,7 @@ make_group_path(const char *name, { cmdLinkedNetwork(); if (name[0] == '\0') - name = NULL; + name = nullptr; Sta::sta()->makeGroupPath(name, is_default, from, thrus, to, comment); } @@ -3751,14 +3751,14 @@ unset_timing_derate_cmd() ClockIterator * clock_iterator() { - return Sta::sta()->clockIterator(); + return new ClockIterator(Sta::sta()->sdc()); } Clock * find_clock(const char *name) { cmdLinkedNetwork(); - return Sta::sta()->findClock(name); + return Sta::sta()->sdc()->findClock(name); } bool @@ -3770,7 +3770,7 @@ is_clock_src(const Pin *pin) Clock * default_arrival_clock() { - return Sta::sta()->defaultArrivalClock(); + return Sta::sta()->sdc()->defaultArrivalClock(); } ClockSeq * @@ -3781,8 +3781,9 @@ find_clocks_matching(const char *pattern, cmdLinkedNetwork(); ClockSeq *clks = new ClockSeq; Sta *sta = Sta::sta(); + Sdc *sdc = sta->sdc(); PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp()); - sta->findClocksMatching(&matcher, clks); + sdc->findClocksMatching(&matcher, clks); return clks; } @@ -3821,7 +3822,7 @@ const char * format_time(const char *value_str, int digits) { - float value = strtof(value_str, NULL); + float value = strtof(value_str, nullptr); return Sta::sta()->units()->timeUnit()->asString(value, digits); } @@ -3829,7 +3830,7 @@ const char * format_capacitance(const char *value_str, int digits) { - float value = strtof(value_str, NULL); + float value = strtof(value_str, nullptr); return Sta::sta()->units()->capacitanceUnit()->asString(value, digits); } @@ -3837,7 +3838,7 @@ const char * format_resistance(const char *value_str, int digits) { - float value = strtof(value_str, NULL); + float value = strtof(value_str, nullptr); return Sta::sta()->units()->resistanceUnit()->asString(value, digits); } @@ -3845,7 +3846,7 @@ const char * format_voltage(const char *value_str, int digits) { - float value = strtof(value_str, NULL); + float value = strtof(value_str, nullptr); return Sta::sta()->units()->voltageUnit()->asString(value, digits); } @@ -3853,7 +3854,7 @@ const char * format_power(const char *value_str, int digits) { - float value = strtof(value_str, NULL); + float value = strtof(value_str, nullptr); return Sta::sta()->units()->powerUnit()->asString(value, digits); } @@ -3998,9 +3999,9 @@ const char * crpr_mode() { switch (Sta::sta()->crprMode()) { - case crpr_mode_same_transition: + case CrprMode::same_transition: return "same_transition"; - case crpr_mode_same_pin: + case CrprMode::same_pin: return "same_pin"; default: return ""; @@ -4011,9 +4012,9 @@ void set_crpr_mode(const char *mode) { if (stringEq(mode, "same_pin")) - Sta::sta()->setCrprMode(crpr_mode_same_pin); + Sta::sta()->setCrprMode(CrprMode::same_pin); else if (stringEq(mode, "same_transition")) - Sta::sta()->setCrprMode(crpr_mode_same_transition); + Sta::sta()->setCrprMode(CrprMode::same_transition); else internalError("unknown common clk pessimism mode."); } @@ -4034,6 +4035,18 @@ set_pocv_enabled(bool enabled) return Sta::sta()->setPocvEnabled(enabled); } +float +pocv_sigma_factor() +{ + return Sta::sta()->sigmaFactor(); +} + +void +set_pocv_sigma_factor(float factor) +{ + Sta::sta()->setSigmaFactor(factor); +} + bool propagate_gated_clock_enable() { @@ -4184,7 +4197,7 @@ find_path_ends(ExceptionFrom *from, group_count, endpoint_count, unique_pins, slack_min, slack_max, sort_by_slack, - groups->size() ? groups : NULL, + groups->size() ? groups : nullptr, setup, hold, recovery, removal, clk_gating_setup, clk_gating_hold); @@ -4329,7 +4342,7 @@ group_path_pins(const char *group_path_name) if (sdc->isGroupPathName(group_path_name)) return sta->findGroupPathPins(group_path_name); else - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -4383,17 +4396,17 @@ report_mpw_check(MinPulseWidthCheck *check, //////////////////////////////////////////////////////////////// MinPeriodCheckSeq & -min_period_violations(const Corner *corner) +min_period_violations() { cmdLinkedNetwork(); - return Sta::sta()->minPeriodViolations(corner); + return Sta::sta()->minPeriodViolations(); } MinPeriodCheck * -min_period_check_slack(const Corner *corner) +min_period_check_slack() { cmdLinkedNetwork(); - return Sta::sta()->minPeriodSlack(corner); + return Sta::sta()->minPeriodSlack(); } void @@ -4524,7 +4537,7 @@ vertex_worst_arrival_path(Vertex *vertex, if (!path.isNull()) return new PathRef(path); else - return NULL; + return nullptr; } PathRef * @@ -4538,7 +4551,7 @@ vertex_worst_arrival_path_tr(Vertex *vertex, if (!path.isNull()) return new PathRef(path); else - return NULL; + return nullptr; } PathRef * @@ -4551,7 +4564,7 @@ vertex_worst_slack_path(Vertex *vertex, if (!path.isNull()) return new PathRef(path); else - return NULL; + return nullptr; } TmpString * @@ -4728,7 +4741,7 @@ pin_case_logic_value(const Pin *pin) { Sta *sta = Sta::sta(); Sdc *sdc = sta->sdc(); - LogicValue value = logic_unknown; + LogicValue value = LogicValue::unknown; bool exists; sdc->caseLogicValue(pin, value, exists); return logicValueString(value); @@ -4739,7 +4752,7 @@ pin_logic_value(const Pin *pin) { Sta *sta = Sta::sta(); Sdc *sdc = sta->sdc(); - LogicValue value = logic_unknown; + LogicValue value = LogicValue::unknown; bool exists; sdc->logicValue(pin, value, exists); return logicValueString(value); @@ -4816,11 +4829,11 @@ set_clock_sense_cmd(PinSet *pins, { ClockSense sense; if (positive) - sense = clk_sense_positive; + sense = ClockSense::positive; else if (negative) - sense = clk_sense_negative; + sense = ClockSense::negative; else if (stop_propagation) - sense = clk_sense_stop; + sense = ClockSense::stop; else internalError("unknown clock sense"); Sta::sta()->setClockSense(pins, clks, sense); @@ -5341,7 +5354,7 @@ function() if (func) return func->asString(); else - return NULL; + return nullptr; } const char * @@ -5351,7 +5364,7 @@ tristate_enable() if (enable) return enable->asString(); else - return NULL; + return nullptr; } float @@ -5491,7 +5504,7 @@ vertices() cmdGraph()->pinVertices(self, vertex, vertex_bidirect_drvr); vertices[0] = vertex; vertices[1] = vertex_bidirect_drvr; - vertices[2] = NULL; + vertices[2] = nullptr; return vertices; } @@ -5706,7 +5719,7 @@ arrivals_clk(const TransRiseFall *tr, { Sta *sta = Sta::sta(); TmpFloatSeq *floats = new FloatSeq; - const ClockEdge *clk_edge = NULL; + const ClockEdge *clk_edge = nullptr; if (clk) clk_edge = clk->edge(clk_tr); PathAnalysisPtIterator ap_iter(sta); @@ -5726,7 +5739,7 @@ arrivals_clk_delays(const TransRiseFall *tr, { Sta *sta = Sta::sta(); StringSeq *arrivals = new StringSeq; - const ClockEdge *clk_edge = NULL; + const ClockEdge *clk_edge = nullptr; if (clk) clk_edge = clk->edge(clk_tr); PathAnalysisPtIterator ap_iter(sta); @@ -5746,7 +5759,7 @@ requireds_clk(const TransRiseFall *tr, { Sta *sta = Sta::sta(); TmpFloatSeq *floats = new FloatSeq; - const ClockEdge *clk_edge = NULL; + const ClockEdge *clk_edge = nullptr; if (clk) clk_edge = clk->edge(clk_tr); PathAnalysisPtIterator ap_iter(sta); @@ -5766,7 +5779,7 @@ requireds_clk_delays(const TransRiseFall *tr, { Sta *sta = Sta::sta(); StringSeq *requireds = new StringSeq; - const ClockEdge *clk_edge = NULL; + const ClockEdge *clk_edge = nullptr; if (clk) clk_edge = clk->edge(clk_tr); PathAnalysisPtIterator ap_iter(sta); @@ -5800,7 +5813,7 @@ slacks_clk(const TransRiseFall *tr, { Sta *sta = Sta::sta(); TmpFloatSeq *floats = new FloatSeq; - const ClockEdge *clk_edge = NULL; + const ClockEdge *clk_edge = nullptr; if (clk) clk_edge = clk->edge(clk_tr); PathAnalysisPtIterator ap_iter(sta); @@ -5820,7 +5833,7 @@ slacks_clk_delays(const TransRiseFall *tr, { Sta *sta = Sta::sta(); StringSeq *slacks = new StringSeq; - const ClockEdge *clk_edge = NULL; + const ClockEdge *clk_edge = nullptr; if (clk) clk_edge = clk->edge(clk_tr); PathAnalysisPtIterator ap_iter(sta); @@ -5934,7 +5947,7 @@ cond() if (cond) return cond->asString(); else - return NULL; + return nullptr; } const char * diff --git a/util/Debug.cc b/util/Debug.cc index 00810cf7..71887752 100644 --- a/util/Debug.cc +++ b/util/Debug.cc @@ -24,7 +24,7 @@ bool debug_on = false; Debug::Debug(Report *&report) : report_(report), - debug_map_(NULL), + debug_map_(nullptr), stats_level_(0) { } @@ -95,7 +95,7 @@ Debug::setLevel(const char *what, else { char *what_cpy = new char[strlen(what) + 1]; strcpy(what_cpy, what); - if (debug_map_ == NULL) + if (debug_map_ == nullptr) debug_map_ = new DebugMap; (*debug_map_)[what_cpy] = level; debug_on = true; diff --git a/util/DisallowCopyAssign.hh b/util/DisallowCopyAssign.hh index 4df6f795..6c5cf394 100644 --- a/util/DisallowCopyAssign.hh +++ b/util/DisallowCopyAssign.hh @@ -20,7 +20,7 @@ // Disallow the copy constructor and operator= functions. // This should be used in the private declarations for a class. #define DISALLOW_COPY_AND_ASSIGN(type_name) \ - type_name(const type_name&); \ - void operator=(const type_name&) + type_name(const type_name&) = delete; \ + void operator=(const type_name&) = delete #endif diff --git a/util/EnumNameMap.hh b/util/EnumNameMap.hh new file mode 100644 index 00000000..71f0a3e9 --- /dev/null +++ b/util/EnumNameMap.hh @@ -0,0 +1,97 @@ +// OpenSTA, Static Timing Analyzer +// Copyright (c) 2019, 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 . + +#ifndef STA_ENUM_NAME_MAP_H +#define STA_ENUM_NAME_MAP_H + +#include +#include + +namespace sta { + +using std::string; +using std::map; +using std::initializer_list; +using std::pair; + +// Helper for mapping enum values to strings and back. +template +class EnumNameMap +{ +public: + EnumNameMap(initializer_list> enum_names); + const char *find(ENUM key) const; + ENUM find(string name, + ENUM unknown_key) const; + void find(string name, + // Return values. + ENUM &key, + bool &exists) const; + +private: + map enum_map_; + map name_map_; +}; + +template +EnumNameMap::EnumNameMap(initializer_list> enum_names) : + enum_map_(enum_names) +{ + for (auto iter = enum_map_.begin(); iter != enum_map_.end(); iter++) + name_map_[iter->second] = iter->first; +} + +template +const char * +EnumNameMap::find(ENUM key) const +{ + auto find_iter = enum_map_.find(key); + if (find_iter != enum_map_.end()) + return find_iter->second.c_str(); + else + return nullptr; +} + +template +void +EnumNameMap::find(string name, + // Return values. + ENUM &key, + bool &exists) const +{ + auto find_iter = name_map_.find(name); + if (find_iter != name_map_.end()) { + key = find_iter->second; + exists = true; + } + else + exists = false; +} + +template +ENUM +EnumNameMap::find(string name, + ENUM unknown_key) const +{ + auto find_iter = name_map_.find(name); + if (find_iter != name_map_.end()) + return find_iter->second; + else + return unknown_key; +} + +} // namespace +#endif diff --git a/util/Fuzzy.hh b/util/Fuzzy.hh index e81b5d29..e31ec363 100644 --- a/util/Fuzzy.hh +++ b/util/Fuzzy.hh @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#ifndef STA_FUZZY_H +#define STA_FUZZY_H + namespace sta { // "Fuzzy" floating point comparisons that allow some tolerance. @@ -39,3 +42,4 @@ bool fuzzyInf(float value); } // namespace +#endif diff --git a/util/HashSet.hh b/util/HashSet.hh index ebf4cbf3..30586229 100644 --- a/util/HashSet.hh +++ b/util/HashSet.hh @@ -70,7 +70,7 @@ public: class Iterator { public: - Iterator() : container_(NULL) {} + Iterator() : container_(nullptr) {} explicit Iterator(HashSet *container) { init(container); } explicit Iterator(HashSet &container) @@ -78,18 +78,18 @@ public: void init(HashSet *container) { container_ = container; hash_= 0; - next_ = NULL; + next_ = nullptr; if (container_) findNext(); } void init(HashSet &container) { container_ = &container; hash_= 0; - next_ = NULL; + next_ = nullptr; if (container_) findNext(); } - bool hasNext() { return container_ && next_ != NULL; } + bool hasNext() { return container_ && next_ != nullptr; } KEY next() { HashSetBucket *next = next_; findNext(); @@ -103,7 +103,7 @@ public: { if (next_) next_ = next_->next(); - while (next_ == NULL + while (next_ == nullptr && hash_ < container_->capacity()) next_ = container_->table_[hash_++]; } @@ -115,16 +115,16 @@ public: class ConstIterator { public: - ConstIterator() : container_(NULL) {} + ConstIterator() : container_(nullptr) {} explicit ConstIterator(const HashSet *container) { init(container); } explicit ConstIterator(const HashSet &container) { init(container); } void init(const HashSet *container) - { container_ = container; hash_= 0; next_ = NULL; findNext(); } + { container_ = container; hash_= 0; next_ = nullptr; findNext(); } void init(HashSet &container) - { container_ = &container; hash_= 0; next_ = NULL; findNext(); } - bool hasNext() { return container_ && next_ != NULL; } + { container_ = &container; hash_= 0; next_ = nullptr; findNext(); } + bool hasNext() { return container_ && next_ != nullptr; } KEY next() { HashSetBucket *next = next_; findNext(); @@ -138,7 +138,7 @@ public: { if (next_) next_ = next_->next(); - while (next_ == NULL + while (next_ == nullptr && hash_ < container_->capacity()) next_ = container_->table_[hash_++]; } @@ -225,10 +225,10 @@ void HashSet::initTable() { size_ = 0; - tmp_ = NULL; + tmp_ = nullptr; table_ = new HashSetBucket*[capacity_]; for (size_t i = 0; i < capacity_; i++) - table_[i] = NULL; + table_[i] = nullptr; } template @@ -259,7 +259,7 @@ HashSet::findKey(KEY key) const return bucket_key; } } - return NULL; + return nullptr; } template @@ -274,7 +274,7 @@ HashSet::findKey(KEY key) return bucket_key; } } - return NULL; + return nullptr; } template @@ -355,7 +355,7 @@ HashSet::eraseKey(KEY key) { size_t hash = hash_(key) % capacity_; HashSetBucket *head = table_[hash]; - HashSetBucket *prev = NULL; + HashSetBucket *prev = nullptr; for (HashSetBucket *bucket = head; bucket; bucket = bucket->next()) { if (equal_(bucket->key(), key)) { if (prev) @@ -384,7 +384,7 @@ HashSet::deleteContentsClear() next = bucket->next(); delete bucket; } - table_[hash] = NULL; + table_[hash] = nullptr; } size_ = 0; } @@ -403,7 +403,7 @@ HashSet::clear() next = bucket->next(); delete bucket; } - table_[hash] = NULL; + table_[hash] = nullptr; } size_ = 0; } diff --git a/util/Machine.cc b/util/Machine.cc index 167248e4..2ec2dff5 100644 --- a/util/Machine.cc +++ b/util/Machine.cc @@ -156,10 +156,10 @@ memoryUsage() if (status) { const size_t line_length = 128; char line[line_length]; - while (fgets(line, line_length, status) != NULL) { + while (fgets(line, line_length, status) != nullptr) { char *field = strtok(line, " \t"); if (stringEq(field, "VmRSS:")) { - char *size = strtok(NULL, " \t"); + char *size = strtok(nullptr, " \t"); if (size) { char *ignore; // VmRSS is in kilobytes. diff --git a/util/Map.hh b/util/Map.hh index 10fcd57f..bb4b0f97 100644 --- a/util/Map.hh +++ b/util/Map.hh @@ -47,11 +47,11 @@ public: VALUE findKey(const KEY key) const { - typename std::map::const_iterator find_iter=this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) return find_iter->second; else - return NULL; + return nullptr; } void findKey(const KEY key, @@ -59,7 +59,7 @@ public: VALUE &value, bool &exists) const { - typename std::map::const_iterator find_iter=this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) { value = find_iter->second; exists = true; @@ -74,8 +74,7 @@ public: VALUE &value, bool &exists) const { - typename std::map::const_iterator - find_iter = this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) { map_key = find_iter->first; value = find_iter->second; @@ -97,7 +96,7 @@ public: void eraseKey(KEY key) { - typename std::map::iterator find_iter = this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) this->erase(find_iter); } @@ -133,18 +132,18 @@ public: class Iterator { public: - Iterator() : container_(NULL) {} + Iterator() : container_(nullptr) {} explicit Iterator(std::map *container) : container_(container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } explicit Iterator(std::map &container) : container_(&container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } void init(std::map *container) - { container_ = container; if (container_ != NULL) iter_=container_->begin();} + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} void init(std::map &container) - { container_ = &container; if (container_ != NULL) iter_=container_->begin();} - bool hasNext() { return container_ != NULL && iter_ != container_->end(); } + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } VALUE next() { return iter_++->second; } void next(KEY &key, VALUE &value) @@ -159,18 +158,18 @@ public: class ConstIterator { public: - ConstIterator() : container_(NULL) {} + ConstIterator() : container_(nullptr) {} explicit ConstIterator(const std::map *container) : container_(container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } explicit ConstIterator(const std::map &container) : container_(&container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } void init(const std::map *container) - { container_ = container; if (container_ != NULL) iter_=container_->begin();} + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} void init(const std::map &container) - { container_ = &container; if (container_ != NULL) iter_=container_->begin();} - bool hasNext() { return container_ != NULL && iter_ != container_->end(); } + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } VALUE next() { return iter_++->second; } void next(KEY &key, VALUE &value) diff --git a/util/MinMax.cc b/util/MinMax.cc index 04eedca6..e7158275 100644 --- a/util/MinMax.cc +++ b/util/MinMax.cc @@ -53,9 +53,9 @@ void MinMax::destroy() { delete min_; - min_ = NULL; + min_ = nullptr; delete max_; - max_ = NULL; + max_ = nullptr; } MinMax::MinMax(const char *name, @@ -97,7 +97,7 @@ MinMax::find(const char *min_max) || stringEq(min_max, "late")) return max(); else - return NULL; + return nullptr; } MinMax * @@ -108,7 +108,7 @@ MinMax::find(int index) else if (index == max_->index()) return max(); else - return NULL; + return nullptr; } bool @@ -136,11 +136,11 @@ void MinMaxAll::destroy() { delete min_; - min_ = NULL; + min_ = nullptr; delete max_; - max_ = NULL; + max_ = nullptr; delete all_; - all_ = NULL; + all_ = nullptr; } MinMaxAll::MinMaxAll(const char *name, @@ -185,7 +185,7 @@ MinMaxAll::find(const char *min_max) || stringEq(min_max, "minmax")) return all_; else - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// diff --git a/util/Mutex.hh b/util/Mutex.hh index e19d63cd..fa46119c 100644 --- a/util/Mutex.hh +++ b/util/Mutex.hh @@ -17,56 +17,11 @@ #ifndef STA_MUTEX_H #define STA_MUTEX_H -#include -#include "Pthread.hh" -#include "DisallowCopyAssign.hh" -#include "ThreadException.hh" +#include namespace sta { -// C++ wrapper/facade for pthread_mutex_t. -class Mutex -{ -public: - Mutex(); - ~Mutex(); - void lock(); - bool trylock(); - void unlock(); - -private: - DISALLOW_COPY_AND_ASSIGN(Mutex); - - pthread_mutex_t mutex_; - - friend class Condition; -}; - -inline void -Mutex::lock() -{ - int error = pthread_mutex_lock(&mutex_); - CheckThreadError(error); -} - -// Return true if lock is successful. -inline bool -Mutex::trylock() -{ - int error = pthread_mutex_trylock(&mutex_); - if (error == 0) - return true; - else if (error != EBUSY) - throw ThreadException(__FILE__, __LINE__, error); - return false; -} - -inline void -Mutex::unlock() -{ - int error = pthread_mutex_unlock(&mutex_); - CheckThreadError(error); -} +typedef std::unique_lock UniqueLock; } // namespace #endif diff --git a/util/PatternMatch.cc b/util/PatternMatch.cc index f3176065..2df559ef 100644 --- a/util/PatternMatch.cc +++ b/util/PatternMatch.cc @@ -34,7 +34,7 @@ PatternMatch::PatternMatch(const char *pattern, is_regexp_(is_regexp), nocase_(nocase), interp_(interp), - regexp_(NULL) + regexp_(nullptr) { if (is_regexp_) compileRegexp(); @@ -44,8 +44,8 @@ PatternMatch::PatternMatch(const char *pattern) : pattern_(pattern), is_regexp_(false), nocase_(false), - interp_(NULL), - regexp_(NULL) + interp_(nullptr), + regexp_(nullptr) { } @@ -55,7 +55,7 @@ PatternMatch::PatternMatch(const char *pattern, is_regexp_(inherit_from->is_regexp_), nocase_(inherit_from->nocase_), interp_(inherit_from->interp_), - regexp_(NULL) + regexp_(nullptr) { if (is_regexp_) compileRegexp(); @@ -74,14 +74,14 @@ PatternMatch::compileRegexp() Tcl_Obj *pattern_obj = Tcl_NewStringObj(anchored_pattern.c_str(), anchored_pattern.size()); regexp_ = Tcl_GetRegExpFromObj(interp_, pattern_obj, flags); - if (regexp_ == NULL && interp_) + if (regexp_ == nullptr && interp_) throw RegexpCompileError(pattern_); } static bool regexpWildcards(const char *pattern) { - return strpbrk(pattern, ".+*?[]") != NULL; + return strpbrk(pattern, ".+*?[]") != nullptr; } bool @@ -97,7 +97,7 @@ bool PatternMatch::match(const char *str) const { if (regexp_) - return Tcl_RegExpExec(NULL, regexp_, str, str) == 1; + return Tcl_RegExpExec(nullptr, regexp_, str, str) == 1; else return patternMatch(pattern_, str); } diff --git a/util/Pool.hh b/util/Pool.hh index 68fb34fe..bb179920 100644 --- a/util/Pool.hh +++ b/util/Pool.hh @@ -36,72 +36,64 @@ class PoolBlock public: explicit PoolBlock(ObjectIndex size, ObjectIndex begin_index); - ~PoolBlock(); OBJ *makeObject(); OBJ *makeObjects(ObjectIndex count); ObjectIndex index(const OBJ *object); OBJ *find(ObjectIndex index); PoolBlock *nextBlock() const { return next_block_; } void setNextBlock(PoolBlock *next); - ObjectIndex size() const { return size_; } + ObjectIndex size() const { return objects_.size(); } private: DISALLOW_COPY_AND_ASSIGN(PoolBlock); - ObjectIndex size_; + std::vector objects_; ObjectIndex begin_index_; - OBJ *objects_; ObjectIndex next_free_; PoolBlock *next_block_; + static constexpr unsigned min_initial_size_ = 100; }; template PoolBlock::PoolBlock(ObjectIndex size, ObjectIndex begin_index) : - size_(size), + objects_(size), begin_index_(begin_index), - objects_(new OBJ[size]), next_free_(0), - next_block_(NULL) + next_block_(nullptr) { } -template -PoolBlock::~PoolBlock() -{ - delete [] objects_; -} - template OBJ * PoolBlock::makeObject() { - if (next_free_ < size_) + if (next_free_ < objects_.size()) return &objects_[next_free_++]; else - return NULL; + return nullptr; } template OBJ * PoolBlock::makeObjects(ObjectIndex count) { - if ((next_free_ + count - 1) < size_) { + if ((next_free_ + count - 1) < objects_.size()) { OBJ *object = &objects_[next_free_]; next_free_ += count; return object; } else - return NULL; + return nullptr; } template ObjectIndex PoolBlock::index(const OBJ *object) { - if (object >= objects_ && object < &objects_[size_]) + if (object >= &objects_[0] && object < &objects_[objects_.size()]) // Index==0 is reserved. - return begin_index_ + object - objects_ + 1; + return begin_index_ + object - &objects_[0] + 1; else return 0; } @@ -113,10 +105,10 @@ PoolBlock::find(ObjectIndex index) // Index==0 is reserved. ObjectIndex index1 = index - 1; if (index1 >= begin_index_ - && index1 < begin_index_ + size_) + && index1 < begin_index_ + objects_.size()) return &objects_[index1 - begin_index_]; else - return NULL; + return nullptr; } template @@ -145,7 +137,7 @@ public: ObjectIndex count); void deleteObjects(ObjectIndex index, ObjectIndex count); - // Index=0 is reserved for the NULL object pointer. + // Index=0 is reserved for the nullptr object pointer. ObjectIndex index(const OBJ *object) const; OBJ *find(ObjectIndex index) const; ObjectIndex size() const { return size_; } @@ -169,13 +161,8 @@ protected: template Pool::Pool(ObjectIndex size) : - size_(0), - growth_factor_(.2F), - blocks_(NULL), - last_block_(NULL) + Pool(size, .2F) { - if (size > 0) - makeBlock(size); } template @@ -183,11 +170,10 @@ Pool::Pool(ObjectIndex size, float growth_factor) : size_(0), growth_factor_(growth_factor), - blocks_(NULL), - last_block_(NULL) + blocks_(nullptr), + last_block_(nullptr) { - if (size > 0) - makeBlock(size); + makeBlock(size); } template @@ -204,12 +190,10 @@ template OBJ * Pool::makeObject() { - if (size_ == 0) - makeBlock(10); OBJ *object = findDeletedObject(1); - if (object == NULL) { + if (object == nullptr) { object = last_block_->makeObject(); - if (object == NULL) { + if (object == nullptr) { ObjectIndex block_size=static_cast(size_*growth_factor_+2); PoolBlock *block = makeBlock(block_size); object = block->makeObject(); @@ -222,8 +206,6 @@ template OBJ * Pool::findDeletedObject(ObjectIndex count) { - if (size_ == 0) - makeBlock(10); if (deleted_list_heads_.size() > count) { ObjectIndex index = deleted_list_heads_[count]; if (index) { @@ -233,7 +215,7 @@ Pool::findDeletedObject(ObjectIndex count) return object; } } - return NULL; + return nullptr; } template @@ -241,9 +223,9 @@ OBJ * Pool::makeObjects(ObjectIndex count) { OBJ *objects = findDeletedObject(count); - if (objects == NULL) { + if (objects == nullptr) { objects = last_block_->makeObjects(count); - if (objects == NULL) { + if (objects == nullptr) { ObjectIndex block_size=max(static_cast(size_*growth_factor_+2), count); PoolBlock *block = makeBlock(block_size); @@ -297,10 +279,10 @@ Pool::find(ObjectIndex index) const return object; } internalError("object index not found in pool"); - return NULL; + return nullptr; } else - return NULL; + return nullptr; } template diff --git a/util/Report.cc b/util/Report.cc index 2a4965b2..797b6e89 100644 --- a/util/Report.cc +++ b/util/Report.cc @@ -24,8 +24,8 @@ namespace sta { using std::min; Report::Report() : - log_stream_(NULL), - redirect_stream_(NULL), + log_stream_(nullptr), + redirect_stream_(nullptr), redirect_to_string_(false), buffer_size_(1000), buffer_(new char[buffer_size_]), @@ -236,7 +236,7 @@ void Report::logBegin(const char *filename) { log_stream_ = fopen(filename, "w"); - if (log_stream_ == NULL) + if (log_stream_ == nullptr) throw FileNotWritable(filename); } @@ -245,14 +245,14 @@ Report::logEnd() { if (log_stream_) fclose(log_stream_); - log_stream_ = NULL; + log_stream_ = nullptr; } void Report::redirectFileBegin(const char *filename) { redirect_stream_ = fopen(filename, "w"); - if (redirect_stream_ == NULL) + if (redirect_stream_ == nullptr) throw FileNotWritable(filename); } @@ -260,7 +260,7 @@ void Report::redirectFileAppendBegin(const char *filename) { redirect_stream_ = fopen(filename, "a"); - if (redirect_stream_ == NULL) + if (redirect_stream_ == nullptr) throw FileNotWritable(filename); } @@ -269,7 +269,7 @@ Report::redirectFileEnd() { if (redirect_stream_) fclose(redirect_stream_); - redirect_stream_ = NULL; + redirect_stream_ = nullptr; } void diff --git a/util/ReportTcl.cc b/util/ReportTcl.cc index 1fb793bc..9925cf61 100644 --- a/util/ReportTcl.cc +++ b/util/ReportTcl.cc @@ -78,13 +78,13 @@ Tcl_ChannelType tcl_encap_type_stdout = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL, // handlerProc - NULL, // wideSeekProc - NULL, // threadActionProc - NULL // truncateProc + nullptr, // flushProc + nullptr, // handlerProc + nullptr, // wideSeekProc + nullptr, // threadActionProc + nullptr // truncateProc }; Tcl_ChannelType tcl_encap_type_stderr = { @@ -98,13 +98,13 @@ Tcl_ChannelType tcl_encap_type_stderr = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL, // handlerProc - NULL, // wideSeekProc - NULL, // threadActionProc - NULL // truncateProc + nullptr, // flushProc + nullptr, // handlerProc + nullptr, // wideSeekProc + nullptr, // threadActionProc + nullptr // truncateProc }; #else @@ -121,12 +121,12 @@ Tcl_ChannelType tcl_encap_type_stdout = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL, // handlerProc - NULL, // wideSeekProc - NULL // threadActionProc + nullptr, // flushProc + nullptr, // handlerProc + nullptr, // wideSeekProc + nullptr // threadActionProc }; Tcl_ChannelType tcl_encap_type_stderr = { @@ -140,12 +140,12 @@ Tcl_ChannelType tcl_encap_type_stderr = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL, // handlerProc - NULL, // wideSeekProc - NULL // threadActionProc + nullptr, // flushProc + nullptr, // handlerProc + nullptr, // wideSeekProc + nullptr // threadActionProc }; #else @@ -162,11 +162,11 @@ Tcl_ChannelType tcl_encap_type_stdout = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL, // handlerProc - NULL // wideSeekProc + nullptr, // flushProc + nullptr, // handlerProc + nullptr // wideSeekProc }; Tcl_ChannelType tcl_encap_type_stderr = { @@ -180,11 +180,11 @@ Tcl_ChannelType tcl_encap_type_stderr = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL, // handlerProc - NULL // wideSeekProc + nullptr, // flushProc + nullptr, // handlerProc + nullptr // wideSeekProc }; #else @@ -202,10 +202,10 @@ Tcl_ChannelType tcl_encap_type_stdout = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL // handlerProc + nullptr, // flushProc + nullptr // handlerProc }; Tcl_ChannelType tcl_encap_type_stderr = { @@ -219,10 +219,10 @@ Tcl_ChannelType tcl_encap_type_stderr = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL, // close2Proc + nullptr, // close2Proc encapBlockModeProc, - NULL, // flushProc - NULL // handlerProc + nullptr, // flushProc + nullptr // handlerProc }; #else @@ -239,7 +239,7 @@ Tcl_ChannelType tcl_encap_type_stdout = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL // close2Proc + nullptr // close2Proc }; Tcl_ChannelType tcl_encap_type_stderr = { @@ -253,7 +253,7 @@ Tcl_ChannelType tcl_encap_type_stderr = { encapGetOptionProc, encapWatchProc, encapGetHandleProc, - NULL // close2Proc + nullptr // close2Proc }; #endif @@ -265,18 +265,18 @@ Tcl_ChannelType tcl_encap_type_stderr = { ReportTcl::ReportTcl() : Report(), - interp_(NULL), - tcl_stdout_(NULL), - tcl_stderr_(NULL), - tcl_encap_stdout_(NULL), - tcl_encap_stderr_(NULL) + interp_(nullptr), + tcl_stdout_(nullptr), + tcl_stderr_(nullptr), + tcl_encap_stdout_(nullptr), + tcl_encap_stderr_(nullptr) { } ReportTcl::~ReportTcl() { - tcl_encap_stdout_ = NULL; - tcl_encap_stderr_ = NULL; + tcl_encap_stdout_ = nullptr; + tcl_encap_stderr_ = nullptr; Tcl_UnstackChannel(interp_, tcl_stdout_); Tcl_UnstackChannel(interp_, tcl_stderr_); } diff --git a/util/Set.hh b/util/Set.hh index d11951f0..5d407e11 100644 --- a/util/Set.hh +++ b/util/Set.hh @@ -34,23 +34,23 @@ public: // Find the entry corresponding to key. KEY findKey(const KEY key) const { - typename std::set::const_iterator find_iter = this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) return *find_iter; else - return NULL; + return nullptr; } // Find out if key is in the set. bool hasKey(const KEY key) const { - typename std::set::const_iterator find_iter = this->find(key); + auto find_iter = this->find(key); return find_iter != this->end(); } // Erase the entry corresponding to key. void eraseKey(KEY key) { - typename std::set::iterator find_iter = this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) this->erase(find_iter); } @@ -91,18 +91,18 @@ public: class Iterator { public: - Iterator() : container_(NULL) {} + Iterator() : container_(nullptr) {} explicit Iterator(std::set *container) : container_(container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } explicit Iterator(std::set &container) : container_(&container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } void init(std::set *container) - { container_ = container; if (container_ != NULL) iter_=container_->begin();} + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} void init(std::set &container) - { container_ = &container; if (container_ != NULL) iter_=container_->begin();} - bool hasNext() { return container_ != NULL && iter_ != container_->end(); } + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } KEY next() { return *iter_++; } std::set *container() { return container_; } @@ -114,19 +114,19 @@ public: class ConstIterator { public: - ConstIterator() : container_(NULL) {} + ConstIterator() : container_(nullptr) {} explicit ConstIterator(const std::set *container) : container_(container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } explicit ConstIterator(const std::set &container) : container_(&container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } void init(const std::set *container) - { container_ = container; if (container_ != NULL) iter_=container_->begin();} + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} void init(const std::set &container) - { container_ = &container; if (container_ != NULL) iter_=container_->begin();} + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} - bool hasNext() { return container_ != NULL && iter_ != container_->end(); } + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } KEY next() { return *iter_++; } const std::set *container() { return container_; } @@ -141,8 +141,8 @@ bool Set::equal(const std::set *set1, const std::set *set2) { - if ((set1 == NULL || set1->empty()) - && (set2 == NULL || set2->empty())) + if ((set1 == nullptr || set1->empty()) + && (set2 == nullptr || set2->empty())) return true; else if (set1 && set2) { if (set1->size() == set2->size()) { @@ -191,10 +191,10 @@ Set::intersects(std::set *set1, small = set2; big = set1; } - typename Set::const_iterator iter1 = big->begin(); - typename Set::const_iterator last1 = big->end(); - typename Set::const_iterator iter2 = small->begin(); - typename Set::const_iterator last2 = small->end(); + auto iter1 = big->begin(); + auto last1 = big->end(); + auto iter2 = small->begin(); + auto last2 = small->end(); if (static_cast(small->size() + big->size()) < (small->size() * log(static_cast(big->size())))) { while (iter1 != last1 && iter2 != last2) { if (*iter1 < *iter2) diff --git a/util/StaConfig.hh.cmake b/util/StaConfig.hh.cmake index 1a343a36..c162013f 100644 --- a/util/StaConfig.hh.cmake +++ b/util/StaConfig.hh.cmake @@ -1,7 +1,5 @@ #define STA_VERSION "${STA_VERSION}" -#define PTHREADS ${PTHREADS} - #define ZLIB ${ZLIB} #define CUDD ${CUDD} diff --git a/util/StringUtil.cc b/util/StringUtil.cc index 40e00441..f28f54e1 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include "Machine.hh" #include "Mutex.hh" #include "StringUtil.hh" @@ -43,7 +44,7 @@ stringCopy(const char *str) return copy; } else - return NULL; + return nullptr; } bool @@ -157,10 +158,10 @@ stringPrintTmp(const char *fmt, //////////////////////////////////////////////////////////////// static int tmp_string_count_ = 100; -static char **tmp_strings_ = NULL; -static size_t *tmp_string_lengths_ = NULL; +static char **tmp_strings_ = nullptr; +static size_t *tmp_string_lengths_ = nullptr; static int tmp_string_next_; -static Mutex string_lock_; +static std::mutex string_lock_; void initTmpStrings() @@ -183,10 +184,10 @@ deleteTmpStrings() for (int i = 0; i < tmp_string_count_; i++) delete [] tmp_strings_[i]; delete [] tmp_strings_; - tmp_strings_ = NULL; + tmp_strings_ = nullptr; delete [] tmp_string_lengths_; - tmp_string_lengths_ = NULL; + tmp_string_lengths_ = nullptr; } } @@ -195,19 +196,18 @@ getTmpString(// Return values. char *&str, size_t &length) { - string_lock_.lock(); + UniqueLock lock(string_lock_); if (tmp_string_next_ == tmp_string_count_) tmp_string_next_ = 0; str = tmp_strings_[tmp_string_next_]; length = tmp_string_lengths_[tmp_string_next_]; tmp_string_next_++; - string_lock_.unlock(); } char * makeTmpString(size_t length) { - string_lock_.lock(); + UniqueLock lock(string_lock_); if (tmp_string_next_ == tmp_string_count_) tmp_string_next_ = 0; char *tmp_str = tmp_strings_[tmp_string_next_]; @@ -220,7 +220,6 @@ makeTmpString(size_t length) tmp_string_lengths_[tmp_string_next_] = length; } tmp_string_next_++; - string_lock_.unlock(); return tmp_str; } diff --git a/util/StringUtil.hh b/util/StringUtil.hh index d0f5ad54..e79c486f 100644 --- a/util/StringUtil.hh +++ b/util/StringUtil.hh @@ -45,7 +45,7 @@ inline bool stringEqIf(const char *str1, const char *str2) { - return (str1 == NULL && str2 == NULL) + return (str1 == nullptr && str2 == nullptr) || (str1 && str2 && strcmp(str1, str2) == 0); } @@ -69,7 +69,7 @@ inline bool stringEqualIf(const char *str1, const char *str2) { - return (str1 == NULL && str2 == NULL) + return (str1 == nullptr && str2 == nullptr) || (str1 && str2 && strcasecmp(str1, str2) == 0); } @@ -84,8 +84,8 @@ inline bool stringLessIf(const char *str1, const char *str2) { - return (str1 == NULL && str2 != NULL) - || (str1 != NULL && str2 != NULL && strcmp(str1, str2) < 0); + return (str1 == nullptr && str2 != nullptr) + || (str1 != nullptr && str2 != nullptr && strcmp(str1, str2) < 0); } class CharPtrLess diff --git a/util/ThreadForEach.hh b/util/ThreadForEach.hh index 5feca83d..e1fc2fce 100644 --- a/util/ThreadForEach.hh +++ b/util/ThreadForEach.hh @@ -17,53 +17,74 @@ #ifndef STA_THREAD_FOR_EACH_H #define STA_THREAD_FOR_EACH_H +#include +#include +#include #include "Iterator.hh" -#include "Thread.hh" -#include "Mutex.hh" namespace sta { template class ForEachArg { public: - ForEachArg() {} ForEachArg(Iterator *iter, - Mutex *lock, + std::mutex &lock, Func *func) : iter_(iter), lock_(lock), func_(func) {} + ~ForEachArg() + { + delete func_; + } + + // Copy constructor. + ForEachArg(const ForEachArg &arg) : + iter_(arg.iter_), + lock_(arg.lock_), + func_(arg.func_->copy()) + { + } + // Move constructor. + ForEachArg(ForEachArg &&arg) : + iter_(arg.iter_), + lock_(arg.lock_), + func_(arg.func_) + { + arg.func_ = nullptr; + } + Iterator *iter_; - Mutex *lock_; + std::mutex &lock_; Func *func_; }; template void -forEachBegin(void *arg) +forEachBegin(ForEachArg arg1) { - ForEachArg *arg1 = - reinterpret_cast*>(arg); - Iterator *iter = arg1->iter_; - Mutex *lock = arg1->lock_; - Func *func = arg1->func_; + Iterator *iter = arg1.iter_; + std::mutex &lock = arg1.lock_; + Func *func = arg1.func_; while (true) { - lock->lock(); + lock.lock(); if (iter->hasNext()) { FuncArg arg = iter->next(); - lock->unlock(); + lock.unlock(); (*func)(arg); } else { - lock->unlock(); + lock.unlock(); break; } } } // Parallel version of STL for_each. +// Each thread has its own functor. +// Func::copy() must be defined. template void forEach(Iterator *iter, @@ -75,55 +96,15 @@ forEach(Iterator *iter, (*func)(iter->next()); } else { - Mutex lock; - ForEachArg arg(iter, &lock, func); - Thread *threads = new Thread[thread_count]; - for (int i = 0; i < thread_count; i++) - threads[i].beginTask(forEachBegin, - reinterpret_cast(&arg)); - - for (int i = 0; i < thread_count; i++) - threads[i].wait(); - - delete [] threads; - } -} - -// forEach2 is similar to forEach, except that each thread has -// its own functor. -// Func::copy() must be defined. -template -void -forEach2(Iterator *iter, - Func *func, - int thread_count) -{ - if (thread_count <= 1) { - while (iter->hasNext()) - (*func)(iter->next()); - } - else { - ForEachArg *args = - new ForEachArg[thread_count]; - Thread *threads = new Thread[thread_count]; - Mutex lock; + std::vector threads; + std::mutex lock; for (int i = 0; i < thread_count; i++) { - ForEachArg *arg = &args[i]; - arg->iter_ = iter; - arg->lock_ = &lock; - arg->func_ = func->copy(); - threads[i].beginTask(forEachBegin, - reinterpret_cast(arg)); + ForEachArg arg(iter, lock, func->copy()); + threads.push_back(std::thread(forEachBegin, arg)); } - for (int i = 0; i < thread_count; i++) { - threads[i].wait(); - ForEachArg *arg = &args[i]; - delete arg->func_; - } - - delete [] threads; - delete [] args; + for (auto &thread : threads) + thread.join(); } } diff --git a/util/TokenParser.cc b/util/TokenParser.cc index 70c34b14..68b1b985 100644 --- a/util/TokenParser.cc +++ b/util/TokenParser.cc @@ -50,10 +50,10 @@ TokenParser::hasNext() while (*token_ != '\0' && isspace(*token_)) token_++; // Skip delimiters. - while (*token_ != '\0' && strchr(delimiters_,*token_) != NULL) + while (*token_ != '\0' && strchr(delimiters_,*token_) != nullptr) token_++; if (*token_ == '\0') - token_ = NULL; + token_ = nullptr; else { token_end_ = strpbrk(token_, delimiters_); if (token_end_) { @@ -65,9 +65,9 @@ TokenParser::hasNext() } } else - token_ = NULL; + token_ = nullptr; } - return token_ != NULL; + return token_ != nullptr; } char * diff --git a/util/UnorderedMap.hh b/util/UnorderedMap.hh index 20fb916a..277908e2 100644 --- a/util/UnorderedMap.hh +++ b/util/UnorderedMap.hh @@ -50,11 +50,11 @@ public: VALUE findKey(const KEY key) const { - typename std::unordered_map::const_iterator find_iter=this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) return find_iter->second; else - return NULL; + return nullptr; } void findKey(const KEY key, @@ -62,7 +62,7 @@ public: VALUE &value, bool &exists) const { - typename std::unordered_map::const_iterator find_iter=this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) { value = find_iter->second; exists = true; @@ -77,7 +77,7 @@ public: VALUE &value, bool &exists) const { - typename std::unordered_map::const_iterator find_iter=this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) { map_key = find_iter->first; value = find_iter->second; @@ -99,7 +99,7 @@ public: void eraseKey(KEY key) { - typename std::unordered_map::const_iterator find_iter=this->find(key); + auto find_iter = this->find(key); if (find_iter != this->end()) this->erase(find_iter); } @@ -127,18 +127,18 @@ public: class Iterator { public: - Iterator() : container_(NULL) {} + Iterator() : container_(nullptr) {} explicit Iterator(std::unordered_map *container) : container_(container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } explicit Iterator(std::unordered_map &container) : container_(&container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } void init(std::unordered_map *container) - { container_ = container; if (container_ != NULL) iter_=container_->begin();} + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} void init(std::unordered_map &container) - { container_ = &container; if (container_ != NULL) iter_=container_->begin();} - bool hasNext() { return container_ != NULL && iter_ != container_->end(); } + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } VALUE next() { return iter_++->second; } void next(KEY &key, VALUE &value) @@ -153,18 +153,18 @@ public: class ConstIterator { public: - ConstIterator() : container_(NULL) {} + ConstIterator() : container_(nullptr) {} explicit ConstIterator(const std::unordered_map *container) : container_(container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } explicit ConstIterator(const std::unordered_map &container) : container_(&container) - { if (container_ != NULL) iter_ = container_->begin(); } + { if (container_ != nullptr) iter_ = container_->begin(); } void init(const std::unordered_map *container) - { container_ = container; if (container_ != NULL) iter_=container_->begin();} + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} void init(const std::unordered_map &container) - { container_ = &container; if (container_ != NULL) iter_=container_->begin();} - bool hasNext() { return container_ != NULL && iter_ != container_->end(); } + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } VALUE next() { return iter_++->second; } void next(KEY &key, VALUE &value) diff --git a/util/UnorderedSet.hh b/util/UnorderedSet.hh new file mode 100644 index 00000000..dee3ecef --- /dev/null +++ b/util/UnorderedSet.hh @@ -0,0 +1,137 @@ +// OpenSTA, Static Timing Analyzer +// Copyright (c) 2019, 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 . + +#ifndef STA_UNORDERED_SET_H +#define STA_UNORDERED_SET_H + +#include +#include + +namespace sta { + +// Add convenience functions around STL container. +template , class EQUAL = std::equal_to > +class UnorderedSet : public std::unordered_set +{ +public: + UnorderedSet() : + std::unordered_set() + { + } + + explicit UnorderedSet(size_t size, + const HASH &hash, + const EQUAL &equal) : + std::unordered_set(size, hash, equal) + { + } + + // Find out if key is in the set. + bool + hasKey(const KEY key) const + { + return this->find(key) != this->end(); + } + + // Find the value corresponding to key. + KEY + findKey(const KEY key) const + { + auto find_iter = this->find(key); + if (find_iter != this->end()) + return *find_iter; + else + return nullptr; + } + + // Erase the value corresponding to key. + void + eraseKey(KEY key) + { + auto find_iter = this->find(key); + if (find_iter != this->end()) + this->erase(find_iter); + } + + void + deleteContents() + { + Iterator iter(this); + while (iter.hasNext()) + delete iter.next(); + } + + void + deleteContentsClear() + { + deleteContents(); + std::unordered_set::clear(); + } + + // Java style container itererator + // Set::Iterator iter(set); + // while (iter.hasNext()) { + // Value *v = iter.next(); + // } + class Iterator + { + public: + Iterator() : container_(nullptr) {} + explicit Iterator(std::unordered_set *container) : + container_(container) + { if (container_ != nullptr) iter_ = container_->begin(); } + explicit Iterator(std::unordered_set &container) : + container_(&container) + { if (container_ != nullptr) iter_ = container_->begin(); } + void init(std::unordered_set *container) + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} + void init(std::unordered_set &container) + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } + KEY next() { return *iter_++; } + std::unordered_set *container() { return container_; } + + private: + std::unordered_set *container_; + typename std::unordered_set::iterator iter_; + }; + + class ConstIterator + { + public: + ConstIterator() : container_(nullptr) {} + explicit ConstIterator(const std::unordered_set *container) : + container_(container) + { if (container_ != nullptr) iter_ = container_->begin(); } + explicit ConstIterator(const std::unordered_set &container) : + container_(&container) + { if (container_ != nullptr) iter_ = container_->begin(); } + void init(const std::unordered_set *container) + { container_ = container; if (container_ != nullptr) iter_=container_->begin();} + void init(const std::unordered_set &container) + { container_ = &container; if (container_ != nullptr) iter_=container_->begin();} + bool hasNext() { return container_ != nullptr && iter_ != container_->end(); } + KEY next() { return iter_++->second; } + const std::unordered_set *container() { return container_; } + + private: + const std::unordered_set *container_; + typename std::unordered_set::const_iterator iter_; + }; +}; + +} // namespace +#endif diff --git a/util/Vector.hh b/util/Vector.hh index 759364c2..8546a4a7 100644 --- a/util/Vector.hh +++ b/util/Vector.hh @@ -35,8 +35,7 @@ public: void eraseObject(OBJ obj) { - typename std::vector::iterator find_iter = - std::find(this->begin(), this->end(), obj); + auto find_iter = std::find(this->begin(), this->end(), obj); if (find_iter != this->end()) this->erase(find_iter); } @@ -73,7 +72,7 @@ public: class Iterator { public: - Iterator() : container_(NULL) {} + Iterator() : container_(nullptr) {} Iterator(std::vector *container) : container_(container) { if (container) iter_ = container->begin(); } @@ -97,13 +96,13 @@ public: class ConstIterator { public: - ConstIterator() : container_(NULL) {} + ConstIterator() : container_(nullptr) {} ConstIterator(const std::vector *container) : container_(container) { if (container_) iter_ = container_->begin(); } ConstIterator(const std::vector &container) : container_(&container) - { if (container_) iter_ = container_->begin(); } + { iter_ = container_->begin(); } void init() { iter_ = container_->begin(); } void init(const std::vector *container) { container_ = container; if (container_) iter_=container_->begin();} diff --git a/util/Zlib.hh b/util/Zlib.hh index 3cf446fb..54c93826 100644 --- a/util/Zlib.hh +++ b/util/Zlib.hh @@ -35,7 +35,7 @@ #define gzclose fclose #define gzgets(stream,s,size) fgets(s,size,stream) #define gzprintf fprintf -#define Z_NULL NULL +#define Z_NULL nullptr #endif // ZLIB diff --git a/verilog/Verilog.hh b/verilog/Verilog.hh index e21d90b4..610ae95d 100644 --- a/verilog/Verilog.hh +++ b/verilog/Verilog.hh @@ -515,7 +515,7 @@ class VerilogNetUnnamed : public VerilogNet public: VerilogNetUnnamed() {} virtual bool isNamed() { return false; } - virtual const char *name() { return NULL; } + virtual const char *name() { return nullptr; } private: DISALLOW_COPY_AND_ASSIGN(VerilogNetUnnamed); @@ -659,7 +659,7 @@ public: virtual int size(VerilogModule *module); virtual VerilogNetNameIterator *nameIterator(VerilogModule *module, VerilogReader *reader); - virtual bool hasNet() { return net_name_ != NULL; } + virtual bool hasNet() { return net_name_ != nullptr; } const char *netName() const { return net_name_; } void setNetName(const char *net_name) { net_name_ = net_name; } @@ -677,7 +677,7 @@ public: virtual int size(VerilogModule *module); virtual VerilogNetNameIterator *nameIterator(VerilogModule *module, VerilogReader *reader); - virtual bool hasNet() { return net_ != NULL; } + virtual bool hasNet() { return net_ != nullptr; } private: DISALLOW_COPY_AND_ASSIGN(VerilogNetPortRefScalar); @@ -707,6 +707,7 @@ public: int to_index, VerilogNet *net); virtual const char *name(); + int toIndex() const { return to_index_; } private: DISALLOW_COPY_AND_ASSIGN(VerilogNetPortRefPart); diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index 8f2a4489..6f8dcb22 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.cc @@ -58,7 +58,7 @@ readVerilogFile(const char *filename, Debug *debug, NetworkReader *network) { - if (verilog_reader == NULL) + if (verilog_reader == nullptr) verilog_reader = new VerilogReader(report, debug, network); return verilog_reader->read(filename); } @@ -67,7 +67,7 @@ void deleteVerilogReader() { delete verilog_reader; - verilog_reader = NULL; + verilog_reader = nullptr; } //////////////////////////////////////////////////////////////// @@ -146,7 +146,7 @@ VerilogReader::VerilogReader(Report *report, report_(report), debug_(debug), network_(network), - library_(NULL), + library_(nullptr), black_box_index_(0), zero_net_name_("zero_"), one_net_name_("one_") @@ -203,7 +203,7 @@ VerilogReader::init(const char *filename) line_ = 1; library_ = network_->findLibrary("verilog"); - if (library_ == NULL) + if (library_ == nullptr) library_ = network_->makeLibrary("verilog"); report_stmt_stats_ = debugCheck(debug_, "verilog", 1); @@ -238,7 +238,7 @@ VerilogReader::getChars(char *buf, { char *status = gzgets(stream_, buf, max_size); if (status == Z_NULL) - result = 0; // YY_NULL + result = 0; // YY_nullptr else result = strlen(buf); } @@ -250,7 +250,7 @@ VerilogReader::getChars(char *buf, { char *status = gzgets(stream_, buf, max_size); if (status == Z_NULL) - result = 0; // YY_NULL + result = 0; // YY_nullptr else result = strlen(buf); } @@ -320,7 +320,7 @@ VerilogReader::makeCellPorts(Cell *cell, while (port_iter.hasNext()) { VerilogNet *mod_port = port_iter.next(); const char *port_name = mod_port->name(); - if (port_names.findKey(port_name) == NULL) { + if (port_names.findKey(port_name) == nullptr) { port_names.insert(stringCopy(port_name)); if (mod_port->isNamed()) { if (mod_port->isNamedPortRef()) @@ -397,7 +397,7 @@ VerilogReader::checkModuleDcls(VerilogModule *module, if (dir->isInput() || dir->isOutput() || dir->isBidirect()) { - if (port_names.findKey(port_name) == NULL) + if (port_names.findKey(port_name) == nullptr) linkWarn(module->filename(), module->line(), "module %s declared signal %s is not in the port list.\n", module->name(), @@ -413,12 +413,12 @@ VerilogReader::makeDcl(PortDirection *dir, { if (dir->isInternal()) { // Prune wire declarations without assigns because they just eat memory. - VerilogDclArgSeq *assign_args = NULL; + VerilogDclArgSeq *assign_args = nullptr; VerilogDclArgSeq::Iterator arg_iter(args); while (arg_iter.hasNext()) { VerilogDclArg *arg = arg_iter.next(); if (arg->assign()) { - if (assign_args == NULL) + if (assign_args == nullptr) assign_args = new VerilogDclArgSeq; assign_args->push_back(arg); } @@ -433,7 +433,7 @@ VerilogReader::makeDcl(PortDirection *dir, return new VerilogDcl(dir, assign_args, line); } else - return NULL; + return nullptr; } else { dcl_count_++; @@ -548,7 +548,7 @@ VerilogReader::makeModuleInst(const char *module_name, int port_count = network_->portBitCount(cell); const char **net_names = new const char *[port_count]; for (int i = 0; i < port_count; i++) - net_names[i] = NULL; + net_names[i] = nullptr; VerilogNetSeq::Iterator pin_iter(pins); while (pin_iter.hasNext()) { VerilogNetPortRefScalarNet *vpin = @@ -556,7 +556,7 @@ VerilogReader::makeModuleInst(const char *module_name, const char *port_name = vpin->name(); const char *net_name = vpin->netName(); // Steal the net name string. - vpin->setNetName(NULL); + vpin->setNetName(nullptr); Port *port = network_->findPort(cell, port_name); LibertyPort *lport = network_->libertyPort(port); if (lport->isBus()) { @@ -569,7 +569,7 @@ VerilogReader::makeModuleInst(const char *module_name, && prev_net_name !=unconnected_net_name) // Repeated port reference. stringDelete(prev_net_name); - net_names[pin_index]=(net_name == NULL) ? unconnected_net_name : net_name; + net_names[pin_index]=(net_name == nullptr) ? unconnected_net_name : net_name; delete vpin; net_port_ref_scalar_net_count_--; } @@ -847,7 +847,7 @@ VerilogModule::checkInstanceName(VerilogInst *inst, const char *inst_name = inst->instanceName(); if (inst_names.findKey(inst_name)) { int i = 1; - const char *replacement_name = NULL; + const char *replacement_name = nullptr; do { if (replacement_name) stringDelete(replacement_name); @@ -1019,12 +1019,12 @@ VerilogDclBus::size() const VerilogDclArg::VerilogDclArg(const char *net_name) : net_name_(net_name), - assign_(NULL) + assign_(nullptr) { } VerilogDclArg::VerilogDclArg(VerilogAssign *assign) : - net_name_(NULL), + net_name_(nullptr), assign_(assign) { } @@ -1043,7 +1043,7 @@ VerilogDclArg::netName() else if (assign_) return assign_->lhs()->name(); else - return NULL; + return nullptr; } VerilogAssign::VerilogAssign(VerilogNet *lhs, @@ -1068,7 +1068,7 @@ class VerilogNullNetNameIterator : public VerilogNetNameIterator public: VerilogNullNetNameIterator() {} virtual bool hasNext() { return false; } - virtual const char *next() { return NULL; } + virtual const char *next() { return nullptr; } private: DISALLOW_COPY_AND_ASSIGN(VerilogNullNetNameIterator); @@ -1096,14 +1096,14 @@ VerilogOneNetNameIterator::VerilogOneNetNameIterator(const char *name) : bool VerilogOneNetNameIterator::hasNext() { - return name_ != NULL; + return name_ != nullptr; } const char * VerilogOneNetNameIterator::next() { const char *name = name_; - name_ = NULL; + name_ = nullptr; return name; } @@ -1237,7 +1237,7 @@ VerilogNetConcatNameIterator(VerilogNetSeq *nets, module_(module), reader_(reader), net_iter_(nets), - net_name_iter_(NULL) + net_name_iter_(nullptr) { if (net_iter_.hasNext()) net_name_iter_ = net_iter_.next()->nameIterator(module, reader); @@ -1269,7 +1269,7 @@ VerilogNetConcatNameIterator::next() return net_name_iter_->next(); } } - return NULL; + return nullptr; } //////////////////////////////////////////////////////////////// @@ -1329,7 +1329,7 @@ verilogNetScalarNameIterator(const char *name, return new VerilogOneNetNameIterator(name); } else - return new VerilogOneNetNameIterator(NULL); + return new VerilogOneNetNameIterator(nullptr); } VerilogNetNameIterator * @@ -1582,7 +1582,7 @@ int VerilogNetPortRefScalarNet::size(VerilogModule *module) { // VerilogNetScalar::size - VerilogDcl *dcl = NULL; + VerilogDcl *dcl = nullptr; if (net_name_) dcl = module->declaration(net_name_); if (dcl) @@ -1704,7 +1704,7 @@ VerilogReader::linkNetwork(Cell *top_cell, VerilogModule *module = verilog_reader->module(top_cell); if (module) { // Seed the recursion for expansion with the top level instance. - Instance *top_instance = network_->makeInstance(top_cell, "", NULL); + Instance *top_instance = network_->makeInstance(top_cell, "", nullptr); VerilogBindingTbl bindings(zero_net_name_, one_net_name_); VerilogNetSeq::Iterator port_iter(module->ports()); while (port_iter.hasNext()) { @@ -1716,8 +1716,8 @@ VerilogReader::linkNetwork(Cell *top_cell, Port *port = network_->findPort(top_cell, net_name); Net *net = bindings.ensureNetBinding(net_name, top_instance, network_); // Guard against repeated port name. - if (network_->findPin(top_instance, port) == NULL) { - Pin *pin = network_->makePin(top_instance, port, NULL); + if (network_->findPin(top_instance, port) == nullptr) { + Pin *pin = network_->makePin(top_instance, port, nullptr); network_->makeTerm(pin, net); } } @@ -1728,14 +1728,14 @@ VerilogReader::linkNetwork(Cell *top_cell, deleteModules(); if (errors) { network_->deleteInstance(top_instance); - return NULL; + return nullptr; } else return top_instance; } else { report->error("%s is not a verilog module.\n", network_->name(top_cell)); - return NULL; + return nullptr; } } @@ -1765,11 +1765,11 @@ VerilogReader::makeModuleInstBody(VerilogModule *module, mergeAssignNet(assign, module, inst, bindings); if (dir->isGround()) { Net *net = bindings->ensureNetBinding(arg->netName(),inst,network_); - network_->addConstantNet(net, logic_zero); + network_->addConstantNet(net, LogicValue::zero); } if (dir->isPower()) { Net *net = bindings->ensureNetBinding(arg->netName(),inst,network_); - network_->addConstantNet(net, logic_one); + network_->addConstantNet(net, LogicValue::one); } } } @@ -1788,7 +1788,7 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, { const char *module_name = mod_inst->moduleName(); Cell *cell = network_->findAnyCell(module_name); - if (cell == NULL) { + if (cell == nullptr) { if (make_black_boxes) { cell = makeBlackBox(mod_inst, parent_module); linkWarn(filename_, mod_inst->line(), @@ -1813,7 +1813,7 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, LibertyCellPortBitIterator port_iter(lib_cell); while (port_iter.hasNext()) { LibertyPort *port = port_iter.next(); - network_->makePin(inst, reinterpret_cast(port), NULL); + network_->makePin(inst, reinterpret_cast(port), nullptr); } } } @@ -1936,7 +1936,7 @@ VerilogReader::makeInstPin(Instance *inst, VerilogBindingTbl *parent_bindings, bool is_leaf) { - const char *net_name = NULL; + const char *net_name = nullptr; if (net_name_iter->hasNext()) net_name = net_name_iter->next(); makeInstPin(inst, port, net_name, bindings, parent, parent_bindings, @@ -1952,7 +1952,7 @@ VerilogReader::makeInstPin(Instance *inst, VerilogBindingTbl *parent_bindings, bool is_leaf) { - Net *net = NULL; + Net *net = nullptr; if (net_name) net = parent_bindings->ensureNetBinding(net_name, parent, network_); if (is_leaf) { @@ -1987,7 +1987,7 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst, const char *net_name = net_names[port->pinIndex()]; // net_name may be the name of a single bit bus. if (net_name) { - Net *net = NULL; + Net *net = nullptr; // If the pin is unconnected (ie, .A()) make the pin but not the net. if (net_name != unconnected_net_name) { VerilogDcl *dcl = parent_module->declaration(net_name); @@ -2006,7 +2006,7 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst, } else // Make unconnected pin. - network_->makePin(inst, reinterpret_cast(port), NULL); + network_->makePin(inst, reinterpret_cast(port), nullptr); } } @@ -2154,13 +2154,13 @@ VerilogBindingTbl::ensureNetBinding(const char *net_name, NetworkReader *network) { Net *net = find(net_name, network); - if (net == NULL) { + if (net == nullptr) { net = network->makeNet(net_name, inst); map_[network->name(net)] = net; if (stringEq(net_name, zero_net_name_)) - network->addConstantNet(net, logic_zero); + network->addConstantNet(net, LogicValue::zero); if (stringEq(net_name, one_net_name_)) - network->addConstantNet(net, logic_one); + network->addConstantNet(net, LogicValue::one); } return net; }