diff --git a/dcalc/DmpCeff.cc b/dcalc/DmpCeff.cc index 577bce5c..6828aa67 100644 --- a/dcalc/DmpCeff.cc +++ b/dcalc/DmpCeff.cc @@ -44,7 +44,6 @@ #include "TimingArc.hh" #include "TableModel.hh" #include "Liberty.hh" -#include "Network.hh" #include "Sdc.hh" #include "Parasitics.hh" #include "ArcDelayCalc.hh" @@ -78,11 +77,11 @@ exp2(double x); class DmpError : public Exception { public: - DmpError(const char *what); - virtual const char *what() const noexcept { return what_; } + DmpError(std::string_view what); + virtual const char *what() const noexcept { return what_.c_str(); } private: - const char *what_; + std::string what_; }; static double @@ -139,9 +138,9 @@ public: double c2, double rpi, double c1); - virtual void gateDelaySlew( // Return values. - double &delay, - double &slew) = 0; + virtual void gateDelaySlew(// Return values. + double &delay, + double &slew) = 0; virtual void loadDelaySlew(const Pin *load_pin, double elmore, // Return values. @@ -685,9 +684,9 @@ public: double c2, double rpi, double c1) override; - void gateDelaySlew( // Return values. - double &delay, - double &slew) override; + void gateDelaySlew(// Return values. + double &delay, + double &slew) override; void loadDelaySlew(const Pin *, double elmore, // Return values. @@ -726,15 +725,15 @@ DmpCap::init(const LibertyLibrary *drvr_library, double c1) { debugPrint(debug_, "dmp_ceff", 3, "Using DMP cap"); - DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi, - c1); + DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, + c2, rpi, c1); ceff_ = c1 + c2; } void -DmpCap::gateDelaySlew( // Return values. - double &delay, - double &slew) +DmpCap::gateDelaySlew(// Return values. + double &delay, + double &slew) { debugPrint(debug_, "dmp_ceff", 3, " ceff = {}", units_->capacitanceUnit()->asString(ceff_)); @@ -801,9 +800,9 @@ public: double c2, double rpi, double c1) override; - void gateDelaySlew( // Return values. - double &delay, - double &slew) override; + void gateDelaySlew(// Return values. + double &delay, + double &slew) override; void evalDmpEqns() override; double voCrossingUpperBound() override; @@ -868,8 +867,8 @@ DmpPi::init(const LibertyLibrary *drvr_library, double c1) { debugPrint(debug_, "dmp_ceff", 3, "Using DMP Pi"); - DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi, - c1); + DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, + c2, rpi, c1); // Find poles/zeros. z1_ = 1.0 / (rpi_ * c1_); @@ -893,9 +892,9 @@ DmpPi::init(const LibertyLibrary *drvr_library, } void -DmpPi::gateDelaySlew( // Return values. - double &delay, - double &slew) +DmpPi::gateDelaySlew(// Return values. + double &delay, + double &slew) { driver_valid_ = false; try { @@ -1127,9 +1126,9 @@ public: double c2, double rpi, double c1) override; - void gateDelaySlew( // Return values. - double &delay, - double &slew) override; + void gateDelaySlew(// Return values. + double &delay, + double &slew) override; private: void V0(double t, @@ -1176,8 +1175,8 @@ DmpZeroC2::init(const LibertyLibrary *drvr_library, double c1) { debugPrint(debug_, "dmp_ceff", 3, "Using DMP C2=0"); - DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi, - c1); + DmpAlg::init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, + c2, rpi, c1); ceff_ = c1; z1_ = 1.0 / (rpi_ * c1_); @@ -1275,8 +1274,10 @@ newtonRaphson(const int max_iter, all_under_x_tol = false; x[i] += p[i]; } - if (all_under_x_tol) + if (all_under_x_tol) { + eval(); return; + } } throw DmpError("Newton-Raphson max iterations exceeded"); } @@ -1557,8 +1558,8 @@ DmpCeffDelayCalc::setCeffAlgorithm(const LibertyLibrary *drvr_library, } else dmp_alg_ = dmp_cap_; - dmp_alg_->init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, c2, rpi, - c1); + dmp_alg_->init(drvr_library, drvr_cell, pvt, gate_model, rf, rd, in_slew, + c2, rpi, c1); debugPrint(debug_, "dmp_ceff", 3, " DMP in_slew = {} c2 = {} rpi = {} c1 = {} Rd = {} ({} alg)", units_->timeUnit()->asString(in_slew), @@ -1667,10 +1668,10 @@ DmpCeffDelayCalc::copyState(const StaState *sta) dmp_zero_c2_->copyState(sta); } -DmpError::DmpError(const char *what) : +DmpError::DmpError(std::string_view what) : what_(what) { - // printf("DmpError %s\n", what); + //sta::print(stdout, "DmpError {}\n", what); } // This saves about 2.5% in overall run time on designs with SPEF. diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index bcfb9cc0..f8984474 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -426,7 +426,8 @@ GraphDelayCalc::seedDrvrSlew(Vertex *drvr_vertex, if (from_port == nullptr) from_port = driveCellDefaultFromPort(drvr_cell, to_port); findInputDriverDelay(drvr_cell, drvr_pin, drvr_vertex, rf, - from_port, from_slews, to_port, scene, min_max); + from_port, from_slews, to_port, scene, min_max, + arc_delay_calc); } else seedNoDrvrCellSlew(drvr_vertex, drvr_pin, rf, drive, scene, min_max, @@ -601,7 +602,8 @@ GraphDelayCalc::findInputDriverDelay(const LibertyCell *drvr_cell, float *from_slews, const LibertyPort *to_port, const Scene *scene, - const MinMax *min_max) + const MinMax *min_max, + ArcDelayCalc *arc_delay_calc) { debugPrint(debug_, "delay_calc", 2, " driver cell {} {}", drvr_cell->name(), @@ -610,11 +612,11 @@ GraphDelayCalc::findInputDriverDelay(const LibertyCell *drvr_cell, for (TimingArc *arc : arc_set->arcs()) { if (arc->toEdge()->asRiseFall() == rf) { float from_slew = from_slews[arc->fromEdge()->index()]; - findInputArcDelay(drvr_pin, drvr_vertex, arc, from_slew, scene, min_max); + findInputArcDelay(drvr_pin, drvr_vertex, arc, from_slew, scene, min_max, + arc_delay_calc); } } } - arc_delay_calc_->finishDrvrPin(); } // Driving cell delay is the load dependent delay, which is the gate @@ -626,7 +628,8 @@ GraphDelayCalc::findInputArcDelay(const Pin *drvr_pin, const TimingArc *arc, float from_slew, const Scene *scene, - const MinMax *min_max) + const MinMax *min_max, + ArcDelayCalc *arc_delay_calc) { debugPrint(debug_, "delay_calc", 3, " {} {} -> {} {} ({})", arc->from()->name(), @@ -640,20 +643,20 @@ GraphDelayCalc::findInputArcDelay(const Pin *drvr_pin, const Parasitic *parasitic; float load_cap; - parasiticLoad(drvr_pin, drvr_rf, scene, min_max, nullptr, arc_delay_calc_, + parasiticLoad(drvr_pin, drvr_rf, scene, min_max, nullptr, arc_delay_calc, load_cap, parasitic); LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex); ArcDcalcResult intrinsic_result = - arc_delay_calc_->gateDelay(drvr_pin, arc, Slew(from_slew), 0.0, nullptr, - load_pin_index_map, scene, min_max); + arc_delay_calc->gateDelay(drvr_pin, arc, Slew(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, - parasitic, - load_pin_index_map, - scene, min_max); + ArcDcalcResult gate_result = arc_delay_calc->gateDelay(drvr_pin, arc, + Slew(from_slew), load_cap, + parasitic, + load_pin_index_map, + scene, min_max); const ArcDelay &gate_delay = gate_result.gateDelay(); const Slew &gate_slew = gate_result.drvrSlew(); @@ -666,7 +669,7 @@ GraphDelayCalc::findInputArcDelay(const Pin *drvr_pin, graph_->setSlew(drvr_vertex, drvr_rf, ap_index, gate_slew); annotateLoadDelays(drvr_vertex, drvr_rf, gate_result, load_pin_index_map, load_delay, false, scene, min_max); - arc_delay_calc_->finishDrvrPin(); + arc_delay_calc->finishDrvrPin(); } } @@ -1598,41 +1601,41 @@ GraphDelayCalc::findCheckEdgeDelays(Edge *edge, for (Scene *scene : scenes_) { for (const MinMax *min_max : MinMax::range()) { DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max); - if (!graph_->arcDelayAnnotated(edge, arc, ap_index)) { - const Slew &from_slew = checkEdgeClkSlew(from_vertex, from_rf, + if (!graph_->arcDelayAnnotated(edge, arc, ap_index)) { + const Slew &from_slew = checkEdgeClkSlew(from_vertex, from_rf, scene, min_max); const Slew to_slew = graph_->slew(to_vertex, to_rf, ap_index); - debugPrint(debug_, "delay_calc", 3, + debugPrint(debug_, "delay_calc", 3, " {} {} -> {} {} ({}) scene:{}/{}", - arc_set->from()->name(), - arc->fromEdge()->to_string(), - arc_set->to()->name(), - arc->toEdge()->to_string(), - arc_set->role()->to_string(), + arc_set->from()->name(), + arc->fromEdge()->to_string(), + arc_set->to()->name(), + arc->toEdge()->to_string(), + arc_set->role()->to_string(), scene->name(), min_max->to_string()); - debugPrint(debug_, "delay_calc", 3, - " from_slew = {} to_slew = {}", - delayAsString(from_slew, this), - delayAsString(to_slew, this)); - float related_out_cap = 0.0; - if (related_out_pin) + debugPrint(debug_, "delay_calc", 3, + " from_slew = {} to_slew = {}", + delayAsString(from_slew, this), + delayAsString(to_slew, this)); + float related_out_cap = 0.0; + if (related_out_pin) related_out_cap = loadCap(related_out_pin, to_rf,scene,min_max, arc_delay_calc); - ArcDelay check_delay = arc_delay_calc->checkDelay(to_pin, arc, from_slew, - to_slew, related_out_cap, + ArcDelay check_delay = arc_delay_calc->checkDelay(to_pin, arc, from_slew, + to_slew, related_out_cap, scene, min_max); - debugPrint(debug_, "delay_calc", 3, - " check_delay = {}", - delayAsString(check_delay, this)); - graph_->setArcDelay(edge, arc, ap_index, check_delay); - delay_changed = true; - arc_delay_calc_->finishDrvrPin(); - } + debugPrint(debug_, "delay_calc", 3, + " check_delay = {}", + delayAsString(check_delay, this)); + graph_->setArcDelay(edge, arc, ap_index, check_delay); + delay_changed = true; + arc_delay_calc_->finishDrvrPin(); + } + } } } } - } if (delay_changed && observer_) observer_->checkDelayChangedTo(to_vertex); diff --git a/include/sta/GraphDelayCalc.hh b/include/sta/GraphDelayCalc.hh index 60c12d43..85d198c6 100644 --- a/include/sta/GraphDelayCalc.hh +++ b/include/sta/GraphDelayCalc.hh @@ -174,7 +174,8 @@ protected: float *from_slews, const LibertyPort *to_port, const Scene *scene, - const MinMax *min_max); + const MinMax *min_max, + ArcDelayCalc *arc_delay_calc); LibertyPort *driveCellDefaultFromPort(const LibertyCell *cell, const LibertyPort *to_port); int findPortIndex(const LibertyCell *cell, @@ -184,7 +185,8 @@ protected: const TimingArc *arc, float from_slew, const Scene *scene, - const MinMax *min_max); + const MinMax *min_max, + ArcDelayCalc *arc_delay_calc); void findDriverDelays(Vertex *drvr_vertex, ArcDelayCalc *arc_delay_calc, LoadPinIndexMap &load_pin_index_map); diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index 926385b2..676d29af 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -108,19 +108,18 @@ GateTableModel::gateDelay(const Pvt *pvt, float &gate_delay, float &drvr_slew) const { - if (delay_models_) + if (delay_models_ && delay_models_->model()) gate_delay = findValue(pvt, delay_models_->model(), in_slew, load_cap, 0.0); else gate_delay = 0.0; - if (slew_models_) + if (slew_models_ && slew_models_->model()) { drvr_slew = findValue(pvt, slew_models_->model(), in_slew, load_cap, 0.0); + // Clip negative slews to zero. + if (drvr_slew < 0.0) + drvr_slew = 0.0; + } else drvr_slew = 0.0; - // TODO: Check for a better solution than clip negative delays and slews to zero. - //if (gate_delay < 0.0) - // gate_delay = 0.0; - if (drvr_slew < 0.0) - drvr_slew = 0.0; } void diff --git a/search/Bfs.cc b/search/Bfs.cc index 8324d54e..4cc7f769 100644 --- a/search/Bfs.cc +++ b/search/Bfs.cc @@ -195,7 +195,7 @@ BfsIterator::visitParallel(Level to_level, for (size_t k = 0; k < thread_count; k++) { // Last thread gets the left overs. size_t to = (k == thread_count - 1) ? vertex_count : from + chunk_size; - dispatch_queue_->dispatch([=, this](int) { + dispatch_queue_->dispatch([=, this](size_t) { for (size_t i = from; i < to; i++) { Vertex *vertex = level_vertices[i]; if (vertex) { diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index 97626ca5..89eab1ea 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.cc @@ -196,7 +196,7 @@ ClkSkews::findClkSkew(ConstClockSeq &clks, std::vector partial_skews(thread_count_); for (Vertex *src_vertex : graph_->regClkVertices()) { if (hasClkPaths(src_vertex)) { - dispatch_queue_->dispatch([this, src_vertex, &partial_skews](int i) { + dispatch_queue_->dispatch([this, src_vertex, &partial_skews](size_t i) { findClkSkewFrom(src_vertex, partial_skews[i]); }); } diff --git a/search/PathGroup.cc b/search/PathGroup.cc index 1d3e6cd0..e2e20a80 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -1025,7 +1025,7 @@ PathGroups::makeGroupPathEnds(VertexSet &endpoints, MakeEndpointPathEnds(visitor, Scene::sceneSet(scenes), min_max, this)); for (const auto endpoint : endpoints) { - dispatch_queue_->dispatch( [endpoint, &visitors](int i) + dispatch_queue_->dispatch( [endpoint, &visitors](size_t i) { visitors[i].visit(endpoint); } ); } dispatch_queue_->finishTasks(); diff --git a/search/Search.cc b/search/Search.cc index f1a9658c..246d5dd6 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -1102,9 +1102,7 @@ Search::findArrivalsSeed() //////////////////////////////////////////////////////////////// ArrivalVisitor::ArrivalVisitor(const StaState *sta) : - PathVisitor(nullptr, - false, - sta) + PathVisitor(nullptr, false, sta) { init0(); init(true, false, nullptr); @@ -1114,9 +1112,7 @@ ArrivalVisitor::ArrivalVisitor(const StaState *sta) : ArrivalVisitor::ArrivalVisitor(bool always_to_endpoints, SearchPred *pred, const StaState *sta) : - PathVisitor(pred, - true, - sta) + PathVisitor(pred, true, sta) { init0(); init(always_to_endpoints, false, pred); @@ -1997,11 +1993,13 @@ PathVisitor::visitFaninPaths(Vertex *to_vertex) VertexInEdgeIterator edge_iter(to_vertex, graph_); while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); - Vertex *from_vertex = edge->from(graph_); - const Pin *from_pin = from_vertex->pin(); - const Pin *to_pin = to_vertex->pin(); - if (!visitEdge(from_pin, from_vertex, edge, to_pin, to_vertex)) - break; + if (!edge->role()->isTimingCheck()) { + Vertex *from_vertex = edge->from(graph_); + const Pin *from_pin = from_vertex->pin(); + const Pin *to_pin = to_vertex->pin(); + if (!visitEdge(from_pin, from_vertex, edge, to_pin, to_vertex)) + break; + } } }