diff --git a/.gitignore b/.gitignore index a9f079e1..267c23f7 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,4 @@ doc/messages.txt # test artifacts */test/*.log -Testing/ +**/Testing/ diff --git a/dcalc/ArnoldiDelayCalc.cc b/dcalc/ArnoldiDelayCalc.cc index 97866a79..2523686e 100644 --- a/dcalc/ArnoldiDelayCalc.cc +++ b/dcalc/ArnoldiDelayCalc.cc @@ -236,7 +236,6 @@ private: int pin_n_; ArnoldiReduce *reduce_; delay_work *delay_work_; - std::vector unsaved_parasitics_; }; ArcDelayCalc * @@ -247,6 +246,7 @@ makeArnoldiDelayCalc(StaState *sta) ArnoldiDelayCalc::ArnoldiDelayCalc(StaState *sta) : LumpedCapDelayCalc(sta), + rcmodel_(nullptr), reduce_(new ArnoldiReduce(sta)), delay_work_(delay_work_create()) { @@ -267,6 +267,7 @@ ArnoldiDelayCalc::~ArnoldiDelayCalc() free(_delayV); free(_slewV); delete reduce_; + delete rcmodel_; } Parasitic * @@ -297,12 +298,11 @@ ArnoldiDelayCalc::findParasitic(const Pin *drvr_pin, } if (parasitic_network) { - rcmodel *rcmodel = reduce_->reduceToArnoldi(parasitic_network, drvr_pin, - parasitics->couplingCapFactor(), - drvr_rf, scene, min_max); + rcmodel_ = reduce_->reduceToArnoldi(parasitic_network, drvr_pin, + parasitics->couplingCapFactor(), + drvr_rf, scene, min_max); // Arnoldi parasitics are their own class that are not saved in the parasitic db. - unsaved_parasitics_.push_back(rcmodel); - parasitic = rcmodel; + parasitic = rcmodel_; } return parasitic; } @@ -321,9 +321,8 @@ ArnoldiDelayCalc::reduceParasitic(const Parasitic *, void ArnoldiDelayCalc::finishDrvrPin() { - for (auto parasitic : unsaved_parasitics_) - delete parasitic; - unsaved_parasitics_.clear(); + delete rcmodel_; + rcmodel_ = nullptr; } ArcDcalcResult diff --git a/dcalc/CcsCeffDelayCalc.cc b/dcalc/CcsCeffDelayCalc.cc index 6ca9cb96..fec6f032 100644 --- a/dcalc/CcsCeffDelayCalc.cc +++ b/dcalc/CcsCeffDelayCalc.cc @@ -445,14 +445,13 @@ CcsCeffDelayCalc::findVlTime(double v, { double t_init = region_ramp_times_[0]; double t_final = region_ramp_times_[region_count_]; - bool root_fail = false; - double time = findRoot( - [&](double t, double &y, double &dy) { - vl(t, elmore, y, dy); - y -= v; - }, - t_init, t_final + elmore * 3.0, .001, 20, root_fail); - vl_fail_ |= root_fail; + auto [time, failed] = + findRoot([&](double t, double &y, double &dy) { + vl(t, elmore, y, dy); + y -= v; + }, + t_init, t_final + elmore * 3.0, .001, 20); + vl_fail_ |= failed; return time; } diff --git a/dcalc/DmpCeff.cc b/dcalc/DmpCeff.cc index 6828aa67..108bf798 100644 --- a/dcalc/DmpCeff.cc +++ b/dcalc/DmpCeff.cc @@ -33,9 +33,12 @@ #include "DmpCeff.hh" #include +#include #include -#include +#include #include +#include +#include #include "Format.hh" #include "Report.hh" @@ -52,15 +55,6 @@ namespace sta { -// Tolerance (as a scale of value) for driver parameters (Ceff, delta t, t0). -static const double driver_param_tol = .01; -// Waveform threshold crossing time tolerance (1.0 = 100%). -static const double vth_time_tol = .01; -// A small number used by luDecomp. -static const double tiny_double = 1.0e-20; -// Max iterations for findRoot. -static const int find_root_max_iter = 20; - // Indices of Newton-Raphson parameter vector. enum DmpParam { t0, dt, ceff }; @@ -92,30 +86,6 @@ gateModelRd(const LibertyCell *cell, double c2, double c1, const Pvt *pvt); -static void -newtonRaphson(const int max_iter, - double x[], - const int n, - const double x_tol, - // eval(state) is called to fill fvec and fjac. - std::function eval, - // Temporaries supplied by caller. - double *fvec, - double **fjac, - int *index, - double *p, - double *scale); -static void -luSolve(double **a, - const int size, - const int *index, - double b[]); -static void -luDecomp(double **a, - const int size, - int *index, - double *scale); - //////////////////////////////////////////////////////////////// // Base class for Dartu/Menezes/Pileggi algorithm. @@ -138,51 +108,32 @@ public: double c2, double rpi, double c1); - virtual void gateDelaySlew(// Return values. - double &delay, - double &slew) = 0; - virtual void loadDelaySlew(const Pin *load_pin, - double elmore, - // Return values. - double &delay, - double &slew); + virtual std::pair gateDelaySlew() = 0; + virtual std::pair loadDelaySlew(const Pin *load_pin, + double elmore); double ceff() { return ceff_; } // Given x_ as a vector of input parameters, fill fvec_ with the // equations evaluated at x_ and fjac_ with the jabobian evaluated at x_. virtual void evalDmpEqns() = 0; - // Output response to vs(t) ramp driving pi model load. - void Vo(double t, - // Return values. - double &vo, - double &dol_dt); - // Load response to driver waveform. - void Vl(double t, - // Return values. - double &vl, - double &dvl_dt); + // Output response to vs(t) ramp driving pi model load (vo, dvo_dt). + std::pair Vo(double t); + // Load response to driver waveform (vl, dvl/dt). + std::pair Vl(double t); protected: + void luDecomp(); + void luSolve(); + void newtonRaphson(); // Find driver parameters t0, delta_t, Ceff. void findDriverParams(double ceff); - void gateCapDelaySlew(double cl, - // Return values. - double &delay, - double &slew); - void gateDelays(double ceff, - // Return values. - double &t_vth, - double &t_vl, - double &slew); - // Partial derivatives of y(t) (jacobian). - void dy(double t, - double t0, - double dt, - double cl, - // Return values. - double &dydt0, - double &dyddt, - double &dydcl); + std::pair gateCapDelaySlew(double cl); + std::tuple gateDelays(double ceff); + // Partial derivatives of y(t) jacobian (dydt0, dyddt, dydcl). + std::tuple dy(double t, + double t0, + double dt, + double cl); double y0dt(double t, double cl); double y0dcl(double t, @@ -190,9 +141,7 @@ protected: void showX(); void showFvec(); void showJacobian(); - void findDriverDelaySlew( // Return values. - double &delay, - double &slew); + std::pair findDriverDelaySlew(); double findVoCrossing(double vth, double lower_bound, double upper_bound); @@ -203,26 +152,22 @@ protected: void showVl(); void fail(std::string_view reason); - // Output response to vs(t) ramp driving capacitive load. - double y(double t, - double t0, - double dt, - double cl); + // Output response to vs(t) ramp driving capacitive load (y, t1). + std::pair y(double t, + double t0, + double dt, + double cl); // Output response to unit ramp driving capacitive load. double y0(double t, double cl); // Output response to unit ramp driving pi model load. - virtual void V0(double t, - // Return values. - double &vo, - double &dvo_dt) = 0; + // Unit ramp output at pi load (vo, dvo_dt). + virtual std::pair V0(double t) = 0; // Upper bound on time that vo crosses vh. virtual double voCrossingUpperBound() = 0; // Load responce to driver unit ramp. - virtual void Vl0(double t, - // Return values. - double &vl, - double &dvl_dt) = 0; + // Unit ramp load response (vl, dvl_dt). + virtual std::pair Vl0(double t) = 0; // Upper bound on time that vl crosses vh. double vlCrossingUpperBound(); @@ -257,13 +202,12 @@ protected: static constexpr int max_nr_order_ = 3; - double x_[max_nr_order_]; - double fvec_[max_nr_order_]; - double fjac_storage_[max_nr_order_ * max_nr_order_]; - double *fjac_[max_nr_order_]; - double scale_[max_nr_order_]; - double p_[max_nr_order_]; - int index_[max_nr_order_]; + std::array x_; + std::array fvec_; + std::array, max_nr_order_> fjac_; + std::array scale_; + std::array p_; + std::array index_; // Driver slew used to check load delay. double drvr_slew_; @@ -273,6 +217,16 @@ protected: // Load rspf elmore delay. double elmore_; double p3_; + + // Tolerance (as a scale of value) for driver parameters (Ceff, delta t, t0). + static constexpr double driver_param_tol_ = .01; + // Waveform threshold crossing time tolerance (1.0 = 100%). + static constexpr double vth_time_tol_ = .01; + // Max iterations for findRoot. + static constexpr int find_root_max_iter_ = 20; + static inline int newton_raphson_max_iter_ = 100; + // A small number used by luDecomp. + static constexpr double tiny_double_ = 1.0e-20; }; DmpAlg::DmpAlg(int nr_order, @@ -283,9 +237,6 @@ DmpAlg::DmpAlg(int nr_order, c1_(0.0), nr_order_(nr_order) { - for (int i = 0; i < nr_order_; i++) - // Only use the upper left block of the matrix - fjac_[i] = fjac_storage_ + i * max_nr_order_; } void @@ -323,16 +274,13 @@ DmpAlg::findDriverParams(double ceff) { if (nr_order_ == 3) x_[DmpParam::ceff] = ceff; - double t_vth, t_vl, slew; - gateDelays(ceff, t_vth, t_vl, slew); + auto [t_vth, t_vl, slew] = gateDelays(ceff); // Scale slew to 0-100% double dt = slew / (vh_ - vl_); double t0 = t_vth + std::log(1.0 - vth_) * rd_ * ceff - vth_ * dt; x_[DmpParam::dt] = dt; x_[DmpParam::t0] = t0; - newtonRaphson( - 100, x_, nr_order_, driver_param_tol, [this]() { evalDmpEqns(); }, fvec_, - fjac_, index_, p_, scale_); + newtonRaphson(); t0_ = x_[DmpParam::t0]; dt_ = x_[DmpParam::dt]; debugPrint(debug_, "dmp_ceff", 3, " t0 = {} dt = {} ceff = {}", @@ -342,45 +290,43 @@ DmpAlg::findDriverParams(double ceff) showVo(); } -void -DmpAlg::gateCapDelaySlew(double ceff, - // Return values. - double &delay, - double &slew) +std::pair +DmpAlg::gateCapDelaySlew(double ceff) { float model_delay, model_slew; gate_model_->gateDelay(pvt_, in_slew_, ceff, model_delay, model_slew); - delay = model_delay; - slew = model_slew; + double delay = model_delay; + double slew = model_slew; + return {delay, slew}; } -void -DmpAlg::gateDelays(double ceff, - // Return values. - double &t_vth, - double &t_vl, - double &slew) +std::tuple +DmpAlg::gateDelays(double ceff) { - double table_slew; - gateCapDelaySlew(ceff, t_vth, table_slew); + auto [t_vth, table_slew] = gateCapDelaySlew(ceff); // Convert reported/table slew to measured slew. - slew = table_slew * slew_derate_; - t_vl = t_vth - slew * (vth_ - vl_) / (vh_ - vl_); + double slew = table_slew * slew_derate_; + double t_vl = t_vth - slew * (vth_ - vl_) / (vh_ - vl_); + return {t_vth, t_vl, slew}; } -double +std::pair DmpAlg::y(double t, double t0, double dt, double cl) { double t1 = t - t0; - if (t1 <= 0.0) - return 0.0; - else if (t1 <= dt) - return y0(t1, cl) / dt; - else - return (y0(t1, cl) - y0(t1 - dt, cl)) / dt; + if (t1 <= 0.0) { + double y = 0.0; + return {y, t1}; + } + if (t1 <= dt) { + double y = y0(t1, cl) / dt; + return {y, t1}; + } + double y = (y0(t1, cl) - y0(t1 - dt, cl)) / dt; + return {y, t1}; } double @@ -390,29 +336,29 @@ DmpAlg::y0(double t, return t - rd_ * cl * (1.0 - exp2(-t / (rd_ * cl))); } -void +std::tuple DmpAlg::dy(double t, double t0, double dt, - double cl, - // Return values. - double &dydt0, - double &dyddt, - double &dydcl) + double cl) { double t1 = t - t0; - if (t1 <= 0.0) - dydt0 = dyddt = dydcl = 0.0; - else if (t1 <= dt) { - dydt0 = -y0dt(t1, cl) / dt; - dyddt = -y0(t1, cl) / (dt * dt); - dydcl = y0dcl(t1, cl) / dt; + if (t1 <= 0.0) { + double dydt0 = 0.0; + double dyddt = 0.0; + double dydcl = 0.0; + return {dydt0, dyddt, dydcl}; } - else { - dydt0 = -(y0dt(t1, cl) - y0dt(t1 - dt, cl)) / dt; - dyddt = -(y0(t1, cl) + y0(t1 - dt, cl)) / (dt * dt) + y0dt(t1 - dt, cl) / dt; - dydcl = (y0dcl(t1, cl) - y0dcl(t1 - dt, cl)) / dt; + if (t1 <= dt) { + double dydt0 = -y0dt(t1, cl) / dt; + double dyddt = -y0(t1, cl) / (dt * dt); + double dydcl = y0dcl(t1, cl) / dt; + return {dydt0, dyddt, dydcl}; } + double dydt0 = -(y0dt(t1, cl) - y0dt(t1 - dt, cl)) / dt; + double dyddt = -(y0(t1, cl) + y0(t1 - dt, cl)) / (dt * dt) + y0dt(t1 - dt, cl) / dt; + double dydcl = (y0dcl(t1, cl) - y0dcl(t1 - dt, cl)) / dt; + return {dydt0, dyddt, dydcl}; } double @@ -459,17 +405,16 @@ DmpAlg::showJacobian() } } -void -DmpAlg::findDriverDelaySlew( // Return values. - double &delay, - double &slew) +std::pair +DmpAlg::findDriverDelaySlew() { double t_upper = voCrossingUpperBound(); - delay = findVoCrossing(vth_, t0_, t_upper); + double delay = findVoCrossing(vth_, t0_, t_upper); double tl = findVoCrossing(vl_, t0_, delay); double th = findVoCrossing(vh_, delay, t_upper); // Convert measured slew to table slew. - slew = (th - tl) / slew_derate_; + double slew = (th - tl) / slew_derate_; + return {delay, slew}; } // Find t such that vo(t)=v. @@ -479,47 +424,40 @@ DmpAlg::findVoCrossing(double vth, double t_upper) { FindRootFunc vo_func = [&](double t, double &y, double &dy) { - double vo, vo_dt; - Vo(t, vo, vo_dt); + auto [vo, dvo_dt] = Vo(t); y = vo - vth; - dy = vo_dt; + dy = dvo_dt; }; - bool fail; - double t_vth = - findRoot(vo_func, t_lower, t_upper, vth_time_tol, find_root_max_iter, fail); - if (fail) + auto [t_vth, failed] = findRoot(vo_func, t_lower, t_upper, vth_time_tol_, + find_root_max_iter_); + if (failed) throw DmpError("find Vo crossing failed"); return t_vth; } -void -DmpAlg::Vo(double t, - // Return values. - double &vo, - double &dvo_dt) +std::pair +DmpAlg::Vo(double t) { double t1 = t - t0_; if (t1 <= 0.0) { - vo = 0.0; - dvo_dt = 0.0; + double vo = 0.0; + double dvo_dt = 0.0; + return {vo, dvo_dt}; } - else if (t1 <= dt_) { - double v0, dv0_dt; - V0(t1, v0, dv0_dt); + if (t1 <= dt_) { + auto [v0, dv0_dt] = V0(t1); - vo = v0 / dt_; - dvo_dt = dv0_dt / dt_; + double vo = v0 / dt_; + double dvo_dt = dv0_dt / dt_; + return {vo, dvo_dt}; } - else { - double v0, dv0_dt; - V0(t1, v0, dv0_dt); + auto [v0, dv0_dt] = V0(t1); - double v0_dt, dv0_dt_dt; - V0(t1 - dt_, v0_dt, dv0_dt_dt); + auto [v0_dt, dv0_dt_dt] = V0(t1 - dt_); - vo = (v0 - v0_dt) / dt_; - dvo_dt = (dv0_dt - dv0_dt_dt) / dt_; - } + double vo = (v0 - v0_dt) / dt_; + double dvo_dt = (dv0_dt - dv0_dt_dt) / dt_; + return {vo, dvo_dt}; } void @@ -527,63 +465,57 @@ DmpAlg::showVo() { report_->report(" t vo(t)"); double ub = voCrossingUpperBound(); - for (double t = t0_; t < t0_ + ub; t += dt_ / 10.0) { - double vo, dvo_dt; - Vo(t, vo, dvo_dt); - report_->report(" {:g} {:g}", t, vo); - } + for (double t = t0_; t < t0_ + ub; t += dt_ / 10.0) + report_->report(" {:g} {:g}", t, Vo(t).first); } -void +std::pair DmpAlg::loadDelaySlew(const Pin *, - double elmore, - double &delay, - double &slew) + double elmore) { if (!driver_valid_ || elmore == 0.0 // Elmore delay is small compared to driver slew. || elmore < drvr_slew_ * 1e-3) { - delay = elmore; - slew = drvr_slew_; + double delay = elmore; + double slew = drvr_slew_; + return {delay, slew}; } - else { - // Use the driver thresholds and rely on thresholdAdjust to - // convert the delay and slew to the load's thresholds. - try { - elmore_ = elmore; - p3_ = 1.0 / elmore; - if (debug_->check("dmp_ceff", 4)) - showVl(); - double t_lower = t0_; - double t_upper = vlCrossingUpperBound(); - double load_delay = findVlCrossing(vth_, t_lower, t_upper); - double tl = findVlCrossing(vl_, t_lower, load_delay); - double th = findVlCrossing(vh_, load_delay, t_upper); - // Measure delay from Vo, the load dependent source excitation. - double delay1 = load_delay - vo_delay_; - // Convert measured slew to reported/table slew. - double slew1 = (th - tl) / slew_derate_; - if (delay1 < 0.0) { - // Only report a problem if the difference is significant. - if (-delay1 > vth_time_tol * vo_delay_) - fail("load delay less than zero"); - // Use elmore delay. - delay1 = elmore; - } - if (slew1 < drvr_slew_) { - // Only report a problem if the difference is significant. - if ((drvr_slew_ - slew1) > vth_time_tol * drvr_slew_) - fail("load slew less than driver slew"); - slew1 = drvr_slew_; - } - delay = delay1; - slew = slew1; - } catch (DmpError &error) { - fail(error.what()); - delay = elmore_; + // Use the driver thresholds and rely on thresholdAdjust to + // convert the delay and slew to the load's thresholds. + try { + elmore_ = elmore; + p3_ = 1.0 / elmore; + if (debug_->check("dmp_ceff", 4)) + showVl(); + double t_lower = t0_; + double t_upper = vlCrossingUpperBound(); + double load_delay = findVlCrossing(vth_, t_lower, t_upper); + double tl = findVlCrossing(vl_, t_lower, load_delay); + double th = findVlCrossing(vh_, load_delay, t_upper); + // Measure delay from Vo, the load dependent source excitation. + double delay = load_delay - vo_delay_; + // Convert measured slew to reported/table slew. + double slew = (th - tl) / slew_derate_; + if (delay < 0.0) { + // Only report a problem if the difference is significant. + if (-delay > vth_time_tol_ * vo_delay_) + fail("load delay less than zero"); + // Use elmore delay. + delay = elmore; + } + if (slew < drvr_slew_) { + // Only report a problem if the difference is significant. + if ((drvr_slew_ - slew) > vth_time_tol_ * drvr_slew_) + fail("load slew less than driver slew"); slew = drvr_slew_; } + return {delay, slew}; + } catch (DmpError &error) { + fail(error.what()); + double delay = elmore_; + double slew = drvr_slew_; + return {delay, slew}; } } @@ -594,15 +526,13 @@ DmpAlg::findVlCrossing(double vth, double t_upper) { FindRootFunc vl_func = [&](double t, double &y, double &dy) { - double vl, vl_dt; - Vl(t, vl, vl_dt); + auto [vl, vl_dt] = Vl(t); y = vl - vth; dy = vl_dt; }; - bool fail; - double t_vth = - findRoot(vl_func, t_lower, t_upper, vth_time_tol, find_root_max_iter, fail); - if (fail) + auto [t_vth, failed] = findRoot(vl_func, t_lower, t_upper, vth_time_tol_, + find_root_max_iter_); + if (failed) throw DmpError("find Vl crossing failed"); return t_vth; } @@ -613,33 +543,23 @@ DmpAlg::vlCrossingUpperBound() return voCrossingUpperBound() + elmore_ * 2.0; } -void -DmpAlg::Vl(double t, - // Return values. - double &vl, - double &dvl_dt) +std::pair +DmpAlg::Vl(double t) { double t1 = t - t0_; - if (t1 <= 0.0) { - vl = 0.0; - dvl_dt = 0.0; + if (t1 <= 0.0) + return {0.0, 0.0}; + if (t1 <= dt_) { + auto [vl0, dvl0_dt] = Vl0(t1); + return {vl0 / dt_, dvl0_dt / dt_}; } - else if (t1 <= dt_) { - double vl0, dvl0_dt; - Vl0(t1, vl0, dvl0_dt); - vl = vl0 / dt_; - dvl_dt = dvl0_dt / dt_; - } - else { - double vl0, dvl0_dt; - Vl0(t1, vl0, dvl0_dt); + auto [vl0, dvl0_dt] = Vl0(t1); - double vl0_dt, dvl0_dt_dt; - Vl0(t1 - dt_, vl0_dt, dvl0_dt_dt); + auto [vl0_dt, dvl0_dt_dt] = Vl0(t1 - dt_); - vl = (vl0 - vl0_dt) / dt_; - dvl_dt = (dvl0_dt - dvl0_dt_dt) / dt_; - } + double vl = (vl0 - vl0_dt) / dt_; + double dvl_dt = (dvl0_dt - dvl0_dt_dt) / dt_; + return {vl, dvl_dt}; } void @@ -647,11 +567,8 @@ DmpAlg::showVl() { report_->report(" t vl(t)"); double ub = vlCrossingUpperBound(); - for (double t = t0_; t < t0_ + ub * 2.0; t += ub / 10.0) { - double vl, dvl_dt; - Vl(t, vl, dvl_dt); - report_->report(" {:g} {:g}", t, vl); - } + for (double t = t0_; t < t0_ + ub * 2.0; t += ub / 10.0) + report_->report(" {:g} {:g}", t, Vl(t).first); } void @@ -684,26 +601,15 @@ public: double c2, double rpi, double c1) override; - void gateDelaySlew(// Return values. - double &delay, - double &slew) override; - void loadDelaySlew(const Pin *, - double elmore, - // Return values. - double &delay, - double &slew) override; + std::pair gateDelaySlew() override; + std::pair loadDelaySlew(const Pin *, + double elmore) override; void evalDmpEqns() override; double voCrossingUpperBound() override; private: - void V0(double t, - // Return values. - double &vo, - double &dvo_dt) override; - void Vl0(double t, - // Return values. - double &vl, - double &dvl_dt) override; + std::pair V0(double t) override; + std::pair Vl0(double t) override; }; DmpCap::DmpCap(StaState *sta) : @@ -730,25 +636,23 @@ DmpCap::init(const LibertyLibrary *drvr_library, ceff_ = c1 + c2; } -void -DmpCap::gateDelaySlew(// Return values. - double &delay, - double &slew) +std::pair +DmpCap::gateDelaySlew() { debugPrint(debug_, "dmp_ceff", 3, " ceff = {}", units_->capacitanceUnit()->asString(ceff_)); - gateCapDelaySlew(ceff_, delay, slew); + auto [delay, slew] = gateCapDelaySlew(ceff_); drvr_slew_ = slew; + return {delay, slew}; } -void +std::pair DmpCap::loadDelaySlew(const Pin *, - double elmore, - double &delay, - double &slew) + double elmore) { - delay = elmore; - slew = drvr_slew_; + double delay = elmore; + double slew = drvr_slew_; + return {delay, slew}; } void @@ -756,14 +660,12 @@ DmpCap::evalDmpEqns() { } -void -DmpCap::V0(double, - // Return values. - double &vo, - double &dvo_dt) +std::pair +DmpCap::V0(double) { - vo = 0.0; - dvo_dt = 0.0; + double vo = 0.0; + double dvo_dt = 0.0; + return {vo, dvo_dt}; } double @@ -772,14 +674,12 @@ DmpCap::voCrossingUpperBound() return 0.0; } -void -DmpCap::Vl0(double, - // Return values. - double &vl, - double &dvl_dt) +std::pair +DmpCap::Vl0(double) { - vl = 0.0; - dvl_dt = 0.0; + double vl = 0.0; + double dvl_dt = 0.0; + return {vl, dvl_dt}; } //////////////////////////////////////////////////////////////// @@ -800,9 +700,7 @@ public: double c2, double rpi, double c1) override; - void gateDelaySlew(// Return values. - double &delay, - double &slew) override; + std::pair gateDelaySlew() override; void evalDmpEqns() override; double voCrossingUpperBound() override; @@ -812,14 +710,8 @@ private: double dt, double ceff_time, double ceff); - void V0(double t, - // Return values. - double &vo, - double &dvo_dt) override; - void Vl0(double t, - // Return values. - double &vl, - double &dvl_dt) override; + std::pair V0(double t) override; + std::pair Vl0(double t) override; // Poles/zero. double p1_; @@ -891,22 +783,20 @@ DmpPi::init(const LibertyLibrary *drvr_library, D_ = (z_ - p2_) / (p2_ * (p2_ - p1_)); } -void -DmpPi::gateDelaySlew(// Return values. - double &delay, - double &slew) +std::pair +DmpPi::gateDelaySlew() { driver_valid_ = false; + double delay = 0.0; + double slew = 0.0; try { findDriverParamsPi(); ceff_ = x_[DmpParam::ceff]; - double table_delay, table_slew; - gateCapDelaySlew(ceff_, table_delay, table_slew); + auto [table_delay, table_slew] = gateCapDelaySlew(ceff_); delay = table_delay; // slew = table_slew; try { - double vo_delay, vo_slew; - findDriverDelaySlew(vo_delay, vo_slew); + auto [vo_delay, vo_slew] = findDriverDelaySlew(); driver_valid_ = true; // Save Vo delay to measure load wire delay waveform. vo_delay_ = vo_delay; @@ -921,9 +811,10 @@ DmpPi::gateDelaySlew(// Return values. fail(error.what()); // Driver calculation failed - use Ceff=c1+c2. ceff_ = c1_ + c2_; - gateCapDelaySlew(ceff_, delay, slew); + std::tie(delay, slew) = gateCapDelaySlew(ceff_); } drvr_slew_ = slew; + return {delay, slew}; } void @@ -950,8 +841,7 @@ DmpPi::evalDmpEqns() if (ceff > (c1_ + c2_)) throw DmpError("eqn eval failed: ceff > c2 + c1"); - double t_vth, t_vl, slew; - gateDelays(ceff, t_vth, t_vl, slew); + auto [t_vth, t_vl, slew] = gateDelays(ceff); if (slew == 0.0) throw DmpError("eqn eval failed: slew = 0"); @@ -966,9 +856,9 @@ DmpPi::evalDmpEqns() double exp_p2_dt = exp2(-p2_ * dt); double exp_dt_rd_ceff = exp2(-dt / (rd_ * ceff)); - double y50 = y(t_vth, t0, dt, ceff); + double y50 = y(t_vth, t0, dt, ceff).first; // Match Vl. - double y20 = y(t_vl, t0, dt, ceff); + double y20 = y(t_vl, t0, dt, ceff).first; fvec_[DmpFunc::ipi] = ipiIceff(t0, dt, ceff_time, ceff); fvec_[DmpFunc::y50] = y50 - vth_; fvec_[DmpFunc::y20] = y20 - vl_; @@ -983,11 +873,13 @@ DmpPi::evalDmpEqns() (2 * rd_ * ceff - dt - (2 * rd_ * ceff + dt) * exp2(-dt / (rd_ * ceff))) / (dt * dt); - dy(t_vl, t0, dt, ceff, fjac_[DmpFunc::y20][DmpParam::t0], - fjac_[DmpFunc::y20][DmpParam::dt], fjac_[DmpFunc::y20][DmpParam::ceff]); + std::tie(fjac_[DmpFunc::y20][DmpParam::t0], + fjac_[DmpFunc::y20][DmpParam::dt], + fjac_[DmpFunc::y20][DmpParam::ceff]) = dy(t_vl, t0, dt, ceff); - dy(t_vth, t0, dt, ceff, fjac_[DmpFunc::y50][DmpParam::t0], - fjac_[DmpFunc::y50][DmpParam::dt], fjac_[DmpFunc::y50][DmpParam::ceff]); + std::tie(fjac_[DmpFunc::y50][DmpParam::t0], + fjac_[DmpFunc::y50][DmpParam::dt], + fjac_[DmpFunc::y50][DmpParam::ceff]) = dy(t_vth, t0, dt, ceff); if (debug_->check("dmp_ceff", 4)) { showX(); @@ -1016,23 +908,18 @@ DmpPi::ipiIceff(double, return ipi - iceff; } -void -DmpPi::V0(double t, - // Return values. - double &vo, - double &dvo_dt) +std::pair +DmpPi::V0(double t) { double exp_p1 = exp2(-p1_ * t); double exp_p2 = exp2(-p2_ * t); - vo = k0_ * (k1_ + k2_ * t + k3_ * exp_p1 + k4_ * exp_p2); - dvo_dt = k0_ * (k2_ - k3_ * p1_ * exp_p1 - k4_ * p2_ * exp_p2); + double vo = k0_ * (k1_ + k2_ * t + k3_ * exp_p1 + k4_ * exp_p2); + double dvo_dt = k0_ * (k2_ - k3_ * p1_ * exp_p1 - k4_ * p2_ * exp_p2); + return {vo, dvo_dt}; } -void -DmpPi::Vl0(double t, - // Return values. - double &vl, - double &dvl_dt) +std::pair +DmpPi::Vl0(double t) { double D1 = k0_ * (k1_ - k2_ / p3_); double D3 = -p3_ * k0_ * k3_ / (p1_ - p3_); @@ -1042,8 +929,9 @@ DmpPi::Vl0(double t, double exp_p1 = exp2(-p1_ * t); double exp_p2 = exp2(-p2_ * t); double exp_p3 = exp2(-p3_ * t); - vl = D1 + t + D3 * exp_p1 + D4 * exp_p2 + D5 * exp_p3; - dvl_dt = 1.0 - D3 * p1_ * exp_p1 - D4 * p2_ * exp_p2 - D5 * p3_ * exp_p3; + double vl = D1 + t + D3 * exp_p1 + D4 * exp_p2 + D5 * exp_p3; + double dvl_dt = 1.0 - D3 * p1_ * exp_p1 - D4 * p2_ * exp_p2 - D5 * p3_ * exp_p3; + return {vl, dvl_dt}; } double @@ -1076,25 +964,27 @@ DmpOnePole::evalDmpEqns() double t0 = x_[DmpParam::t0]; double dt = x_[DmpParam::dt]; - double t_vth, t_vl, ignore1, ignore2; - gateDelays(ceff_, t_vth, t_vl, ignore1); + auto [t_vth, t_vl, ignore1] = gateDelays(ceff_); + double ignore2; if (dt <= 0.0) dt = x_[DmpParam::dt] = (t_vl - t_vth) / 100; - fvec_[DmpFunc::y50] = y(t_vth, t0, dt, ceff_) - vth_; - fvec_[DmpFunc::y20] = y(t_vl, t0, dt, ceff_) - vl_; + fvec_[DmpFunc::y50] = y(t_vth, t0, dt, ceff_).first - vth_; + fvec_[DmpFunc::y20] = y(t_vl, t0, dt, ceff_).first - vl_; if (debug_->check("dmp_ceff", 4)) { showX(); showFvec(); } - dy(t_vl, t0, dt, ceff_, fjac_[DmpFunc::y20][DmpParam::t0], - fjac_[DmpFunc::y20][DmpParam::dt], ignore2); + std::tie(fjac_[DmpFunc::y20][DmpParam::t0], + fjac_[DmpFunc::y20][DmpParam::dt], + ignore2) = dy(t_vl, t0, dt, ceff_); - dy(t_vth, t0, dt, ceff_, fjac_[DmpFunc::y50][DmpParam::t0], - fjac_[DmpFunc::y50][DmpParam::dt], ignore2); + std::tie(fjac_[DmpFunc::y50][DmpParam::t0], + fjac_[DmpFunc::y50][DmpParam::dt], + ignore2) = dy(t_vth, t0, dt, ceff_); if (debug_->check("dmp_ceff", 4)) { showJacobian(); @@ -1126,19 +1016,11 @@ public: double c2, double rpi, double c1) override; - void gateDelaySlew(// Return values. - double &delay, - double &slew) override; + std::pair gateDelaySlew() override; private: - void V0(double t, - // Return values. - double &vo, - double &dvo_dt) override; - void Vl0(double t, - // Return values. - double &vl, - double &dvl_dt) override; + std::pair V0(double t) override; + std::pair Vl0(double t) override; double voCrossingUpperBound() override; // Pole/zero. @@ -1188,51 +1070,49 @@ DmpZeroC2::init(const LibertyLibrary *drvr_library, k3_ = -k1_; } -void -DmpZeroC2::gateDelaySlew(// Return values. - double &delay, - double &slew) +std::pair +DmpZeroC2::gateDelaySlew() { + double delay = 0.0; + double slew = 0.0; try { findDriverParams(c1_); ceff_ = c1_; - findDriverDelaySlew(delay, slew); + std::tie(delay, slew) = findDriverDelaySlew(); driver_valid_ = true; vo_delay_ = delay; - } catch (DmpError &error) { + } + catch (DmpError &error) { fail(error.what()); // Fall back to table slew. driver_valid_ = false; ceff_ = c1_; - gateCapDelaySlew(ceff_, delay, slew); + std::tie(delay, slew) = gateCapDelaySlew(ceff_); } drvr_slew_ = slew; + return {delay, slew}; } -void -DmpZeroC2::V0(double t, - // Return values. - double &vo, - double &dvo_dt) +std::pair +DmpZeroC2::V0(double t) { double exp_p1 = exp2(-p1_ * t); - vo = k0_ * (k1_ + k2_ * t + k3_ * exp_p1); - dvo_dt = k0_ * (k2_ - k3_ * p1_ * exp_p1); + double vo = k0_ * (k1_ + k2_ * t + k3_ * exp_p1); + double dvo_dt = k0_ * (k2_ - k3_ * p1_ * exp_p1); + return {vo, dvo_dt}; } -void -DmpZeroC2::Vl0(double t, - // Return values. - double &vl, - double &dvl_dt) +std::pair +DmpZeroC2::Vl0(double t) { double D1 = k0_ * (k1_ - k2_ / p3_); double D3 = -p3_ * k0_ * k3_ / (p1_ - p3_); double D5 = k0_ * (k2_ / p3_ - k1_ + p3_ * k3_ / (p1_ - p3_)); double exp_p1 = exp2(-p1_ * t); double exp_p3 = exp2(-p3_ * t); - vl = D1 + t + D3 * exp_p1 + D5 * exp_p3; - dvl_dt = 1.0 - D3 * p1_ * exp_p1 - D5 * p3_ * exp_p3; + double vl = D1 + t + D3 * exp_p1 + D5 * exp_p3; + double dvl_dt = 1.0 - D3 * p1_ * exp_p1 - D5 * p3_ * exp_p3; + return {vl, dvl_dt}; } double @@ -1244,38 +1124,27 @@ DmpZeroC2::voCrossingUpperBound() //////////////////////////////////////////////////////////////// // Newton-Raphson iteration to find zeros of a function. -// x_tol is percentage that all changes in x must be less than (1.0 = 100%). -// Eval(state) is called to fill fvec and fjac (returns false if fails). -// Return error msg on failure. -static void -newtonRaphson(const int max_iter, - double x[], - const int size, - const double x_tol, - std::function eval, - // Temporaries supplied by caller. - double *fvec, - double **fjac, - int *index, - double *p, - double *scale) +// driver_param_tol_ is the scale that all changes in x must be under (1.0 = 100%). +// evalDmpEqns() fills fvec_ and fjac_. +void +DmpAlg::newtonRaphson() { - for (int k = 0; k < max_iter; k++) { - eval(); - for (int i = 0; i < size; i++) + for (int k = 0; k < newton_raphson_max_iter_; k++) { + evalDmpEqns(); + for (int i = 0; i < nr_order_; i++) // Right-hand side of linear equations. - p[i] = -fvec[i]; - luDecomp(fjac, size, index, scale); - luSolve(fjac, size, index, p); + p_[i] = -fvec_[i]; + luDecomp(); + luSolve(); bool all_under_x_tol = true; - for (int i = 0; i < size; i++) { - if (std::abs(p[i]) > std::abs(x[i]) * x_tol) + for (int i = 0; i < nr_order_; i++) { + if (std::abs(p_[i]) > std::abs(x_[i]) * driver_param_tol_) all_under_x_tol = false; - x[i] += p[i]; + x_[i] += p_[i]; } if (all_under_x_tol) { - eval(); + evalDmpEqns(); return; } } @@ -1287,41 +1156,37 @@ newtonRaphson(const int max_iter, // ftp://ftp.mcc.ac.uk/pub/matclass/libmat.tar.Z // Crout's Method of LU decomposition of square matrix, with implicit -// partial pivoting. A is overwritten. U is explicit in the upper +// partial pivoting. fjac_ is overwritten. U is explicit in the upper // triangle and L is in multiplier form in the subdiagionals i.e. subdiag // a[i,j] is the multiplier used to eliminate the [i,j] term. // -// Replaces a[0..size-1][0..size-1] by the LU decomposition. -// index[0..size-1] is an output vector of the row permutations. -// Return error msg on failure. +// Replaces fjac_[0..nr_order_-1][*] by the LU decomposition. +// index_[0..nr_order_-1] is an output vector of the row permutations. void -luDecomp(double **a, - const int size, - int *index, - // Temporary supplied by caller. - // scale stores the implicit scaling of each row. - double *scale) +DmpAlg::luDecomp() { + const int size = nr_order_; + // Find implicit scaling factors. for (int i = 0; i < size; i++) { double big = 0.0; for (int j = 0; j < size; j++) { - double temp = std::abs(a[i][j]); + double temp = std::abs(fjac_[i][j]); if (temp > big) big = temp; } if (big == 0.0) throw DmpError("LU decomposition: no non-zero row element"); - scale[i] = 1.0 / big; + scale_[i] = 1.0 / big; } int size_1 = size - 1; for (int j = 0; j < size; j++) { // Run down jth column from top to diag, to form the elements of U. for (int i = 0; i < j; i++) { - double sum = a[i][j]; + double sum = fjac_[i][j]; for (int k = 0; k < i; k++) - sum -= a[i][k] * a[k][j]; - a[i][j] = sum; + sum -= fjac_[i][k] * fjac_[k][j]; + fjac_[i][j] = sum; } // Run down jth subdiag to form the residuals after the elimination // of the first j-1 subdiags. These residuals diviyded by the @@ -1331,11 +1196,11 @@ luDecomp(double **a, double big = 0.0; int imax = 0; for (int i = j; i < size; i++) { - double sum = a[i][j]; + double sum = fjac_[i][j]; for (int k = 0; k < j; k++) - sum -= a[i][k] * a[k][j]; - a[i][j] = sum; - double dum = scale[i] * std::abs(sum); + sum -= fjac_[i][k] * fjac_[k][j]; + fjac_[i][j] = sum; + double dum = scale_[i] * std::abs(sum); if (dum >= big) { big = dum; imax = i; @@ -1345,100 +1210,56 @@ luDecomp(double **a, if (j != imax) { // Yes, do so... for (int k = 0; k < size; k++) { - double dum = a[imax][k]; - a[imax][k] = a[j][k]; - a[j][k] = dum; + double dum = fjac_[imax][k]; + fjac_[imax][k] = fjac_[j][k]; + fjac_[j][k] = dum; } - scale[imax] = scale[j]; + scale_[imax] = scale_[j]; } - index[j] = imax; + index_[j] = imax; // If diag term is not zero divide subdiag to form multipliers. - if (a[j][j] == 0.0) - a[j][j] = tiny_double; + if (fjac_[j][j] == 0.0) + fjac_[j][j] = tiny_double_; if (j != size_1) { - double pivot = 1.0 / a[j][j]; + double pivot = 1.0 / fjac_[j][j]; for (int i = j + 1; i < size; i++) - a[i][j] *= pivot; + fjac_[i][j] *= pivot; } } } -// Solves the set of size linear equations a*x=b, assuming A is LU form -// but assume b has not been transformed. -// a[0..size-1] is LU decomposition -// Returns the solution vector x in b. -// a and index are not modified. +// Solves fjac_ * x = p_ for x, assuming fjac_ is LU form from luDecomp. +// Solution overwrites p_. void -luSolve(double **a, - const int size, - const int *index, - double b[]) +DmpAlg::luSolve() { - // Transform b allowing for leading zeros. + const int size = nr_order_; + + // Transform p_ allowing for leading zeros. int non_zero = -1; for (int i = 0; i < size; i++) { - int iperm = index[i]; - double sum = b[iperm]; - b[iperm] = b[i]; + int iperm = index_[i]; + double sum = p_[iperm]; + p_[iperm] = p_[i]; if (non_zero != -1) { for (int j = non_zero; j <= i - 1; j++) - sum -= a[i][j] * b[j]; + sum -= fjac_[i][j] * p_[j]; } else { if (sum != 0.0) non_zero = i; } - b[i] = sum; + p_[i] = sum; } // Backsubstitution. for (int i = size - 1; i >= 0; i--) { - double sum = b[i]; + double sum = p_[i]; for (int j = i + 1; j < size; j++) - sum -= a[i][j] * b[j]; - b[i] = sum / a[i][i]; + sum -= fjac_[i][j] * p_[j]; + p_[i] = sum / fjac_[i][i]; } } -#if 0 -// Solve: -// x + y = 5 -// x - y = 1 -// x = 3 -// y = 2 -void -testLuDecomp1() -{ - double a0[2] = {1, 1}; - double a1[2] = {1, -1}; - double *a[2] = {a0, a1}; - int index[2]; - double b[2] = {5, 1}; - double scale[2]; - luDecomp(a, 2, index, scale); - luSolve(a, 2, index, b); - printf("x = %f y= %f\n", b[0], b[1]); -} - -// Solve -// x + 2y = 3 -// 3x - 4y = 19 -// x = 5 -// y = -1 -void -testLuDecomp2() -{ - double a0[2] = {1, 2}; - double a1[2] = {3, -4}; - double *a[2] = {a0, a1}; - int index[2]; - double b[2] = {3, 19}; - double scale[2]; - luDecomp(a, 2, index, scale); - luSolve(a, 2, index, b); - printf("x = %f y= %f\n", b[0], b[1]); -} -#endif - //////////////////////////////////////////////////////////////// bool DmpCeffDelayCalc::unsuppored_model_warned_ = false; @@ -1484,8 +1305,7 @@ DmpCeffDelayCalc::gateDelay(const Pin *drvr_pin, const Pvt *pvt = pinPvt(drvr_pin, scene, min_max); setCeffAlgorithm(drvr_library, drvr_cell, pvt, table_model, rf, in_slew1, c2, rpi, c1); - double gate_delay, drvr_slew; - gateDelaySlew(gate_delay, drvr_slew); + auto [gate_delay, drvr_slew] = gateDelaySlew(); // Fill in pocv parameters. double ceff = dmp_alg_->ceff(); @@ -1640,22 +1460,19 @@ gateModelRd(const LibertyCell *cell, return rd; } -void -DmpCeffDelayCalc::gateDelaySlew( // Return values. - double &delay, - double &slew) +std::pair +DmpCeffDelayCalc::gateDelaySlew() { - dmp_alg_->gateDelaySlew(delay, slew); + return dmp_alg_->gateDelaySlew(); } -void +std::optional> DmpCeffDelayCalc::loadDelaySlewElmore(const Pin *load_pin, - double elmore, - double &delay, - double &slew) + double elmore) { if (dmp_alg_) - dmp_alg_->loadDelaySlew(load_pin, elmore, delay, slew); + return dmp_alg_->loadDelaySlew(load_pin, elmore); + return std::nullopt; } // Notify algorithm components. diff --git a/dcalc/DmpCeff.hh b/dcalc/DmpCeff.hh index 4d3b7fd5..065a0026 100644 --- a/dcalc/DmpCeff.hh +++ b/dcalc/DmpCeff.hh @@ -24,6 +24,9 @@ #pragma once +#include +#include + #include "LibertyClass.hh" #include "LumpedCapDelayCalc.hh" @@ -71,13 +74,10 @@ protected: // Return values. double &wire_delay, double &load_slew) = 0; - void gateDelaySlew(// Return values. - double &delay, - double &slew); - void loadDelaySlewElmore(const Pin *load_pin, - double elmore, - double &delay, - double &slew); + std::pair gateDelaySlew(); + std::optional> + loadDelaySlewElmore(const Pin *load_pin, + double elmore); // Select the appropriate special case Dartu/Menezes/Pileggi algorithm. void setCeffAlgorithm(const LibertyLibrary *library, const LibertyCell *cell, diff --git a/dcalc/DmpDelayCalc.cc b/dcalc/DmpDelayCalc.cc index 3fefc53b..d89b319d 100644 --- a/dcalc/DmpDelayCalc.cc +++ b/dcalc/DmpDelayCalc.cc @@ -125,8 +125,12 @@ DmpCeffElmoreDelayCalc::loadDelaySlew(const Pin *load_pin, float elmore = 0.0; if (parasitic) parasitics_->findElmore(parasitic, load_pin, elmore, elmore_exists); - if (elmore_exists) - loadDelaySlewElmore(load_pin, elmore, wire_delay, load_slew); + if (elmore_exists) { + if (auto r = loadDelaySlewElmore(load_pin, elmore)) { + wire_delay = r->first; + load_slew = r->second; + } + } thresholdAdjust(load_pin, drvr_library, rf, wire_delay, load_slew); } diff --git a/dcalc/FindRoot.cc b/dcalc/FindRoot.cc index dd35e7ba..5ca987df 100644 --- a/dcalc/FindRoot.cc +++ b/dcalc/FindRoot.cc @@ -28,47 +28,38 @@ namespace sta { -double +std::pair findRoot(FindRootFunc func, double x1, double x2, double x_tol, - int max_iter, - // Return value. - bool &fail) + int max_iter) { double y1, y2, dy1; func(x1, y1, dy1); func(x2, y2, dy1); - return findRoot(func, x1, y1, x2, y2, x_tol, max_iter, fail); + return findRoot(func, x1, y1, x2, y2, x_tol, max_iter); } -double +std::pair findRoot(FindRootFunc func, double x1, double y1, double x2, double y2, double x_tol, - int max_iter, - // Return value. - bool &fail) + int max_iter) { if ((y1 > 0.0 && y2 > 0.0) || (y1 < 0.0 && y2 < 0.0)) { // Initial bounds do not surround a root. - fail = true; - return 0.0; + return {0.0, true}; } - if (y1 == 0.0) { - fail = false; - return x1; - } + if (y1 == 0.0) + return {x1, false}; - if (y2 == 0.0) { - fail = false; - return x2; - } + if (y2 == 0.0) + return {x2, false}; if (y1 > 0.0) // Swap x1/x2 so func(x1) < 0. @@ -95,8 +86,7 @@ findRoot(FindRootFunc func, } if (std::abs(dx) <= x_tol * std::abs(root)) { // Converged. - fail = false; - return root; + return {root, false}; } func(root, y, dy); @@ -105,8 +95,7 @@ findRoot(FindRootFunc func, else x2 = root; } - fail = true; - return root; + return {root, true}; } } // namespace diff --git a/dcalc/FindRoot.hh b/dcalc/FindRoot.hh index a137b48a..ab35ab4e 100644 --- a/dcalc/FindRoot.hh +++ b/dcalc/FindRoot.hh @@ -25,6 +25,7 @@ #pragma once #include +#include namespace sta { @@ -33,24 +34,22 @@ using FindRootFunc = const std::function; -double +// first: root estimate; second: true if the search failed. +std::pair findRoot(FindRootFunc func, double x1, double x2, double x_tol, - int max_iter, - // Return value. - bool &fail); + int max_iter); -double +// first: root estimate; second: true if the search failed. +std::pair findRoot(FindRootFunc func, double x1, double y1, double x2, double y2, double x_tol, - int max_iter, - // Return value. - bool &fail); + int max_iter); } // namespace diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index f8984474..67536ef0 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -648,12 +648,12 @@ GraphDelayCalc::findInputArcDelay(const Pin *drvr_pin, LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex); ArcDcalcResult intrinsic_result = - arc_delay_calc->gateDelay(drvr_pin, arc, Slew(from_slew), 0.0, nullptr, + arc_delay_calc->gateDelay(drvr_pin, arc, from_slew, 0.0, nullptr, load_pin_index_map, scene, min_max); const ArcDelay &intrinsic_delay = intrinsic_result.gateDelay(); ArcDcalcResult gate_result = arc_delay_calc->gateDelay(drvr_pin, arc, - Slew(from_slew), load_cap, + from_slew, load_cap, parasitic, load_pin_index_map, scene, min_max); diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index 9cea3ea6..1169327a 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -194,8 +194,8 @@ PrimaDelayCalc::gateDelay(const Pin *drvr_pin, ArcDcalcArgSeq dcalc_args; dcalc_args.emplace_back(nullptr, drvr_pin, nullptr, arc, in_slew, load_cap, parasitic); - ArcDcalcResultSeq dcalc_results = - gateDelays(dcalc_args, load_pin_index_map, scene, min_max); + ArcDcalcResultSeq dcalc_results = gateDelays(dcalc_args, load_pin_index_map, + scene, min_max); return dcalc_results[0]; } @@ -399,6 +399,7 @@ void PrimaDelayCalc::initSim() { ceff_.resize(drvr_count_); + ceff_vth_.resize(drvr_count_); drvr_current_.resize(drvr_count_); findNodeCount(); @@ -615,8 +616,12 @@ PrimaDelayCalc::updateCeffIdrvr() if (drvr_rf_ == RiseFall::rise()) { if (drvr_current != 0.0 && dv > 0.0) { double ceff = drvr_current * time_step_ / dv; - if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) + if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) { ceff_[drvr_idx] = ceff; + // Record the Ceff at Vth. + if (v1 >= vth_ && v2 < vth_) + ceff_vth_[drvr_idx] = ceff; + } } if (v1 > (vdd_ - .01)) // Whoa partner. Head'n for the weeds. @@ -628,8 +633,12 @@ PrimaDelayCalc::updateCeffIdrvr() else { if (drvr_current != 0.0 && dv < 0.0) { double ceff = drvr_current * time_step_ / dv; - if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) + if (output_waveforms_[drvr_idx]->capAxis()->inBounds(ceff)) { ceff_[drvr_idx] = ceff; + // Record the Ceff at Vth. + if (v1 <= vth_ && v2 > vth_) + ceff_vth_[drvr_idx] = ceff; + } } if (v1 < 0.01) { // Whoa partner. Head'n for the weeds. @@ -711,8 +720,13 @@ PrimaDelayCalc::dcalcResults() float ref_time = output_waveforms_[drvr_idx]->referenceTime(dcalc_arg.inSlewFlt()); double gate_delay = drvr_times[threshold_vth] - ref_time; double drvr_slew = std::abs(drvr_times[threshold_vh] - drvr_times[threshold_vl]); - dcalc_result.setGateDelay(gate_delay); - dcalc_result.setDrvrSlew(drvr_slew); + + ArcDelay gate_delay2(gate_delay); + Slew drvr_slew2(drvr_slew); + delaySlewPocv(dcalc_arg, drvr_idx, gate_delay2, drvr_slew2); + dcalc_result.setGateDelay(gate_delay2); + dcalc_result.setDrvrSlew(drvr_slew2); + debugPrint(debug_, "ccs_dcalc", 2, "{} gate delay {} slew {}", network_->pathName(drvr_pin), delayAsString(gate_delay, this), delayAsString(drvr_slew, this)); @@ -740,6 +754,28 @@ PrimaDelayCalc::dcalcResults() return dcalc_results; } +// Fill in pocv parameters in gate_delay/drvr_slew. +void +PrimaDelayCalc::delaySlewPocv(ArcDcalcArg &dcalc_arg, + size_t drvr_idx, + ArcDelay &gate_delay, + Slew &drvr_slew) +{ + if (variables_->pocvEnabled()) { + GateTableModel *table_model = dcalc_arg.arc()->gateTableModel(scene_, min_max_); + if (table_model) { + double ceff = ceff_vth_[drvr_idx]; + if (ceff == 0.0) + ceff = dcalc_arg.loadCap(); + float in_slew = delayAsFloat(dcalc_arg.inSlew()); + const Pvt *pvt = pinPvt(dcalc_arg.drvrPin(), scene_, min_max_); + table_model->gateDelayPocv(pvt, in_slew, ceff, min_max_, + variables_->pocvMode(), + gate_delay, drvr_slew); + } + } +} + //////////////////////////////////////////////////////////////// void @@ -896,17 +932,21 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, const TimingArc *arc, const Slew &in_slew, float load_cap, - const Parasitic *, - const LoadPinIndexMap &, + const Parasitic *parasitic, + const LoadPinIndexMap &load_pin_index_map, const Scene *scene, const MinMax *min_max, int digits) { GateTimingModel *model = arc->gateModel(scene, min_max); if (model) { + // Delay calc to find ceff. + gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic, + load_pin_index_map, scene, min_max); float in_slew1 = delayAsFloat(in_slew); + float ceff = ceff_vth_.empty() ? load_cap : ceff_vth_[0]; return model->reportGateDelay(pinPvt(drvr_pin, scene, min_max), - in_slew1, load_cap, min_max, + in_slew1, ceff, min_max, PocvMode::scalar, digits); } return ""; diff --git a/dcalc/PrimaDelayCalc.hh b/dcalc/PrimaDelayCalc.hh index 8ed47a05..c0b39ba7 100644 --- a/dcalc/PrimaDelayCalc.hh +++ b/dcalc/PrimaDelayCalc.hh @@ -108,6 +108,10 @@ public: Waveform watchWaveform(const Pin *pin) override; protected: + void delaySlewPocv(ArcDcalcArg &dcalc_arg, + size_t drvr_idx, + ArcDelay &gate_delay, + Slew &drvr_slew); ArcDcalcResultSeq tableDcalcResults(); void simulate(); void simulate1(const MatrixSd &G, @@ -215,6 +219,8 @@ protected: // Indexed by driver index. std::vector ceff_; + // Ceff at Vth + std::vector ceff_vth_; std::vector drvr_current_; double time_step_; diff --git a/dcalc/test/CMakeLists.txt b/dcalc/test/CMakeLists.txt index 2322a85f..6caa2a23 100644 --- a/dcalc/test/CMakeLists.txt +++ b/dcalc/test/CMakeLists.txt @@ -1 +1,6 @@ +sta_module_tests("dcalc" + TESTS + prima_report +) + add_subdirectory(cpp) diff --git a/dcalc/test/cpp/TestDcalc.cc b/dcalc/test/cpp/TestDcalc.cc index b392ca12..a471575a 100644 --- a/dcalc/test/cpp/TestDcalc.cc +++ b/dcalc/test/cpp/TestDcalc.cc @@ -166,9 +166,8 @@ TEST_F(FindRootAdditionalTest, RootAtX1) { y = x - 5.0; dy = 1.0; }; - bool fail = false; // y1 = 5-5 = 0, y2 = 10-5 = 5 - double root = findRoot(func, 5.0, 0.0, 10.0, 5.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 5.0, 0.0, 10.0, 5.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 5.0, 1e-8); } @@ -179,9 +178,8 @@ TEST_F(FindRootAdditionalTest, RootAtX2) { y = x - 5.0; dy = 1.0; }; - bool fail = false; // y1 = 0-5 = -5, y2 = 5-5 = 0 - double root = findRoot(func, 0.0, -5.0, 5.0, 0.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.0, -5.0, 5.0, 0.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 5.0, 1e-8); } @@ -192,9 +190,8 @@ TEST_F(FindRootAdditionalTest, BothPositiveFails) { y = x * x + 1.0; dy = 2.0 * x; }; - bool fail = false; // y1 = 2, y2 = 5 -- both positive - findRoot(func, 1.0, 2.0, 2.0, 5.0, 1e-10, 100, fail); + auto [root_, fail] = findRoot(func, 1.0, 2.0, 2.0, 5.0, 1e-10, 100); EXPECT_TRUE(fail); } @@ -204,8 +201,7 @@ TEST_F(FindRootAdditionalTest, BothNegativeFails) { y = -x * x - 1.0; dy = -2.0 * x; }; - bool fail = false; - findRoot(func, 1.0, -2.0, 2.0, -5.0, 1e-10, 100, fail); + auto [root_, fail] = findRoot(func, 1.0, -2.0, 2.0, -5.0, 1e-10, 100); EXPECT_TRUE(fail); } @@ -215,9 +211,8 @@ TEST_F(FindRootAdditionalTest, MaxIterationsExceeded) { y = x * x - 2.0; dy = 2.0 * x; }; - bool fail = false; // Very tight tolerance with only 1 iteration - findRoot(func, 0.0, 3.0, 1e-15, 1, fail); + auto [root_, fail] = findRoot(func, 0.0, 3.0, 1e-15, 1); EXPECT_TRUE(fail); } @@ -227,9 +222,8 @@ TEST_F(FindRootAdditionalTest, SwapWhenY1Positive) { y = x - 3.0; dy = 1.0; }; - bool fail = false; // y1 = 2.0 > 0, y2 = -2.0 < 0 => swap internally - double root = findRoot(func, 5.0, 2.0, 1.0, -2.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 5.0, 2.0, 1.0, -2.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-8); } @@ -240,8 +234,7 @@ TEST_F(FindRootAdditionalTest, CubicRoot) { y = x * x * x - 8.0; dy = 3.0 * x * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -252,8 +245,7 @@ TEST_F(FindRootAdditionalTest, TwoArgOverloadCubic) { y = x * x * x - 27.0; dy = 3.0 * x * x; }; - bool fail = false; - double root = findRoot(func, 2.0, 4.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.0, 4.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-8); } @@ -1502,9 +1494,8 @@ TEST_F(FindRootAdditionalTest, FlatDerivative) { y = (x - 2.0) * (x - 2.0) * (x - 2.0); dy = 3.0 * (x - 2.0) * (x - 2.0); }; - bool fail = false; // y at x=1 = -1, y at x=3 = 1 - double root = findRoot(func, 1.0, 3.0, 1e-8, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-8, 100); if (!fail) { EXPECT_NEAR(root, 2.0, 1e-4); } @@ -1516,8 +1507,7 @@ TEST_F(FindRootAdditionalTest, LinearFunction) { y = 2.0 * x - 6.0; dy = 2.0; }; - bool fail = false; - double root = findRoot(func, 0.0, 10.0, 1e-12, 100, fail); + auto [root, fail] = findRoot(func, 0.0, 10.0, 1e-12, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-8); } @@ -1528,9 +1518,8 @@ TEST_F(FindRootAdditionalTest, FourArgNormalBracket) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; // y1 = 1-4 = -3, y2 = 9-4 = 5 - double root = findRoot(func, 1.0, -3.0, 3.0, 5.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, -3.0, 3.0, 5.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -2091,9 +2080,8 @@ TEST_F(FindRootAdditionalTest, TightBoundsLinear) { y = 2.0 * x - 6.0; dy = 2.0; }; - bool fail = false; // y1 = 2*2.9-6 = -0.2, y2 = 2*3.1-6 = 0.2 - double root = findRoot(func, 2.9, -0.2, 3.1, 0.2, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.9, -0.2, 3.1, 0.2, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-8); } @@ -2105,8 +2093,7 @@ TEST_F(FindRootAdditionalTest, NewtonOutOfBracket) { y = x * x * x - x - 2.0; dy = 3.0 * x * x - 1.0; }; - bool fail = false; - double root = findRoot(func, 1.0, 2.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-10, 100); EXPECT_FALSE(fail); // Root is near 1.52138 EXPECT_NEAR(root, 1.52138, 1e-4); @@ -2118,9 +2105,8 @@ TEST_F(FindRootAdditionalTest, SinRoot) { y = sin(x); dy = cos(x); }; - bool fail = false; // Root near pi - double root = findRoot(func, 3.0, 3.3, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 3.0, 3.3, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, M_PI, 1e-8); } @@ -2131,8 +2117,7 @@ TEST_F(FindRootAdditionalTest, ExpMinusConst) { y = exp(x) - 3.0; dy = exp(x); }; - bool fail = false; - double root = findRoot(func, 0.0, 2.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.0, 2.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, log(3.0), 1e-8); } @@ -2394,8 +2379,7 @@ TEST_F(FindRootAdditionalTest, QuadraticExact) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -2406,9 +2390,8 @@ TEST_F(FindRootAdditionalTest, QuadraticFourArg) { y = x * x - 9.0; dy = 2.0 * x; }; - bool fail = false; // y(2.5) = 6.25-9 = -2.75, y(3.5) = 12.25-9 = 3.25 - double root = findRoot(func, 2.5, -2.75, 3.5, 3.25, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.5, -2.75, 3.5, 3.25, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-8); } @@ -2589,8 +2572,7 @@ TEST_F(FindRootAdditionalTest, LinearFunction2) { y = 2.0 * x - 10.0; dy = 2.0; }; - bool fail = false; - double root = findRoot(func, 0.0, 10.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.0, 10.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 5.0, 1e-8); } @@ -2600,9 +2582,8 @@ TEST_F(FindRootAdditionalTest, FourArgLinear) { y = 3.0 * x - 6.0; dy = 3.0; }; - bool fail = false; // y(1.0) = -3, y(3.0) = 3 - double root = findRoot(func, 1.0, -3.0, 3.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, -3.0, 3.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -2612,8 +2593,7 @@ TEST_F(FindRootAdditionalTest, HighOrderPoly) { y = x * x * x * x - 16.0; dy = 4.0 * x * x * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-6); } @@ -2623,8 +2603,7 @@ TEST_F(FindRootAdditionalTest, NegativeRoot) { y = x + 3.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, -5.0, -1.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -5.0, -1.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, -3.0, 1e-8); } @@ -2634,9 +2613,8 @@ TEST_F(FindRootAdditionalTest, TrigFunction) { y = std::cos(x); dy = -std::sin(x); }; - bool fail = false; // Root at pi/2 - double root = findRoot(func, 1.0, 2.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, M_PI / 2.0, 1e-8); } @@ -2646,8 +2624,7 @@ TEST_F(FindRootAdditionalTest, VeryTightBounds) { y = x - 5.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, 4.999, 5.001, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 4.999, 5.001, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 5.0, 1e-8); } @@ -2657,8 +2634,7 @@ TEST_F(FindRootAdditionalTest, ExpFunction) { y = std::exp(x) - 10.0; dy = std::exp(x); }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, std::log(10.0), 1e-8); } @@ -2668,9 +2644,8 @@ TEST_F(FindRootAdditionalTest, FourArgSwap) { y = x - 7.0; dy = 1.0; }; - bool fail = false; // y1 = 3.0 > 0, y2 = -7.0 < 0 => internal swap - double root = findRoot(func, 10.0, 3.0, 0.0, -7.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 10.0, 3.0, 0.0, -7.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 7.0, 1e-8); } @@ -3367,8 +3342,7 @@ TEST_F(FindRootAdditionalTest, SteepDerivative) { y = 1000.0 * x - 500.0; dy = 1000.0; }; - bool fail = false; - double root = findRoot(func, 0.0, 1.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.0, 1.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 0.5, 1e-8); } @@ -3379,8 +3353,7 @@ TEST_F(FindRootAdditionalTest, QuarticRoot) { y = x*x*x*x - 81.0; dy = 4.0*x*x*x; }; - bool fail = false; - double root = findRoot(func, 2.0, 4.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.0, 4.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-6); } @@ -3391,8 +3364,7 @@ TEST_F(FindRootAdditionalTest, FourArgNegBracket) { y = x + 5.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, -8.0, -3.0, -2.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -8.0, -3.0, -2.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, -5.0, 1e-8); } diff --git a/dcalc/test/cpp/TestFindRoot.cc b/dcalc/test/cpp/TestFindRoot.cc index 4300c363..545a676b 100644 --- a/dcalc/test/cpp/TestFindRoot.cc +++ b/dcalc/test/cpp/TestFindRoot.cc @@ -17,8 +17,7 @@ TEST_F(FindRootTest, QuadraticPositiveRoot) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -29,8 +28,7 @@ TEST_F(FindRootTest, QuadraticNegativeRoot) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, -3.0, -1.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -3.0, -1.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, -2.0, 1e-8); } @@ -41,8 +39,7 @@ TEST_F(FindRootTest, LinearRoot) { y = x - 1.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, 0.0, 2.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.0, 2.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 1.0, 1e-8); } @@ -53,8 +50,7 @@ TEST_F(FindRootTest, SinRoot) { y = sin(x); dy = cos(x); }; - bool fail = false; - double root = findRoot(func, 2.5, 3.8, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.5, 3.8, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, M_PI, 1e-6); } @@ -65,8 +61,7 @@ TEST_F(FindRootTest, ExponentialRoot) { y = exp(x) - 2.0; dy = exp(x); }; - bool fail = false; - double root = findRoot(func, 0.0, 1.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.0, 1.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, log(2.0), 1e-8); } @@ -77,8 +72,7 @@ TEST_F(FindRootTest, TightTolerance) { y = x * x - 2.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 2.0, 1e-14, 200, fail); + auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-14, 200); EXPECT_FALSE(fail); EXPECT_NEAR(root, sqrt(2.0), 1e-12); } @@ -89,9 +83,8 @@ TEST_F(FindRootTest, WithPrecomputedY) { y = x * x - 9.0; dy = 2.0 * x; }; - bool fail = false; // x1=2, y1=4-9=-5, x2=4, y2=16-9=7 - double root = findRoot(func, 2.0, -5.0, 4.0, 7.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.0, -5.0, 4.0, 7.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-8); } @@ -106,8 +99,7 @@ TEST_F(FindRootTest, VeryTightTolerance) { y = x - 5.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, 3.0, 7.0, 1e-15, 500, fail); + auto [root, fail] = findRoot(func, 3.0, 7.0, 1e-15, 500); EXPECT_FALSE(fail); EXPECT_NEAR(root, 5.0, 1e-13); } @@ -118,8 +110,7 @@ TEST_F(FindRootTest, LooseTolerance) { y = x * x - 25.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 3.0, 7.0, 1e-1, 100, fail); + auto [root, fail] = findRoot(func, 3.0, 7.0, 1e-1, 100); EXPECT_FALSE(fail); // With 10% relative tolerance, result should still be in the right ballpark EXPECT_NEAR(root, 5.0, 0.6); @@ -132,8 +123,7 @@ TEST_F(FindRootTest, ZeroTolerance) { y = x - 3.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, 1.0, 5.0, 0.0, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 5.0, 0.0, 100); // May or may not converge -- for a linear function Newton converges in 1 step // so dx can be exactly 0. Accept either outcome. if (!fail) { @@ -152,8 +142,7 @@ TEST_F(FindRootTest, OneIteration) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 1, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 1); // With only 1 iteration, a quadratic likely won't converge to tight tol // The algorithm may or may not fail depending on initial bisection step // Root should still be a finite number within the bracket @@ -169,8 +158,7 @@ TEST_F(FindRootTest, TwoIterations) { y = x - 7.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, 5.0, 9.0, 1e-10, 2, fail); + auto [root, fail] = findRoot(func, 5.0, 9.0, 1e-10, 2); // Linear function: Newton should converge very fast // After the initial midpoint (7.0), Newton step should nail it if (!fail) { @@ -184,8 +172,7 @@ TEST_F(FindRootTest, ZeroMaxIterations) { y = x - 1.0; dy = 1.0; }; - bool fail = false; - findRoot(func, 0.0, 2.0, 1e-10, 0, fail); + auto [root_, fail] = findRoot(func, 0.0, 2.0, 1e-10, 0); EXPECT_TRUE(fail); } @@ -195,8 +182,7 @@ TEST_F(FindRootTest, LargeMaxIter) { y = x * x - 16.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 10.0, 1e-12, 10000, fail); + auto [root, fail] = findRoot(func, 1.0, 10.0, 1e-12, 10000); EXPECT_FALSE(fail); EXPECT_NEAR(root, 4.0, 1e-10); } @@ -211,8 +197,7 @@ TEST_F(FindRootTest, CubicRoot) { y = x * x * x - 8.0; dy = 3.0 * x * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -223,8 +208,7 @@ TEST_F(FindRootTest, QuarticRoot) { y = x * x * x * x - 16.0; dy = 4.0 * x * x * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -235,8 +219,7 @@ TEST_F(FindRootTest, ExponentialRoot2) { y = exp(x) - 10.0; dy = exp(x); }; - bool fail = false; - double root = findRoot(func, 1.0, 4.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 4.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, log(10.0), 1e-8); } @@ -248,8 +231,7 @@ TEST_F(FindRootTest, SqrtFunctionRoot) { y = sqrt(x) - 3.0; dy = 0.5 / sqrt(x); }; - bool fail = false; - double root = findRoot(func, 1.0, 20.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 20.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 9.0, 1e-6); } @@ -267,8 +249,7 @@ TEST_F(FindRootTest, NearZeroRootLinear) { y = x - 1e-10; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, -1.0, 1.0, 1e-6, 200, fail); + auto [root, fail] = findRoot(func, -1.0, 1.0, 1e-6, 200); // Newton on a linear function converges in 1-2 steps regardless of root location if (!fail) { EXPECT_NEAR(root, 1e-10, 1e-6); @@ -283,8 +264,7 @@ TEST_F(FindRootTest, RootExactlyAtZero) { y = x; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, -1.0, 1.0, 1e-10, 200, fail); + auto [root, fail] = findRoot(func, -1.0, 1.0, 1e-10, 200); // Even if fail is true, root should be very close to 0 EXPECT_NEAR(root, 0.0, 1e-6); } @@ -299,8 +279,7 @@ TEST_F(FindRootTest, NegativeDomainRoot) { y = x + 100.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, -200.0, 0.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -200.0, 0.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, -100.0, 1e-6); } @@ -311,8 +290,7 @@ TEST_F(FindRootTest, NegativeBracketRoot) { y = x * x - 1.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, -2.0, -0.5, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -2.0, -0.5, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, -1.0, 1e-8); } @@ -327,8 +305,7 @@ TEST_F(FindRootTest, SinRootAtZero) { y = sin(x); dy = cos(x); }; - bool fail = false; - double root = findRoot(func, -1.0, 1.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -1.0, 1.0, 1e-10, 100); // Root at 0 has the relative-tolerance issue, but Newton converges fast for sin EXPECT_NEAR(root, 0.0, 1e-4); } @@ -339,8 +316,7 @@ TEST_F(FindRootTest, SinRootAt2Pi) { y = sin(x); dy = cos(x); }; - bool fail = false; - double root = findRoot(func, 5.5, 7.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 5.5, 7.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0 * M_PI, 1e-6); } @@ -351,8 +327,7 @@ TEST_F(FindRootTest, CosRootAtPiOver2) { y = cos(x); dy = -sin(x); }; - bool fail = false; - double root = findRoot(func, 1.0, 2.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 2.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, M_PI / 2.0, 1e-6); } @@ -368,8 +343,7 @@ TEST_F(FindRootTest, MultipleRootsFindFirst) { y = (x - 1.0) * (x - 2.0); dy = 2.0 * x - 3.0; }; - bool fail = false; - double root = findRoot(func, 0.5, 1.5, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.5, 1.5, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 1.0, 1e-8); } @@ -380,8 +354,7 @@ TEST_F(FindRootTest, MultipleRootsFindSecond) { y = (x - 1.0) * (x - 2.0); dy = 2.0 * x - 3.0; }; - bool fail = false; - double root = findRoot(func, 1.5, 2.5, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 1.5, 2.5, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -397,8 +370,7 @@ TEST_F(FindRootTest, AbsValueRoot) { y = fabs(x) - 1.0; dy = (x >= 0.0) ? 1.0 : -1.0; }; - bool fail = false; - double root = findRoot(func, 0.5, 2.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.5, 2.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 1.0, 1e-8); } @@ -409,8 +381,7 @@ TEST_F(FindRootTest, AbsValueNegativeRoot) { y = fabs(x) - 1.0; dy = (x >= 0.0) ? 1.0 : -1.0; }; - bool fail = false; - double root = findRoot(func, -2.0, -0.5, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -2.0, -0.5, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, -1.0, 1e-8); } @@ -430,8 +401,7 @@ TEST_F(FindRootTest, FlatFifthOrderRootFails) { y = d4 * d; // (x-3)^5 dy = 5.0 * d4; // 5*(x-3)^4 }; - bool fail = false; - findRoot(func, 2.0, 4.0, 1e-6, 500, fail); + auto [root_, fail] = findRoot(func, 2.0, 4.0, 1e-6, 500); // The algorithm is expected to fail because dy -> 0 at the root EXPECT_TRUE(fail); } @@ -444,8 +414,7 @@ TEST_F(FindRootTest, FlatSinhRoot) { y = sinh(x - 3.0); dy = cosh(x - 3.0); }; - bool fail = false; - double root = findRoot(func, 2.0, 4.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.0, 4.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-6); } @@ -460,8 +429,7 @@ TEST_F(FindRootTest, SteepLinearRoot) { y = 1000.0 * (x - 5.0); dy = 1000.0; }; - bool fail = false; - double root = findRoot(func, 3.0, 7.0, 1e-12, 100, fail); + auto [root, fail] = findRoot(func, 3.0, 7.0, 1e-12, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 5.0, 1e-10); } @@ -472,8 +440,7 @@ TEST_F(FindRootTest, VerySteepLinearRoot) { y = 1e6 * (x - 2.0); dy = 1e6; }; - bool fail = false; - double root = findRoot(func, 1.0, 3.0, 1e-14, 100, fail); + auto [root, fail] = findRoot(func, 1.0, 3.0, 1e-14, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-12); } @@ -488,8 +455,7 @@ TEST_F(FindRootTest, LargeBracket) { y = x - 42.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, -1000.0, 1000.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -1000.0, 1000.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 42.0, 1e-6); } @@ -500,8 +466,7 @@ TEST_F(FindRootTest, LargeBracketQuadratic) { y = x * x - 100.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 1.0, 1000.0, 1e-10, 200, fail); + auto [root, fail] = findRoot(func, 1.0, 1000.0, 1e-10, 200); EXPECT_FALSE(fail); EXPECT_NEAR(root, 10.0, 1e-6); } @@ -516,8 +481,7 @@ TEST_F(FindRootTest, SmallBracket) { y = x - 1.0; dy = 1.0; }; - bool fail = false; - double root = findRoot(func, 0.999999, 1.000001, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.999999, 1.000001, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 1.0, 1e-6); } @@ -528,8 +492,7 @@ TEST_F(FindRootTest, SmallBracketQuadratic) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 1.9999, 2.0001, 1e-12, 100, fail); + auto [root, fail] = findRoot(func, 1.9999, 2.0001, 1e-12, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -545,14 +508,12 @@ TEST_F(FindRootTest, OverloadsProduceSameResult) { dy = 3.0 * x * x; }; - bool fail_2arg = false; - double root_2arg = findRoot(func, 2.0, 4.0, 1e-12, 100, fail_2arg); + auto [root_2arg, fail_2arg] = findRoot(func, 2.0, 4.0, 1e-12, 100); // Pre-compute y values for 4-arg version double y1 = 2.0 * 2.0 * 2.0 - 27.0; // 8 - 27 = -19 double y2 = 4.0 * 4.0 * 4.0 - 27.0; // 64 - 27 = 37 - bool fail_4arg = false; - double root_4arg = findRoot(func, 2.0, y1, 4.0, y2, 1e-12, 100, fail_4arg); + auto [root_4arg, fail_4arg] = findRoot(func, 2.0, y1, 4.0, y2, 1e-12, 100); EXPECT_FALSE(fail_2arg); EXPECT_FALSE(fail_4arg); @@ -567,9 +528,8 @@ TEST_F(FindRootTest, FourArgX1IsRoot) { y = x - 5.0; dy = 1.0; }; - bool fail = false; // y1 = 5 - 5 = 0 - double root = findRoot(func, 5.0, 0.0, 8.0, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 5.0, 0.0, 8.0, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_DOUBLE_EQ(root, 5.0); } @@ -580,9 +540,8 @@ TEST_F(FindRootTest, FourArgX2IsRoot) { y = x - 5.0; dy = 1.0; }; - bool fail = false; // y2 = 5 - 5 = 0 - double root = findRoot(func, 2.0, -3.0, 5.0, 0.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 2.0, -3.0, 5.0, 0.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_DOUBLE_EQ(root, 5.0); } @@ -597,8 +556,7 @@ TEST_F(FindRootTest, BothEndpointsPositiveFails) { y = x * x + 1.0; // Always positive, no real root dy = 2.0 * x; }; - bool fail = false; - findRoot(func, 1.0, 3.0, 1e-10, 100, fail); + auto [root_, fail] = findRoot(func, 1.0, 3.0, 1e-10, 100); EXPECT_TRUE(fail); } @@ -608,8 +566,7 @@ TEST_F(FindRootTest, BothEndpointsNegativeFails) { y = -x * x - 1.0; // Always negative dy = -2.0 * x; }; - bool fail = false; - findRoot(func, -3.0, 3.0, 1e-10, 100, fail); + auto [root_, fail] = findRoot(func, -3.0, 3.0, 1e-10, 100); EXPECT_TRUE(fail); } @@ -619,9 +576,8 @@ TEST_F(FindRootTest, FourArgSameSignFails) { y = x * x; dy = 2.0 * x; }; - bool fail = false; // Both y values positive - findRoot(func, 1.0, 1.0, 2.0, 4.0, 1e-10, 100, fail); + auto [root_, fail] = findRoot(func, 1.0, 1.0, 2.0, 4.0, 1e-10, 100); EXPECT_TRUE(fail); } @@ -635,8 +591,7 @@ TEST_F(FindRootTest, SymmetryPositiveBracket) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, 0.5, 3.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 0.5, 3.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 2.0, 1e-8); } @@ -646,8 +601,7 @@ TEST_F(FindRootTest, SymmetryNegativeBracket) { y = x * x - 4.0; dy = 2.0 * x; }; - bool fail = false; - double root = findRoot(func, -3.0, -0.5, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, -3.0, -0.5, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, -2.0, 1e-8); } @@ -662,9 +616,8 @@ TEST_F(FindRootTest, SwappedBracketOrder) { y = x - 3.0; dy = 1.0; }; - bool fail = false; // x1=5 > x2=1 (reversed order) - double root = findRoot(func, 5.0, 1.0, 1e-10, 100, fail); + auto [root, fail] = findRoot(func, 5.0, 1.0, 1e-10, 100); EXPECT_FALSE(fail); EXPECT_NEAR(root, 3.0, 1e-8); } diff --git a/dcalc/test/dcalc_prima_report.ok b/dcalc/test/dcalc_prima_report.ok new file mode 100644 index 00000000..028acd17 --- /dev/null +++ b/dcalc/test/dcalc_prima_report.ok @@ -0,0 +1,91 @@ +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13178, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13211, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13244, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13277, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13310, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13343, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13376, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14772, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14805, timing group from output port. +Warning 1212: ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14838, timing group from output port. +Startpoint: r2 (rising edge-triggered flip-flop clocked by clk) +Endpoint: r3 (rising edge-triggered flip-flop clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 ^ r2/CLK (DFFHQx4_ASAP7_75t_R) + 52.65 52.65 ^ r2/Q (DFFHQx4_ASAP7_75t_R) + 49.30 101.95 ^ u1/Y (BUFx2_ASAP7_75t_R) + 61.03 162.97 ^ u2/Y (AND2x2_ASAP7_75t_R) + 15.77 178.74 ^ r3/D (DFFHQx4_ASAP7_75t_R) + 178.74 data arrival time + + 500.00 500.00 clock clk (rise edge) + 0.00 500.00 clock network delay (ideal) + 0.00 500.00 clock reconvergence pessimism + 500.00 ^ r3/CLK (DFFHQx4_ASAP7_75t_R) + -13.66 486.34 library setup time + 486.34 data required time +--------------------------------------------------------- + 486.34 data required time + -178.74 data arrival time +--------------------------------------------------------- + 307.59 slack (MET) + + +Library: asap7sc7p5t_INVBUF_RVT_FF_nldm_211120 +Cell: BUFx2_ASAP7_75t_R +Arc sense: positive_unate +Arc type: combinational +A ^ -> Y ^ +P = 1.00 V = 0.77 T = 0.00 +------- input_net_transition = 50.73 +| total_output_net_capacitance = 13.97 +| 11.52 23.04 +v -------------------- +40.00 | 35.12 50.39 +80.00 | 40.08 55.44 +Table value = 39.70 +PVT scale factor = 1.00 +Delay = 39.70 + +------- input_net_transition = 50.73 +| total_output_net_capacitance = 13.97 +| 11.52 23.04 +v -------------------- +40.00 | 37.28 71.28 +80.00 | 38.13 71.69 +Table value = 44.70 +PVT scale factor = 1.00 +Slew = 44.70 + +............................................. + +A v -> Y v +P = 1.00 V = 0.77 T = 0.00 +------- input_net_transition = 48.72 +| total_output_net_capacitance = 13.97 +| 11.52 23.04 +v -------------------- +40.00 | 36.17 49.65 +80.00 | 43.28 56.72 +Table value = 40.58 +PVT scale factor = 1.00 +Delay = 40.58 + +------- input_net_transition = 48.72 +| total_output_net_capacitance = 13.97 +| 11.52 23.04 +v -------------------- +40.00 | 31.72 59.66 +80.00 | 32.63 60.23 +Table value = 37.84 +PVT scale factor = 1.00 +Slew = 37.84 + +............................................. + diff --git a/dcalc/test/dcalc_prima_report.tcl b/dcalc/test/dcalc_prima_report.tcl new file mode 100644 index 00000000..c9d719aa --- /dev/null +++ b/dcalc/test/dcalc_prima_report.tcl @@ -0,0 +1,16 @@ +# Prima report_dcalc with -name spef +read_liberty ../../test/asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib +read_liberty ../../test/asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz +read_liberty ../../test/asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz +read_liberty ../../test/asap7/asap7sc7p5t_OA_RVT_FF_nldm_211120.lib.gz +read_liberty ../../test/asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz +read_verilog ../../test/reg1_asap7.v +link_design top + +read_spef -name spef -reduce ../../test/reg1_asap7.spef +create_clock -name clk -period 500 -waveform {0 250} {clk1 clk2 clk3} + +set_delay_calculator prima +read_spef -name spef ../../test/reg1_asap7.spef +report_checks +report_dcalc -from u1/A -to u1/Y diff --git a/include/sta/ConcreteLibrary.hh b/include/sta/ConcreteLibrary.hh index e3983076..fc831a99 100644 --- a/include/sta/ConcreteLibrary.hh +++ b/include/sta/ConcreteLibrary.hh @@ -56,8 +56,8 @@ using ConcretePortMemberIterator = VectorIterator +#include +#include +#include +#include +#include #include #include // for std::declval -#include -#include #include -#include -#include -#include namespace sta { diff --git a/include/sta/FilterObjects.hh b/include/sta/FilterObjects.hh index bbabd4b0..7420b450 100644 --- a/include/sta/FilterObjects.hh +++ b/include/sta/FilterObjects.hh @@ -40,67 +40,56 @@ class Report; PortSeq filterPorts(std::string_view filter_expression, PortSeq *objects, - bool bool_props_as_int, Sta *sta); InstanceSeq filterInstances(std::string_view filter_expression, InstanceSeq *objects, - bool bool_props_as_int, Sta *sta); PinSeq filterPins(std::string_view filter_expression, PinSeq *objects, - bool bool_props_as_int, Sta *sta); NetSeq filterNets(std::string_view filter_expression, NetSeq *objects, - bool bool_props_as_int, Sta *sta); ClockSeq filterClocks(std::string_view filter_expression, ClockSeq *objects, - bool bool_props_as_int, Sta *sta); LibertyCellSeq filterLibCells(std::string_view filter_expression, LibertyCellSeq *objects, - bool bool_props_as_int, Sta *sta); LibertyPortSeq filterLibPins(std::string_view filter_expression, LibertyPortSeq *objects, - bool bool_props_as_int, Sta *sta); LibertyLibrarySeq filterLibertyLibraries(std::string_view filter_expression, LibertyLibrarySeq *objects, - bool bool_props_as_int, Sta *sta); EdgeSeq filterTimingArcs(std::string_view filter_expression, EdgeSeq *objects, - bool bool_props_as_int, Sta *sta); PathEndSeq filterPathEnds(std::string_view filter_expression, PathEndSeq *objects, - bool bool_props_as_int, Sta *sta); // For FilterExpr unit tests. StringSeq filterExprToPostfix(std::string_view expr, - bool bool_props_as_int, Report *report); } // namespace diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 732545a4..a6f8b5b3 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -69,7 +69,7 @@ class DriverWaveform; class ModeValueDef { public: - ModeValueDef(std::string value); + ModeValueDef(std::string_view value); ModeValueDef(ModeValueDef &&other) noexcept; ~ModeValueDef(); const std::string &value() const { return value_; } @@ -204,8 +204,8 @@ timingSenseOpposite(TimingSense sense); class LibertyLibrary : public ConcreteLibrary { public: - LibertyLibrary(std::string name, - std::string filename); + LibertyLibrary(std::string_view name, + std::string_view filename); virtual ~LibertyLibrary(); LibertyCell *findLibertyCell(std::string_view name) const; LibertyCellSeq findLibertyCellsMatching(PatternMatch *pattern); @@ -215,12 +215,12 @@ public: DelayModelType delayModelType() const { return delay_model_type_; } void setDelayModelType(DelayModelType type); - BusDcl *makeBusDcl(std::string name, + BusDcl *makeBusDcl(std::string_view name, int from, int to); BusDcl *findBusDcl(std::string_view name); BusDclSeq busDcls() const; - TableTemplate *makeTableTemplate(std::string name, + TableTemplate *makeTableTemplate(std::string_view name, TableTemplateType type); TableTemplate *findTableTemplate(std::string_view name, TableTemplateType type); @@ -235,7 +235,7 @@ public: void setScaleFactors(ScaleFactors *scales); // Make named scale factor group. Returns pointer to the inserted element. - ScaleFactors *makeScaleFactors(std::string name); + ScaleFactors *makeScaleFactors(std::string_view name); ScaleFactors *findScaleFactors(std::string_view name); ScaleFactors *scaleFactors() const { return scale_factors_; } float scaleFactor(ScaleFactorType type, @@ -336,18 +336,18 @@ public: Units *units() { return units_; } const Units *units() const { return units_; } - Wireload *makeWireload(std::string name); + Wireload *makeWireload(std::string_view name); const Wireload *findWireload(std::string_view name); void setDefaultWireload(const Wireload *wireload); const Wireload *defaultWireload() const; - WireloadSelection *makeWireloadSelection(std::string name); + WireloadSelection *makeWireloadSelection(std::string_view name); const WireloadSelection *findWireloadSelection(std::string_view name) const; const WireloadSelection *defaultWireloadSelection() const; WireloadMode defaultWireloadMode() const; void setDefaultWireloadMode(WireloadMode mode); void setDefaultWireloadSelection(const WireloadSelection *selection); - OperatingConditions *makeOperatingConditions(std::string name); + OperatingConditions *makeOperatingConditions(std::string_view name); OperatingConditions *findOperatingConditions(std::string_view name); OperatingConditions *defaultOperatingConditions() const; void setDefaultOperatingConditions(OperatingConditions *op_cond); @@ -358,9 +358,9 @@ public: void setOcvArcDepth(float depth); OcvDerate *defaultOcvDerate() const; void setDefaultOcvDerate(OcvDerate *derate); - OcvDerate *makeOcvDerate(std::string name); + OcvDerate *makeOcvDerate(std::string_view name); OcvDerate *findOcvDerate(std::string_view derate_name); - void addSupplyVoltage(std::string suppy_name, + void addSupplyVoltage(std::string_view suppy_name, float voltage); bool supplyExists(std::string_view supply_name) const; void supplyVoltage(std::string_view supply_name, @@ -369,8 +369,8 @@ public: bool &exists) const; // Make scaled cell. Call LibertyCell::addScaledCell after it is complete. - LibertyCell *makeScaledCell(std::string name, - std::string filename); + LibertyCell *makeScaledCell(std::string_view name, + std::string_view filename); static void makeSceneMap(LibertyLibrary *lib, @@ -395,7 +395,7 @@ public: DriverWaveform *findDriverWaveform(std::string_view name); DriverWaveform *driverWaveformDefault() { return findDriverWaveform(""); } - DriverWaveform *makeDriverWaveform(std::string name, + DriverWaveform *makeDriverWaveform(std::string_view name, TablePtr waveforms); protected: @@ -474,8 +474,8 @@ class LibertyCell : public ConcreteCell { public: LibertyCell(LibertyLibrary *library, - std::string name, - std::string filename); + std::string_view name, + std::string_view filename); virtual ~LibertyCell(); LibertyLibrary *libertyLibrary() const { return liberty_library_; } LibertyLibrary *libertyLibrary() { return liberty_library_; } @@ -484,7 +484,7 @@ public: bool hasInternalPorts() const { return has_internal_ports_; } ScaleFactors *scaleFactors() const { return scale_factors_; } void setScaleFactors(ScaleFactors *scale_factors); - ModeDef *makeModeDef(std::string name); + ModeDef *makeModeDef(std::string_view name); const ModeDef *findModeDef(std::string_view name) const; float area() const { return area_; } @@ -544,7 +544,7 @@ public: const Statetable *statetable() const { return statetable_; } // Find bus declaration local to this cell. - BusDcl *makeBusDcl(std::string name, + BusDcl *makeBusDcl(std::string_view name, int from, int to); BusDcl *findBusDcl(std::string_view name); @@ -565,7 +565,7 @@ public: // AOCV float ocvArcDepth() const; OcvDerate *ocvDerate() const; - OcvDerate *makeOcvDerate(std::string name); + OcvDerate *makeOcvDerate(std::string_view name); OcvDerate *findOcvDerate(std::string_view derate_name); // Build helpers. @@ -620,9 +620,9 @@ public: static void checkLibertyScenes(); void ensureVoltageWaveforms(const SceneSeq &scenes); const std::string &footprint() const { return footprint_; } - void setFootprint(std::string footprint); + void setFootprint(std::string_view footprint); const std::string &userFunctionClass() const { return user_function_class_; } - void setUserFunctionClass(std::string user_function_class); + void setUserFunctionClass(std::string_view user_function_class); protected: void addPort(ConcretePort *port); @@ -758,7 +758,7 @@ public: PwrGndType pwrGndType() const { return pwr_gnd_type_; } void setPwrGndType(PwrGndType type); const std::string &voltageName() const { return voltage_name_; } - void setVoltageName(std::string voltage_name); + void setVoltageName(std::string_view voltage_name); //////////////////////////////////////////////////////////////// ScanSignalType scanSignalType() const { return scan_signal_type_; } @@ -906,7 +906,7 @@ public: protected: // Constructor is internal to LibertyBuilder. LibertyPort(LibertyCell *cell, - std::string name, + std::string_view name, bool is_bus, BusDcl *bus_dcl, int from_index, @@ -1016,7 +1016,7 @@ protected: class OperatingConditions : public Pvt { public: - OperatingConditions(std::string name); + OperatingConditions(std::string_view name); const std::string &name() const { return name_; } WireloadTree wireloadTree() const { return wire_load_tree_; } void setWireloadTree(WireloadTree tree); @@ -1029,7 +1029,7 @@ protected: class ScaleFactors { public: - ScaleFactors(std::string name); + ScaleFactors(std::string_view name); const std::string &name() const { return name_; } float scale(ScaleFactorType type, ScaleFactorPvt pvt, @@ -1056,7 +1056,7 @@ protected: class BusDcl { public: - BusDcl(std::string name, + BusDcl(std::string_view name, int from, int to); const std::string &name() const { return name_; } @@ -1073,9 +1073,9 @@ protected: class ModeDef { public: - ModeDef(std::string name); + ModeDef(std::string_view name); const std::string &name() const { return name_; } - ModeValueDef *defineValue(std::string value); + ModeValueDef *defineValue(std::string_view value); const ModeValueDef *findValueDef(std::string_view value) const; const ModeValueMap &values() const { return values_; } @@ -1090,15 +1090,15 @@ private: class TableTemplate { public: - TableTemplate(std::string name); - TableTemplate(std::string name, + TableTemplate(std::string_view name); + TableTemplate(std::string_view name, TableTemplateType type); - TableTemplate(std::string name, + TableTemplate(std::string_view name, TableAxisPtr axis1, TableAxisPtr axis2, TableAxisPtr axis3); const std::string &name() const { return name_; } - void setName(std::string name); + void setName(std::string_view name); TableTemplateType type() const { return type_; } const TableAxis *axis1() const { return axis1_.get(); } TableAxisPtr axis1ptr() const { return axis1_; } @@ -1122,8 +1122,8 @@ class TestCell : public LibertyCell { public: TestCell(LibertyLibrary *library, - std::string name, - std::string filename); + std::string_view name, + std::string_view filename); protected: }; @@ -1131,7 +1131,7 @@ protected: class OcvDerate { public: - OcvDerate(std::string name); + OcvDerate(std::string_view name); ~OcvDerate(); const std::string &name() const { return name_; } const Table *derateTable(const RiseFall *rf, diff --git a/include/sta/Network.hh b/include/sta/Network.hh index b12db2db..32dd25b3 100644 --- a/include/sta/Network.hh +++ b/include/sta/Network.hh @@ -307,18 +307,18 @@ public: [[nodiscard]] bool isHierarchical(const Pin *pin) const; [[nodiscard]] bool isTopLevelPort(const Pin *pin) const; // Is pin inside the instance hier_pin is attached to? - bool isInside(const Pin *pin, - const Pin *hier_pin) const; + [[nodiscard]] bool isInside(const Pin *pin, + const Pin *hier_pin) const; // Is pin inside of hier_inst? - bool isInside(const Pin *pin, - const Instance *hier_inst) const; - bool isDriver(const Pin *pin) const; - bool isLoad(const Pin *pin) const; + [[nodiscard]] bool isInside(const Pin *pin, + const Instance *hier_inst) const; + [[nodiscard]] bool isDriver(const Pin *pin) const; + [[nodiscard]] bool isLoad(const Pin *pin) const; // Has register/latch rise/fall edges from pin. - bool isRegClkPin(const Pin *pin) const; + [[nodiscard]] bool isRegClkPin(const Pin *pin) const; // Pin clocks a timing check. - bool isCheckClk(const Pin *pin) const; - bool isLatchData(const Pin *pin) const; + [[nodiscard]] bool isCheckClk(const Pin *pin) const; + [[nodiscard]] bool isLatchData(const Pin *pin) const; // Iterate over all of the pins connected to a pin and the parent // and child nets it is hierarchically connected to (port, leaf and diff --git a/include/sta/PortDirection.hh b/include/sta/PortDirection.hh index 1a21bbd2..1d54271c 100644 --- a/include/sta/PortDirection.hh +++ b/include/sta/PortDirection.hh @@ -41,7 +41,7 @@ public: static PortDirection *internal() { return internal_; } static PortDirection *ground() { return ground_; } static PortDirection *power() { return power_; } - static PortDirection *bias() { return bias_; } + static PortDirection *well() { return well_; } static PortDirection *unknown() { return unknown_; } static PortDirection *find(const char *dir_name); std::string_view name() const { return name_; } @@ -58,8 +58,8 @@ public: bool isAnyTristate() const; bool isGround() const { return this == ground_; } bool isPower() const { return this == power_; } - bool isBias() const { return this == bias_; } - // Ground, power, or bias. + bool isWell() const { return this == well_; } + // Ground, power, or well. bool isPowerGround() const; bool isInternal() const { return this == internal_; } bool isUnknown() const { return this == unknown_; } @@ -78,7 +78,7 @@ private: static PortDirection *internal_; static PortDirection *ground_; static PortDirection *power_; - static PortDirection *bias_; + static PortDirection *well_; static PortDirection *unknown_; }; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index a26aee13..741ce875 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -62,9 +62,9 @@ deleteLiberty() TimingArcSet::destroy(); } -LibertyLibrary::LibertyLibrary(std::string name, - std::string filename) : - ConcreteLibrary(std::move(name), std::move(filename), true), +LibertyLibrary::LibertyLibrary(std::string_view name, + std::string_view filename) : + ConcreteLibrary(name, filename, true), units_(new Units()), delay_model_type_(DelayModelType::table), // default nominal_process_(0.0), @@ -178,12 +178,12 @@ LibertyLibrary::setDelayModelType(DelayModelType type) } BusDcl * -LibertyLibrary::makeBusDcl(std::string name, +LibertyLibrary::makeBusDcl(std::string_view name, int from, int to) { - std::string key = name; - auto [it, inserted] = bus_dcls_.try_emplace(std::move(key), std::move(name), from, to); + std::string key(name); + auto [it, inserted] = bus_dcls_.try_emplace(std::move(key), std::string(name), from, to); return &it->second; } @@ -203,13 +203,13 @@ LibertyLibrary::busDcls() const } TableTemplate * -LibertyLibrary::makeTableTemplate(std::string name, - TableTemplateType type) +LibertyLibrary::makeTableTemplate(std::string_view name, + TableTemplateType type) { - std::string key = name; + std::string key(name); auto [it, inserted] = template_maps_[int(type)].try_emplace(std::move(key), - std::move(name), - type); + std::string(name), + type); return &it->second; } @@ -265,10 +265,10 @@ LibertyLibrary::setScaleFactors(ScaleFactors *scales) } ScaleFactors * -LibertyLibrary::makeScaleFactors(std::string name) +LibertyLibrary::makeScaleFactors(std::string_view name) { - std::string key = name; - auto [it, inserted] = scale_factors_map_.emplace(std::move(key), std::move(name)); + std::string key(name); + auto [it, inserted] = scale_factors_map_.emplace(std::move(key), std::string(name)); return &it->second; } @@ -565,9 +565,10 @@ LibertyLibrary::setDefaultOutputPinRes(const RiseFall *rf, } Wireload * -LibertyLibrary::makeWireload(std::string name) +LibertyLibrary::makeWireload(std::string_view name) { - auto [it, inserted] = wireloads_.try_emplace(name, name, this); + std::string key(name); + auto [it, inserted] = wireloads_.try_emplace(std::move(key), std::string(name), this); return &it->second; } @@ -590,11 +591,11 @@ LibertyLibrary::defaultWireload() const } WireloadSelection * -LibertyLibrary::makeWireloadSelection(std::string name) +LibertyLibrary::makeWireloadSelection(std::string_view name) { - std::string key = name; + std::string key(name); auto [it, inserted] = wire_load_selections_.try_emplace(std::move(key), - std::move(name)); + std::string(name)); return &it->second; } @@ -629,10 +630,10 @@ LibertyLibrary::setDefaultWireloadMode(WireloadMode mode) } OperatingConditions * -LibertyLibrary::makeOperatingConditions(std::string name) +LibertyLibrary::makeOperatingConditions(std::string_view name) { - std::string key = name; - auto [it, inserted] = operating_conditions_.try_emplace(std::move(key), std::move(name)); + std::string key(name); + auto [it, inserted] = operating_conditions_.try_emplace(std::move(key), std::string(name)); return &it->second; } @@ -719,10 +720,10 @@ LibertyLibrary::setSlewDerateFromLibrary(float derate) } LibertyCell * -LibertyLibrary::makeScaledCell(std::string name, - std::string filename) +LibertyLibrary::makeScaledCell(std::string_view name, + std::string_view filename) { - return new LibertyCell(this, std::move(name), std::move(filename)); + return new LibertyCell(this, name, filename); } //////////////////////////////////////////////////////////////// @@ -853,10 +854,10 @@ LibertyLibrary::setDefaultOcvDerate(OcvDerate *derate) } OcvDerate * -LibertyLibrary::makeOcvDerate(std::string name) +LibertyLibrary::makeOcvDerate(std::string_view name) { - std::string key = name; - auto [it, inserted] = ocv_derate_map_.try_emplace(std::move(key), std::move(name)); + std::string key(name); + auto [it, inserted] = ocv_derate_map_.try_emplace(std::move(key), std::string(name)); return &it->second; } @@ -867,10 +868,10 @@ LibertyLibrary::findOcvDerate(std::string_view derate_name) } void -LibertyLibrary::addSupplyVoltage(std::string supply_name, +LibertyLibrary::addSupplyVoltage(std::string_view supply_name, float voltage) { - supply_voltage_map_[std::move(supply_name)] = voltage; + supply_voltage_map_[std::string(supply_name)] = voltage; } void @@ -903,13 +904,13 @@ LibertyLibrary::findDriverWaveform(std::string_view name) } DriverWaveform * -LibertyLibrary::makeDriverWaveform(std::string name, +LibertyLibrary::makeDriverWaveform(std::string_view name, TablePtr waveforms) { - std::string key = name; + std::string key(name); auto [it, inserted] = driver_waveform_map_.try_emplace(std::move(key), - std::move(name), - waveforms); + std::string(name), + waveforms); return &it->second; } @@ -935,8 +936,8 @@ LibertyCellIterator::next() //////////////////////////////////////////////////////////////// LibertyCell::LibertyCell(LibertyLibrary *library, - std::string name, - std::string filename) : + std::string_view name, + std::string_view filename) : ConcreteCell(name, filename, true, library), liberty_library_(library), area_(0.0), @@ -1019,10 +1020,10 @@ LibertyCell::setHasInternalPorts(bool has_internal) } ModeDef * -LibertyCell::makeModeDef(std::string name) +LibertyCell::makeModeDef(std::string_view name) { - std::string key = name; - auto [it, inserted] = mode_defs_.try_emplace(std::move(key), std::move(name)); + std::string key(name); + auto [it, inserted] = mode_defs_.try_emplace(std::move(key), std::string(name)); return &it->second; } @@ -1039,12 +1040,12 @@ LibertyCell::setScaleFactors(ScaleFactors *scale_factors) } BusDcl * -LibertyCell::makeBusDcl(std::string name, +LibertyCell::makeBusDcl(std::string_view name, int from, int to) { - std::string key = name; - auto [it, inserted] = bus_dcls_.try_emplace(std::move(key), std::move(name), from, to); + std::string key(name); + auto [it, inserted] = bus_dcls_.try_emplace(std::move(key), std::string(name), from, to); return &it->second; } @@ -1624,10 +1625,10 @@ LibertyCell::setOcvDerate(OcvDerate *derate) } OcvDerate * -LibertyCell::makeOcvDerate(std::string name) +LibertyCell::makeOcvDerate(std::string_view name) { - std::string key = name; - auto [it, inserted] = ocv_derate_map_.try_emplace(std::move(key), std::move(name)); + std::string key(name); + auto [it, inserted] = ocv_derate_map_.try_emplace(std::move(key), std::string(name)); return &it->second; } @@ -1929,15 +1930,15 @@ LibertyCell::ensureVoltageWaveforms(const SceneSeq &scenes) } void -LibertyCell::setFootprint(std::string footprint) +LibertyCell::setFootprint(std::string_view footprint) { - footprint_ = std::move(footprint); + footprint_ = footprint; } void -LibertyCell::setUserFunctionClass(std::string user_function_class) +LibertyCell::setUserFunctionClass(std::string_view user_function_class) { - user_function_class_ = std::move(user_function_class); + user_function_class_ = user_function_class; } //////////////////////////////////////////////////////////////// @@ -1986,7 +1987,7 @@ LibertyCellPortBitIterator::next() //////////////////////////////////////////////////////////////// LibertyPort::LibertyPort(LibertyCell *cell, - std::string name, + std::string_view name, bool is_bus, BusDcl *bus_dcl, int from_index, @@ -2079,9 +2080,9 @@ LibertyPort::setPwrGndType(PwrGndType type) } void -LibertyPort::setVoltageName(std::string voltage_name) +LibertyPort::setVoltageName(std::string_view voltage_name) { - voltage_name_ = std::move(voltage_name); + voltage_name_ = voltage_name; } static EnumNameMap pwr_gnd_type_map = @@ -2840,10 +2841,10 @@ LibertyPortMemberIterator::next() //////////////////////////////////////////////////////////////// -BusDcl::BusDcl(std::string name, +BusDcl::BusDcl(std::string_view name, int from, int to) : - name_(std::move(name)), + name_(name), from_(from), to_(to) { @@ -2851,16 +2852,16 @@ BusDcl::BusDcl(std::string name, //////////////////////////////////////////////////////////////// -ModeDef::ModeDef(std::string name) : - name_(std::move(name)) +ModeDef::ModeDef(std::string_view name) : + name_(name) { } ModeValueDef * -ModeDef::defineValue(std::string value) +ModeDef::defineValue(std::string_view value) { - std::string key = value; - auto [it, inserted] = values_.try_emplace(std::move(key), std::move(value)); + std::string key(value); + auto [it, inserted] = values_.try_emplace(std::move(key), std::string(value)); return &it->second; } @@ -2872,8 +2873,8 @@ ModeDef::findValueDef(std::string_view value) const //////////////////////////////////////////////////////////////// -ModeValueDef::ModeValueDef(std::string value) : - value_(std::move(value)), +ModeValueDef::ModeValueDef(std::string_view value) : + value_(value), cond_(nullptr) { } @@ -2905,8 +2906,8 @@ ModeValueDef::setSdfCond(std::string sdf_cond) //////////////////////////////////////////////////////////////// -TableTemplate::TableTemplate(std::string name) : - name_(std::move(name)), +TableTemplate::TableTemplate(std::string_view name) : + name_(name), type_(TableTemplateType::delay), axis1_(nullptr), axis2_(nullptr), @@ -2914,9 +2915,9 @@ TableTemplate::TableTemplate(std::string name) : { } -TableTemplate::TableTemplate(std::string name, +TableTemplate::TableTemplate(std::string_view name, TableTemplateType type) : - name_(std::move(name)), + name_(name), type_(type), axis1_(nullptr), axis2_(nullptr), @@ -2924,11 +2925,11 @@ TableTemplate::TableTemplate(std::string name, { } -TableTemplate::TableTemplate(std::string name, +TableTemplate::TableTemplate(std::string_view name, TableAxisPtr axis1, TableAxisPtr axis2, TableAxisPtr axis3) : - name_(std::move(name)), + name_(name), type_(TableTemplateType::delay), axis1_(axis1), axis2_(axis2), @@ -2937,9 +2938,9 @@ TableTemplate::TableTemplate(std::string name, } void -TableTemplate::setName(std::string name) +TableTemplate::setName(std::string_view name) { - name_ = std::move(name); + name_ = name; } void @@ -2989,9 +2990,9 @@ Pvt::setTemperature(float temp) temperature_ = temp; } -OperatingConditions::OperatingConditions(std::string name) : +OperatingConditions::OperatingConditions(std::string_view name) : Pvt(0.0, 0.0, 0.0), - name_(std::move(name)), + name_(name), // Default wireload tree. wire_load_tree_(WireloadTree::unknown) { @@ -3085,8 +3086,8 @@ scaleFactorPvtName(ScaleFactorPvt pvt) //////////////////////////////////////////////////////////////// -ScaleFactors::ScaleFactors(std::string name) : - name_(std::move(name)) +ScaleFactors::ScaleFactors(std::string_view name) : + name_(name) { for (int type = 0; type < scale_factor_type_count; type++) { for (int pvt = 0; pvt < scale_factor_pvt_count; pvt++) { @@ -3168,16 +3169,16 @@ ScaleFactors::report(Report *report) } TestCell::TestCell(LibertyLibrary *library, - std::string name, - std::string filename) : + std::string_view name, + std::string_view filename) : LibertyCell(library, name, filename) { } //////////////////////////////////////////////////////////////// -OcvDerate::OcvDerate(std::string name) : - name_(std::move(name)) +OcvDerate::OcvDerate(std::string_view name) : + name_(name) { for (auto el_index : EarlyLate::rangeIndex()) { for (auto rf_index : RiseFall::rangeIndex()) { diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc index e7e92791..f296fdec 100644 --- a/liberty/LibertyBuilder.cc +++ b/liberty/LibertyBuilder.cc @@ -124,7 +124,7 @@ LibertyBuilder::makePort(LibertyCell *cell, LibertyPort * LibertyBuilder::makeBundlePort(LibertyCell *cell, - const char *name, + std::string_view name, ConcretePortSeq *members) { LibertyPort *port = new LibertyPort(cell, name, false, nullptr, -1, -1, true, members); diff --git a/liberty/LibertyBuilder.hh b/liberty/LibertyBuilder.hh index 11e8c2b1..27a07677 100644 --- a/liberty/LibertyBuilder.hh +++ b/liberty/LibertyBuilder.hh @@ -54,7 +54,7 @@ public: int to_index, BusDcl *bus_dcl); LibertyPort *makeBundlePort(LibertyCell *cell, - const char *name, + std::string_view name, ConcretePortSeq *members); // Build timing arc sets and their arcs given a type and sense. // Port functions and cell latches are also used by this builder diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 8489f6f8..a76b6893 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -176,7 +176,7 @@ LibertyReader::endCell(const LibertyGroup *cell_group, if (cell_group->hasFirstParam()) { const std::string &name = cell_group->firstParam(); debugPrint(debug_, "liberty", 1, "cell {}", name); - LibertyCell *cell = builder_.makeCell(library_, name, std::string(filename_)); + LibertyCell *cell = builder_.makeCell(library_, name, filename_); readCell(cell, cell_group); } else @@ -849,7 +849,7 @@ LibertyReader::readDefaultWireLoadSelection(const LibertyGroup *library_group) library_group->findAttrString("default_wire_load_selection"); if (!selection_name.empty()) { const WireloadSelection *selection = - library_->findWireloadSelection(selection_name.c_str()); + library_->findWireloadSelection(selection_name); if (selection) library_->setDefaultWireloadSelection(selection); else @@ -1003,9 +1003,8 @@ LibertyReader::readScaledCell(const LibertyGroup *scaled_cell_group) OperatingConditions *op_cond = library_->findOperatingConditions(op_cond_name); if (op_cond) { debugPrint(debug_, "liberty", 1, "scaled cell {} {}", - name.c_str(), op_cond_name.c_str()); - LibertyCell *scaled_cell = library_->makeScaledCell(name, - std::string(filename_)); + name, op_cond_name); + LibertyCell *scaled_cell = library_->makeScaledCell(name, filename_); readCell(scaled_cell, scaled_cell_group); checkScaledCell(scaled_cell, owner, scaled_cell_group, op_cond_name); // Add scaled cell AFTER ports and timing arcs are defined. @@ -1163,8 +1162,7 @@ LibertyReader::makeBundlePort(LibertyCell *cell, members->push_back(member); } } - LibertyPort *bundle_port = builder_.makeBundlePort(cell, bundle_name.c_str(), - members); + LibertyPort *bundle_port = builder_.makeBundlePort(cell, bundle_name, members); port_group_map[bundle_group].push_back(bundle_port); // Make ports for pin groups inside the bundle group. makeBundlePinPorts(cell, bundle_group, port_group_map); @@ -1204,7 +1202,7 @@ LibertyReader::makePgPinPort(LibertyCell *cell, const std::string &type_name = pg_pin_group->findAttrString("pg_type"); if (!type_name.empty()) { - PwrGndType type = findPwrGndType(type_name.c_str()); + PwrGndType type = findPwrGndType(type_name); PortDirection *dir = PortDirection::unknown(); switch (type) { case PwrGndType::primary_ground: @@ -1221,7 +1219,7 @@ LibertyReader::makePgPinPort(LibertyCell *cell, case PwrGndType::pwell: case PwrGndType::deepnwell: case PwrGndType::deeppwell: - dir = PortDirection::bias(); + dir = PortDirection::well(); break; case PwrGndType::none: error(1291, pg_pin_group, "unknown pg_type."); @@ -1235,7 +1233,7 @@ LibertyReader::makePgPinPort(LibertyCell *cell, const std::string &voltate_name = pg_pin_group->findAttrString("voltage_name"); if (!voltate_name.empty()) - pg_port->setVoltageName(voltate_name.c_str()); + pg_port->setVoltageName(voltate_name); } else warn(1314, pg_pin_group, "pg_pin missing name."); @@ -1295,7 +1293,7 @@ LibertyReader::readDriverWaveform(const LibertyPortSeq &ports, : "driver_waveform_fall"; const std::string &name = port_group->findAttrString(attr_name); if (!name.empty()) { - DriverWaveform *waveform = library_->findDriverWaveform(name.c_str()); + DriverWaveform *waveform = library_->findDriverWaveform(name); if (waveform) { for (LibertyPort *port : ports) port->setDriverWaveform(waveform, rf); @@ -1830,9 +1828,9 @@ LibertyReader::readCellAttributes(LibertyCell *cell, const std::string &clock_gate_type = cell_group->findAttrString("clock_gating_integrated_cell"); if (!clock_gate_type.empty()) { - if (stringBeginEqual(clock_gate_type.c_str(), "latch_posedge")) + if (stringBeginEqual(clock_gate_type, "latch_posedge")) cell->setClockGateType(ClockGateType::latch_posedge); - else if (stringBeginEqual(clock_gate_type.c_str(), "latch_negedge")) + else if (stringBeginEqual(clock_gate_type, "latch_negedge")) cell->setClockGateType(ClockGateType::latch_negedge); else cell->setClockGateType(ClockGateType::other); @@ -1852,7 +1850,7 @@ LibertyReader::readScaleFactors(LibertyCell *cell, cell_group->findAttrString("scaling_factors"); if (!scale_factors_name.empty()) { ScaleFactors *scale_factors = - library_->findScaleFactors(scale_factors_name.c_str()); + library_->findScaleFactors(scale_factors_name); if (scale_factors) cell->setScaleFactors(scale_factors); else @@ -1862,7 +1860,7 @@ LibertyReader::readScaleFactors(LibertyCell *cell, void LibertyReader::readCellAttrString(std::string_view attr_name, - void (LibertyCell::*set_func)(std::string value), + void (LibertyCell::*set_func)(std::string_view value), LibertyCell *cell, const LibertyGroup *group) { @@ -2943,9 +2941,9 @@ LibertyReader::readCellOcvDerateGroup(LibertyCell *cell, { const std::string &derate_name = cell_group->findAttrString("ocv_derate_group"); if (!derate_name.empty()) { - OcvDerate *derate = cell->findOcvDerate(derate_name.c_str()); + OcvDerate *derate = cell->findOcvDerate(derate_name); if (derate == nullptr) - derate = library_->findOcvDerate(derate_name.c_str()); + derate = library_->findOcvDerate(derate_name); if (derate) cell->setOcvDerate(derate); else @@ -3453,7 +3451,7 @@ LibertyReader::readDefaultOcvDerateGroup(const LibertyGroup *library_group) const std::string &derate_name = library_group->findAttrString("default_ocv_derate_group"); if (!derate_name.empty()) { - OcvDerate *derate = library_->findOcvDerate(derate_name.c_str()); + OcvDerate *derate = library_->findOcvDerate(derate_name); if (derate) library_->setDefaultOcvDerate(derate); else diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index a840ebb2..28683aef 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -375,7 +375,7 @@ protected: void readScaleFactors(LibertyCell *cell, const LibertyGroup *cell_group); void readCellAttrString(std::string_view attr_name, - void (LibertyCell::*set_func)(std::string value), + void (LibertyCell::*set_func)(std::string_view value), LibertyCell *cell, const LibertyGroup *group); void readCellAttrFloat(std::string_view attr_name, diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index d38774e8..79d4f780 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -569,8 +569,9 @@ LibertyWriter::asString(const PortDirection *dir) return "internal"; else if (dir == PortDirection::bidirect()) return "inout"; - else if (dir == PortDirection::ground() || dir == PortDirection::power() - || dir == PortDirection::bias()) + else if (dir == PortDirection::ground() + || dir == PortDirection::power() + || dir == PortDirection::well()) return "input"; return "unknown"; } diff --git a/liberty/test/liberty_cell_deep.ok b/liberty/test/liberty_cell_deep.ok index 11b40443..32b15dda 100644 --- a/liberty/test/liberty_cell_deep.ok +++ b/liberty/test/liberty_cell_deep.ok @@ -111,8 +111,8 @@ Cell sky130_fd_sc_hd__ebufn_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 1.73-1.88 TE_B input 2.93-3.34 @@ -135,8 +135,8 @@ Cell sky130_fd_sc_hd__ebufn_2 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 1.74-1.89 TE_B input 3.75-4.41 @@ -159,8 +159,8 @@ Cell sky130_fd_sc_hd__ebufn_4 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 2.37-2.60 TE_B input 6.26-7.48 @@ -183,8 +183,8 @@ Cell sky130_fd_sc_hd__dlxtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power D input 1.70-1.85 GATE input 1.68-1.82 @@ -216,8 +216,8 @@ Cell sky130_fd_sc_hd__dlxtn_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power D input 1.70-1.89 GATE_N input 1.66-1.82 @@ -249,8 +249,8 @@ Cell sky130_fd_sc_hd__sdfxtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 1.69-1.86 D input 1.62-1.78 @@ -297,8 +297,8 @@ Cell sky130_fd_sc_hd__sdfxbp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 1.70-1.87 D input 1.61-1.78 @@ -350,8 +350,8 @@ Cell sky130_fd_sc_hd__dfxtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 1.71-1.88 D input 1.67-1.68 @@ -380,8 +380,8 @@ Cell sky130_fd_sc_hd__dfrtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 1.71-1.87 D input 1.95-2.01 @@ -423,8 +423,8 @@ Cell sky130_fd_sc_hd__dfstp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 1.69-1.86 D input 2.23-2.49 @@ -466,8 +466,8 @@ Cell sky130_fd_sc_hd__dfbbp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 1.69-1.89 D input 1.49-1.70 @@ -545,8 +545,8 @@ Cell sky130_fd_sc_hd__mux2_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A0 input 1.51-1.61 A1 input 1.81-1.96 @@ -574,8 +574,8 @@ Cell sky130_fd_sc_hd__mux2i_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A0 input 2.10-2.31 A1 input 2.15-2.36 @@ -603,8 +603,8 @@ Cell sky130_fd_sc_hd__mux4_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A0 input 1.48-1.57 A1 input 1.40-1.48 diff --git a/liberty/test/liberty_clkgate_lvlshift.ok b/liberty/test/liberty_clkgate_lvlshift.ok index 82566916..13711dbe 100644 --- a/liberty/test/liberty_clkgate_lvlshift.ok +++ b/liberty/test/liberty_clkgate_lvlshift.ok @@ -14,8 +14,8 @@ Cell sky130_fd_sc_hd__dlclkp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 GATE input 0.00-0.00 @@ -43,8 +43,8 @@ Cell sky130_fd_sc_hd__dlclkp_2 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 GATE input 0.00-0.00 @@ -72,8 +72,8 @@ Cell sky130_fd_sc_hd__dlclkp_4 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.01 GATE input 0.00-0.00 @@ -98,8 +98,8 @@ Timing arcs v -> v sky130_fd_sc_hd__sdlclkp_1 area=18.768000 VGND dir=ground func= - VNB dir=bias func= - VPB dir=bias func= + VNB dir=well func= + VPB dir=well func= VPWR dir=power func= CLK dir=input func= GATE dir=input func= @@ -108,8 +108,8 @@ sky130_fd_sc_hd__sdlclkp_1 area=18.768000 SCE dir=input func= sky130_fd_sc_hd__sdlclkp_2 area=20.019199 VGND dir=ground func= - VNB dir=bias func= - VPB dir=bias func= + VNB dir=well func= + VPB dir=well func= VPWR dir=power func= CLK dir=input func= GATE dir=input func= @@ -118,8 +118,8 @@ sky130_fd_sc_hd__sdlclkp_2 area=20.019199 SCE dir=input func= sky130_fd_sc_hd__sdlclkp_4 area=22.521601 VGND dir=ground func= - VNB dir=bias func= - VPB dir=bias func= + VNB dir=well func= + VPB dir=well func= VPWR dir=power func= CLK dir=input func= GATE dir=input func= diff --git a/liberty/test/liberty_func_expr.ok b/liberty/test/liberty_func_expr.ok index 6636f95a..98de38c6 100644 --- a/liberty/test/liberty_func_expr.ok +++ b/liberty/test/liberty_func_expr.ok @@ -3861,8 +3861,8 @@ Cell sky130_fd_sc_hd__a21o_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.31-2.47 A2 input 2.23-2.43 @@ -3886,8 +3886,8 @@ Cell sky130_fd_sc_hd__a21oi_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.28-2.43 A2 input 2.22-2.42 @@ -3911,8 +3911,8 @@ Cell sky130_fd_sc_hd__a22o_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.26-2.43 A2 input 2.26-2.53 @@ -3941,8 +3941,8 @@ Cell sky130_fd_sc_hd__a22oi_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.28-2.43 A2 input 2.26-2.50 @@ -3971,8 +3971,8 @@ Cell sky130_fd_sc_hd__a31o_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.27-2.42 A2 input 2.28-2.46 @@ -4001,8 +4001,8 @@ Cell sky130_fd_sc_hd__a32o_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.26-2.43 A2 input 2.23-2.44 @@ -4036,8 +4036,8 @@ Cell sky130_fd_sc_hd__o21a_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.25-2.47 A2 input 2.26-2.57 @@ -4061,8 +4061,8 @@ Cell sky130_fd_sc_hd__o21ai_0 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 1.68-1.82 A2 input 1.60-1.81 @@ -4086,8 +4086,8 @@ Cell sky130_fd_sc_hd__o22a_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 2.25-2.45 A2 input 2.27-2.58 @@ -4116,8 +4116,8 @@ Cell sky130_fd_sc_hd__mux2_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A0 input 1.51-1.61 A1 input 1.81-1.96 @@ -4145,8 +4145,8 @@ Cell sky130_fd_sc_hd__mux4_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A0 input 1.48-1.57 A1 input 1.40-1.48 @@ -4193,8 +4193,8 @@ Cell sky130_fd_sc_hd__xor2_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 4.21-4.54 B input 4.17-4.51 @@ -4221,8 +4221,8 @@ Cell sky130_fd_sc_hd__xnor2_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 4.34-4.68 B input 4.47-4.65 @@ -4249,8 +4249,8 @@ Cell sky130_fd_sc_hd__fa_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 6.56-6.90 B input 5.87-6.18 @@ -4299,8 +4299,8 @@ Cell sky130_fd_sc_hd__ha_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 2.95-3.10 B input 2.83-2.84 @@ -4336,8 +4336,8 @@ Cell sky130_fd_sc_hd__maj3_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 2.67-2.82 B input 2.42-2.66 @@ -4361,8 +4361,8 @@ Cell sky130_fd_sc_hd__dlxtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power D input 1.70-1.85 GATE input 1.68-1.82 @@ -4394,8 +4394,8 @@ Cell sky130_fd_sc_hd__sdfxtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 1.69-1.86 D input 1.62-1.78 @@ -4442,8 +4442,8 @@ Cell sky130_fd_sc_hd__ebufn_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 1.73-1.88 TE_B input 2.93-3.34 diff --git a/liberty/test/liberty_leakage_power_deep.ok b/liberty/test/liberty_leakage_power_deep.ok index c4a16079..ce4c2192 100644 --- a/liberty/test/liberty_leakage_power_deep.ok +++ b/liberty/test/liberty_leakage_power_deep.ok @@ -4,8 +4,8 @@ Cell sky130_fd_sc_hd__inv_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 Y output function=!A @@ -19,8 +19,8 @@ Cell sky130_fd_sc_hd__nand2_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -39,8 +39,8 @@ Cell sky130_fd_sc_hd__dfxtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 diff --git a/liberty/test/liberty_pgpin_voltage.ok b/liberty/test/liberty_pgpin_voltage.ok index d387f5b4..be418d4e 100644 --- a/liberty/test/liberty_pgpin_voltage.ok +++ b/liberty/test/liberty_pgpin_voltage.ok @@ -6,8 +6,8 @@ VNB exists = 1 BOGUS_SUPPLY exists = 0 --- pg pin port queries --- inv_1/VGND dir=ground is_pg=1 -inv_1/VNB dir=bias is_pg=1 -inv_1/VPB dir=bias is_pg=1 +inv_1/VNB dir=well is_pg=1 +inv_1/VPB dir=well is_pg=1 inv_1/VPWR dir=power is_pg=1 sky130_fd_sc_hd__buf_1 pg_pin_count=4 sky130_fd_sc_hd__nand2_1 pg_pin_count=4 @@ -72,8 +72,8 @@ Cell sky130_fd_sc_hd__inv_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 Y output function=!A @@ -87,8 +87,8 @@ Cell sky130_fd_sc_hd__dfxtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -117,8 +117,8 @@ Cell sky130_fd_sc_hd__dfrtp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -160,8 +160,8 @@ Cell sky130_fd_sc_hd__ebufn_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 TE_B input 0.00-0.00 @@ -184,8 +184,8 @@ Cell sky130_fd_sc_hd__dlclkp_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 GATE input 0.00-0.00 diff --git a/liberty/test/liberty_properties.ok b/liberty/test/liberty_properties.ok index f2083d0f..a9a73238 100644 --- a/liberty/test/liberty_properties.ok +++ b/liberty/test/liberty_properties.ok @@ -2564,8 +2564,8 @@ Cell sky130_fd_sc_hd__inv_1 Library sky130_fd_sc_hd__tt_025C_1v80 File ../../test/sky130hd/sky130hd_tt.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 2.21-2.39 Y output function=!A diff --git a/liberty/test/liberty_sky130_corners.ok b/liberty/test/liberty_sky130_corners.ok index d981bc82..46dac943 100644 --- a/liberty/test/liberty_sky130_corners.ok +++ b/liberty/test/liberty_sky130_corners.ok @@ -118,8 +118,8 @@ Cell sky130_fd_sc_hd__inv_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 Y output function=!A @@ -133,8 +133,8 @@ Cell sky130_fd_sc_hd__inv_2 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 Y output function=!A @@ -148,8 +148,8 @@ Cell sky130_fd_sc_hd__inv_4 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.01-0.01 Y output function=!A @@ -163,8 +163,8 @@ Cell sky130_fd_sc_hd__buf_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 X output function=A @@ -178,8 +178,8 @@ Cell sky130_fd_sc_hd__buf_2 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 X output function=A @@ -193,8 +193,8 @@ Cell sky130_fd_sc_hd__buf_4 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 X output function=A @@ -208,8 +208,8 @@ Cell sky130_fd_sc_hd__nand2_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -228,8 +228,8 @@ Cell sky130_fd_sc_hd__nand3_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -253,8 +253,8 @@ Cell sky130_fd_sc_hd__nand4_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -283,8 +283,8 @@ Cell sky130_fd_sc_hd__nor2_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -303,8 +303,8 @@ Cell sky130_fd_sc_hd__nor3_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -328,8 +328,8 @@ Cell sky130_fd_sc_hd__nor4_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -358,8 +358,8 @@ Cell sky130_fd_sc_hd__and2_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -378,8 +378,8 @@ Cell sky130_fd_sc_hd__and3_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -403,8 +403,8 @@ Cell sky130_fd_sc_hd__and4_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -433,8 +433,8 @@ Cell sky130_fd_sc_hd__or2_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -453,8 +453,8 @@ Cell sky130_fd_sc_hd__or3_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -478,8 +478,8 @@ Cell sky130_fd_sc_hd__or4_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -508,8 +508,8 @@ Cell sky130_fd_sc_hd__xor2_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -536,8 +536,8 @@ Cell sky130_fd_sc_hd__xnor2_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -564,8 +564,8 @@ Cell sky130_fd_sc_hd__a21o_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -589,8 +589,8 @@ Cell sky130_fd_sc_hd__a21oi_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -614,8 +614,8 @@ Cell sky130_fd_sc_hd__a22o_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -644,8 +644,8 @@ Cell sky130_fd_sc_hd__a22oi_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -674,8 +674,8 @@ Cell sky130_fd_sc_hd__o21a_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -699,8 +699,8 @@ Cell sky130_fd_sc_hd__o21ai_0 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -724,8 +724,8 @@ Cell sky130_fd_sc_hd__o22a_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -754,8 +754,8 @@ Cell sky130_fd_sc_hd__o22ai_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -784,8 +784,8 @@ Cell sky130_fd_sc_hd__a31o_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -814,8 +814,8 @@ Cell sky130_fd_sc_hd__a32o_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A1 input 0.00-0.00 A2 input 0.00-0.00 @@ -849,8 +849,8 @@ Cell sky130_fd_sc_hd__mux2_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A0 input 0.00-0.00 A1 input 0.00-0.00 @@ -878,8 +878,8 @@ Cell sky130_fd_sc_hd__mux4_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A0 input 0.00-0.00 A1 input 0.00-0.00 @@ -926,8 +926,8 @@ Cell sky130_fd_sc_hd__fa_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.01-0.01 B input 0.01-0.01 @@ -976,8 +976,8 @@ Cell sky130_fd_sc_hd__ha_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00 @@ -1013,8 +1013,8 @@ Cell sky130_fd_sc_hd__maj3_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 B input 0.00-0.00 @@ -1038,8 +1038,8 @@ Cell sky130_fd_sc_hd__dfxtp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -1068,8 +1068,8 @@ Cell sky130_fd_sc_hd__dfrtp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -1111,8 +1111,8 @@ Cell sky130_fd_sc_hd__dfstp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -1154,8 +1154,8 @@ Cell sky130_fd_sc_hd__dfbbp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -1233,8 +1233,8 @@ Cell sky130_fd_sc_hd__dlxtp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power D input 0.00-0.00 GATE input 0.00-0.00 @@ -1266,8 +1266,8 @@ Cell sky130_fd_sc_hd__dlxtn_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power D input 0.00-0.00 GATE_N input 0.00-0.00 @@ -1299,8 +1299,8 @@ Cell sky130_fd_sc_hd__sdfxtp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -1347,8 +1347,8 @@ Cell sky130_fd_sc_hd__sdfxbp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -1400,8 +1400,8 @@ Cell sky130_fd_sc_hd__ebufn_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 TE_B input 0.00-0.00 @@ -1424,8 +1424,8 @@ Cell sky130_fd_sc_hd__ebufn_2 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 TE_B input 0.00-0.00 @@ -1448,8 +1448,8 @@ Cell sky130_fd_sc_hd__clkbuf_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 X output function=A @@ -1463,8 +1463,8 @@ Cell sky130_fd_sc_hd__clkbuf_2 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 X output function=A @@ -1478,8 +1478,8 @@ Cell sky130_fd_sc_hd__clkinv_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.00 Y output function=!A @@ -1493,8 +1493,8 @@ Cell sky130_fd_sc_hd__clkinv_2 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power A input 0.00-0.01 Y output function=!A @@ -1508,8 +1508,8 @@ Cell sky130_fd_sc_hd__conb_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power HI output function=1 LO output function=0 @@ -1517,8 +1517,8 @@ Cell sky130_fd_sc_hd__diode_2 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power DIODE input 0.00-0.00 sky130_fd_sc_hd__inv_1: area=3.753600 dont_use=0 diff --git a/liberty/test/liberty_timing_types_deep.ok b/liberty/test/liberty_timing_types_deep.ok index ce03bbc6..c8728e8a 100644 --- a/liberty/test/liberty_timing_types_deep.ok +++ b/liberty/test/liberty_timing_types_deep.ok @@ -251,8 +251,8 @@ Cell sky130_fd_sc_hd__dfrtp_1 Library sky130_fd_sc_hd__ff_n40C_1v95 File ../../test/sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 @@ -294,8 +294,8 @@ Cell sky130_fd_sc_hd__dfrtp_1 Library sky130_fd_sc_hd__ss_n40C_1v40 File ../../test/sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib VGND ground - VNB bias - VPB bias + VNB well + VPB well VPWR power CLK input 0.00-0.00 D input 0.00-0.00 diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index 74c37b15..3864239c 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -38,12 +38,12 @@ namespace sta { static constexpr char escape_ = '\\'; -ConcreteLibrary::ConcreteLibrary(std::string name, - std::string filename, +ConcreteLibrary::ConcreteLibrary(std::string_view name, + std::string_view filename, bool is_liberty) : - name_(std::move(name)), + name_(name), id_(ConcreteNetwork::nextObjectId()), - filename_(std::move(filename)), + filename_(filename), is_liberty_(is_liberty), bus_brkt_left_('['), bus_brkt_right_(']') diff --git a/network/PortDirection.cc b/network/PortDirection.cc index 2ade330d..608eb2b0 100644 --- a/network/PortDirection.cc +++ b/network/PortDirection.cc @@ -35,7 +35,7 @@ PortDirection *PortDirection::bidirect_; PortDirection *PortDirection::internal_; PortDirection *PortDirection::ground_; PortDirection *PortDirection::power_; -PortDirection *PortDirection::bias_; +PortDirection *PortDirection::well_; PortDirection *PortDirection::unknown_; void @@ -48,7 +48,7 @@ PortDirection::init() internal_ = new PortDirection("internal", 4); ground_ = new PortDirection("ground", 5); power_ = new PortDirection("power", 6); - bias_ = new PortDirection("bias", 7); + well_ = new PortDirection("well", 7); unknown_ = new PortDirection("unknown", 8); } @@ -69,8 +69,8 @@ PortDirection::destroy() ground_ = nullptr; delete power_; power_ = nullptr; - delete bias_; - bias_ = nullptr; + delete well_; + well_ = nullptr; delete unknown_; unknown_ = nullptr; } @@ -99,8 +99,8 @@ PortDirection::find(const char *dir_name) return ground_; else if (stringEqual(dir_name, "power")) return power_; - else if (stringEqual(dir_name, "bias")) - return bias_; + else if (stringEqual(dir_name, "well")) + return well_; else return nullptr; } @@ -130,7 +130,9 @@ PortDirection::isAnyTristate() const bool PortDirection::isPowerGround() const { - return this == ground_ || this == power_ || this == bias_; + return this == ground_ + || this == power_ + || this == well_; } } // namespace diff --git a/network/test/cpp/TestNetwork.cc b/network/test/cpp/TestNetwork.cc index 06e4b178..bc4f4778 100644 --- a/network/test/cpp/TestNetwork.cc +++ b/network/test/cpp/TestNetwork.cc @@ -161,13 +161,13 @@ TEST_F(PortDirectionTest, PowerSingleton) { EXPECT_TRUE(dir->isPower()); } -TEST_F(PortDirectionTest, BiasSingleton) +TEST_F(PortDirectionTest, WellSingleton) { - PortDirection *dir = PortDirection::bias(); + PortDirection *dir = PortDirection::well(); EXPECT_NE(dir, nullptr); - EXPECT_EQ(dir->name(), "bias"); + EXPECT_EQ(dir->name(), "well"); EXPECT_EQ(dir->index(), 7); - EXPECT_TRUE(dir->isBias()); + EXPECT_TRUE(dir->isWell()); } TEST_F(PortDirectionTest, UnknownSingleton) { @@ -186,7 +186,7 @@ TEST_F(PortDirectionTest, FindByName) { EXPECT_EQ(PortDirection::find("internal"), PortDirection::internal()); EXPECT_EQ(PortDirection::find("ground"), PortDirection::ground()); EXPECT_EQ(PortDirection::find("power"), PortDirection::power()); - EXPECT_EQ(PortDirection::find("bias"), PortDirection::bias()); + EXPECT_EQ(PortDirection::find("well"), PortDirection::well()); EXPECT_EQ(PortDirection::find("nonexistent"), nullptr); } @@ -198,7 +198,7 @@ TEST_F(PortDirectionTest, IsAnyInput) { EXPECT_FALSE(PortDirection::internal()->isAnyInput()); EXPECT_FALSE(PortDirection::ground()->isAnyInput()); EXPECT_FALSE(PortDirection::power()->isAnyInput()); - EXPECT_FALSE(PortDirection::bias()->isAnyInput()); + EXPECT_FALSE(PortDirection::well()->isAnyInput()); EXPECT_FALSE(PortDirection::unknown()->isAnyInput()); } @@ -210,7 +210,7 @@ TEST_F(PortDirectionTest, IsAnyOutput) { EXPECT_FALSE(PortDirection::internal()->isAnyOutput()); EXPECT_FALSE(PortDirection::ground()->isAnyOutput()); EXPECT_FALSE(PortDirection::power()->isAnyOutput()); - EXPECT_FALSE(PortDirection::bias()->isAnyOutput()); + EXPECT_FALSE(PortDirection::well()->isAnyOutput()); EXPECT_FALSE(PortDirection::unknown()->isAnyOutput()); } @@ -222,14 +222,14 @@ TEST_F(PortDirectionTest, IsAnyTristate) { EXPECT_FALSE(PortDirection::internal()->isAnyTristate()); EXPECT_FALSE(PortDirection::ground()->isAnyTristate()); EXPECT_FALSE(PortDirection::power()->isAnyTristate()); - EXPECT_FALSE(PortDirection::bias()->isAnyTristate()); + EXPECT_FALSE(PortDirection::well()->isAnyTristate()); EXPECT_FALSE(PortDirection::unknown()->isAnyTristate()); } TEST_F(PortDirectionTest, IsPowerGround) { EXPECT_TRUE(PortDirection::power()->isPowerGround()); EXPECT_TRUE(PortDirection::ground()->isPowerGround()); - EXPECT_TRUE(PortDirection::bias()->isPowerGround()); + EXPECT_TRUE(PortDirection::well()->isPowerGround()); EXPECT_FALSE(PortDirection::input()->isPowerGround()); EXPECT_FALSE(PortDirection::output()->isPowerGround()); EXPECT_FALSE(PortDirection::tristate()->isPowerGround()); @@ -865,7 +865,7 @@ TEST(PortDirectionExtraTest, AllDirections) { EXPECT_NE(PortDirection::internal(), nullptr); EXPECT_NE(PortDirection::ground(), nullptr); EXPECT_NE(PortDirection::power(), nullptr); - EXPECT_NE(PortDirection::bias(), nullptr); + EXPECT_NE(PortDirection::well(), nullptr); EXPECT_NE(PortDirection::unknown(), nullptr); } @@ -888,7 +888,7 @@ TEST(PortDirectionExtraTest, DirectionProperties) { EXPECT_TRUE(PortDirection::ground()->isPowerGround()); EXPECT_TRUE(PortDirection::power()->isPowerGround()); - EXPECT_TRUE(PortDirection::bias()->isPowerGround()); + EXPECT_TRUE(PortDirection::well()->isPowerGround()); } TEST(PortDirectionExtraTest, DirectionNames) { @@ -902,7 +902,7 @@ TEST(PortDirectionExtraTest, DirectionNames) { EXPECT_EQ(PortDirection::internal()->name(), "internal"); EXPECT_EQ(PortDirection::ground()->name(), "ground"); EXPECT_EQ(PortDirection::power()->name(), "power"); - EXPECT_EQ(PortDirection::bias()->name(), "bias"); + EXPECT_EQ(PortDirection::well()->name(), "well"); EXPECT_EQ(PortDirection::unknown()->name(), "unknown"); } @@ -917,7 +917,7 @@ TEST(PortDirectionExtraTest, FindAllByName) { EXPECT_EQ(PortDirection::find("internal"), PortDirection::internal()); EXPECT_EQ(PortDirection::find("ground"), PortDirection::ground()); EXPECT_EQ(PortDirection::find("power"), PortDirection::power()); - EXPECT_EQ(PortDirection::find("bias"), PortDirection::bias()); + EXPECT_EQ(PortDirection::find("well"), PortDirection::well()); // "unknown" is not findable by name, returns nullptr EXPECT_EQ(PortDirection::find("nonexistent"), nullptr); } diff --git a/sdc/FilterObjects.cc b/sdc/FilterObjects.cc index b7d47671..6e263037 100644 --- a/sdc/FilterObjects.cc +++ b/sdc/FilterObjects.cc @@ -73,9 +73,9 @@ public: FilterExpr(std::string_view expression, Report *report); - std::vector> postfix(bool bool_props_as_int); + std::vector> postfix(); private: - std::vector> lex(bool bool_props_as_int); + std::vector> lex(); std::vector> shuntingYard(std::vector> &infix); std::string raw_; @@ -106,20 +106,21 @@ FilterExpr::FilterExpr(std::string_view expression, } std::vector> -FilterExpr::postfix(bool bool_props_as_int) +FilterExpr::postfix() { - auto infix = lex(bool_props_as_int); + auto infix = lex(); return shuntingYard(infix); } std::vector> -FilterExpr::lex(bool bool_props_as_int) +FilterExpr::lex() { std::vector> token_regexes = { {std::regex("^\\s+"), Token::Kind::skip}, {std::regex("^defined\\(([a-zA-Z_]+)\\)"), Token::Kind::defined}, {std::regex("^undefined\\(([a-zA-Z_]+)\\)"), Token::Kind::undefined}, - {std::regex("^@?([a-zA-Z_]+) *((==|!=|=~|!~) *([0-9a-zA-Z_\\/$\\[\\]*?.]+))?"), Token::Kind::predicate}, + {std::regex("^@?([a-zA-Z_]+) *((==|!=|=~|!~) *([0-9a-zA-Z_\\/$\\[\\]*?.]+))?"), + Token::Kind::predicate}, {std::regex("^(&&)"), Token::Kind::op_and}, {std::regex("^(\\|\\|)"), Token::Kind::op_or}, {std::regex("^(!)"), Token::Kind::op_inv}, @@ -139,9 +140,9 @@ FilterExpr::lex(bool bool_props_as_int) std::string property = token_match[1].str(); // The default operation on a predicate if an op and arg are - // omitted is 'arg == 1' / 'arg == true'. + // omitted is 'prop == 1 || true'. std::string op = "=="; - std::string arg = (bool_props_as_int ? "1" : "true"); + std::string arg = "1"; if (token_match[2].length() != 0) { op = token_match[3].str(); @@ -250,13 +251,18 @@ filterObjects(const char *property, bool not_pattern_match = stringEq(op, "!~"); for (T *object : all) { PropertyValue value = properties.getProperty(object, property); - std::string prop_str = value.to_string(network); - const char *prop = prop_str.c_str(); - if (prop && - ((exact_match && stringEq(prop, pattern)) - || (not_match && !stringEq(prop, pattern)) - || (pattern_match && patternMatch(pattern, prop)) - || (not_pattern_match && !patternMatch(pattern, prop)))) + std::string prop = value.to_string(network); + if (value.type() == PropertyValue::Type::bool_) { + // Canonicalize bool true/false to 1/0. + if (stringEqual(pattern, "true")) + pattern = "1"; + else if (stringEqual(pattern, "false")) + pattern = "0"; + } + if ((exact_match && stringEq(prop.c_str(), pattern)) + || (not_match && !stringEq(prop.c_str(), pattern)) + || (pattern_match && patternMatch(pattern, prop)) + || (not_pattern_match && !patternMatch(pattern, prop))) filtered_objects.insert(object); } return filtered_objects; @@ -265,7 +271,6 @@ filterObjects(const char *property, template std::vector filterObjects(std::string_view filter_expression, std::vector *objects, - bool bool_props_as_int, Sta *sta) { Report *report = sta->report(); @@ -278,7 +283,7 @@ filterObjects(std::string_view filter_expression, all.insert(object); FilterExpr filter(filter_expression, report); - auto postfix = filter.postfix(bool_props_as_int); + auto postfix = filter.postfix(); std::stack> eval_stack; for (auto &token : postfix) { if (token->kind == FilterExpr::Token::Kind::op_or) { @@ -405,100 +410,89 @@ filterObjects(std::string_view filter_expression, PortSeq filterPorts(std::string_view filter_expression, PortSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } InstanceSeq filterInstances(std::string_view filter_expression, InstanceSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } PinSeq filterPins(std::string_view filter_expression, PinSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } NetSeq filterNets(std::string_view filter_expression, NetSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } ClockSeq filterClocks(std::string_view filter_expression, ClockSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } LibertyCellSeq filterLibCells(std::string_view filter_expression, LibertyCellSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } LibertyPortSeq filterLibPins(std::string_view filter_expression, LibertyPortSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } LibertyLibrarySeq filterLibertyLibraries(std::string_view filter_expression, LibertyLibrarySeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } EdgeSeq filterTimingArcs(std::string_view filter_expression, EdgeSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } PathEndSeq filterPathEnds(std::string_view filter_expression, PathEndSeq *objects, - bool bool_props_as_int, Sta *sta) { - return filterObjects(filter_expression, objects, bool_props_as_int, sta); + return filterObjects(filter_expression, objects, sta); } StringSeq filterExprToPostfix(std::string_view expr, - bool bool_props_as_int, Report *report) { FilterExpr filter(expr, report); - auto postfix = filter.postfix(bool_props_as_int); + auto postfix = filter.postfix(); StringSeq result; for (auto &token : postfix) result.push_back(token->text); diff --git a/sdc/Sdc.i b/sdc/Sdc.i index eccd234e..60107704 100644 --- a/sdc/Sdc.i +++ b/sdc/Sdc.i @@ -1493,101 +1493,90 @@ find_register_output_pins(ClockSet *clks, PortSeq filter_ports(const char *filter_expression, - PortSeq *ports, - bool bool_props_as_int) + PortSeq *ports) { sta::Sta *sta = Sta::sta(); - return filterPorts(filter_expression, ports, bool_props_as_int, sta); + return filterPorts(filter_expression, ports, sta); } InstanceSeq filter_insts(const char *filter_expression, - InstanceSeq *insts, - bool bool_props_as_int) + InstanceSeq *insts) { sta::Sta *sta = Sta::sta(); - return filterInstances(filter_expression, insts, bool_props_as_int, sta); + return filterInstances(filter_expression, insts, sta); } PinSeq filter_pins(const char *filter_expression, - PinSeq *pins, - bool bool_props_as_int) + PinSeq *pins) { sta::Sta *sta = Sta::sta(); - return filterPins(filter_expression, pins, bool_props_as_int, sta); + return filterPins(filter_expression, pins, sta); } NetSeq filter_nets(const char *filter_expression, - NetSeq *nets, - bool bool_props_as_int) + NetSeq *nets) { sta::Sta *sta = Sta::sta(); - return filterNets(filter_expression, nets, bool_props_as_int, sta); + return filterNets(filter_expression, nets, sta); } ClockSeq filter_clocks(const char *filter_expression, - ClockSeq *clocks, - bool bool_props_as_int) + ClockSeq *clocks) { sta::Sta *sta = Sta::sta(); - return filterClocks(filter_expression, clocks, bool_props_as_int, sta); + return filterClocks(filter_expression, clocks, sta); } LibertyCellSeq filter_lib_cells(const char *filter_expression, - LibertyCellSeq *cells, - bool bool_props_as_int) + LibertyCellSeq *cells) { sta::Sta *sta = Sta::sta(); - return filterLibCells(filter_expression, cells, bool_props_as_int, sta); + return filterLibCells(filter_expression, cells, sta); } LibertyPortSeq filter_lib_pins(const char *filter_expression, - LibertyPortSeq *pins, - bool bool_props_as_int) + LibertyPortSeq *pins) { sta::Sta *sta = Sta::sta(); - return filterLibPins(filter_expression, pins, bool_props_as_int, sta); + return filterLibPins(filter_expression, pins, sta); } LibertyLibrarySeq filter_liberty_libraries(const char *filter_expression, - LibertyLibrarySeq *libs, - bool bool_props_as_int) + LibertyLibrarySeq *libs) { sta::Sta *sta = Sta::sta(); - return filterLibertyLibraries(filter_expression, libs, bool_props_as_int, sta); + return filterLibertyLibraries(filter_expression, libs, sta); } EdgeSeq filter_timing_arcs(const char *filter_expression, - EdgeSeq *edges, - bool bool_props_as_int) + EdgeSeq *edges) { sta::Sta *sta = Sta::sta(); - return filterTimingArcs(filter_expression, edges, bool_props_as_int, sta); + return filterTimingArcs(filter_expression, edges, sta); } PathEndSeq filter_path_ends(const char *filter_expression, - PathEndSeq *path_ends, - bool bool_props_as_int) + PathEndSeq *path_ends) { sta::Sta *sta = Sta::sta(); - return filterPathEnds(filter_expression, path_ends, bool_props_as_int, sta); + return filterPathEnds(filter_expression, path_ends, sta); } // For FilterExpr unit tests. StringSeq -filter_expr_to_postfix(const char* expr, - bool bool_props_as_int) +filter_expr_to_postfix(const char* expr) { Report *report = Sta::sta()->report(); - return filterExprToPostfix(expr, bool_props_as_int, report); + return filterExprToPostfix(expr, report); } //////////////////////////////////////////////////////////////// diff --git a/sdc/Sdc.tcl b/sdc/Sdc.tcl index dd5374cd..d8e5aef1 100644 --- a/sdc/Sdc.tcl +++ b/sdc/Sdc.tcl @@ -393,7 +393,7 @@ proc get_cells { args } { } } if [info exists keys(-filter)] { - set insts [filter_insts $keys(-filter) $insts 1] + set insts [filter_insts $keys(-filter) $insts] } return $insts } @@ -436,7 +436,7 @@ proc get_clocks { args } { } } if [info exists keys(-filter)] { - set clocks [filter_clocks $keys(-filter) $clocks 1] + set clocks [filter_clocks $keys(-filter) $clocks] } return $clocks } @@ -517,7 +517,7 @@ proc get_lib_cells { args } { } } if [info exists keys(-filter)] { - set cells [filter_lib_cells $keys(-filter) $cells 1] + set cells [filter_lib_cells $keys(-filter) $cells] } return $cells } @@ -621,7 +621,7 @@ proc get_lib_pins { args } { } } if [info exists keys(-filter)] { - set ports [filter_lib_pins $keys(-filter) $ports 1] + set ports [filter_lib_pins $keys(-filter) $ports] } return $ports } @@ -671,7 +671,7 @@ proc get_libs { args } { } } if [info exists keys(-filter)] { - set libs [filter_liberty_libraries $keys(-filter) $libs 1] + set libs [filter_liberty_libraries $keys(-filter) $libs] } return $libs } @@ -772,7 +772,7 @@ proc get_nets { args } { } } if [info exists keys(-filter)] { - set nets [filter_nets $keys(-filter) $nets 1] + set nets [filter_nets $keys(-filter) $nets] } return $nets } @@ -863,7 +863,7 @@ proc get_pins { args } { } } if [info exists keys(-filter)] { - set pins [filter_pins $keys(-filter) $pins 1] + set pins [filter_pins $keys(-filter) $pins] } return $pins } @@ -919,7 +919,7 @@ proc get_ports { args } { } } if [info exists keys(-filter)] { - set ports [filter_ports $keys(-filter) $ports 1] + set ports [filter_ports $keys(-filter) $ports] } return $ports } diff --git a/sdc/test/sdc_filter_dot.tcl b/sdc/test/sdc_filter_dot.tcl index bf75fe86..ca81630a 100644 --- a/sdc/test/sdc_filter_dot.tcl +++ b/sdc/test/sdc_filter_dot.tcl @@ -12,4 +12,4 @@ puts {[get_cells -filter {name =~ r.*} *]} report_object_full_names [get_cells -filter {name =~ r.*} *] # Verify filter_expr_to_postfix parses dot-containing values -puts [sta::filter_expr_to_postfix "name =~ tcdm_master_.*req_.*_i" 0] +puts [sta::filter_expr_to_postfix "name =~ tcdm_master_.*req_.*_i"] diff --git a/sdc/test/sdc_filter_query.tcl b/sdc/test/sdc_filter_query.tcl index fa2a3467..33a80fdb 100644 --- a/sdc/test/sdc_filter_query.tcl +++ b/sdc/test/sdc_filter_query.tcl @@ -137,32 +137,32 @@ puts "is_path_group_name nonexistent = $is_gp" # filter_ports set all_ports [get_ports *] -set filtered [sta::filter_ports "direction==input" $all_ports 0] +set filtered [sta::filter_ports "direction==input" $all_ports] puts "filter_ports direction == input: [llength $filtered]" # filter_clocks set all_clks [get_clocks *] -set filtered [sta::filter_clocks "is_virtual==0" $all_clks 1] +set filtered [sta::filter_clocks "is_virtual==0" $all_clks] puts "filter_clocks is_virtual == 0: [llength $filtered]" # filter_lib_cells set all_cells [get_lib_cells NangateOpenCellLibrary/*] -set filtered [sta::filter_lib_cells "is_buffer==1" $all_cells 1] +set filtered [sta::filter_lib_cells "is_buffer==1" $all_cells] puts "filter_lib_cells is_buffer: [llength $filtered]" # filter_insts set all_insts [get_cells *] -set filtered [sta::filter_insts "ref_name=~BUF*" $all_insts 0] +set filtered [sta::filter_insts "ref_name=~BUF*" $all_insts] puts "filter_insts ref_name =~ BUF*: [llength $filtered]" # filter_pins set all_pins [get_pins buf1/*] -set filtered [sta::filter_pins "direction==input" $all_pins 0] +set filtered [sta::filter_pins "direction==input" $all_pins] puts "filter_pins direction == input: [llength $filtered]" # filter_nets set all_nets [get_nets *] -set filtered [sta::filter_nets "full_name=~n*" $all_nets 0] +set filtered [sta::filter_nets "full_name=~n*" $all_nets] puts "filter_nets full_name =~ n*: [llength $filtered]" ############################################################ diff --git a/search/Property.cc b/search/Property.cc index cdb0c088..067298d7 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -564,7 +564,7 @@ PropertyValue::to_string(const Network *network) const case Type::float_: return unit_->asString(float_, 6); case Type::bool_: - // true/false would be better but these are TCL true/false values. + // These are TCL true/false values. if (bool_) return "1"; else diff --git a/search/Sta.cc b/search/Sta.cc index 9dbc309e..c8b00443 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4167,6 +4167,12 @@ Sta::readSpef(std::string_view name, parasitics = findParasitics(std::string(name)); if (parasitics == nullptr) parasitics = makeConcreteParasitics(std::string(name), std::string(filename)); + if (scene) + scene->setParasitics(parasitics, min_max); + else { + for (Scene *scn : scenes_) + scn->setParasitics(parasitics, min_max); + } } bool success = readSpefFile(filename, instance, pin_cap_included, diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl index f6daed10..8796df34 100644 --- a/tcl/Sta.tcl +++ b/tcl/Sta.tcl @@ -300,7 +300,7 @@ proc get_timing_edges_cmd { cmd cmd_args } { cmd_usage_error $cmd } if [info exists keys(-filter)] { - set arcs [filter_timing_arcs $keys(-filter) $arcs 1] + set arcs [filter_timing_arcs $keys(-filter) $arcs] } return $arcs } diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index 9157a3fc..afbc74f5 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -280,7 +280,7 @@ using namespace sta; } %typemap(in) std::string_view { - int length; + Tcl_Size length; const char *str = Tcl_GetStringFromObj($input, &length); $1 = std::string_view(str, length); } @@ -415,7 +415,7 @@ using namespace sta; } %typemap(in) Transition* { - int length; + Tcl_Size length; const char *arg = Tcl_GetStringFromObj($input, &length); Transition *tr = Transition::find(std::string_view(arg, length)); if (tr == nullptr) { @@ -433,7 +433,7 @@ using namespace sta; } %typemap(in) RiseFall* { - int length; + Tcl_Size length; const char *arg = Tcl_GetStringFromObj($input, &length); const RiseFall *rf = RiseFall::find(std::string_view(arg, length)); if (rf == nullptr) { @@ -451,7 +451,7 @@ using namespace sta; } %typemap(in) RiseFallBoth* { - int length; + Tcl_Size length; const char *arg = Tcl_GetStringFromObj($input, &length); const RiseFallBoth *rf = RiseFallBoth::find(std::string_view(arg, length)); if (rf == nullptr) { @@ -469,7 +469,7 @@ using namespace sta; } %typemap(in) PortDirection* { - int length; + Tcl_Size length; const char *arg = Tcl_GetStringFromObj($input, &length); PortDirection *dir = PortDirection::find(arg); if (dir == nullptr) { @@ -481,7 +481,7 @@ using namespace sta; } %typemap(in) TimingRole* { - int length; + Tcl_Size length; const char *arg = Tcl_GetStringFromObj($input, &length); const TimingRole *role = TimingRole::find(arg); if (role) @@ -498,7 +498,7 @@ using namespace sta; } %typemap(in) LogicValue { - int length; + Tcl_Size length; std::string arg = Tcl_GetStringFromObj($input, &length); if (arg == "0" || stringEqual(arg, "zero")) $1 = LogicValue::zero; @@ -517,7 +517,7 @@ using namespace sta; } %typemap(in) AnalysisType { - int length; + Tcl_Size length; const char *arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "single")) $1 = AnalysisType::single; @@ -831,7 +831,7 @@ using namespace sta; } %typemap(in) MinMax* { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); // Swig is retarded and drops const on args. MinMax *min_max = const_cast(MinMax::find(arg)); @@ -852,7 +852,7 @@ using namespace sta; } %typemap(in) MinMaxAll* { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); // Swig is retarded and drops const on args. MinMaxAll *min_max = const_cast(MinMaxAll::find(arg)); @@ -865,7 +865,7 @@ using namespace sta; } %typemap(in) MinMaxAllNull* { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "NULL")) $1 = nullptr; @@ -887,7 +887,7 @@ using namespace sta; // SetupHold is typedef'd to MinMax. %typemap(in) const SetupHold* { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); // Swig is retarded and drops const on args. if (stringEqual(arg, "hold") @@ -904,7 +904,7 @@ using namespace sta; // SetupHoldAll is typedef'd to MinMaxAll. %typemap(in) const SetupHoldAll* { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); // Swig is retarded and drops const on args. if (stringEqual(arg, "hold") @@ -925,7 +925,7 @@ using namespace sta; // EarlyLate is typedef'd to MinMax. %typemap(in) const EarlyLate* { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); // Swig is retarded and drops const on args. EarlyLate *early_late = const_cast(EarlyLate::find(arg)); @@ -939,7 +939,7 @@ using namespace sta; // EarlyLateAll is typedef'd to MinMaxAll. %typemap(in) const EarlyLateAll* { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); // Swig is retarded and drops const on args. EarlyLateAll *early_late = const_cast(EarlyLateAll::find(arg)); @@ -952,7 +952,7 @@ using namespace sta; } %typemap(in) TimingDerateType { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "net_delay")) $1 = TimingDerateType::net_delay; @@ -967,7 +967,7 @@ using namespace sta; } %typemap(in) TimingDerateCellType { - int length; + Tcl_Size length; char *arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "cell_delay")) $1 = TimingDerateCellType::cell_delay; @@ -980,7 +980,7 @@ using namespace sta; } %typemap(in) PathClkOrData { - int length; + Tcl_Size length; std::string arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "clk")) $1 = PathClkOrData::clk; @@ -993,7 +993,7 @@ using namespace sta; } %typemap(in) ReportSortBy { - int length; + Tcl_Size length; std::string arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "group")) $1 = sort_by_group; @@ -1006,7 +1006,7 @@ using namespace sta; } %typemap(in) ReportPathFormat { - int length; + Tcl_Size length; std::string arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "full")) $1 = ReportPathFormat::full; @@ -1188,7 +1188,7 @@ using namespace sta; if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK && argc > 0) { for (int i = 0; i < argc; i++) { - int length; + Tcl_Size length; const char *mode_name = Tcl_GetStringFromObj(argv[i], &length); Mode *mode = sta->findMode(mode_name); if (mode) @@ -1215,7 +1215,7 @@ using namespace sta; %typemap(in) Scene* { sta::Sta *sta = Sta::sta(); - int length; + Tcl_Size length; std::string scene_name = Tcl_GetStringFromObj($input, &length); // parse_scene_or_all support depreated 11/21/2025 if (scene_name == "NULL") @@ -1248,7 +1248,7 @@ using namespace sta; if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK && argc > 0) { for (int i = 0; i < argc; i++) { - int length; + Tcl_Size length; const char *scene_name = Tcl_GetStringFromObj(argv[i], &length); Scene *scene = sta->findScene(scene_name); if (scene) @@ -1274,7 +1274,7 @@ using namespace sta; } %typemap(in) PropertyValue { - int length; + Tcl_Size length; const char *arg = Tcl_GetStringFromObj($input, &length); $1 = PropertyValue(arg); } @@ -1411,7 +1411,7 @@ using namespace sta; } %typemap(in) CircuitSim { - int length; + Tcl_Size length; std::string arg = Tcl_GetStringFromObj($input, &length); if (stringEqual(arg, "hspice")) $1 = CircuitSim::hspice; diff --git a/tcl/TclTypeHelpers.cc b/tcl/TclTypeHelpers.cc index 48ccbf57..bcd4f264 100644 --- a/tcl/TclTypeHelpers.cc +++ b/tcl/TclTypeHelpers.cc @@ -40,7 +40,7 @@ tclListStringSeq(Tcl_Obj *const source, StringSeq seq; if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { for (int i = 0; i < argc; i++) { - int length; + Tcl_Size length; const char *str = Tcl_GetStringFromObj(argv[i], &length); seq.push_back(str); } @@ -58,7 +58,7 @@ tclListStringSeqPtr(Tcl_Obj *const source, if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { StringSeq *seq = new StringSeq; for (int i = 0; i < argc; i++) { - int length; + Tcl_Size length; const char *str = Tcl_GetStringFromObj(argv[i], &length); seq->push_back(str); } @@ -78,7 +78,7 @@ tclListStringSet(Tcl_Obj *const source, if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) { StringSet *set = new StringSet; for (int i = 0; i < argc; i++) { - int length; + Tcl_Size length; const char *str = Tcl_GetStringFromObj(argv[i], &length); set->insert(str); } @@ -183,11 +183,11 @@ arcDcalcArgTcl(Tcl_Obj *obj, { Sta *sta = Sta::sta(); sta->ensureGraph(); - int list_argc; + Tcl_Size list_argc; Tcl_Obj **list_argv; if (Tcl_ListObjGetElements(interp, obj, &list_argc, &list_argv) == TCL_OK) { const char *input_delay = "0.0"; - int length; + Tcl_Size length; if (list_argc == 6) input_delay = Tcl_GetStringFromObj(list_argv[5], &length); if (list_argc == 5 || list_argc == 6) { diff --git a/tcl/Variables.tcl b/tcl/Variables.tcl index ba8f37b3..0ea66690 100644 --- a/tcl/Variables.tcl +++ b/tcl/Variables.tcl @@ -33,13 +33,13 @@ namespace eval sta { # Default digits to print after decimal point for reporting commands. set ::sta_report_default_digits 2 -trace variable ::sta_report_default_digits "rw" \ +trace add variable ::sta_report_default_digits {read write} \ sta::trace_report_default_digits proc trace_report_default_digits { name1 name2 op } { global sta_report_default_digits - if { $op == "w" } { + if { $op == "write" } { if { !([string is integer $sta_report_default_digits] \ && $sta_report_default_digits >= 0) } { sta_error 590 "sta_report_default_digits must be a positive integer." @@ -47,7 +47,7 @@ proc trace_report_default_digits { name1 name2 op } { } } -trace variable ::sta_crpr_enabled "rw" \ +trace add variable ::sta_crpr_enabled {read write} \ sta::trace_crpr_enabled proc trace_crpr_enabled { name1 name2 op } { @@ -55,15 +55,15 @@ proc trace_crpr_enabled { name1 name2 op } { crpr_enabled set_crpr_enabled } -trace variable ::sta_crpr_mode "rw" \ +trace add variable ::sta_crpr_mode {read write} \ sta::trace_crpr_mode proc trace_crpr_mode { name1 name2 op } { global sta_crpr_mode - if { $op == "r" } { + if { $op == "read" } { set sta_crpr_mode [crpr_mode] - } elseif { $op == "w" } { + } elseif { $op == "write" } { if { $sta_crpr_mode == "same_pin" || $sta_crpr_mode == "same_transition" } { set_crpr_mode $sta_crpr_mode } else { @@ -72,7 +72,7 @@ proc trace_crpr_mode { name1 name2 op } { } } -trace variable ::sta_cond_default_arcs_enabled "rw" \ +trace add variable ::sta_cond_default_arcs_enabled {read write} \ sta::trace_cond_default_arcs_enabled proc trace_cond_default_arcs_enabled { name1 name2 op } { @@ -80,7 +80,7 @@ proc trace_cond_default_arcs_enabled { name1 name2 op } { cond_default_arcs_enabled set_cond_default_arcs_enabled } -trace variable ::sta_gated_clock_checks_enabled "rw" \ +trace add variable ::sta_gated_clock_checks_enabled {read write} \ sta::trace_gated_clk_checks_enabled proc trace_gated_clk_checks_enabled { name1 name2 op } { @@ -88,7 +88,7 @@ proc trace_gated_clk_checks_enabled { name1 name2 op } { gated_clk_checks_enabled set_gated_clk_checks_enabled } -trace variable ::sta_internal_bidirect_instance_paths_enabled "rw" \ +trace add variable ::sta_internal_bidirect_instance_paths_enabled {read write} \ sta::trace_internal_bidirect_instance_paths_enabled proc trace_internal_bidirect_instance_paths_enabled { name1 name2 op } { @@ -96,7 +96,7 @@ proc trace_internal_bidirect_instance_paths_enabled { name1 name2 op } { bidirect_inst_paths_enabled set_bidirect_inst_paths_enabled } -trace variable ::sta_clock_through_tristate_enabled "rw" \ +trace add variable ::sta_clock_through_tristate_enabled {read write} \ sta::trace_clock_through_tristate_enabled proc trace_clock_through_tristate_enabled { name1 name2 op } { @@ -104,7 +104,7 @@ proc trace_clock_through_tristate_enabled { name1 name2 op } { clk_thru_tristate_enabled set_clk_thru_tristate_enabled } -trace variable ::sta_preset_clear_arcs_enabled "rw" \ +trace add variable ::sta_preset_clear_arcs_enabled {read write} \ sta::trace_preset_clr_arcs_enabled proc trace_preset_clr_arcs_enabled { name1 name2 op } { @@ -112,7 +112,7 @@ proc trace_preset_clr_arcs_enabled { name1 name2 op } { preset_clr_arcs_enabled set_preset_clr_arcs_enabled } -trace variable ::sta_recovery_removal_checks_enabled "rw" \ +trace add variable ::sta_recovery_removal_checks_enabled {read write} \ sta::trace_recovery_removal_checks_enabled proc trace_recovery_removal_checks_enabled { name1 name2 op } { @@ -120,7 +120,7 @@ proc trace_recovery_removal_checks_enabled { name1 name2 op } { recovery_removal_checks_enabled set_recovery_removal_checks_enabled } -trace variable ::sta_dynamic_loop_breaking "rw" \ +trace add variable ::sta_dynamic_loop_breaking {read write} \ sta::trace_dynamic_loop_breaking proc trace_dynamic_loop_breaking { name1 name2 op } { @@ -128,7 +128,7 @@ proc trace_dynamic_loop_breaking { name1 name2 op } { dynamic_loop_breaking set_dynamic_loop_breaking } -trace variable ::sta_input_port_default_clock "rw" \ +trace add variable ::sta_input_port_default_clock {read write} \ sta::trace_input_port_default_clock proc trace_input_port_default_clock { name1 name2 op } { @@ -136,7 +136,7 @@ proc trace_input_port_default_clock { name1 name2 op } { use_default_arrival_clock set_use_default_arrival_clock } -trace variable ::sta_propagate_all_clocks "rw" \ +trace add variable ::sta_propagate_all_clocks {read write} \ sta::trace_propagate_all_clocks proc trace_propagate_all_clocks { name1 name2 op } { @@ -144,7 +144,7 @@ proc trace_propagate_all_clocks { name1 name2 op } { propagate_all_clocks set_propagate_all_clocks } -trace variable ::sta_propagate_gated_clock_enable "rw" \ +trace add variable ::sta_propagate_gated_clock_enable {read write} \ sta::trace_propagate_gated_clock_enable proc trace_propagate_gated_clock_enable { name1 name2 op } { @@ -152,15 +152,15 @@ proc trace_propagate_gated_clock_enable { name1 name2 op } { propagate_gated_clock_enable set_propagate_gated_clock_enable } -trace variable ::sta_pocv_mode "rw" \ +trace add variable ::sta_pocv_mode {read write} \ sta::trace_pocv_mode proc trace_pocv_mode { name1 name2 op } { global sta_pocv_mode - if { $op == "r" } { + if { $op == "read" } { set sta_pocv_mode [pocv_mode] - } elseif { $op == "w" } { + } elseif { $op == "write" } { if { $sta_pocv_mode == "scalar" \ || $sta_pocv_mode == "normal" \ || $sta_pocv_mode == "skew_normal" } { @@ -171,15 +171,15 @@ proc trace_pocv_mode { name1 name2 op } { } } -trace variable ::sta_pocv_quantile "rw" \ +trace add variable ::sta_pocv_quantile {read write} \ sta::trace_pocv_quantile proc trace_pocv_quantile { name1 name2 op } { global sta_pocv_quantile - if { $op == "r" } { + if { $op == "read" } { set sta_pocv_quantile [pocv_quantile] - } elseif { $op == "w" } { + } elseif { $op == "write" } { if { [string is double $sta_pocv_quantile] \ && $sta_pocv_quantile >= 0.0 } { set_pocv_quantile $sta_pocv_quantile @@ -194,9 +194,9 @@ proc trace_pocv_quantile { name1 name2 op } { proc trace_boolean_var { op var_name get_proc set_proc } { upvar 1 $var_name var - if { $op == "r" } { + if { $op == "read" } { set var [$get_proc] - } elseif { $op == "w" } { + } elseif { $op == "write" } { if { $var == 0 } { $set_proc 0 } elseif { $var == 1 } { diff --git a/test/asap7_small.lib.gz b/test/asap7_small.lib.gz index 3c47419f..f0381ded 100644 Binary files a/test/asap7_small.lib.gz and b/test/asap7_small.lib.gz differ diff --git a/test/get_filter.ok b/test/get_filter.ok index 8bd8c18a..1f0402ec 100644 --- a/test/get_filter.ok +++ b/test/get_filter.ok @@ -1,24 +1,11 @@ [get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *] u1 -[get_clocks -filter is_virtual==0 *] -clk -[get_clocks -filter is_virtual==1 *] -vclk [get_clocks -filter is_virtual *] vclk -[get_clocks -filter is_virtual&&is_generated *] -[get_clocks -filter is_virtual&&is_generated==0 *] -vclk -[get_clocks -filter is_virtual||is_generated *] -vclk -[get_clocks -filter is_virtual==0||is_generated *] -clk -[get_lib_cells -filter is_buffer==1 *] +[get_lib_cells -filter is_buffer *] asap7_small/BUFx2_ASAP7_75t_R -[get_lib_cells -filter is_inverter==0 *] -asap7_small/AND2x2_ASAP7_75t_R -asap7_small/BUFx2_ASAP7_75t_R -asap7_small/DFFHQx4_ASAP7_75t_R +[get_lib_cells -filter is_inverter *] +asap7_small/INVx2_ASAP7_75t_R [get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*] A [get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*] @@ -54,9 +41,22 @@ in2 out [get_cells -filter {name ~= *r1*} *] Error: 2600 -filter parsing failed at '~= *r1*'. +direction == input && name =~ clk* clk1 clk2 clk3 +(direction == input) && (name =~ clk*)" clk1 clk2 clk3 +[get_clocks -filter is_virtual||is_generated *] +vclk +[get_clocks -filter is_virtual==0 *] +clk +[get_clocks -filter is_virtual==false *] +clk +[get_clocks -filter is_virtual==1 *] +vclk +[get_clocks -filter is_virtual==true *] +vclk +{direction == input} {name =~ clk*} {is_clock == 1} && && diff --git a/test/get_filter.tcl b/test/get_filter.tcl index d6009a89..b373e944 100644 --- a/test/get_filter.tcl +++ b/test/get_filter.tcl @@ -5,29 +5,16 @@ link_design top create_clock -name clk -period 500 {clk1 clk2 clk3} create_clock -name vclk -period 1000 -# Test filters for each SDC get_* command. puts {[get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]} report_object_full_names [get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *] -puts {[get_clocks -filter is_virtual==0 *]} -report_object_full_names [get_clocks -filter is_virtual==0 *] -puts {[get_clocks -filter is_virtual==1 *]} -report_object_full_names [get_clocks -filter is_virtual==1 *] puts {[get_clocks -filter is_virtual *]} report_object_full_names [get_clocks -filter is_virtual *] -puts {[get_clocks -filter is_virtual&&is_generated *]} -report_object_full_names [get_clocks -filter is_virtual&&is_generated *] -puts {[get_clocks -filter is_virtual&&is_generated==0 *]} -report_object_full_names [get_clocks -filter is_virtual&&is_generated==0 *] -puts {[get_clocks -filter is_virtual||is_generated *]} -report_object_full_names [get_clocks -filter is_virtual||is_generated *] -puts {[get_clocks -filter is_virtual==0||is_generated *]} -report_object_full_names [get_clocks -filter is_virtual==0||is_generated *] -puts {[get_lib_cells -filter is_buffer==1 *]} -report_object_full_names [get_lib_cells -filter is_buffer==1 *] -puts {[get_lib_cells -filter is_inverter==0 *]} -report_object_full_names [get_lib_cells -filter is_inverter==0 *] +puts {[get_lib_cells -filter is_buffer *]} +report_object_full_names [get_lib_cells -filter is_buffer *] +puts {[get_lib_cells -filter is_inverter *]} +report_object_full_names [get_lib_cells -filter is_inverter *] puts {[get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]} report_object_full_names [get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*] @@ -55,9 +42,32 @@ puts {[get_cells -filter {name ~= *r1*} *]} catch {get_cells -filter {name ~= *r1*} *} result puts $result -# AND pattern match expr +# AND expr +puts {direction == input && name =~ clk*} report_object_names [get_ports -filter "direction == input && name =~ clk*" *] # parens around sub-exprs +puts {(direction == input) && (name =~ clk*)"} report_object_names [get_ports -filter "(direction == input) && (name =~ clk*)" *] -sta::filter_expr_to_postfix "direction == input && name =~ clk* && is_clock" 1 +# OR expr +puts {[get_clocks -filter is_virtual||is_generated *]} +report_object_full_names [get_clocks -filter is_virtual||is_generated *] + + +# unary==0 / unary==false +puts {[get_clocks -filter is_virtual==0 *]} +report_object_full_names [get_clocks -filter is_virtual==0 *] +puts {[get_clocks -filter is_virtual==false *]} +report_object_full_names [get_clocks -filter is_virtual==false *] + +# unary==1 / unary==true +puts {[get_clocks -filter is_virtual==1 *]} +report_object_full_names [get_clocks -filter is_virtual==1 *] +puts {[get_clocks -filter is_virtual==true *]} +report_object_full_names [get_clocks -filter is_virtual==true *] + +# glob pattern with . (literal dot, no match symantics) +report_object_full_names [get_cells -filter {name =~ .1} *] + +puts [sta::filter_expr_to_postfix "direction == input && name =~ clk* && is_clock"] + diff --git a/test/get_lib_pins_of_objects.ok b/test/get_lib_pins_of_objects.ok index 8c8489b9..850bfc85 100644 --- a/test/get_lib_pins_of_objects.ok +++ b/test/get_lib_pins_of_objects.ok @@ -5,6 +5,7 @@ Y [get_lib_pins -of_objects [get_lib_cells *]] A A +A B CLK D @@ -13,3 +14,4 @@ IQN Q Y Y +Y diff --git a/test/get_noargs.ok b/test/get_noargs.ok index b952fdaa..4da70ba1 100644 --- a/test/get_noargs.ok +++ b/test/get_noargs.ok @@ -11,9 +11,11 @@ vclk asap7_small/AND2x2_ASAP7_75t_R asap7_small/BUFx2_ASAP7_75t_R asap7_small/DFFHQx4_ASAP7_75t_R +asap7_small/INVx2_ASAP7_75t_R [get_lib_pins] A A +A B CLK D @@ -22,6 +24,7 @@ IQN Q Y Y +Y [get_libs] asap7_small [get_nets] diff --git a/test/get_objrefs.ok b/test/get_objrefs.ok index 5430faff..08593630 100644 --- a/test/get_objrefs.ok +++ b/test/get_objrefs.ok @@ -9,9 +9,11 @@ vclk asap7_small/AND2x2_ASAP7_75t_R asap7_small/BUFx2_ASAP7_75t_R asap7_small/DFFHQx4_ASAP7_75t_R +asap7_small/INVx2_ASAP7_75t_R [get_lib_pins [get_lib_pins]] A A +A B CLK D @@ -20,6 +22,7 @@ IQN Q Y Y +Y [get_libs [get_libs]] asap7_small [get_nets [get_nets]] diff --git a/test/prima3.ok b/test/prima3.ok index a4ac1d9c..cd2c8cac 100644 --- a/test/prima3.ok +++ b/test/prima3.ok @@ -31,3 +31,55 @@ Path Type: max 228.48 slack (MET) +Library: asap7_small +Cell: BUFx2_ASAP7_75t_R +Arc sense: positive_unate +Arc type: combinational +A ^ -> Y ^ +P = 1.00 V = 0.70 T = 25.00 +------- input_net_transition = 59.28 +| total_output_net_capacitance = 13.54 +| 11.52 23.04 +v -------------------- +40.00 | 48.68 71.50 +80.00 | 56.23 79.10 +Table value = 56.33 +PVT scale factor = 1.00 +Delay = 56.33 + +------- input_net_transition = 59.28 +| total_output_net_capacitance = 13.54 +| 11.52 23.04 +v -------------------- +40.00 | 53.99 104.08 +80.00 | 54.58 104.40 +Table value = 63.04 +PVT scale factor = 1.00 +Slew = 63.04 + +............................................. + +A v -> Y v +P = 1.00 V = 0.70 T = 25.00 +------- input_net_transition = 52.93 +| total_output_net_capacitance = 12.09 +| 11.52 23.04 +v -------------------- +40.00 | 48.42 67.20 +80.00 | 57.92 76.86 +Table value = 52.43 +PVT scale factor = 1.00 +Delay = 52.43 + +------- input_net_transition = 52.93 +| total_output_net_capacitance = 12.09 +| 11.52 23.04 +v -------------------- +40.00 | 42.77 80.89 +80.00 | 43.84 81.48 +Table value = 45.00 +PVT scale factor = 1.00 +Slew = 45.00 + +............................................. + diff --git a/test/prima3.tcl b/test/prima3.tcl index b2e20eab..0b285c72 100644 --- a/test/prima3.tcl +++ b/test/prima3.tcl @@ -9,3 +9,4 @@ set_propagated_clock {clk1 clk2 clk3} read_spef reg1_asap7.spef sta::set_delay_calculator prima report_checks -fields {input_pins slew} -format full_clock +report_dcalc -from u1/A -to u1/Y diff --git a/test/regression.tcl b/test/regression.tcl index 8afefbf4..3afe8287 100755 --- a/test/regression.tcl +++ b/test/regression.tcl @@ -176,11 +176,10 @@ proc run_tests {} { run_test $test } } - write_failure_file } proc run_test { test } { - global result_dir diff_file errors diff_options + global result_dir diff_file errors diff_options failed_tests puts -nonewline $test flush stdout @@ -267,8 +266,6 @@ proc run_tests_parallel {} { vwait reg_parallel_job_done } } - # update results/failures and results/diffs - write_failure_file } } @@ -432,26 +429,21 @@ proc test_failed { test reason } { } lappend failed_tests $test incr errors($reason) + append_diff_file $test } -proc write_failure_file {} { - global failure_file failed_tests failed_tests_summery +proc append_diff_file { test } { + global failure_file global diff_file diff_options set fail_ch [open $failure_file "a"] - foreach test $failed_tests { - if { ![info exists failed_tests_summery($test)] } { - puts $fail_ch $test - - # Append diff to results/diffs - set log_file [test_log_file $test] - set ok_file [test_ok_file $test] - catch [concat exec diff $diff_options $ok_file $log_file >> $diff_file] - - set failed_tests_summery($test) 1 - } - } + puts $fail_ch $test close $fail_ch + + # Append diff to results/diffs + set log_file [test_log_file $test] + set ok_file [test_ok_file $test] + catch [concat exec diff $diff_options $ok_file $log_file >> $diff_file] } # Error messages can be found in "valgrind/memcheck/mc_errcontext.c". @@ -530,6 +522,10 @@ proc show_summary {} { global app_path app puts "------------------------------------------------------" + if { $valgrind_shared_lib_failure } { + puts "WARNING: valgrind failed because the executable is not statically linked." + } + puts "See $result_dir for log files" set test_count [llength $tests] if { [found_errors] } { if { $errors(error) != 0 } { @@ -556,10 +552,6 @@ proc show_summary {} { } else { puts "Passed $test_count" } - if { $valgrind_shared_lib_failure } { - puts "WARNING: valgrind failed because the executable is not statically linked." - } - puts "See $result_dir for log files" } proc found_errors {} { @@ -590,22 +582,27 @@ proc save_ok_main {} { } } else { foreach test $argv { - save_ok $test + if { [lsearch [group_tests "all"] $test] == -1 } { + puts "Error: test $test not found." + } else { + save_ok $test + } } } } +# hook for pvt/public sync. proc save_ok { test } { - if { [lsearch [group_tests "all"] $test] == -1 } { - puts "Error: test $test not found." + save_ok_file $test +} + +proc save_ok_file { test } { + set ok_file [test_ok_file $test] + set log_file [test_log_file $test] + if { ! [file exists $log_file] } { + puts "Error: log file $log_file not found." } else { - set ok_file [test_ok_file $test] - set log_file [test_log_file $test] - if { ! [file exists $log_file] } { - puts "Error: log file $log_file not found." - } else { - file copy -force $log_file $ok_file - } + file copy -force $log_file $ok_file } } diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index 94c6924a..9fea5ade 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -166,6 +166,7 @@ record_public_tests { report_json2 suppress_msg verilog_attribute + verilog_well_supplies verilog_specify verilog_write_escape verilog_unconnected_hpin diff --git a/test/verilog_well_supplies.ok b/test/verilog_well_supplies.ok new file mode 100644 index 00000000..41b72482 --- /dev/null +++ b/test/verilog_well_supplies.ok @@ -0,0 +1,26 @@ +module top (y, + a); + output y; + input a; + + + sky130_fd_sc_hd__buf_1 u1 (.A(a), + .X(y)); +endmodule +module top (y, + a); + output y; + input a; + + wire VGND; + wire VNB; + wire VPB; + wire VPWR; + + sky130_fd_sc_hd__buf_1 u1 (.VGND(VGND), + .VNB(VNB), + .VPB(VPB), + .VPWR(VPWR), + .A(a), + .X(y)); +endmodule diff --git a/test/verilog_well_supplies.tcl b/test/verilog_well_supplies.tcl new file mode 100644 index 00000000..b4028711 --- /dev/null +++ b/test/verilog_well_supplies.tcl @@ -0,0 +1,12 @@ +# Check that write_verilog excludes well pins along with power/ground pins. +source helpers.tcl +read_liberty ../examples/sky130hd_tt.lib.gz +read_verilog verilog_well_supplies.v +link_design top +set verilog_file [make_result_file "verilog_well_supplies.v"] +write_verilog $verilog_file +report_file $verilog_file + +set verilog_pwr_file [make_result_file "verilog_well_supplies_pwr.v"] +write_verilog -include_pwr_gnd $verilog_pwr_file +report_file $verilog_pwr_file diff --git a/test/verilog_well_supplies.v b/test/verilog_well_supplies.v new file mode 100644 index 00000000..6ae13580 --- /dev/null +++ b/test/verilog_well_supplies.v @@ -0,0 +1,17 @@ +module top ( + output y, + input a +); + supply1 VPWR; + supply0 VGND; + supply1 VPB; + supply0 VNB; + sky130_fd_sc_hd__buf_1 u1 ( + .X(y), + .A(a), + .VPWR(VPWR), + .VGND(VGND), + .VPB(VPB), + .VNB(VNB) + ); +endmodule diff --git a/util/ReportTcl.cc b/util/ReportTcl.cc index a418a53a..e782c23c 100644 --- a/util/ReportTcl.cc +++ b/util/ReportTcl.cc @@ -72,6 +72,11 @@ encapGetHandleProc(ClientData instanceData, static int encapBlockModeProc(ClientData instanceData, int mode); +static int +encapClose2Proc(ClientData instanceData, + Tcl_Interp *interp, + int flags); + #if TCL_MAJOR_VERSION < 9 static int encapCloseProc(ClientData instanceData, Tcl_Interp *interp); @@ -97,13 +102,13 @@ Tcl_ChannelType tcl_encap_type_stdout = { #if TCL_MAJOR_VERSION < 9 encapSeekProc, #else - nullptr, // close2Proc + nullptr, // seekProc unused #endif encapSetOptionProc, encapGetOptionProc, encapWatchProc, encapGetHandleProc, - nullptr, // close2Proc + encapClose2Proc, encapBlockModeProc, nullptr, // flushProc nullptr, // handlerProc @@ -290,17 +295,31 @@ encapBlockModeProc(ClientData, return 0; } +// Close channel implementing CloseProc() or Close2Proc() +static int +closeChannel(ReportTcl *report) +{ + report->logEnd(); + report->redirectFileEnd(); + report->redirectStringEnd(); + return 0; +} + +static int +encapClose2Proc(ClientData instanceData, + Tcl_Interp *, + int) +{ + return closeChannel(reinterpret_cast(instanceData)); +} + #if TCL_MAJOR_VERSION < 9 static int encapCloseProc(ClientData instanceData, Tcl_Interp *) { - ReportTcl *report = reinterpret_cast(instanceData); - report->logEnd(); - report->redirectFileEnd(); - report->redirectStringEnd(); - return 0; + return closeChannel(reinterpret_cast(instanceData)); } static int diff --git a/util/StringUtil.cc b/util/StringUtil.cc index 00a36ec4..c070cb6e 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -28,6 +28,7 @@ #include #include #include +#include namespace sta { @@ -56,12 +57,22 @@ std::pair stringFloat(const std::string &str) { float value; + // OsX 15.xx and earlier clang do not support std::from_chars. +#if defined(__cpp_lib_to_chars) && __cpp_lib_to_chars >= 201611L auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value); if (ec == std::errc() && *ptr == '\0') return {value, true}; else return {0.0, false}; +#else + char *ptr; + value = strtof(str.data(), &ptr); + if (!errno || *ptr != '\0') + return {0.0, false}; + else + return {value, true}; +#endif } void diff --git a/verilog/VerilogWriter.cc b/verilog/VerilogWriter.cc index 114051c8..49ecedf3 100644 --- a/verilog/VerilogWriter.cc +++ b/verilog/VerilogWriter.cc @@ -253,7 +253,7 @@ VerilogWriter::verilogPortDir(PortDirection *dir) return "inout"; else if (dir == PortDirection::ground()) return "inout"; - else if (dir == PortDirection::bias()) + else if (dir == PortDirection::well()) return "inout"; else if (dir == PortDirection::internal() || dir == PortDirection::unknown())