diff --git a/README.md b/README.md index 3d4ca48d..5bea8316 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ is also licensed for commerical applications by Parallax Software without the GPL's requirements. OpenSTA is open source, meaning the sources are published and can be compiled locally. -Derivatives works are supported as long as they adhere to the GPL license requirements. +Derivative works are supported as long as they adhere to the GPL license requirements. However, OpenSTA is not supported by a public community of developers as many other open source projects are. The copyright and develpment are exclusive to Parallax Software. OpenSTA does not accept external code contributions. diff --git a/dcalc/ArnoldiDelayCalc.cc b/dcalc/ArnoldiDelayCalc.cc index 3d1d6e3f..99ed4942 100644 --- a/dcalc/ArnoldiDelayCalc.cc +++ b/dcalc/ArnoldiDelayCalc.cc @@ -113,42 +113,40 @@ class ArnoldiDelayCalc : public RCDelayCalc public: ArnoldiDelayCalc(StaState *sta); virtual ~ArnoldiDelayCalc(); - virtual ArcDelayCalc *copy(); - virtual Parasitic *findParasitic(const Pin *drvr_pin, - const RiseFall *rf, - const DcalcAnalysisPt *dcalc_ap); - virtual ReducedParasiticType reducedParasiticType() const; - virtual void gateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - // Pass in load_cap or drvr_parasitic. - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - // Return values. - ArcDelay &gate_delay, - Slew &drvr_slew); - virtual void loadDelay(const Pin *load_pin, - // Return values. - ArcDelay &wire_delay, - Slew &load_slew); - virtual void inputPortDelay(const Pin *port_pin, - float in_slew, - const RiseFall *rf, - const Parasitic *parasitic, - const DcalcAnalysisPt *dcalc_ap); - virtual void reportGateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result); + ArcDelayCalc *copy() override; + Parasitic *findParasitic(const Pin *drvr_pin, + const RiseFall *rf, + const DcalcAnalysisPt *dcalc_ap) override; + ReducedParasiticType reducedParasiticType() const override; + void inputPortDelay(const Pin *port_pin, + float in_slew, + const RiseFall *rf, + const Parasitic *parasitic, + const DcalcAnalysisPt *dcalc_ap) override; + void gateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + // Return values. + ArcDelay &gate_delay, + Slew &drvr_slew) override; + void loadDelay(const Pin *load_pin, + // Return values. + ArcDelay &wire_delay, + Slew &load_slew) override; + string reportGateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits) override; void delay_work_set_thresholds(delay_work *D, double lo, double hi, @@ -455,7 +453,7 @@ ArnoldiDelayCalc::loadDelay(const Pin *load_pin, thresholdAdjust(load_pin, wire_delay, load_slew); } -void +string ArnoldiDelayCalc::reportGateDelay(const LibertyCell *, const TimingArc *, const Slew &, @@ -464,9 +462,9 @@ ArnoldiDelayCalc::reportGateDelay(const LibertyCell *, float, const Pvt *, const DcalcAnalysisPt *, - int, - string *) + int) { + return ""; } //////////////////////////////////////////////////////////////// diff --git a/dcalc/DelayCalc.i b/dcalc/DelayCalc.i index 561f4c1d..52711847 100644 --- a/dcalc/DelayCalc.i +++ b/dcalc/DelayCalc.i @@ -48,7 +48,7 @@ set_delay_calc_incremental_tolerance(float tol) sta::Sta::sta()->setIncrementalDelayTolerance(tol); } -TmpString * +string report_delay_calc_cmd(Edge *edge, TimingArc *arc, const Corner *corner, diff --git a/dcalc/DmpCeff.cc b/dcalc/DmpCeff.cc index 3ee23201..9a95417b 100644 --- a/dcalc/DmpCeff.cc +++ b/dcalc/DmpCeff.cc @@ -1666,7 +1666,7 @@ DmpCeffDelayCalc::ceff(const LibertyCell *drvr_cell, return load_cap; } -void +string DmpCeffDelayCalc::reportGateDelay(const LibertyCell *drvr_cell, const TimingArc *arc, const Slew &in_slew, @@ -1675,8 +1675,7 @@ DmpCeffDelayCalc::reportGateDelay(const LibertyCell *drvr_cell, float related_out_cap, const Pvt *pvt, const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result) + int digits) { ArcDelay gate_delay; Slew drvr_slew; @@ -1685,6 +1684,7 @@ DmpCeffDelayCalc::reportGateDelay(const LibertyCell *drvr_cell, gate_delay, drvr_slew); GateTimingModel *model = gateModel(arc, dcalc_ap); float c_eff = 0.0; + string result; if (drvr_parasitic_ && dmp_alg_) { c_eff = dmp_alg_->ceff(); const LibertyLibrary *drvr_library = drvr_cell->libertyLibrary(); @@ -1693,24 +1693,24 @@ DmpCeffDelayCalc::reportGateDelay(const LibertyCell *drvr_cell, const Unit *res_unit = units->resistanceUnit(); float c2, rpi, c1; parasitics_->piModel(drvr_parasitic_, c2, rpi, c1); - *result += "Pi model C2="; - *result += cap_unit->asString(c2, digits); - *result += " Rpi="; - *result += res_unit->asString(rpi, digits); - *result += " C1="; - *result += cap_unit->asString(c1, digits); - *result += ", Ceff="; - *result += cap_unit->asString(c_eff, digits); - *result += '\n'; + result += "Pi model C2="; + result += cap_unit->asString(c2, digits); + result += " Rpi="; + result += res_unit->asString(rpi, digits); + result += " C1="; + result += cap_unit->asString(c1, digits); + result += ", Ceff="; + result += cap_unit->asString(c_eff, digits); + result += '\n'; } else c_eff = load_cap; if (model) { float in_slew1 = delayAsFloat(in_slew); - model->reportGateDelay(drvr_cell, pvt, in_slew1, c_eff, - related_out_cap, pocv_enabled_, - digits, result); + result += model->reportGateDelay(drvr_cell, pvt, in_slew1, c_eff, + related_out_cap, pocv_enabled_, digits); } + return result; } static double diff --git a/dcalc/DmpCeff.hh b/dcalc/DmpCeff.hh index fed347c0..2844130b 100644 --- a/dcalc/DmpCeff.hh +++ b/dcalc/DmpCeff.hh @@ -58,16 +58,15 @@ public: float related_out_cap, const Pvt *pvt, const DcalcAnalysisPt *dcalc_ap); - virtual void reportGateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result); + virtual string reportGateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits); virtual void copyState(const StaState *sta); protected: diff --git a/dcalc/DmpDelayCalc.cc b/dcalc/DmpDelayCalc.cc index 64e6e1e0..4d5d4b14 100644 --- a/dcalc/DmpDelayCalc.cc +++ b/dcalc/DmpDelayCalc.cc @@ -33,21 +33,21 @@ class DmpCeffElmoreDelayCalc : public DmpCeffDelayCalc { public: DmpCeffElmoreDelayCalc(StaState *sta); - virtual ArcDelayCalc *copy(); - virtual void gateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - // Return values. - ArcDelay &gate_, - Slew &drvr_slew); - virtual void loadDelay(const Pin *load_pin, - ArcDelay &wire_delay, - Slew &load_slew); + ArcDelayCalc *copy() override; + void gateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + // Return values. + ArcDelay &gate_, + Slew &drvr_slew) override; + void loadDelay(const Pin *load_pin, + ArcDelay &wire_delay, + Slew &load_slew) override; }; ArcDelayCalc * diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index 709aca3d..748d6cbd 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -36,14 +36,14 @@ GraphDelayCalc::setObserver(DelayCalcObserver *observer) delete observer; } -string * +string GraphDelayCalc::reportDelayCalc(Edge *, TimingArc *, const Corner *, const MinMax *, int) { - return new string; + return ""; } float diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index 0da85599..300a4450 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -1629,7 +1629,7 @@ GraphDelayCalc1::ceff(Edge *edge, //////////////////////////////////////////////////////////////// -string * +string GraphDelayCalc1::reportDelayCalc(Edge *edge, TimingArc *arc, const Corner *corner, @@ -1643,7 +1643,7 @@ GraphDelayCalc1::reportDelayCalc(Edge *edge, Instance *inst = network_->instance(to_pin); LibertyCell *cell = network_->libertyCell(inst); TimingArcSet *arc_set = edge->timingArcSet(); - string *result = new string; + string result; DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max); const Pvt *pvt = sdc_->pvt(inst, dcalc_ap->constraintMinMax()); if (pvt == nullptr) @@ -1668,19 +1668,19 @@ GraphDelayCalc1::reportDelayCalc(Edge *edge, const Slew &to_slew = graph_->slew(to_vertex, to_rf, slew_index); bool from_ideal_clk = clk_network_->isIdealClock(from_vertex->pin()); const char *from_slew_annotation = from_ideal_clk ? " (ideal clock)" : nullptr; - arc_delay_calc_->reportCheckDelay(cell, arc, from_slew, from_slew_annotation, - to_slew, related_out_cap, pvt, dcalc_ap, - digits, result); + result = arc_delay_calc_->reportCheckDelay(cell, arc, from_slew, + from_slew_annotation, to_slew, + related_out_cap, pvt, dcalc_ap, + digits); } else { Parasitic *to_parasitic = arc_delay_calc_->findParasitic(to_pin, to_rf, dcalc_ap); const Slew &from_slew = edgeFromSlew(from_vertex, from_rf, edge, dcalc_ap); float load_cap = loadCap(to_pin, to_parasitic, to_rf, dcalc_ap); - arc_delay_calc_->reportGateDelay(cell, arc, - from_slew, load_cap, to_parasitic, - related_out_cap, pvt, dcalc_ap, - digits, result); + result = arc_delay_calc_->reportGateDelay(cell, arc, + from_slew, load_cap, to_parasitic, + related_out_cap, pvt, dcalc_ap, digits); } arc_delay_calc_->finishDrvrPin(); } diff --git a/dcalc/GraphDelayCalc1.hh b/dcalc/GraphDelayCalc1.hh index 471955f3..268da284 100644 --- a/dcalc/GraphDelayCalc1.hh +++ b/dcalc/GraphDelayCalc1.hh @@ -44,11 +44,11 @@ public: virtual void clear(); virtual void findDelays(Level level); virtual void findDelays(Vertex *drvr_vertex); - virtual string *reportDelayCalc(Edge *edge, - TimingArc *arc, - const Corner *corner, - const MinMax *min_max, - int digits); + virtual string reportDelayCalc(Edge *edge, + TimingArc *arc, + const Corner *corner, + const MinMax *min_max, + int digits); virtual float incrementalDelayTolerance(); virtual void setIncrementalDelayTolerance(float tol); virtual void setObserver(DelayCalcObserver *observer); diff --git a/dcalc/LumpedCapDelayCalc.cc b/dcalc/LumpedCapDelayCalc.cc index e9ddfad6..bb748a82 100644 --- a/dcalc/LumpedCapDelayCalc.cc +++ b/dcalc/LumpedCapDelayCalc.cc @@ -165,7 +165,7 @@ LumpedCapDelayCalc::gateDelay(const LibertyCell *drvr_cell, Slew drvr_slew1; float in_slew1 = delayAsFloat(in_slew); // NaNs cause seg faults during table lookup. - if (isnan(load_cap) || isnan(related_out_cap) || isnan(in_slew)) + if (isnan(load_cap) || isnan(related_out_cap) || isnan(delayAsFloat(in_slew))) report_->error(710, "gate delay input variable is NaN"); model->gateDelay(drvr_cell, pvt, in_slew1, load_cap, related_out_cap, pocv_enabled_, gate_delay1, drvr_slew1); @@ -238,7 +238,7 @@ LumpedCapDelayCalc::thresholdLibrary(const Pin *load_pin) } } -void +string LumpedCapDelayCalc::reportGateDelay(const LibertyCell *drvr_cell, const TimingArc *arc, const Slew &in_slew, @@ -247,15 +247,15 @@ LumpedCapDelayCalc::reportGateDelay(const LibertyCell *drvr_cell, float related_out_cap, const Pvt *pvt, const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result) + int digits) { GateTimingModel *model = gateModel(arc, dcalc_ap); if (model) { float in_slew1 = delayAsFloat(in_slew); - model->reportGateDelay(drvr_cell, pvt, in_slew1, load_cap, - related_out_cap, false, digits, result); + return model->reportGateDelay(drvr_cell, pvt, in_slew1, load_cap, + related_out_cap, false, digits); } + return ""; } void @@ -280,7 +280,7 @@ LumpedCapDelayCalc::checkDelay(const LibertyCell *cell, margin = delay_zero; } -void +string LumpedCapDelayCalc::reportCheckDelay(const LibertyCell *cell, const TimingArc *arc, const Slew &from_slew, @@ -289,16 +289,16 @@ LumpedCapDelayCalc::reportCheckDelay(const LibertyCell *cell, float related_out_cap, const Pvt *pvt, const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result) + int digits) { CheckTimingModel *model = checkModel(arc, dcalc_ap); if (model) { float from_slew1 = delayAsFloat(from_slew); float to_slew1 = delayAsFloat(to_slew); - model->reportCheckDelay(cell, pvt, from_slew1, from_slew_annotation, to_slew1, - related_out_cap, false, digits, result); + return model->reportCheckDelay(cell, pvt, from_slew1, from_slew_annotation, to_slew1, + related_out_cap, false, digits); } + return ""; } void diff --git a/dcalc/LumpedCapDelayCalc.hh b/dcalc/LumpedCapDelayCalc.hh index 20218c1d..0f502e33 100644 --- a/dcalc/LumpedCapDelayCalc.hh +++ b/dcalc/LumpedCapDelayCalc.hh @@ -26,70 +26,68 @@ class LumpedCapDelayCalc : public ArcDelayCalc { public: LumpedCapDelayCalc(StaState *sta); - virtual ArcDelayCalc *copy(); - virtual Parasitic *findParasitic(const Pin *drvr_pin, - const RiseFall *rf, - const DcalcAnalysisPt *dcalc_ap); - virtual ReducedParasiticType reducedParasiticType() const; - virtual void inputPortDelay(const Pin *port_pin, - float in_slew, - const RiseFall *rf, - const Parasitic *parasitic, - const DcalcAnalysisPt *dcalc_ap); - virtual void gateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - // Return values. - ArcDelay &gate_delay, - Slew &drvr_slew); - virtual void setMultiDrvrSlewFactor(float factor); - virtual void loadDelay(const Pin *load_pin, - // Return values. - ArcDelay &wire_delay, - Slew &load_slew); - virtual void checkDelay(const LibertyCell *cell, - const TimingArc *arc, - const Slew &from_slew, - const Slew &to_slew, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - // Return values. - ArcDelay &margin); - virtual float ceff(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap); - virtual void reportGateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result); - virtual void reportCheckDelay(const LibertyCell *cell, - const TimingArc *arc, - const Slew &from_slew, - const char *from_slew_annotation, - const Slew &to_slew, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result); - virtual void finishDrvrPin(); + ArcDelayCalc *copy() override; + Parasitic *findParasitic(const Pin *drvr_pin, + const RiseFall *rf, + const DcalcAnalysisPt *dcalc_ap) override; + ReducedParasiticType reducedParasiticType() const override; + void inputPortDelay(const Pin *port_pin, + float in_slew, + const RiseFall *rf, + const Parasitic *parasitic, + const DcalcAnalysisPt *dcalc_ap) override; + void gateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + // Return values. + ArcDelay &gate_delay, + Slew &drvr_slew) override; + void setMultiDrvrSlewFactor(float) override; + float ceff(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap) override; + void loadDelay(const Pin *load_pin, + // Return values. + ArcDelay &wire_delay, + Slew &load_slew) override; + void checkDelay(const LibertyCell *cell, + const TimingArc *arc, + const Slew &from_slew, + const Slew &to_slew, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + // Return values. + ArcDelay &margin) override; + string reportGateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits) override; + string reportCheckDelay(const LibertyCell *cell, + const TimingArc *arc, + const Slew &from_slew, + const char *from_slew_annotation, + const Slew &to_slew, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits) override; + void finishDrvrPin() override; protected: // Find the liberty library to use for logic/slew thresholds. diff --git a/dcalc/RCDelayCalc.hh b/dcalc/RCDelayCalc.hh index d2203bb0..fcffefbc 100644 --- a/dcalc/RCDelayCalc.hh +++ b/dcalc/RCDelayCalc.hh @@ -25,12 +25,12 @@ class RCDelayCalc : public LumpedCapDelayCalc { public: RCDelayCalc(StaState *sta); - virtual ArcDelayCalc *copy(); - virtual void inputPortDelay(const Pin *port_pin, - float in_slew, - const RiseFall *rf, - const Parasitic *parasitic, - const DcalcAnalysisPt *dcalc_ap); + ArcDelayCalc *copy() override; + void inputPortDelay(const Pin *port_pin, + float in_slew, + const RiseFall *rf, + const Parasitic *parasitic, + const DcalcAnalysisPt *dcalc_ap) override; protected: // Helper function for input ports driving dspf parasitic. diff --git a/dcalc/UnitDelayCalc.cc b/dcalc/UnitDelayCalc.cc index e0d44c77..20ddaf14 100644 --- a/dcalc/UnitDelayCalc.cc +++ b/dcalc/UnitDelayCalc.cc @@ -97,7 +97,7 @@ UnitDelayCalc::ceff(const LibertyCell *, return 0.0; } -void +string UnitDelayCalc::reportGateDelay(const LibertyCell *, const TimingArc *, const Slew &, @@ -106,11 +106,11 @@ UnitDelayCalc::reportGateDelay(const LibertyCell *, float, const Pvt *, const DcalcAnalysisPt *, - int, - string *result) + int) { - *result += "Delay = 1.0\n"; - *result += "Slew = 0.0\n"; + string result("Delay = 1.0\n"); + result += "Slew = 0.0\n"; + return result; } void @@ -127,7 +127,7 @@ UnitDelayCalc::checkDelay(const LibertyCell *, margin = units_->timeUnit()->scale(); } -void +string UnitDelayCalc::reportCheckDelay(const LibertyCell *, const TimingArc *, const Slew &, @@ -136,10 +136,9 @@ UnitDelayCalc::reportCheckDelay(const LibertyCell *, float, const Pvt *, const DcalcAnalysisPt *, - int, - string *result) + int) { - *result += "Check = 1.0\n"; + return "Check = 1.0\n"; } void diff --git a/dcalc/UnitDelayCalc.hh b/dcalc/UnitDelayCalc.hh index 84f327f8..1b7b22b9 100644 --- a/dcalc/UnitDelayCalc.hh +++ b/dcalc/UnitDelayCalc.hh @@ -25,70 +25,68 @@ class UnitDelayCalc : public ArcDelayCalc { public: UnitDelayCalc(StaState *sta); - virtual ArcDelayCalc *copy(); - virtual Parasitic *findParasitic(const Pin *drvr_pin, - const RiseFall *rf, - const DcalcAnalysisPt *dcalc_ap); - virtual ReducedParasiticType reducedParasiticType() const; - virtual void gateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - // Return values. - ArcDelay &gate_delay, - Slew &drvr_slew); - virtual void loadDelay(const Pin *load_pin, - // Return values. - ArcDelay &wire_delay, - Slew &load_slew); - virtual void setMultiDrvrSlewFactor(float) {} - virtual float ceff(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap); - virtual void inputPortDelay(const Pin *port_pin, - float in_slew, - const RiseFall *rf, - const Parasitic *parasitic, - const DcalcAnalysisPt *dcalc_ap); - virtual void checkDelay(const LibertyCell *cell, - const TimingArc *arc, - const Slew &from_slew, - const Slew &to_slew, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - // Return values. - ArcDelay &margin); - virtual void reportGateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result); - virtual void reportCheckDelay(const LibertyCell *cell, - const TimingArc *arc, - const Slew &from_slew, - const char *from_slew_annotation, - const Slew &to_slew, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result); - virtual void finishDrvrPin(); + ArcDelayCalc *copy() override; + Parasitic *findParasitic(const Pin *drvr_pin, + const RiseFall *rf, + const DcalcAnalysisPt *dcalc_ap) override; + ReducedParasiticType reducedParasiticType() const override; + void inputPortDelay(const Pin *port_pin, + float in_slew, + const RiseFall *rf, + const Parasitic *parasitic, + const DcalcAnalysisPt *dcalc_ap) override; + void gateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + // Return values. + ArcDelay &gate_delay, + Slew &drvr_slew) override; + void loadDelay(const Pin *load_pin, + // Return values. + ArcDelay &wire_delay, + Slew &load_slew) override; + void setMultiDrvrSlewFactor(float) override {} + float ceff(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap) override; + void checkDelay(const LibertyCell *cell, + const TimingArc *arc, + const Slew &from_slew, + const Slew &to_slew, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + // Return values. + ArcDelay &margin) override; + string reportGateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits) override; + string reportCheckDelay(const LibertyCell *cell, + const TimingArc *arc, + const Slew &from_slew, + const char *from_slew_annotation, + const Slew &to_slew, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits) override; + void finishDrvrPin() override; }; ArcDelayCalc * diff --git a/examples/example5.tcl b/examples/example5.tcl deleted file mode 100644 index 19b2931f..00000000 --- a/examples/example5.tcl +++ /dev/null @@ -1,15 +0,0 @@ -# 3 corners with +/- 10% derating example -define_corners ss tt ff -read_liberty -corner ss nangate45_slow.lib -read_liberty -corner tt nangate45_typ.lib -read_liberty -corner ff nangate45_fast.lib -read_verilog example1.v -link_design top -set_timing_derate -early 0.9 -set_timing_derate -late 1.1 -create_clock -name clk -period 10 {clk1 clk2 clk3} -set_input_delay -clock clk 0 {in1 in2} -# report all corners -report_checks -path_delay min_max -# report typical corner -report_checks -corner tt diff --git a/include/sta/ArcDelayCalc.hh b/include/sta/ArcDelayCalc.hh index 236744fa..7eb117ef 100644 --- a/include/sta/ArcDelayCalc.hh +++ b/include/sta/ArcDelayCalc.hh @@ -105,28 +105,26 @@ public: // Return values. ArcDelay &margin) = 0; // Report delay and slew calculation. - virtual void reportGateDelay(const LibertyCell *drvr_cell, - const TimingArc *arc, - const Slew &in_slew, - // Pass in load_cap or drvr_parasitic. - float load_cap, - const Parasitic *drvr_parasitic, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result) = 0; + virtual string reportGateDelay(const LibertyCell *drvr_cell, + const TimingArc *arc, + const Slew &in_slew, + // Pass in load_cap or drvr_parasitic. + float load_cap, + const Parasitic *drvr_parasitic, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits) = 0; // Report timing check delay calculation. - virtual void reportCheckDelay(const LibertyCell *cell, - const TimingArc *arc, - const Slew &from_slew, - const char *from_slew_annotation, - const Slew &to_slew, - float related_out_cap, - const Pvt *pvt, - const DcalcAnalysisPt *dcalc_ap, - int digits, - string *result) = 0; + virtual string reportCheckDelay(const LibertyCell *cell, + const TimingArc *arc, + const Slew &from_slew, + const char *from_slew_annotation, + const Slew &to_slew, + float related_out_cap, + const Pvt *pvt, + const DcalcAnalysisPt *dcalc_ap, + int digits) = 0; virtual void finishDrvrPin() = 0; protected: diff --git a/include/sta/GraphDelayCalc.hh b/include/sta/GraphDelayCalc.hh index 4b23baff..830eafad 100644 --- a/include/sta/GraphDelayCalc.hh +++ b/include/sta/GraphDelayCalc.hh @@ -56,11 +56,11 @@ public: // Reset to virgin state. virtual void clear() {} // Returned string is owned by the caller. - virtual string *reportDelayCalc(Edge *edge, - TimingArc *arc, - const Corner *corner, - const MinMax *min_max, - int digits); + virtual string reportDelayCalc(Edge *edge, + TimingArc *arc, + const Corner *corner, + const MinMax *min_max, + int digits); // Percentage (0.0:1.0) change in delay that causes downstream // delays to be recomputed during incremental delay calculation. virtual float incrementalDelayTolerance(); diff --git a/include/sta/InternalPower.hh b/include/sta/InternalPower.hh index ed6fcea6..c6610998 100644 --- a/include/sta/InternalPower.hh +++ b/include/sta/InternalPower.hh @@ -79,12 +79,11 @@ public: const Pvt *pvt, float in_slew, float load_cap) const; - void reportPower(const LibertyCell *cell, - const Pvt *pvt, - float in_slew, - float load_cap, - int digits, - string *result) const; + string reportPower(const LibertyCell *cell, + const Pvt *pvt, + float in_slew, + float load_cap, + int digits) const; protected: void findAxisValues(float in_slew, diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index db628187..9ba8f7dd 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -1106,7 +1106,7 @@ private: LibertyCell *cell_; }; -const char * +string portLibertyToSta(const char *port_name); } // namespace diff --git a/include/sta/LinearModel.hh b/include/sta/LinearModel.hh index 9fe23b1d..f06558e0 100644 --- a/include/sta/LinearModel.hh +++ b/include/sta/LinearModel.hh @@ -24,28 +24,27 @@ class GateLinearModel : public GateTimingModel { public: GateLinearModel(float intrinsic, float resistance); - // gate delay calculation - virtual void gateDelay(const LibertyCell *cell, - const Pvt *pvt, - float load_cap, float in_slew, - float related_out_cap, - bool pocv_enabled, - // return values - ArcDelay &gate_delay, - Slew &drvr_slew) const; - virtual void reportGateDelay(const LibertyCell *cell, - const Pvt *pvt, - float load_cap, - float in_slew, - float related_out_cap, - bool pocv_enabled, - int digits, - string *result) const; - virtual float driveResistance(const LibertyCell *cell, - const Pvt *pvt) const; + void gateDelay(const LibertyCell *cell, + const Pvt *pvt, + float in_slew, + float load_cap, + float related_out_cap, + bool pocv_enabled, + // Return values. + ArcDelay &gate_delay, + Slew &drvr_slew) const override; + string reportGateDelay(const LibertyCell *cell, + const Pvt *pvt, + float in_slew, + float load_cap, + float related_out_cap, + bool pocv_enabled, + int digits) const override; + float driveResistance(const LibertyCell *cell, + const Pvt *pvt) const override; protected: - virtual void setIsScaled(bool is_scaled); + void setIsScaled(bool is_scaled) override; float intrinsic_; float resistance_; @@ -55,26 +54,25 @@ class CheckLinearModel : public CheckTimingModel { public: explicit CheckLinearModel(float intrinsic); - // Timing check margin delay calculation. - virtual void checkDelay(const LibertyCell *cell, - const Pvt *pvt, - float from_slew, - float to_slew, - float related_out_cap, - bool pocv_enabled, - ArcDelay &margin) const; - virtual void reportCheckDelay(const LibertyCell *cell, - const Pvt *pvt, - float from_slew, - const char *from_slew_annotation, - float to_slew, - float related_out_cap, - bool pocv_enabled, - int digits, - string *result) const; + void checkDelay(const LibertyCell *cell, + const Pvt *pvt, + float from_slew, + float to_slew, + float related_out_cap, + bool pocv_enabled, + // Return values. + ArcDelay &margin) const override; + string reportCheckDelay(const LibertyCell *cell, + const Pvt *pvt, + float from_slew, + const char *from_slew_annotation, + float to_slew, + float related_out_cap, + bool pocv_enabled, + int digits) const override; protected: - virtual void setIsScaled(bool is_scaled); + void setIsScaled(bool is_scaled) override; float intrinsic_; }; diff --git a/include/sta/ParseBus.hh b/include/sta/ParseBus.hh index 09967524..66021a2a 100644 --- a/include/sta/ParseBus.hh +++ b/include/sta/ParseBus.hh @@ -16,8 +16,12 @@ #pragma once +#include + namespace sta { +using std::string; + // Return true if name is a bus. bool isBusName(const char *name, @@ -38,7 +42,8 @@ parseBusName(const char *name, const char brkt_right, char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &index); // Allow multiple different left/right bus brackets. void @@ -47,7 +52,8 @@ parseBusName(const char *name, const char *brkts_right, char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &index); // Parse a bus range, such as BUS[4:0]. @@ -59,7 +65,8 @@ parseBusRange(const char *name, const char brkt_right, char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &from, int &to); // brkt_lefts and brkt_rights are corresponding strings of legal @@ -70,12 +77,13 @@ parseBusRange(const char *name, const char *brkts_right, const char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &from, int &to); // Insert escapes before ch1 and ch2 in token. -const char * +string escapeChars(const char *token, const char ch1, const char ch2, diff --git a/include/sta/PatternMatch.hh b/include/sta/PatternMatch.hh index a6913a9d..0604d4f4 100644 --- a/include/sta/PatternMatch.hh +++ b/include/sta/PatternMatch.hh @@ -44,7 +44,10 @@ public: PatternMatch(const char *pattern); PatternMatch(const char *pattern, const PatternMatch *inherit_from); + PatternMatch(const string &pattern, + const PatternMatch *inherit_from); bool match(const char *str) const; + bool match(const string &str) const; bool matchNoCase(const char *str) const; const char *pattern() const { return pattern_; } bool isRegexp() const { return is_regexp_; } diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 36bd2ef4..0d63c334 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -934,11 +934,11 @@ public: PinSet findGroupPathPins(const char *group_path_name); // Find all required times after updateTiming(). void findRequireds(); - string *reportDelayCalc(Edge *edge, - TimingArc *arc, - const Corner *corner, - const MinMax *min_max, - int digits); + string reportDelayCalc(Edge *edge, + TimingArc *arc, + const Corner *corner, + const MinMax *min_max, + int digits); void writeSdc(const char *filename, // Map hierarchical pins and instances to leaf pins and instances. bool leaf, diff --git a/include/sta/TableModel.hh b/include/sta/TableModel.hh index 39d1c320..b3f805ac 100644 --- a/include/sta/TableModel.hh +++ b/include/sta/TableModel.hh @@ -58,25 +58,24 @@ public: ReceiverModelPtr receiver_model, OutputWaveforms *output_waveforms); virtual ~GateTableModel(); - virtual void gateDelay(const LibertyCell *cell, - const Pvt *pvt, - float in_slew, - float load_cap, - float related_out_cap, - bool pocv_enabled, - // Return values. - ArcDelay &gate_delay, - Slew &drvr_slew) const; - virtual void reportGateDelay(const LibertyCell *cell, - const Pvt *pvt, - float in_slew, - float load_cap, - float related_out_cap, - bool pocv_enabled, - int digits, - string *result) const; - virtual float driveResistance(const LibertyCell *cell, - const Pvt *pvt) const; + void gateDelay(const LibertyCell *cell, + const Pvt *pvt, + float in_slew, + float load_cap, + float related_out_cap, + bool pocv_enabled, + // Return values. + ArcDelay &gate_delay, + Slew &drvr_slew) const override; + string reportGateDelay(const LibertyCell *cell, + const Pvt *pvt, + float in_slew, + float load_cap, + float related_out_cap, + bool pocv_enabled, + int digits) const override; + float driveResistance(const LibertyCell *cell, + const Pvt *pvt) const override; const TableModel *delayModel() const { return delay_model_; } const TableModel *slewModel() const { return slew_model_; } @@ -92,7 +91,7 @@ protected: const Pvt *pvt, float &slew, float &cap) const; - virtual void setIsScaled(bool is_scaled); + void setIsScaled(bool is_scaled) override; float axisValue(TableAxisPtr axis, float load_cap, float in_slew, @@ -104,16 +103,15 @@ protected: float in_slew, float load_cap, float related_out_cap) const; - void reportTableLookup(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - const TableModel *model, - float in_slew, - float load_cap, - float related_out_cap, - int digits, - string *result) const; + string reportTableLookup(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + const TableModel *model, + float in_slew, + float load_cap, + float related_out_cap, + int digits) const; void findAxisValues(const TableModel *model, float in_slew, float load_cap, @@ -138,23 +136,22 @@ public: explicit CheckTableModel(TableModel *model, TableModel *sigma_models[EarlyLate::index_count]); virtual ~CheckTableModel(); - virtual void checkDelay(const LibertyCell *cell, - const Pvt *pvt, - float from_slew, - float to_slew, - float related_out_cap, - bool pocv_enabled, - // Return values. - ArcDelay &margin) const; - virtual void reportCheckDelay(const LibertyCell *cell, - const Pvt *pvt, - float from_slew, - const char *from_slew_annotation, - float to_slew, - float related_out_cap, - bool pocv_enabled, - int digits, - string *result) const; + void checkDelay(const LibertyCell *cell, + const Pvt *pvt, + float from_slew, + float to_slew, + float related_out_cap, + bool pocv_enabled, + // Return values. + ArcDelay &margin) const override; + string reportCheckDelay(const LibertyCell *cell, + const Pvt *pvt, + float from_slew, + const char *from_slew_annotation, + float to_slew, + float related_out_cap, + bool pocv_enabled, + int digits) const override; const TableModel *model() const { return model_; } // Check the axes before making the model. @@ -162,7 +159,7 @@ public: static bool checkAxes(const TablePtr table); protected: - virtual void setIsScaled(bool is_scaled); + void setIsScaled(bool is_scaled) override; float findValue(const LibertyLibrary *library, const LibertyCell *cell, const Pvt *pvt, @@ -181,17 +178,16 @@ protected: float load_cap, float in_slew, float related_out_cap) const; - void reportTableDelay(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - const TableModel *model, - float from_slew, - const char *from_slew_annotation, - float to_slew, - float related_out_cap, - int digits, - string *result) const; + string reportTableDelay(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + const TableModel *model, + float from_slew, + const char *from_slew_annotation, + float to_slew, + float related_out_cap, + int digits) const; static bool checkAxis(TableAxisPtr axis); TableModel *model_; @@ -227,29 +223,27 @@ public: float value1, float value2, float value3) const; - void reportValue(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits, - string *result) const; - void report(const Units *units, - Report *report) const; + string reportValue(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const; + string report(const Units *units, + Report *report) const; protected: float scaleFactor(const LibertyLibrary *library, const LibertyCell *cell, const Pvt *pvt) const; - void reportPvtScaleFactor(const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - int digits, - string *result) const; + string reportPvtScaleFactor(const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + int digits) const; TablePtr table_; TableTemplate *tbl_template_; @@ -285,17 +279,16 @@ public: float axis_value1, float axis_value2, float axis_value3) const; - virtual void reportValue(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits, - string *result) const = 0; + virtual string reportValue(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const = 0; virtual void report(const Units *units, Report *report) const = 0; }; @@ -305,26 +298,25 @@ class Table0 : public Table { public: Table0(float value); - virtual int order() const { return 0; } - virtual float value(size_t axis_index1, - size_t axis_index2, - size_t axis_index3) const; - virtual float findValue(float axis_value1, - float axis_value2, - float axis_value3) const; - virtual void reportValue(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits, - string *result) const; - virtual void report(const Units *units, - Report *report) const; + int order() const override { return 0; } + float value(size_t axis_index1, + size_t axis_index2, + size_t axis_index3) const override; + float findValue(float axis_value1, + float axis_value2, + float axis_value3) const override; + string reportValue(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const override; + void report(const Units *units, + Report *report) const override; using Table::findValue; private: @@ -341,35 +333,36 @@ public: virtual ~Table1(); Table1(Table1 &&table); Table1 &operator= (Table1 &&table); - virtual int order() const { return 1; } - virtual TableAxisPtr axis1() const { return axis1_; } - virtual float value(size_t axis_index1, - size_t axis_index2, - size_t axis_index3) const; + int order() const override { return 1; } + TableAxisPtr axis1() const override { return axis1_; } + float value(size_t axis_index1, + size_t axis_index2, + size_t axis_index3) const override; + float findValue(float value1, + float value2, + float value3) const override; + string reportValue(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const override; + void report(const Units *units, + Report *report) const override; + + // Table1 specific functions. float value(size_t index1) const; - float findValue(float axis_value1) const; void findValue(float axis_value1, // Return values. float &value, bool &extrapolated) const; + float findValue(float axis_value1) const; float findValueClip(float axis_value1, float clip_value) const; - virtual float findValue(float value1, - float value2, - float value3) const; - virtual void reportValue(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits, - string *result) const; - virtual void report(const Units *units, - Report *report) const; FloatSeq *values() const { return values_; } using Table::findValue; @@ -386,31 +379,33 @@ public: TableAxisPtr axis1, TableAxisPtr axis2); virtual ~Table2(); - virtual int order() const { return 2; } - TableAxisPtr axis1() const { return axis1_; } - TableAxisPtr axis2() const { return axis2_; } - virtual float value(size_t axis_index1, - size_t axis_index2, - size_t axis_index3) const; + int order() const override { return 2; } + TableAxisPtr axis1() const override { return axis1_; } + TableAxisPtr axis2() const override { return axis2_; } + float value(size_t axis_index1, + size_t axis_index2, + size_t axis_index3) const override; + float findValue(float value1, + float value2, + float value3) const override; + string reportValue(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const override; + void report(const Units *units, + Report *report) const override; + + // Table2 specific functions. float value(size_t axis_index1, size_t axis_index2) const; - virtual float findValue(float axis_value1, - float axis_value2, - float axis_value3) const; FloatTable *values3() { return values_; } - virtual void reportValue(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits, - string *result) const; - virtual void report(const Units *units, - Report *report) const; + using Table::findValue; protected: @@ -430,27 +425,28 @@ public: TableAxisPtr axis2, TableAxisPtr axis3); virtual ~Table3() {} - virtual int order() const { return 3; } - TableAxisPtr axis3() const { return axis3_; } - virtual float value(size_t axis_index1, - size_t axis_index2, - size_t axis_index3) const; - virtual float findValue(float axis_value1, - float axis_value2, - float axis_value3) const; - virtual void reportValue(const char *result_name, - const LibertyLibrary *library, - const LibertyCell *cell, - const Pvt *pvt, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits, - string *result) const; - virtual void report(const Units *units, - Report *report) const; + int order() const override { return 3; } + TableAxisPtr axis1() const override { return axis1_; } + TableAxisPtr axis2() const override { return axis2_; } + TableAxisPtr axis3() const override { return axis3_; } + float value(size_t axis_index1, + size_t axis_index2, + size_t axis_index3) const override; + float findValue(float value1, + float value2, + float value3) const override; + string reportValue(const char *result_name, + const LibertyLibrary *library, + const LibertyCell *cell, + const Pvt *pvt, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const override; + void report(const Units *units, + Report *report) const override; using Table::findValue; private: diff --git a/include/sta/TimingModel.hh b/include/sta/TimingModel.hh index 03278592..9fbe65a3 100644 --- a/include/sta/TimingModel.hh +++ b/include/sta/TimingModel.hh @@ -50,14 +50,13 @@ public: // Return values. ArcDelay &gate_delay, Slew &drvr_slew) const = 0; - virtual void reportGateDelay(const LibertyCell *cell, - const Pvt *pvt, - float in_slew, - float load_cap, - float related_out_cap, - bool pocv_enabled, - int digits, - string *result) const = 0; + virtual string reportGateDelay(const LibertyCell *cell, + const Pvt *pvt, + float in_slew, + float load_cap, + float related_out_cap, + bool pocv_enabled, + int digits) const = 0; virtual float driveResistance(const LibertyCell *cell, const Pvt *pvt) const = 0; }; @@ -75,15 +74,14 @@ public: bool pocv_enabled, // Return values. ArcDelay &margin) const = 0; - virtual void reportCheckDelay(const LibertyCell *cell, - const Pvt *pvt, - float from_slew, - const char *from_slew_annotation, - float to_slew, - float related_out_cap, - bool pocv_enabled, - int digits, - string *result) const = 0; + virtual string reportCheckDelay(const LibertyCell *cell, + const Pvt *pvt, + float from_slew, + const char *from_slew_annotation, + float to_slew, + float related_out_cap, + bool pocv_enabled, + int digits) const = 0; }; } // namespace diff --git a/include/sta/VerilogNamespace.hh b/include/sta/VerilogNamespace.hh index 302771fd..830e11ee 100644 --- a/include/sta/VerilogNamespace.hh +++ b/include/sta/VerilogNamespace.hh @@ -16,25 +16,29 @@ #pragma once +#include + namespace sta { -const char * +using std::string; + +string instanceVerilogName(const char *sta_name, const char escape); -const char * +string netVerilogName(const char *sta_name, const char escape); -const char * +string portVerilogName(const char *sta_name, const char escape); -const char * +string moduleVerilogToSta(const char *sta_name); -const char * +string instanceVerilogToSta(const char *sta_name); -const char * +string netVerilogToSta(const char *sta_name); -const char * +string portVerilogToSta(const char *sta_name); } // namespace diff --git a/liberty/InternalPower.cc b/liberty/InternalPower.cc index 51cb14bd..efa6afce 100644 --- a/liberty/InternalPower.cc +++ b/liberty/InternalPower.cc @@ -139,23 +139,23 @@ InternalPowerModel::power(const LibertyCell *cell, return 0.0; } -void +string InternalPowerModel::reportPower(const LibertyCell *cell, const Pvt *pvt, float in_slew, float load_cap, - int digits, - string *result) const + int digits) const { if (model_) { float axis_value1, axis_value2, axis_value3; findAxisValues(in_slew, load_cap, axis_value1, axis_value2, axis_value3); const LibertyLibrary *library = cell->libertyLibrary(); - model_->reportValue("Power", library, cell, pvt, - axis_value1, nullptr, axis_value2, axis_value3, - library->units()->powerUnit(), digits, result); + return model_->reportValue("Power", library, cell, pvt, + axis_value1, nullptr, axis_value2, axis_value3, + library->units()->powerUnit(), digits); } + return ""; } void diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 69e3780d..6929f8e2 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -125,6 +125,8 @@ LibertyLibrary::~LibertyLibrary() stringDelete(supply_name); } delete buffers_; + driver_waveform_map_.deleteContents(); + delete driver_waveform_default_; } LibertyCell * @@ -2518,23 +2520,20 @@ LibertyPort::setReceiverModel(ReceiverModelPtr receiver_model) receiver_model_ = receiver_model; } -const char * +string portLibertyToSta(const char *port_name) { constexpr char bus_brkt_left = '['; constexpr char bus_brkt_right = ']'; size_t name_length = strlen(port_name); - char *sta_name = makeTmpString(name_length * 2); - //char *sta_name = new char[name_length * 2];//makeTmpString(name_length * 2); - char *p = sta_name; + string sta_name; for (size_t i = 0; i < name_length; i++) { char ch = port_name[i]; if (ch == bus_brkt_left || ch == bus_brkt_right) - *p++ = '\\'; - *p++ = ch; + sta_name += '\\'; + sta_name += ch; } - *p++ = '\0'; return sta_name; } diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc index 15f1ac4f..764e0373 100644 --- a/liberty/LibertyBuilder.cc +++ b/liberty/LibertyBuilder.cc @@ -41,8 +41,8 @@ LibertyPort * LibertyBuilder::makePort(LibertyCell *cell, const char *port_name) { - const char *sta_name = portLibertyToSta(port_name); - LibertyPort *port = new LibertyPort(cell, sta_name, false, nullptr, + string sta_name = portLibertyToSta(port_name); + LibertyPort *port = new LibertyPort(cell, sta_name.c_str(), false, nullptr, -1, -1, false, nullptr); cell->addPort(port); return port; @@ -89,12 +89,13 @@ LibertyBuilder::makeBusPortBit(ConcreteLibrary *library, const char *bus_name, int bit_index) { - char *bit_name = stringPrintTmp("%s%c%d%c", - bus_name, - library->busBrktLeft(), - bit_index, - library->busBrktRight()); - LibertyPort *port = makePort(cell, bit_name, bit_index); + string bit_name; + stringPrint(bit_name, "%s%c%d%c", + bus_name, + library->busBrktLeft(), + bit_index, + library->busBrktRight()); + LibertyPort *port = makePort(cell, bit_name.c_str(), bit_index); bus_port->addPortBit(port); cell->addPortBit(port); } diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index e47fc6e0..ee578c67 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -523,38 +523,42 @@ LibertyReader::defineScalingFactorVisitors() if (scaleFactorTypeRiseFallSuffix(type)) { for (auto tr : RiseFall::range()) { const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall"; - const char *attr_name = stringPrintTmp("k_%s_%s_%s", - pvt_name, - type_name, - tr_name); - defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorSuffix); + string attr_name; + stringPrint(attr_name, "k_%s_%s_%s", + pvt_name, + type_name, + tr_name); + defineAttrVisitor(attr_name.c_str() ,&LibertyReader::visitScaleFactorSuffix); } } else if (scaleFactorTypeRiseFallPrefix(type)) { for (auto tr : RiseFall::range()) { const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall"; - const char *attr_name = stringPrintTmp("k_%s_%s_%s", - pvt_name, - tr_name, - type_name); - defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorPrefix); + string attr_name; + stringPrint(attr_name, "k_%s_%s_%s", + pvt_name, + tr_name, + type_name); + defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactorPrefix); } } else if (scaleFactorTypeLowHighSuffix(type)) { for (auto tr : RiseFall::range()) { const char *tr_name = (tr == RiseFall::rise()) ? "high":"low"; - const char *attr_name = stringPrintTmp("k_%s_%s_%s", - pvt_name, - tr_name, - type_name); - defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorHiLow); + string attr_name; + stringPrint(attr_name, "k_%s_%s_%s", + pvt_name, + tr_name, + type_name); + defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactorHiLow); } } else { - const char *attr_name = stringPrintTmp("k_%s_%s", - pvt_name, - type_name); - defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactor); + string attr_name; + stringPrint(attr_name, "k_%s_%s", + pvt_name, + type_name); + defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactor); } } } @@ -770,39 +774,32 @@ LibertyReader::parseUnits(LibertyAttr *attr, float &scale_var, Unit *unit) { - const char *unit_str = getAttrString(attr); - if (unit_str) { - unsigned unit_str_length = strlen(unit_str); - + string units = getAttrString(attr); + if (!units.empty()) { // Unit format is . // Find the multiplier digits. - char *mult_str = makeTmpString(unit_str_length); - const char *s = unit_str; - char *m = mult_str; - for (; *s; s++) { - char ch = *s; - if (isdigit(ch)) - *m++ = ch; - else - break; - } - *m = '\0'; - + string units = getAttrString(attr); + size_t mult_end = units.find_first_not_of("01234567890"); float mult = 1.0F; - if (*mult_str != '\0') { - if (stringEq(mult_str, "1")) + string scale_suffix; + if (mult_end != units.npos) { + string unit_mult = units.substr(0, mult_end); + scale_suffix = units.substr(mult_end); + if (unit_mult == "1") mult = 1.0F; - else if (stringEq(mult_str, "10")) + else if (unit_mult == "10") mult = 10.0F; - else if (stringEq(mult_str, "100")) + else if (unit_mult == "100") mult = 100.0F; else - libWarn(38, attr, "unknown unit multiplier %s.", mult_str); + libWarn(38, attr, "unknown unit multiplier %s.", unit_mult.c_str()); } + else + scale_suffix = units; float scale_mult = 1.0F; - if (*s && stringEqual(s + 1, unit_suffix)) { - char scale_char = tolower(*s); + if (scale_suffix.size() >= 2 && scale_suffix.substr(1) == unit_suffix) { + char scale_char = tolower(scale_suffix[0]); if (scale_char == 'k') scale_mult = 1E+3F; else if (scale_char == 'm') @@ -818,8 +815,8 @@ LibertyReader::parseUnits(LibertyAttr *attr, else libWarn(39, attr, "unknown unit scale %c.", scale_char); } - else if (!stringEqual(s, unit_suffix)) - libWarn(40, attr, "unknown unit suffix %s.", s + 1); + else if (!stringEqual(scale_suffix.c_str(), unit_suffix)) + libWarn(40, attr, "unknown unit suffix %s.", scale_suffix.c_str()); scale_var = scale_mult * mult; unit->setScale(scale_var); @@ -2526,7 +2523,7 @@ LibertyReader::endOutputCurrentRiseFall(LibertyGroup *group) cap_axis->findAxisIndex(waveform->cap(), cap_index, cap_exists); if (slew_exists && cap_exists) { size_t index = slew_index * cap_axis->size() + cap_index; - current_waveforms[index] = waveform->currents(); + current_waveforms[index] = waveform->stealCurrents(); (*ref_times)[slew_index] = waveform->referenceTime(); } else @@ -2539,6 +2536,7 @@ LibertyReader::endOutputCurrentRiseFall(LibertyGroup *group) current_waveforms, ref_time_tbl); timing_->setOutputWaveforms(rf_, output_current); + output_currents_.deleteContentsClear(); } void @@ -3191,8 +3189,8 @@ libertyReaderFindPort(LibertyCell *cell, char brkt_right = library->busBrktRight(); const char escape = '\\'; // Pins at top level with bus names have escaped brackets. - port_name = escapeChars(port_name, brkt_left, brkt_right, escape); - port = cell->findLibertyPort(port_name); + string escaped_port_name = escapeChars(port_name, brkt_left, brkt_right, escape); + port = cell->findLibertyPort(escaped_port_name.c_str()); } return port; } @@ -4770,11 +4768,12 @@ LibertyReader::parseFunc(const char *func, const char *attr_name, int line) { - const char *error_msg = stringPrintTmp("%s, line %d %s", - filename_, - line, - attr_name); - return parseFuncExpr(func, cell_, error_msg, report_); + string error_msg; + stringPrint(error_msg, "%s, line %d %s", + filename_, + line, + attr_name); + return parseFuncExpr(func, cell_, error_msg.c_str(), report_); } EarlyLateAll * @@ -5627,7 +5626,6 @@ PortNameBitIterator::PortNameBitIterator(LibertyCell *cell, port_(nullptr), bit_iterator_(nullptr), range_bus_port_(nullptr), - range_bus_name_(nullptr), range_name_next_(nullptr), size_(0) { @@ -5648,11 +5646,13 @@ PortNameBitIterator::init(const char *port_name) else { // Check for bus range. LibertyLibrary *library = visitor_->library(); + bool is_bus; + string bus_name; int from, to; - char *bus_name; - parseBusRange(port_name, library->busBrktLeft(), library->busBrktRight(), - '\\', bus_name, from, to); - if (bus_name) { + parseBusRange(port_name, library->busBrktLeft(), + library->busBrktRight(), '\\', + is_bus, bus_name, from, to); + if (is_bus) { port = visitor_->findPort(port_name); if (port) { if (port->isBus()) { @@ -5662,7 +5662,6 @@ PortNameBitIterator::init(const char *port_name) range_from_ = from; range_to_ = to; range_bit_ = from; - delete [] bus_name; } else visitor_->libWarn(156, line_, "port %s subscript out of range.", @@ -5671,7 +5670,7 @@ PortNameBitIterator::init(const char *port_name) else visitor_->libWarn(157, line_, "port range %s of non-bus port %s.", port_name, - bus_name); + bus_name.c_str()); } else { range_bus_name_ = bus_name; @@ -5689,7 +5688,6 @@ PortNameBitIterator::init(const char *port_name) PortNameBitIterator::~PortNameBitIterator() { - stringDelete(range_bus_name_); delete bit_iterator_; } @@ -5702,7 +5700,7 @@ PortNameBitIterator::hasNext() && ((range_from_ > range_to_) ? range_bit_ >= range_to_ : range_bit_ <= range_from_)) - || (range_bus_name_ + || (!range_bus_name_.empty() && range_name_next_); } @@ -5724,7 +5722,7 @@ PortNameBitIterator::next() range_bit_++; return next; } - else if (range_bus_name_) { + else if (!range_bus_name_.empty()) { LibertyPort *next = range_name_next_; findRangeBusNameNext(); return next; @@ -5740,12 +5738,13 @@ PortNameBitIterator::findRangeBusNameNext() ? range_bit_ >= range_to_ : range_bit_ <= range_to_) { LibertyLibrary *library = visitor_->library(); - const char *bus_bit_name = stringPrintTmp("%s%c%d%c", - range_bus_name_, - library->busBrktLeft(), - range_bit_, - library->busBrktRight()); - range_name_next_ = visitor_->findPort(bus_bit_name); + string bus_bit_name; + stringPrint(bus_bit_name, "%s%c%d%c", + range_bus_name_.c_str(), + library->busBrktLeft(), + range_bit_, + library->busBrktRight()); + range_name_next_ = visitor_->findPort(bus_bit_name.c_str()); if (range_name_next_) { if (range_from_ > range_to_) range_bit_--; @@ -5753,7 +5752,7 @@ PortNameBitIterator::findRangeBusNameNext() range_bit_++; } else - visitor_->libWarn(159, line_, "port %s not found.", bus_bit_name); + visitor_->libWarn(159, line_, "port %s not found.", bus_bit_name.c_str()); } else range_name_next_ = nullptr; @@ -5777,4 +5776,12 @@ OutputWaveform::~OutputWaveform() delete currents_; } +Table1 * +OutputWaveform::stealCurrents() +{ + Table1 *currents = currents_; + currents_ = nullptr; + return currents; +} + } // namespace diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index 15f3af0a..4a5cf678 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -861,7 +861,7 @@ protected: LibertyPort *port_; LibertyPortMemberIterator *bit_iterator_; LibertyPort *range_bus_port_; - const char *range_bus_name_; + string range_bus_name_; LibertyPort *range_name_next_; int range_from_; int range_to_; @@ -880,8 +880,9 @@ public: float slew() const { return slew_; } float cap() const { return cap_; } Table1 *currents() const { return currents_; } - float referenceTime() const { return reference_time_; } - + Table1 *stealCurrents(); + float referenceTime() { return reference_time_; } + private: float slew_; float cap_; diff --git a/liberty/LinearModel.cc b/liberty/LinearModel.cc index 6ba66ecd..6baa5671 100644 --- a/liberty/LinearModel.cc +++ b/liberty/LinearModel.cc @@ -43,30 +43,30 @@ GateLinearModel::gateDelay(const LibertyCell *, drvr_slew = 0.0; } -void +string GateLinearModel::reportGateDelay(const LibertyCell *cell, const Pvt *, float, float load_cap, float, bool, - int digits, - string *result) const + int digits) const { const LibertyLibrary *library = cell->libertyLibrary(); const Units *units = library->units(); const Unit *time_unit = units->timeUnit(); const Unit *res_unit = units->resistanceUnit(); const Unit *cap_unit = units->capacitanceUnit(); - *result += "Delay = "; - *result += time_unit->asString(intrinsic_, digits); - *result += " + "; - *result += res_unit->asString(resistance_, digits); - *result += " * "; - *result += cap_unit->asString(load_cap, digits); - *result += " = "; + string result = "Delay = "; + result += time_unit->asString(intrinsic_, digits); + result += " + "; + result += res_unit->asString(resistance_, digits); + result += " * "; + result += cap_unit->asString(load_cap, digits); + result += " = "; float delay = intrinsic_ + resistance_ * load_cap; - *result += time_unit->asString(delay, digits); + result += time_unit->asString(delay, digits); + return result; } float @@ -98,7 +98,7 @@ CheckLinearModel::checkDelay(const LibertyCell *, margin = intrinsic_; } -void +string CheckLinearModel::reportCheckDelay(const LibertyCell *cell, const Pvt *, float, @@ -106,14 +106,14 @@ CheckLinearModel::reportCheckDelay(const LibertyCell *cell, float, float, bool, - int digits, - string *result) const + int digits) const { const LibertyLibrary *library = cell->libertyLibrary(); const Units *units = library->units(); const Unit *time_unit = units->timeUnit(); - *result += "Check = "; - *result += time_unit->asString(intrinsic_, digits); + string result = "Check = "; + result += time_unit->asString(intrinsic_, digits); + return result; } void diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index 8bb00889..7e2be728 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -33,13 +33,12 @@ using std::make_shared; static void deleteSigmaModels(TableModel *models[EarlyLate::index_count]); -static void +static string reportPvt(const LibertyLibrary *library, const Pvt *pvt, - int digits, - string *result); + int digits); static void -appendSpaces(string *result, +appendSpaces(string &result, int count); GateTableModel::GateTableModel(TableModel *delay_model, @@ -136,46 +135,46 @@ GateTableModel::gateDelay(const LibertyCell *cell, drvr_slew = makeDelay(slew, sigma_early, sigma_late); } -void +string GateTableModel::reportGateDelay(const LibertyCell *cell, const Pvt *pvt, float in_slew, float load_cap, float related_out_cap, bool pocv_enabled, - int digits, - string *result) const + int digits) const { const LibertyLibrary *library = cell->libertyLibrary(); - reportPvt(library, pvt, digits, result); - reportTableLookup("Delay", library, cell, pvt, delay_model_, in_slew, - load_cap, related_out_cap, digits, result); + string result = reportPvt(library, pvt, digits); + result += reportTableLookup("Delay", library, cell, pvt, delay_model_, in_slew, + load_cap, related_out_cap, digits); if (pocv_enabled && delay_sigma_models_[EarlyLate::earlyIndex()]) - reportTableLookup("Delay sigma(early)", library, cell, pvt, - delay_sigma_models_[EarlyLate::earlyIndex()], - in_slew, load_cap, related_out_cap, digits, result); + result += reportTableLookup("Delay sigma(early)", library, cell, pvt, + delay_sigma_models_[EarlyLate::earlyIndex()], + in_slew, load_cap, related_out_cap, digits); if (pocv_enabled && delay_sigma_models_[EarlyLate::lateIndex()]) - reportTableLookup("Delay sigma(late)", library, cell, pvt, - delay_sigma_models_[EarlyLate::lateIndex()], - in_slew, load_cap, related_out_cap, digits, result); - *result += '\n'; - reportTableLookup("Slew", library, cell, pvt, slew_model_, in_slew, - load_cap, related_out_cap, digits, result); + result += reportTableLookup("Delay sigma(late)", library, cell, pvt, + delay_sigma_models_[EarlyLate::lateIndex()], + in_slew, load_cap, related_out_cap, digits); + result += '\n'; + result += reportTableLookup("Slew", library, cell, pvt, slew_model_, in_slew, + load_cap, related_out_cap, digits); if (pocv_enabled && slew_sigma_models_[EarlyLate::earlyIndex()]) - reportTableLookup("Slew sigma(early)", library, cell, pvt, + result += reportTableLookup("Slew sigma(early)", library, cell, pvt, slew_sigma_models_[EarlyLate::earlyIndex()], - in_slew, load_cap, related_out_cap, digits, result); + in_slew, load_cap, related_out_cap, digits); if (pocv_enabled && slew_sigma_models_[EarlyLate::lateIndex()]) - reportTableLookup("Slew sigma(late)", library, cell, pvt, + result += reportTableLookup("Slew sigma(late)", library, cell, pvt, slew_sigma_models_[EarlyLate::lateIndex()], - in_slew, load_cap, related_out_cap, digits, result); + in_slew, load_cap, related_out_cap, digits); float drvr_slew = findValue(library, cell, pvt, slew_model_, in_slew, load_cap, related_out_cap); if (drvr_slew < 0.0) - *result += "Negative slew clipped to 0.0\n"; + result += "Negative slew clipped to 0.0\n"; + return result; } -void +string GateTableModel::reportTableLookup(const char *result_name, const LibertyLibrary *library, const LibertyCell *cell, @@ -184,17 +183,17 @@ GateTableModel::reportTableLookup(const char *result_name, float in_slew, float load_cap, float related_out_cap, - int digits, - string *result) const + int digits) const { if (model) { float axis_value1, axis_value2, axis_value3; findAxisValues(model, in_slew, load_cap, related_out_cap, axis_value1, axis_value2, axis_value3); - model->reportValue(result_name, library, cell, pvt, - axis_value1, nullptr, axis_value2, axis_value3, - library->units()->timeUnit(), digits, result); + return model->reportValue(result_name, library, cell, pvt, + axis_value1, nullptr, axis_value2, axis_value3, + library->units()->timeUnit(), digits); } + return ""; } float @@ -470,7 +469,7 @@ CheckTableModel::findValue(const LibertyLibrary *library, return 0.0; } -void +string CheckTableModel::reportCheckDelay(const LibertyCell *cell, const Pvt *pvt, float from_slew, @@ -478,26 +477,26 @@ CheckTableModel::reportCheckDelay(const LibertyCell *cell, float to_slew, float related_out_cap, bool pocv_enabled, - int digits, - string *result) const + int digits) const { const LibertyLibrary *library = cell->libertyLibrary(); - reportTableDelay("Check", library, cell, pvt, model_, - from_slew, from_slew_annotation, to_slew, - related_out_cap, digits, result); + string result = reportTableDelay("Check", library, cell, pvt, model_, + from_slew, from_slew_annotation, to_slew, + related_out_cap, digits); if (pocv_enabled && sigma_models_[EarlyLate::earlyIndex()]) - reportTableDelay("Check sigma early", library, cell, pvt, - sigma_models_[EarlyLate::earlyIndex()], - from_slew, from_slew_annotation, to_slew, - related_out_cap, digits, result); + result += reportTableDelay("Check sigma early", library, cell, pvt, + sigma_models_[EarlyLate::earlyIndex()], + from_slew, from_slew_annotation, to_slew, + related_out_cap, digits); if (pocv_enabled && sigma_models_[EarlyLate::lateIndex()]) - reportTableDelay("Check sigma late", library, cell, pvt, - sigma_models_[EarlyLate::lateIndex()], - from_slew, from_slew_annotation, to_slew, - related_out_cap, digits, result); + result += reportTableDelay("Check sigma late", library, cell, pvt, + sigma_models_[EarlyLate::lateIndex()], + from_slew, from_slew_annotation, to_slew, + related_out_cap, digits); + return result; } -void +string CheckTableModel::reportTableDelay(const char *result_name, const LibertyLibrary *library, const LibertyCell *cell, @@ -507,18 +506,19 @@ CheckTableModel::reportTableDelay(const char *result_name, const char *from_slew_annotation, float to_slew, float related_out_cap, - int digits, - string *result) const + int digits) const { if (model) { float axis_value1, axis_value2, axis_value3; findAxisValues(from_slew, to_slew, related_out_cap, axis_value1, axis_value2, axis_value3); - reportPvt(library, pvt, digits, result); - model_->reportValue(result_name, library, cell, pvt, - axis_value1, from_slew_annotation, axis_value2, - axis_value3, library->units()->timeUnit(), digits, result); + string result = reportPvt(library, pvt, digits); + result += model_->reportValue(result_name, library, cell, pvt, + axis_value1, from_slew_annotation, axis_value2, + axis_value3, library->units()->timeUnit(), digits); + return result; } + return ""; } void @@ -690,7 +690,7 @@ TableModel::scaleFactor(const LibertyLibrary *library, rf_index_, cell, pvt); } -void +string TableModel::reportValue(const char *result_name, const LibertyLibrary *library, const LibertyCell *cell, @@ -700,55 +700,55 @@ TableModel::reportValue(const char *result_name, float value2, float value3, const Unit *table_unit, - int digits, - string *result) const + int digits) const { - table_->reportValue("Table value", library, cell, pvt, value1, - comment1, value2, value3, table_unit, digits, result); + string result = table_->reportValue("Table value", library, cell, pvt, value1, + comment1, value2, value3, table_unit, digits); - reportPvtScaleFactor(library, cell, pvt, digits, result); + result += reportPvtScaleFactor(library, cell, pvt, digits); - *result += result_name; - *result += " = "; - *result += table_unit->asString(findValue(library, cell, pvt, + result += result_name; + result += " = "; + result += table_unit->asString(findValue(library, cell, pvt, value1, value2, value3), digits); - *result += '\n'; + result += '\n'; + return result; } -static void +static string reportPvt(const LibertyLibrary *library, const Pvt *pvt, - int digits, - string *result) + int digits) { if (pvt == nullptr) pvt = library->defaultOperatingConditions(); if (pvt) { - string pvt_str; - stringPrint(pvt_str, "P = %.*f V = %.*f T = %.*f\n", + string result; + stringPrint(result, "P = %.*f V = %.*f T = %.*f\n", digits, pvt->process(), digits, pvt->voltage(), digits, pvt->temperature()); - *result += pvt_str; + return result; } + return ""; } -void +string TableModel::reportPvtScaleFactor(const LibertyLibrary *library, const LibertyCell *cell, const Pvt *pvt, - int digits, - string *result) const + int digits) const { if (pvt == nullptr) pvt = library->defaultOperatingConditions(); if (pvt) { - string scale_str; - stringPrint(scale_str, "PVT scale factor = %.*f\n", + string result; + stringPrint(result, "PVT scale factor = %.*f\n", digits, scaleFactor(library, cell, pvt)); - *result += scale_str; + return result; } + return ""; } //////////////////////////////////////////////////////////////// @@ -775,7 +775,7 @@ Table0::findValue(float, return value_; } -void +string Table0::reportValue(const char *result_name, const LibertyLibrary *, const LibertyCell *, @@ -785,15 +785,15 @@ Table0::reportValue(const char *result_name, float value2, float value3, const Unit *table_unit, - int digits, - string *result) const + int digits) const { - *result += result_name; - *result += " constant = "; - *result += table_unit->asString(findValue(value1, value2, value3), digits); + string result = result_name; + result += " constant = "; + result += table_unit->asString(findValue(value1, value2, value3), digits); if (comment1) - *result += comment1; - *result += '\n'; + result += comment1; + result += '\n'; + return result; } void @@ -913,7 +913,7 @@ Table1::findValue(float axis_value1, } } -void +string Table1::reportValue(const char *result_name, const LibertyLibrary *library, const LibertyCell *, @@ -923,42 +923,41 @@ Table1::reportValue(const char *result_name, const float value2, float value3, const Unit *table_unit, - int digits, - string *result) const + int digits) const { const Units *units = library->units(); const Unit *unit1 = axis1_->unit(units); - *result += "Table is indexed by\n"; - *result += " "; - *result += axis1_->variableString(); - *result += " = "; - *result += unit1->asString(value1, digits); + string result = "Table is indexed by\n "; + result += axis1_->variableString(); + result += " = "; + result += unit1->asString(value1, digits); if (comment1) - *result += comment1; - *result += '\n'; + result += comment1; + result += '\n'; if (axis1_->size() != 1) { size_t index1 = axis1_->findAxisIndex(value1); - *result += " "; - *result += unit1->asString(axis1_->axisValue(index1), digits); - *result += " "; - *result += unit1->asString(axis1_->axisValue(index1 + 1), digits); - *result += '\n'; + result += " "; + result += unit1->asString(axis1_->axisValue(index1), digits); + result += " "; + result += unit1->asString(axis1_->axisValue(index1 + 1), digits); + result += '\n'; - *result += " --------------------\n"; + result += " --------------------\n"; - *result += "| "; - *result += table_unit->asString(value(index1), digits); - *result += " "; - *result += table_unit->asString(value(index1 + 1), + result += "| "; + result += table_unit->asString(value(index1), digits); + result += " "; + result += table_unit->asString(value(index1 + 1), digits); - *result += '\n'; + result += '\n'; } - *result += result_name; - *result += " = "; - *result += table_unit->asString(findValue(value1, value2, value3), digits); - *result += '\n'; + result += result_name; + result += " = "; + result += table_unit->asString(findValue(value1, value2, value3), digits); + result += '\n'; + return result; } void @@ -1081,7 +1080,7 @@ Table2::findValue(float axis_value1, } } -void +string Table2::reportValue(const char *result_name, const LibertyLibrary *library, const LibertyCell *, @@ -1091,62 +1090,62 @@ Table2::reportValue(const char *result_name, float value2, float value3, const Unit *table_unit, - int digits, - string *result) const + int digits) const { const Units *units = library->units(); const Unit *unit1 = axis1_->unit(units); const Unit *unit2 = axis2_->unit(units); - *result += "------- "; - *result += axis1_->variableString(), - *result += " = "; - *result += unit1->asString(value1, digits); + string result = "------- "; + result += axis1_->variableString(), + result += " = "; + result += unit1->asString(value1, digits); if (comment1) - *result += comment1; - *result += '\n'; + result += comment1; + result += '\n'; - *result += "| "; - *result += axis2_->variableString(); - *result += " = "; - *result += unit2->asString(value2, digits); - *result += '\n'; + result += "| "; + result += axis2_->variableString(); + result += " = "; + result += unit2->asString(value2, digits); + result += '\n'; size_t index1 = axis1_->findAxisIndex(value1); size_t index2 = axis2_->findAxisIndex(value2); - *result += "| "; - *result += unit2->asString(axis2_->axisValue(index2), digits); + result += "| "; + result += unit2->asString(axis2_->axisValue(index2), digits); if (axis2_->size() != 1) { - *result += " "; - *result += unit2->asString(axis2_->axisValue(index2 + 1), digits); + result += " "; + result += unit2->asString(axis2_->axisValue(index2 + 1), digits); } - *result += '\n'; + result += '\n'; - *result += "v --------------------\n"; - *result += unit1->asString(axis1_->axisValue(index1), digits); - *result += " | "; + result += "v --------------------\n"; + result += unit1->asString(axis1_->axisValue(index1), digits); + result += " | "; - *result += table_unit->asString(value(index1, index2), digits); + result += table_unit->asString(value(index1, index2), digits); if (axis2_->size() != 1) { - *result += " "; - *result += table_unit->asString(value(index1, index2 + 1), digits); + result += " "; + result += table_unit->asString(value(index1, index2 + 1), digits); } - *result += '\n'; + result += '\n'; if (axis1_->size() != 1) { - *result += unit1->asString(axis1_->axisValue(index1 + 1), digits); - *result += " | "; - *result += table_unit->asString(value(index1 + 1, index2), digits); + result += unit1->asString(axis1_->axisValue(index1 + 1), digits); + result += " | "; + result += table_unit->asString(value(index1 + 1, index2), digits); if (axis2_->size() != 1) { - *result += " "; - *result +=table_unit->asString(value(index1 + 1, index2 + 1),digits); + result += " "; + result +=table_unit->asString(value(index1 + 1, index2 + 1),digits); } } - *result += '\n'; + result += '\n'; - *result += result_name; - *result += " = "; - *result += table_unit->asString(findValue(value1, value2, value3), digits); - *result += '\n'; + result += result_name; + result += " = "; + result += table_unit->asString(findValue(value1, value2, value3), digits); + result += '\n'; + return result; } void @@ -1272,7 +1271,7 @@ Table3::findValue(float axis_value1, // 0.00 0.20 | 0.10 0.20 // |/ 0.30 0.32 // 0.40 | 0.20 0.30 -void +string Table3::reportValue(const char *result_name, const LibertyLibrary *library, const LibertyCell *, @@ -1282,117 +1281,117 @@ Table3::reportValue(const char *result_name, float value2, float value3, const Unit *table_unit, - int digits, - string *result) const + int digits) const { const Units *units = library->units(); const Unit *unit1 = axis1_->unit(units); const Unit *unit2 = axis2_->unit(units); const Unit *unit3 = axis3_->unit(units); - *result += " --------- "; - *result += axis1_->variableString(), - *result += " = "; - *result += unit1->asString(value1, digits); + string result = " --------- "; + result += axis1_->variableString(), + result += " = "; + result += unit1->asString(value1, digits); if (comment1) - *result += comment1; - *result += '\n'; + result += comment1; + result += '\n'; - *result += " | ---- "; - *result += axis2_->variableString(), - *result += " = "; - *result += unit2->asString(value2, digits); - *result += '\n'; + result += " | ---- "; + result += axis2_->variableString(), + result += " = "; + result += unit2->asString(value2, digits); + result += '\n'; - *result += " | | "; - *result += axis3_->variableString(); - *result += " = "; - *result += unit3->asString(value3, digits); - *result += '\n'; + result += " | | "; + result += axis3_->variableString(); + result += " = "; + result += unit3->asString(value3, digits); + result += '\n'; size_t axis_index1 = axis1_->findAxisIndex(value1); size_t axis_index2 = axis2_->findAxisIndex(value2); size_t axis_index3 = axis3_->findAxisIndex(value3); - *result += " | | "; - *result += unit3->asString(axis3_->axisValue(axis_index3), digits); + result += " | | "; + result += unit3->asString(axis3_->axisValue(axis_index3), digits); if (axis3_->size() != 1) { - *result += " "; - *result += unit3->asString(axis3_->axisValue(axis_index3 + 1), digits); + result += " "; + result += unit3->asString(axis3_->axisValue(axis_index3 + 1), digits); } - *result += '\n'; + result += '\n'; - *result += " v | --------------------\n"; + result += " v | --------------------\n"; if (axis1_->size() != 1) { - *result += " "; - *result += unit1->asString(axis1_->axisValue(axis_index1+1), digits); - *result += " v / "; - *result += table_unit->asString(value(axis_index1+1,axis_index2,axis_index3), + result += " "; + result += unit1->asString(axis1_->axisValue(axis_index1+1), digits); + result += " v / "; + result += table_unit->asString(value(axis_index1+1,axis_index2,axis_index3), digits); if (axis3_->size() != 1) { - *result += " "; - *result += table_unit->asString(value(axis_index1+1,axis_index2,axis_index3+1), + result += " "; + result += table_unit->asString(value(axis_index1+1,axis_index2,axis_index3+1), digits); } } else { appendSpaces(result, digits+3); - *result += " v / "; + result += " v / "; } - *result += '\n'; + result += '\n'; - *result += unit1->asString(axis1_->axisValue(axis_index1), digits); - *result += " "; - *result += unit2->asString(axis2_->axisValue(axis_index2), digits); - *result += " | "; - *result += table_unit->asString(value(axis_index1, axis_index2, axis_index3), digits); + result += unit1->asString(axis1_->axisValue(axis_index1), digits); + result += " "; + result += unit2->asString(axis2_->axisValue(axis_index2), digits); + result += " | "; + result += table_unit->asString(value(axis_index1, axis_index2, axis_index3), digits); if (axis3_->size() != 1) { - *result += " "; - *result += table_unit->asString(value(axis_index1, axis_index2, axis_index3+1), + result += " "; + result += table_unit->asString(value(axis_index1, axis_index2, axis_index3+1), digits); } - *result += '\n'; + result += '\n'; - *result += " |/ "; + result += " |/ "; if (axis1_->size() != 1 && axis2_->size() != 1) { - *result += table_unit->asString(value(axis_index1+1,axis_index2+1,axis_index3), + result += table_unit->asString(value(axis_index1+1,axis_index2+1,axis_index3), digits); if (axis3_->size() != 1) { - *result += " "; - *result +=table_unit->asString(value(axis_index1+1,axis_index2+1,axis_index3+1), + result += " "; + result +=table_unit->asString(value(axis_index1+1,axis_index2+1,axis_index3+1), digits); } } - *result += '\n'; + result += '\n'; - *result += " "; - *result += unit2->asString(axis2_->axisValue(axis_index2 + 1), digits); - *result += " | "; + result += " "; + result += unit2->asString(axis2_->axisValue(axis_index2 + 1), digits); + result += " | "; if (axis2_->size() != 1) { - *result += table_unit->asString(value(axis_index1, axis_index2+1, axis_index3), - digits); + result += table_unit->asString(value(axis_index1, axis_index2+1, axis_index3), + digits); if (axis3_->size() != 1) { - *result += " "; - *result +=table_unit->asString(value(axis_index1, axis_index2+1,axis_index3+1), - digits); + result += " "; + result +=table_unit->asString(value(axis_index1, axis_index2+1,axis_index3+1), + digits); } } - *result += '\n'; + result += '\n'; - *result += result_name; - *result += " = "; - *result += table_unit->asString(findValue(value1, value2, value3), digits); - *result += '\n'; + result += result_name; + result += " = "; + result += table_unit->asString(findValue(value1, value2, value3), digits); + result += '\n'; + return result; } static void -appendSpaces(string *result, +appendSpaces(string &result, int count) { while (count--) - *result += ' '; + result += ' '; } void diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index d7dc91e7..6072a5db 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -25,6 +25,8 @@ namespace sta { +using std::map; + static constexpr char escape_ = '\\'; ConcreteLibrary::ConcreteLibrary(const char *name, @@ -381,7 +383,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, { const char bus_brkts_left[2]{bus_brkt_left, '\0'}; const char bus_brkts_right[2]{bus_brkt_right, '\0'}; - BusPortMap port_map; + map port_map; // Find ungrouped bus ports. // Remove bus bit ports from the ports_ vector during the scan by // keeping an index to the next insertion index and skipping over @@ -390,19 +392,21 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, ports_.clear(); for (ConcretePort *port : ports) { const char *port_name = port->name(); - char *bus_name; + bool is_bus; + string bus_name; int index; parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_, - bus_name, index); - if (bus_name) { + is_bus, bus_name, index); + if (is_bus) { if (!port->isBusBit()) { - BusPort *bus_port = port_map.findKey(bus_name); - if (bus_port) - stringDelete(bus_name); - else { - bus_port = new BusPort(bus_name, index, port->direction()); + auto name_bus_port = port_map.find(bus_name); + BusPort *bus_port; + if (name_bus_port == port_map.end()) { + bus_port = new BusPort(bus_name.c_str(), index, port->direction()); port_map[bus_name] = bus_port; } + else + bus_port = name_bus_port->second; bus_port->pushMember(port); } else @@ -413,47 +417,45 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, } // Make the bus ports. - BusPortMap::Iterator bus_iter(port_map); - while (bus_iter.hasNext()) { - BusPort *bus_port = bus_iter.next(); - const char *bus_name = bus_port->name(); - bool msb_first = port_msb_first(bus_name); + for (auto name_bus : port_map) { + const string &bus_name = name_bus.first; + BusPort *bus_port = name_bus.second; + bool msb_first = port_msb_first(bus_name.c_str()); ConcretePortSeq *members = bus_port->members(); sort(members, [&](ConcretePort *port1, ConcretePort *port2) { - char *bus_name; - int index1, index2; - parseBusName(port1->name(), bus_brkts_left, bus_brkts_right, escape_, - bus_name, index1); - stringDelete(bus_name); - parseBusName(port2->name(), bus_brkts_left, bus_brkts_right, escape_, - bus_name, index2); - stringDelete(bus_name); - return msb_first ? index1 > index2 : index1 < index2; - }); + bool is_bus; + string bus_name; + int index1, index2; + parseBusName(port1->name(), bus_brkts_left, bus_brkts_right, escape_, + is_bus, bus_name, index1); + parseBusName(port2->name(), bus_brkts_left, bus_brkts_right, escape_, + is_bus, bus_name, index2); + return msb_first ? index1 > index2 : index1 < index2; + }); - char *bus_name1; + bool is_bus1; + string bus_name1; int from_index, to_index; parseBusName((*members)[0]->name(), bus_brkts_left, bus_brkts_right, escape_, - bus_name1, from_index); - stringDelete(bus_name1); + is_bus1, bus_name1, from_index); parseBusName((*members)[members->size() - 1]->name(), bus_brkts_left, bus_brkts_right, escape_, - bus_name1, to_index); - stringDelete(bus_name1); + is_bus1, bus_name1, to_index); - ConcretePort *port = makeBusPort(bus_name, from_index, to_index, members); + ConcretePort *port = makeBusPort(bus_name.c_str(), from_index, + to_index, members); port->setDirection(bus_port->direction()); delete bus_port; for (ConcretePort *port : *members) { - char *bus_name; + bool is_bus; + string bus_name; int index; parseBusName(port->name(), bus_brkts_left, bus_brkts_right, escape_, - bus_name, index); + is_bus, bus_name, index); port->setBusBitIndex(index); - stringDelete(bus_name); } } } diff --git a/network/ParseBus.cc b/network/ParseBus.cc index d035e132..0920daac 100644 --- a/network/ParseBus.cc +++ b/network/ParseBus.cc @@ -51,12 +51,14 @@ parseBusName(const char *name, const char brkt_right, const char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &index) { const char brkts_left[2] = {brkt_left, '\0'}; const char brkts_right[2] = {brkt_right, '\0'}; - parseBusName(name, brkts_left, brkts_right, escape, bus_name, index); + parseBusName(name, brkts_left, brkts_right, escape, + is_bus, bus_name, index); } void @@ -65,10 +67,11 @@ parseBusName(const char *name, const char *brkts_right, char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &index) { - bus_name = nullptr; + is_bus = false; size_t len = strlen(name); // Shortest bus name is a[0]. if (len >= 4 @@ -81,10 +84,9 @@ parseBusName(const char *name, char brkt_left = brkts_left[brkt_index]; const char *left = strrchr(name, brkt_left); if (left) { + is_bus = true; size_t bus_name_len = left - name; - bus_name = new char[bus_name_len + 1]; - strncpy(bus_name, name, bus_name_len); - bus_name[bus_name_len] = '\0'; + bus_name.append(name, bus_name_len); // Simple bus subscript. index = atoi(left + 1); } @@ -98,13 +100,15 @@ parseBusRange(const char *name, const char brkt_right, char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &from, int &to) { const char brkts_left[2] = {brkt_left, '\0'}; const char brkts_right[2] = {brkt_right, '\0'}; - parseBusRange(name, brkts_left, brkts_right, escape, bus_name, from, to); + parseBusRange(name, brkts_left, brkts_right, escape, + is_bus, bus_name, from, to); } void @@ -113,11 +117,12 @@ parseBusRange(const char *name, const char *brkts_right, char escape, // Return values. - char *&bus_name, + bool &is_bus, + string &bus_name, int &from, int &to) { - bus_name = nullptr; + is_bus = false; size_t len = strlen(name); // Shortest bus range is a[1:0]. if (len >= 6 @@ -134,10 +139,8 @@ parseBusRange(const char *name, const char range_sep = ':'; const char *range = strchr(name, range_sep); if (range) { - size_t bus_name_len = left - name; - bus_name = new char[bus_name_len + 1]; - strncpy(bus_name, name, bus_name_len); - bus_name[bus_name_len] = '\0'; + is_bus = true; + bus_name.append(name, left - name); // No need to terminate bus subscript because atoi stops // scanning at first non-digit character. from = atoi(left + 1); @@ -148,54 +151,32 @@ parseBusRange(const char *name, } } -const char * +string escapeChars(const char *token, const char ch1, const char ch2, const char escape) { - int result_length = 0; - bool need_escapes = false; + string escaped; for (const char *s = token; *s; s++) { char ch = *s; if (ch == escape) { char next_ch = s[1]; // Make sure we don't skip the null if escape is the last char. - if (next_ch != '\0') - result_length++; + if (next_ch != '\0') { + escaped += ch; + escaped += next_ch; + s++; + } } else if (ch == ch1 || ch == ch2) { - result_length++; - need_escapes = true; + escaped += escape; + escaped += ch; } - result_length++; + else + escaped += ch; } - if (need_escapes) { - char *result = makeTmpString(result_length + 1); - char *r = result; - for (const char *s = token; *s; s++) { - char ch = *s; - if (ch == escape) { - char next_ch = s[1]; - // Make sure we don't skip the null if escape is the last char. - if (next_ch != '\0') { - *r++ = ch; - *r++ = next_ch; - s++; - } - } - else if (ch == ch1 || ch == ch2) { - *r++ = escape; - *r++ = ch; - } - else - *r++ = ch; - } - *r++ = '\0'; - return result; - } - else - return token; + return escaped; } } // namespace diff --git a/network/SdcNetwork.cc b/network/SdcNetwork.cc index 12d3ac29..12a652fd 100644 --- a/network/SdcNetwork.cc +++ b/network/SdcNetwork.cc @@ -22,10 +22,10 @@ namespace sta { -static const char * +static string escapeDividers(const char *token, const Network *network); -static const char * +static string escapeBrackets(const char *token, const Network *network); @@ -631,21 +631,22 @@ SdcNetwork::findPort(const Cell *cell, Port *port = network_->findPort(cell, name); if (port == nullptr) { // Look for matches after escaping brackets. - char *bus_name; + bool is_bus; + string bus_name; int index; - parseBusName(name, '[', ']', pathEscape(), bus_name, index); - if (bus_name) { - const char *escaped1 = escapeBrackets(name, this); - port = network_->findPort(cell, escaped1); - if (port == nullptr - && bus_name[strlen(bus_name) - 1] == ']') { + parseBusName(name, '[', ']', pathEscape(), is_bus, bus_name, index); + if (is_bus) { + string escaped1 = escapeBrackets(name, this); + port = network_->findPort(cell, escaped1.c_str()); + if (port == nullptr) { // Try escaping base foo\[0\][1] - const char *escaped2 = stringPrintTmp("%s[%d]", - escapeBrackets(bus_name, this), - index); - port = network_->findPort(cell, escaped2); + string escaped2; + string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); + stringPrint(escaped2, "%s[%d]", + escaped_bus_name.c_str(), + index); + port = network_->findPort(cell, escaped2.c_str()); } - stringDelete(bus_name); } } return port; @@ -658,23 +659,25 @@ SdcNetwork::findPortsMatching(const Cell *cell, PortSeq matches = network_->findPortsMatching(cell, pattern); if (matches.empty()) { // Look for matches after escaping brackets. - char *bus_name; + bool is_bus; + string bus_name; int index; - parseBusName(pattern->pattern(), '[', ']', pathEscape(), bus_name, index); - if (bus_name) { - const char *escaped1 = escapeBrackets(pattern->pattern(), this); - PatternMatch escaped_pattern1(escaped1, pattern); + parseBusName(pattern->pattern(), '[', ']', pathEscape(), + is_bus, bus_name, index); + if (is_bus) { + string escaped1 = escapeBrackets(pattern->pattern(), this); + PatternMatch escaped_pattern1(escaped1.c_str(), pattern); matches = network_->findPortsMatching(cell, &escaped_pattern1); - if (matches.empty() - && bus_name[strlen(bus_name) - 1] == ']') { + if (matches.empty()) { // Try escaping base foo\[0\][1] - const char *escaped2 = stringPrintTmp("%s[%d]", - escapeBrackets(bus_name, this), - index); - PatternMatch escaped_pattern2(escaped2, pattern); + string escaped2; + string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); + stringPrint(escaped2, "%s[%d]", + escaped_bus_name.c_str(), + index); + PatternMatch escaped_pattern2(escaped2.c_str(), pattern); matches = network_->findPortsMatching(cell, &escaped_pattern2); } - stringDelete(bus_name); } } return matches; @@ -739,8 +742,10 @@ SdcNetwork::findInstance(const char *path_name) const if (parent == nullptr) parent = network_->topInstance(); Instance *child = findChild(parent, child_name); - if (child == nullptr) - child = findChild(parent, escapeDividers(child_name, this)); + if (child == nullptr) { + string escaped_name = escapeDividers(child_name, this); + child = findChild(parent, escaped_name.c_str()); + } return child; } @@ -774,8 +779,8 @@ SdcNetwork::findChild(const Instance *parent, { Instance *child = network_->findChild(parent, name); if (child == nullptr) { - const char *escaped = escapeBrackets(name, this); - child = network_->findChild(parent, escaped); + string escaped = escapeBrackets(name, this); + child = network_->findChild(parent, escaped.c_str()); } return child; } @@ -799,8 +804,8 @@ SdcNetwork::findNet(const Instance *instance, { Net *net = network_->findNet(instance, net_name); if (net == nullptr) { - const char *net_name_ = escapeBrackets(net_name, this); - net = network_->findNet(instance, net_name_); + string net_name1 = escapeBrackets(net_name, this); + net = network_->findNet(instance, net_name1.c_str()); } return net; } @@ -829,14 +834,13 @@ SdcNetwork::findInstNetsMatching(const Instance *instance, network_->findInstNetsMatching(instance, pattern, matches); if (matches.empty()) { // Look for matches after escaping path dividers. - const PatternMatch escaped_dividers(escapeDividers(pattern->pattern(), - this), - pattern); + string escaped_pattern = escapeDividers(pattern->pattern(), this); + const PatternMatch escaped_dividers(escaped_pattern.c_str(), pattern); network_->findInstNetsMatching(instance, &escaped_dividers, matches); if (matches.empty()) { // Look for matches after escaping brackets. - const PatternMatch escaped_brkts(escapeBrackets(pattern->pattern(),this), - pattern); + string escaped_pattern2 = escapeBrackets(pattern->pattern(),this); + const PatternMatch escaped_brkts(escaped_pattern2.c_str(), pattern); network_->findInstNetsMatching(instance, &escaped_brkts, matches); } } @@ -862,21 +866,21 @@ SdcNetwork::findPin(const Instance *instance, Pin *pin = network_->findPin(instance, port_name); if (pin == nullptr) { // Look for match after escaping brackets. - char *bus_name; + bool is_bus; + string bus_name; int index; - parseBusName(port_name, '[', ']', pathEscape(), bus_name, index); - if (bus_name) { - const char *escaped1 = escapeBrackets(port_name, this); - pin = network_->findPin(instance, escaped1); - if (pin == nullptr - && bus_name[strlen(bus_name) - 1] == ']') { + parseBusName(port_name, '[', ']', pathEscape(), + is_bus, bus_name, index); + if (is_bus) { + string escaped1 = escapeBrackets(port_name, this); + pin = network_->findPin(instance, escaped1.c_str()); + if (pin == nullptr) { // Try escaping base foo\[0\][1] - const char *escaped2 = stringPrintTmp("%s[%d]", - escapeBrackets(bus_name, this), - index); - pin = network_->findPin(instance, escaped2); + string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); + string escaped2; + stringPrint(escaped2, "%s[%d]", escaped_bus_name.c_str(), index); + pin = network_->findPin(instance, escaped2.c_str()); } - stringDelete(bus_name); } } return pin; @@ -967,16 +971,16 @@ SdcNetwork::makeInstance(LibertyCell *cell, const char *name, Instance *parent) { - const char *escaped_name = escapeDividers(name, this); - return network_edit_->makeInstance(cell, escaped_name, parent); + string escaped_name = escapeDividers(name, this); + return network_edit_->makeInstance(cell, escaped_name.c_str(), parent); } Net * SdcNetwork::makeNet(const char *name, Instance *parent) { - const char *escaped_name = escapeDividers(name, this); - return network_edit_->makeNet(escaped_name, parent); + string escaped_name = escapeDividers(name, this); + return network_edit_->makeNet(escaped_name.c_str(), parent); } //////////////////////////////////////////////////////////////// @@ -1154,10 +1158,9 @@ SdcNetwork::visitMatches(const Instance *parent, found_match |= visit_tail(parent, &tail_pattern); if (!found_match && has_brkts) { // Look for matches after escaping brackets. - char *escaped_path = stringCopy(escapeBrackets(inst_path, this)); + string escaped_path = escapeBrackets(inst_path, this); const PatternMatch escaped_tail(escaped_path, pattern); found_match |= visit_tail(parent, &escaped_tail); - stringDelete(escaped_path); } } stringDelete(inst_path); @@ -1166,7 +1169,7 @@ SdcNetwork::visitMatches(const Instance *parent, //////////////////////////////////////////////////////////////// -static const char * +static string escapeDividers(const char *token, const Network *network) { @@ -1174,7 +1177,7 @@ escapeDividers(const char *token, network->pathEscape()); } -static const char * +static string escapeBrackets(const char *token, const Network *network) { diff --git a/network/VerilogNamespace.cc b/network/VerilogNamespace.cc index 9b0b3431..bb48502f 100644 --- a/network/VerilogNamespace.cc +++ b/network/VerilogNamespace.cc @@ -23,72 +23,63 @@ namespace sta { -static const char * +static string staToVerilog(const char *sta_name, const char escape); -static const char * +static string staToVerilog2(const char *sta_name, const char escape); -static const char * +static string verilogToSta(const char *verilog_name); -static inline void -vstringAppend(char *&str, - char *&str_end, - char *&insert, - char ch); -const char * +string instanceVerilogName(const char *sta_name, const char escape) { return staToVerilog(sta_name, escape); } -const char * +string netVerilogName(const char *sta_name, const char escape) { - char *bus_name; + bool is_bus; + string bus_name; int index; - parseBusName(sta_name, '[', ']', escape, bus_name, index); - if (bus_name) { - const char *vname = stringPrintTmp("%s[%d]", - staToVerilog(bus_name, escape), - index); - stringDelete(bus_name); + parseBusName(sta_name, '[', ']', escape, is_bus, bus_name, index); + if (is_bus) { + string bus_vname = staToVerilog(bus_name.c_str(), escape); + string vname; + stringPrint(vname, "%s[%d]", bus_vname.c_str(), index); return vname; } else return staToVerilog2(sta_name, escape); } -const char * +string portVerilogName(const char *sta_name, const char escape) { return staToVerilog2(sta_name, escape); } -static const char * +static string staToVerilog(const char *sta_name, const char escape) { // Leave room for leading escape and trailing space if the name // needs to be escaped. - size_t verilog_name_length = strlen(sta_name) + 3; - char *verilog_name = makeTmpString(verilog_name_length); - char *verilog_name_end = &verilog_name[verilog_name_length]; - char *v = verilog_name; // Assume the name has to be escaped and start copying while scanning. + string escaped_name = "\\"; bool escaped = false; - *v++ = '\\'; for (const char *s = sta_name; *s ; s++) { char ch = s[0]; if (ch == escape) { char next_ch = s[1]; if (next_ch == escape) { - vstringAppend(verilog_name, verilog_name_end, v, ch); - vstringAppend(verilog_name, verilog_name_end, v, next_ch); + escaped_name += ch; + escaped_name += next_ch; s++; } else @@ -98,20 +89,19 @@ staToVerilog(const char *sta_name, else { if ((!(isalnum(ch) || ch == '_'))) escaped = true; - vstringAppend(verilog_name, verilog_name_end, v, ch); + escaped_name += ch; } } if (escaped) { // Add a terminating space. - vstringAppend(verilog_name, verilog_name_end, v, ' '); - vstringAppend(verilog_name, verilog_name_end, v, '\0'); - return verilog_name; + escaped_name += ' '; + return escaped_name; } else - return sta_name; + return string(sta_name); } -static const char * +static string staToVerilog2(const char *sta_name, const char escape) { @@ -119,20 +109,16 @@ staToVerilog2(const char *sta_name, constexpr char bus_brkt_right = ']'; // Leave room for leading escape and trailing space if the name // needs to be escaped. - size_t verilog_name_length = strlen(sta_name) + 3; - char *verilog_name = makeTmpString(verilog_name_length); - char *verilog_name_end = &verilog_name[verilog_name_length]; - char *v = verilog_name; + string escaped_name = "\\"; // Assume the name has to be escaped and start copying while scanning. bool escaped = false; - *v++ = '\\'; for (const char *s = sta_name; *s ; s++) { char ch = s[0]; if (ch == escape) { char next_ch = s[1]; if (next_ch == escape) { - vstringAppend(verilog_name, verilog_name_end, v, ch); - vstringAppend(verilog_name, verilog_name_end, v, next_ch); + escaped_name += ch; + escaped_name += next_ch; s++; } else @@ -144,46 +130,45 @@ staToVerilog2(const char *sta_name, if ((!(isalnum(ch) || ch == '_') && !is_brkt) || is_brkt) escaped = true; - vstringAppend(verilog_name, verilog_name_end, v, ch); + escaped_name += ch; } } if (escaped) { // Add a terminating space. - vstringAppend(verilog_name, verilog_name_end, v, ' '); - vstringAppend(verilog_name, verilog_name_end, v, '\0'); - return verilog_name; + escaped_name += ' '; + return escaped_name; } else - return sta_name; + return string(sta_name); } //////////////////////////////////////////////////////////////// -const char * +string moduleVerilogToSta(const char *module_name) { return verilogToSta(module_name); } -const char * +string instanceVerilogToSta(const char *inst_name) { return verilogToSta(inst_name); } -const char * +string netVerilogToSta(const char *net_name) { return verilogToSta(net_name); } -const char * +string portVerilogToSta(const char *port_name) { return verilogToSta(port_name); } -static const char * +static string verilogToSta(const char *verilog_name) { if (verilog_name && verilog_name[0] == '\\') { @@ -197,11 +182,7 @@ verilogToSta(const char *verilog_name) size_t verilog_name_length = strlen(verilog_name); if (verilog_name[verilog_name_length - 1] == ' ') verilog_name_length--; - // +1 for \0, +2 for escaping brackets. - size_t sta_name_length = verilog_name_length + 1; - char *sta_name = makeTmpString(sta_name_length); - char *sta_name_end = &sta_name[sta_name_length]; - char *s = sta_name; + string sta_name; for (size_t i = 0; i < verilog_name_length; i++) { char ch = verilog_name[i]; if (ch == bus_brkt_left @@ -209,33 +190,13 @@ verilogToSta(const char *verilog_name) || ch == divider || ch == escape) // Escape bus brackets, dividers and escapes. - vstringAppend(sta_name, sta_name_end, s, escape); - vstringAppend(sta_name, sta_name_end, s, ch); + sta_name += escape; + sta_name += ch; } - vstringAppend(sta_name, sta_name_end, s, '\0'); return sta_name; } else - return verilog_name; -} - -// Append ch to str at insert. Resize str if necessary. -static inline void -vstringAppend(char *&str, - char *&str_end, - char *&insert, - char ch) -{ - if (insert == str_end) { - size_t length = str_end - str; - size_t length2 = length * 2; - char *new_str = makeTmpString(length2); - strncpy(new_str, str, length); - str = new_str; - str_end = &str[length2]; - insert = &str[length]; - } - *insert++ = ch; + return string(verilog_name); } } // namespace diff --git a/power/Power.cc b/power/Power.cc index 773219ee..1a313eac 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -321,6 +321,7 @@ PropActivityVisitor::PropActivityVisitor(Power *power, BfsFwdIterator *bfs) : StaState(power), visited_regs_(network_), + max_change_(0.0), power_(power), bfs_(bfs) { diff --git a/power/ReadVcdActivities.cc b/power/ReadVcdActivities.cc index ae28c180..9e2706c4 100644 --- a/power/ReadVcdActivities.cc +++ b/power/ReadVcdActivities.cc @@ -131,14 +131,15 @@ ReadVcdActivities::setVarActivity(VcdVar *var, string &var_name, const VcdValues &var_values) { - const char *sta_name = netVerilogToSta(var_name.c_str()); + string sta_name = netVerilogToSta(var_name.c_str()); if (var->width() == 1) - setVarActivity(sta_name, var_values, 0); + setVarActivity(sta_name.c_str(), var_values, 0); else { - char *bus_name; + bool is_bus; + string bus_name; int from, to; - parseBusRange(sta_name, '[', ']', '\\', - bus_name, from, to); + parseBusRange(sta_name.c_str(), '[', ']', '\\', + is_bus, bus_name, from, to); int value_bit = 0; if (to < from) { for (int bus_bit = to; bus_bit <= from; bus_bit++) { @@ -160,7 +161,6 @@ ReadVcdActivities::setVarActivity(VcdVar *var, value_bit++; } } - stringDelete(bus_name); } } diff --git a/sdf/SdfParse.yy b/sdf/SdfParse.yy index 4fa07844..b2cf1e54 100644 --- a/sdf/SdfParse.yy +++ b/sdf/SdfParse.yy @@ -128,8 +128,10 @@ celltype: ; cell_instance: - '(' INSTANCE ')' { sta::sdf_reader->setInstance(NULL); } -| '(' INSTANCE '*' ')' { sta::sdf_reader->setInstanceWildcard(); } + '(' INSTANCE ')' + { sta::sdf_reader->setInstance(NULL); } +| '(' INSTANCE '*' ')' + { sta::sdf_reader->setInstanceWildcard(); } | '(' INSTANCE path ')' { sta::sdf_reader->setInstance($3); } ; @@ -266,7 +268,10 @@ port: ID { $$ = sta::sdf_reader->unescaped($1); } | ID '[' DNUMBER ']' - { $$ = sta::stringPrint("%s[%d]", sta::sdf_reader->unescaped($1), $3); } + { const char *bus_name = sta::sdf_reader->unescaped($1); + $$ = sta::stringPrint("%s[%d]", bus_name, $3); + sta::stringDelete(bus_name); + } ; port_instance: @@ -292,7 +297,7 @@ port_tchk: | '(' COND EXPR_ID_CLOSE { $$ = sta::sdf_reader->makeCondPortSpec($3); } | '(' COND EXPR_OPEN port_transition port_instance ')' ')' - { $$ = sta::sdf_reader->makePortSpec($4, $5, $3); sta::stringDelete($3); } + { $$ = sta::sdf_reader->makePortSpec($4, $5, $3); } ; value: diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index c57f6a10..5fa136e8 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -210,6 +210,8 @@ SdfReader::interconnect(const char *from_pin_name, sdfWarn(186, "pin %s not found.", to_pin_name); } } + stringDelete(from_pin_name); + stringDelete(to_pin_name); deleteTripleSeq(triples); } @@ -234,6 +236,7 @@ SdfReader::port(const char *to_pin_name, } } } + stringDelete(to_pin_name); deleteTripleSeq(triples); } @@ -312,6 +315,7 @@ SdfReader::setInstance(const char *instance_name) } else instance_ = nullptr; + stringDelete(instance_name); } void @@ -399,6 +403,7 @@ SdfReader::iopath(SdfPortSpec *from_edge, } } } + stringDelete(to_port_name); deletePortSpec(from_edge); deleteTripleSeq(triples); stringDelete(cond); @@ -688,6 +693,7 @@ SdfReader::device(const char *to_port_name, setDevicePinDelays(to_pin, triples); } } + stringDelete(to_port_name); deleteTripleSeq(triples); } @@ -822,7 +828,10 @@ SdfReader::makePortSpec(Transition *tr, const char *port, const char *cond) { - return new SdfPortSpec(tr, port, cond); + SdfPortSpec *port_spec = new SdfPortSpec(tr, port, cond); + stringDelete(port); + stringDelete(cond); + return port_spec; } SdfPortSpec * @@ -837,9 +846,9 @@ SdfReader::makeCondPortSpec(const char *cond_port) auto cond_end = cond_port1.find_last_not_of(" ", port_idx); if (cond_end != cond_port1.npos) { string cond1 = cond_port1.substr(0, cond_end + 1); - SdfPortSpec *port_spec = makePortSpec(Transition::riseFall(), - port1.c_str(), - cond1.c_str()); + SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(), + port1.c_str(), + cond1.c_str()); stringDelete(cond_port); return port_spec; } @@ -919,7 +928,7 @@ SdfReader::unescaped(const char *token) { char path_escape = network_->pathEscape(); char path_divider = network_->pathDivider(); - char *unescaped = makeTmpString(strlen(token) + 1); + char *unescaped = new char[strlen(token) + 1]; char *u = unescaped; size_t token_length = strlen(token); @@ -962,10 +971,12 @@ char * SdfReader::makePath(const char *head, const char *tail) { - char *path = stringPrintTmp("%s%c%s", - head, - network_->pathDivider(), - tail); + char *path = stringPrint("%s%c%s", + head, + network_->pathDivider(), + tail); + sta::stringDelete(head); + sta::stringDelete(tail); return path; } diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index 36a14df9..c3103ec1 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -100,10 +100,10 @@ protected: void writeSdfTriple(float min, float max); void writeSdfDelay(double delay); - char *sdfPortName(const Pin *pin); - char *sdfPathName(const Pin *pin); - char *sdfPathName(const Instance *inst); - char *sdfName(const Instance *inst); + string sdfPortName(const Pin *pin); + string sdfPathName(const Pin *pin); + string sdfPathName(const Instance *inst); + string sdfName(const Instance *inst); private: char sdf_divider_; @@ -310,9 +310,11 @@ SdfWriter::writeInterconnectFromPin(Pin *drvr_pin) Edge *edge = edge_iter.next(); if (edge->isWire()) { Pin *load_pin = edge->to(graph_)->pin(); + string drvr_pin_name = sdfPathName(drvr_pin); + string load_pin_name = sdfPathName(load_pin); gzprintf(stream_, " (INTERCONNECT %s %s ", - sdfPathName(drvr_pin), - sdfPathName(load_pin)); + drvr_pin_name.c_str(), + load_pin_name.c_str()); writeArcDelays(edge); gzprintf(stream_, ")\n"); } @@ -340,7 +342,8 @@ SdfWriter::writeInstHeader(const Instance *inst) { gzprintf(stream_, " (CELL\n"); gzprintf(stream_, " (CELLTYPE \"%s\")\n", network_->cellName(inst)); - gzprintf(stream_, " (INSTANCE %s)\n", sdfPathName(inst)); + string inst_name = sdfPathName(inst); + gzprintf(stream_, " (INSTANCE %s)\n", inst_name.c_str()); } void @@ -384,9 +387,11 @@ SdfWriter::writeIopaths(const Instance *inst, gzprintf(stream_, " (COND %s\n", sdf_cond); gzprintf(stream_, " "); } - gzprintf(stream_, " (IOPATH %s %s ", - sdfPortName(from_pin), - sdfPortName(to_pin)); + string from_pin_name = sdfPortName(from_pin); + string to_pin_name = sdfPortName(to_pin); + gzprintf(stream_, " (IOPATH %s %s ", + from_pin_name.c_str(), + to_pin_name.c_str()); writeArcDelays(edge); if (sdf_cond) gzprintf(stream_, ")"); @@ -651,12 +656,14 @@ SdfWriter::writeCheck(Edge *edge, if (sdf_cond_start) gzprintf(stream_, "(COND %s ", sdf_cond_start); - if (use_data_edge) + string to_pin_name = sdfPortName(to_pin); + if (use_data_edge) { gzprintf(stream_, "(%s %s)", sdfEdge(arc->toEdge()), - sdfPortName(to_pin)); + to_pin_name.c_str()); + } else - gzprintf(stream_, "%s", sdfPortName(to_pin)); + gzprintf(stream_, "%s", to_pin_name.c_str()); if (sdf_cond_start) gzprintf(stream_, ")"); @@ -666,12 +673,13 @@ SdfWriter::writeCheck(Edge *edge, if (sdf_cond_end) gzprintf(stream_, "(COND %s ", sdf_cond_end); + string from_pin_name = sdfPortName(from_pin); if (use_clk_edge) gzprintf(stream_, "(%s %s)", sdfEdge(arc->fromEdge()), - sdfPortName(from_pin)); + from_pin_name.c_str()); else - gzprintf(stream_, "%s", sdfPortName(from_pin)); + gzprintf(stream_, "%s", from_pin_name.c_str()); if (sdf_cond_end) gzprintf(stream_, ")"); @@ -691,9 +699,10 @@ SdfWriter::writeWidthCheck(const Pin *pin, float min_width, float max_width) { + string pin_name = sdfPortName(pin); gzprintf(stream_, " (WIDTH (%s %s) ", sdfEdge(hi_low->asTransition()), - sdfPortName(pin)); + pin_name.c_str()); writeSdfTriple(min_width, max_width); gzprintf(stream_, ")\n"); } @@ -702,8 +711,8 @@ void SdfWriter::writePeriodCheck(const Pin *pin, float min_period) { - gzprintf(stream_, " (PERIOD %s ", - sdfPortName(pin)); + string pin_name = sdfPortName(pin); + gzprintf(stream_, " (PERIOD %s ", pin_name.c_str()); writeSdfTriple(min_period, min_period); gzprintf(stream_, ")\n"); } @@ -720,81 +729,68 @@ SdfWriter::sdfEdge(const Transition *tr) //////////////////////////////////////////////////////////////// -char * +string SdfWriter::sdfPathName(const Pin *pin) { Instance *inst = network_->instance(pin); if (network_->isTopInstance(inst)) return sdfPortName(pin); else { - char *inst_path = sdfPathName(inst); - const char *port_name = sdfPortName(pin); - size_t length = strlen(inst_path) + 1 + strlen(port_name) + 1; - char *sdf_name = makeTmpString(length); - snprintf(sdf_name, length, "%s%c%s", inst_path, sdf_divider_, port_name); + string inst_path = sdfPathName(inst); + string port_name = sdfPortName(pin); + string sdf_name = inst_path; + sdf_name += sdf_divider_; + sdf_name += port_name; return sdf_name; } } // Based on Network::pathName. -char * +string SdfWriter::sdfPathName(const Instance *instance) { InstanceSeq inst_path; network_->path(instance, inst_path); - size_t name_length = 0; InstanceSeq::Iterator path_iter1(inst_path); - while (path_iter1.hasNext()) { - const Instance *inst = path_iter1.next(); - name_length += strlen(sdfName(inst)) + 1; - } - char *path_name = makeTmpString(name_length); - char *path_ptr = path_name; - // Top instance has null string name, so terminate the string here. - *path_name = '\0'; - while (inst_path.size()) { + string path_name; + while (!inst_path.empty()) { const Instance *inst = inst_path.back(); - const char *inst_name = sdfName(inst); - strcpy(path_ptr, inst_name); - path_ptr += strlen(inst_name); + string inst_name = sdfName(inst); + path_name += inst_name; inst_path.pop_back(); - if (inst_path.size()) - *path_ptr++ = sdf_divider_; - *path_ptr = '\0'; + if (!inst_path.empty()) + path_name += sdf_divider_; } return path_name; } // Escape for non-alpha numeric characters. -char * +string SdfWriter::sdfName(const Instance *inst) { const char *name = network_->name(inst); - char *sdf_name = makeTmpString(strlen(name) * 2 + 1); + string sdf_name; const char *p = name; - char *s = sdf_name; while (*p) { char ch = *p; // Ignore sta escapes. if (ch != network_escape_) { if (!(isalnum(ch) || ch == '_')) // Insert escape. - *s++ = sdf_escape_; - *s++ = ch; + sdf_name += sdf_escape_; + sdf_name += ch; } p++; } - *s = '\0'; return sdf_name; } -char * +string SdfWriter::sdfPortName(const Pin *pin) { const char *name = network_->portName(pin); size_t name_length = strlen(name); - char *sdf_name = makeTmpString(name_length * 2 + 1); - char *s = sdf_name; + string sdf_name; constexpr char bus_brkt_left = '['; constexpr char bus_brkt_right = ']'; @@ -809,18 +805,17 @@ SdfWriter::sdfPortName(const Pin *pin) char ch = name[i]; if (ch == network_escape_) { // Copy escape and escaped char. - *s++ = sdf_escape_; - *s++ = name[++i]; + sdf_name += sdf_escape_; + sdf_name += name[++i]; } else { if (!(isalnum(ch) || ch == '_') && !(i >= bus_index && (ch == bus_brkt_right || ch == bus_brkt_left))) // Insert escape. - *s++ = sdf_escape_; - *s++ = ch; + sdf_name += sdf_escape_; + sdf_name += ch; } } - *s = '\0'; return sdf_name; } diff --git a/search/ClkInfo.cc b/search/ClkInfo.cc index 40e9904d..6ab578ad 100644 --- a/search/ClkInfo.cc +++ b/search/ClkInfo.cc @@ -113,34 +113,35 @@ ClkInfo::asString(const StaState *sta) const { Network *network = sta->network(); Corners *corners = sta->corners(); - string str; + string result; PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_); - str += stringPrintTmp("%s/%d ", - path_ap->pathMinMax()->asString(), - path_ap_index_); + result += path_ap->pathMinMax()->asString(); + result += "/"; + result += std::to_string(path_ap_index_); + if (clk_edge_) - str += clk_edge_->name(); + result += clk_edge_->name(); else - str += "unclocked"; + result += "unclocked"; if (clk_src_) { - str += " clk_src "; - str += network->pathName(clk_src_); + result += " clk_src "; + result += network->pathName(clk_src_); } if (!crpr_clk_path_.isNull()) { const Pin *crpr_clk_pin = crpr_clk_path_.vertex(sta)->pin(); - str += " crpr_pin "; - str += network->pathName(crpr_clk_pin); + result += " crpr_pin "; + result += network->pathName(crpr_clk_pin); } if (is_gen_clk_src_path_) - str += " genclk"; + result += " genclk"; - char *result = makeTmpString(str.size() + 1); - strcpy(result, str.c_str()); - return result; + char *tmp = makeTmpString(result.size() + 1); + strcpy(tmp, result.c_str()); + return tmp; } const Clock * diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 68cb1ab4..e36c87c3 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -558,13 +558,14 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin, Slew in_slew = graph_->slew(gate_in_vertex, drvr_arc->fromEdge()->asRiseFall(), dcalc_ap->index()); + float in_slew1 = delayAsFloat(in_slew); TimingModel *drvr_model = drvr_arc->cornerArc(lib_index)->model(op_cond); GateTableModel *drvr_gate_model = dynamic_cast(drvr_model); if (drvr_gate_model) { float output_load_cap = graph_delay_calc_->loadCap(output_pin, dcalc_ap); ArcDelay drvr_self_delay; Slew drvr_self_slew; - drvr_gate_model->gateDelay(drvr_cell, pvt, in_slew, + drvr_gate_model->gateDelay(drvr_cell, pvt, in_slew1, output_load_cap, 0.0, false, drvr_self_delay, drvr_self_slew); @@ -579,12 +580,13 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin, // get slew from driver input pin ArcDelay gate_delay; Slew gate_slew; - drvr_gate_model->gateDelay(drvr_cell, pvt, in_slew, + drvr_gate_model->gateDelay(drvr_cell, pvt, in_slew1, load_cap, 0.0, false, gate_delay, gate_slew); // Remove the self delay driving the output pin net load cap. - load_values->push_back(delay + gate_delay - drvr_self_delay); - slew_values->push_back(gate_slew); + load_values->push_back(delayAsFloat(delay + gate_delay + - drvr_self_delay)); + slew_values->push_back(delayAsFloat(gate_slew)); } FloatSeq *axis_values = new FloatSeq(*drvr_axis_values); diff --git a/search/Property.cc b/search/Property.cc index 8abc350c..459ca7a0 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -1028,7 +1028,9 @@ getProperty(Edge *edge, auto graph = sta->graph(); const char *from = edge->from(graph)->name(network); const char *to = edge->to(graph)->name(network); - return PropertyValue(stringPrintTmp("%s -> %s", from, to)); + string full_name; + stringPrint(full_name, "%s -> %s", from, to); + return PropertyValue(full_name); } if (stringEqual(property, "delay_min_fall")) return edgeDelayProperty(edge, RiseFall::fall(), MinMax::min(), sta); diff --git a/search/Sta.cc b/search/Sta.cc index 0e9d4904..10eb408b 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -2657,7 +2657,7 @@ Sta::endpointViolationCount(const MinMax *min_max) { int violations = 0; for (Vertex *end : *search_->endpoints()) { - if (vertexSlack(end, min_max) < 0.0) + if (delayLess(vertexSlack(end, min_max), 0.0, this)) violations++; } return violations; @@ -2815,7 +2815,8 @@ Sta::pinArrival(const Pin *pin, if (bidirect_vertex) { Arrival arrival1 = vertexArrival(bidirect_vertex, rf, clk_edge_wildcard, nullptr, min_max); - arrival = min_max->minMax(arrival, arrival1); + if (delayLess(arrival1, arrival, this)) + arrival = arrival1; } return arrival; } @@ -3256,7 +3257,7 @@ Sta::worstSlack(const Corner *corner, //////////////////////////////////////////////////////////////// -string * +string Sta::reportDelayCalc(Edge *edge, TimingArc *arc, const Corner *corner, diff --git a/search/Tag.cc b/search/Tag.cc index a4f49144..b29e97f4 100644 --- a/search/Tag.cc +++ b/search/Tag.cc @@ -94,83 +94,84 @@ Tag::asString(bool report_index, { const Network *network = sta->network(); const Corners *corners = sta->corners(); - string str; + string result; if (report_index) - str += stringPrintTmp("%4d ", index_); + result += std::to_string(index_); if (report_rf_min_max) { const RiseFall *rf = transition(); PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_); - str += stringPrintTmp("%s %s/%d ", - rf->asString(), - path_ap->pathMinMax()->asString(), - path_ap_index_); + result += rf->asString(); + result += " "; + result += path_ap->pathMinMax()->asString(); + result += "/"; + result += std::to_string(path_ap_index_); } const ClockEdge *clk_edge = clkEdge(); if (clk_edge) - str += clk_edge->name(); + result += clk_edge->name(); else - str += "unclocked"; + result += "unclocked"; bool is_genclk_src = clk_info_->isGenClkSrcPath(); if (is_clk_ || is_genclk_src) { - str += " ("; + result += " ("; if (is_clk_) { - str += "clock"; + result += "clock"; if (clk_info_->isPropagated()) - str += " prop"; + result += " prop"; else - str += " ideal"; + result += " ideal"; if (is_genclk_src) - str += " "; + result += " "; } if (clk_info_->isGenClkSrcPath()) - str += "genclk"; - str += ")"; + result += "genclk"; + result += ")"; } const Pin *clk_src = clkSrc(); if (clk_src) { - str += " clk_src "; - str += network->pathName(clk_src); + result += " clk_src "; + result += network->pathName(clk_src); } const PathVertex crpr_clk_path(clk_info_->crprClkPath(), sta); if (!crpr_clk_path.isNull()) { - str += " crpr_pin "; - str += network->pathName(crpr_clk_path.pin(sta)); + result += " crpr_pin "; + result += network->pathName(crpr_clk_path.pin(sta)); } if (input_delay_) { - str += " input "; - str += network->pathName(input_delay_->pin()); + result += " input "; + result += network->pathName(input_delay_->pin()); } if (is_segment_start_) - str += " segment_start"; + result += " segment_start"; if (states_) { for (ExceptionState *state : *states_) { ExceptionPath *exception = state->exception(); - str += " "; - str += exception->asString(network); + result += " "; + result += exception->asString(network); if (state->nextThru()) { - str += " (next thru "; - str += state->nextThru()->asString(network); - str += ")"; + result += " (next thru "; + result += state->nextThru()->asString(network); + result += ")"; } else { if (exception->thrus() != nullptr) - str += " (thrus complete)"; + result += " (thrus complete)"; } } } - char *result = makeTmpString(str.size() + 1); - strcpy(result, str.c_str()); - return result; + char *tmp = makeTmpString(result.size() + 1); + strcpy(tmp, result.c_str()); + return tmp; } const RiseFall * diff --git a/tcl/Search.tcl b/tcl/Search.tcl index 8aae3240..1e464f1f 100644 --- a/tcl/Search.tcl +++ b/tcl/Search.tcl @@ -289,13 +289,13 @@ proc report_wrt_clk { vertex what clk clk_rf } { } } -proc rise_fall_short_name { tr } { - if { $tr eq "rise" } { +proc rise_fall_short_name { rf } { + if { $rf == "rise" } { return [rise_short_name] - } elseif { $tr eq "fall" } { + } elseif { $rf == "fall" } { return [fall_short_name] } else { - error "unknown transition name $tr" + error "unknown transition name $rf" } } diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 1b37d6b8..86ec7975 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -402,6 +402,13 @@ using namespace sta; // //////////////////////////////////////////////////////////////// +// String that is deleted after crossing over to tcland. +%typemap(out) string { + string &str = $1; + // String is volatile because it is deleted. + Tcl_SetResult(interp, const_cast(str.c_str()), TCL_VOLATILE); +} + // String that is deleted after crossing over to tcland. %typemap(out) TmpString* { string *str = $1; @@ -5953,7 +5960,7 @@ requireds_clk(const RiseFall *rf, clk_edge = clk->edge(clk_rf); for (auto path_ap : sta->corners()->pathAnalysisPts()) { requireds.push_back(delayAsFloat(sta->vertexRequired(self, rf, clk_edge, - path_ap))); + path_ap))); } return requireds; } diff --git a/test/regression.tcl b/test/regression.tcl index eb44ee49..72ad544a 100755 --- a/test/regression.tcl +++ b/test/regression.tcl @@ -93,7 +93,7 @@ proc parse_args {} { } proc expand_tests { argv } { - global test_groups + global test_groups errors set tests {} foreach arg $argv { @@ -111,7 +111,8 @@ proc expand_tests { argv } { lappend tests $arg } else { puts "Error: test $arg not found." - } + incr errors(no_cmd) + } } return $tests } diff --git a/util/PatternMatch.cc b/util/PatternMatch.cc index 80baa3f7..1202c369 100644 --- a/util/PatternMatch.cc +++ b/util/PatternMatch.cc @@ -57,6 +57,18 @@ PatternMatch::PatternMatch(const char *pattern, compileRegexp(); } +PatternMatch::PatternMatch(const string &pattern, + const PatternMatch *inherit_from) : + pattern_(pattern.c_str()), + is_regexp_(inherit_from->is_regexp_), + nocase_(inherit_from->nocase_), + interp_(inherit_from->interp_), + regexp_(nullptr) +{ + if (is_regexp_) + compileRegexp(); +} + void PatternMatch::compileRegexp() { @@ -89,6 +101,12 @@ PatternMatch::hasWildcards() const return patternWildcards(pattern_); } +bool +PatternMatch::match(const string &str) const +{ + return match(str.c_str()); +} + bool PatternMatch::match(const char *str) const { diff --git a/verilog/VerilogParse.yy b/verilog/VerilogParse.yy index e52bcbd8..fa876261 100644 --- a/verilog/VerilogParse.yy +++ b/verilog/VerilogParse.yy @@ -394,7 +394,7 @@ inst_named_pins: inst_named_pin: // Scalar port. '.' ID '(' ')' - { $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2, NULL); } + { $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2); } | '.' ID '(' ID ')' { $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2, $4); } | '.' ID '(' ID '[' INT ']' ')' diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index 0f1a650b..f6b94864 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.cc @@ -36,9 +36,9 @@ namespace sta { VerilogReader *verilog_reader; static const char *unconnected_net_name = reinterpret_cast(1); -static const char * -verilogBusBitNameTmp(const char *bus_name, - int index); +static string +verilogBusBitName(const char *bus_name, + int index); static int hierarchyLevel(Net *net, Network *network); @@ -255,17 +255,18 @@ VerilogReader::makeModule(const char *module_vname, VerilogStmtSeq *stmts, int line) { - const char *module_name = moduleVerilogToSta(module_vname); - Cell *cell = network_->findCell(library_, module_name); + string module_name = moduleVerilogToSta(module_vname); + Cell *cell = network_->findCell(library_, module_name.c_str()); if (cell) { VerilogModule *module = module_map_[cell]; delete module; module_map_.erase(cell); network_->deleteCell(cell); } - VerilogModule *module = new VerilogModule(module_name, ports, stmts, + VerilogModule *module = new VerilogModule(module_name.c_str(), + ports, stmts, filename_, line, this); - cell = network_->makeCell(library_, module_name, false, filename_); + cell = network_->makeCell(library_, module_name.c_str(), false, filename_); module_map_[cell] = module; makeCellPorts(cell, module, ports); module_count_++; @@ -300,26 +301,25 @@ VerilogReader::makeCellPorts(Cell *cell, VerilogModule *module, VerilogNetSeq *ports) { - StringSet port_names; + set port_names; for (VerilogNet *mod_port : *ports) { - const char *port_name = mod_port->name(); - if (port_names.findKey(port_name) == nullptr) { - port_names.insert(stringCopy(port_name)); + const string &port_name = mod_port->name(); + if (port_names.find(port_name) == port_names.end()) { + port_names.insert(port_name); if (mod_port->isNamed()) { if (mod_port->isNamedPortRef()) makeNamedPortRefCellPorts(cell, module, mod_port, port_names); else - makeCellPort(cell, module, mod_port->name()); + makeCellPort(cell, module, mod_port->name().c_str()); } } else warn(165, module->filename(), module->line(), "module %s repeated port name %s.", module->name(), - port_name); + port_name.c_str()); } checkModuleDcls(module, port_names); - deleteContents(&port_names); } Port * @@ -351,25 +351,25 @@ void VerilogReader::makeNamedPortRefCellPorts(Cell *cell, VerilogModule *module, VerilogNet *mod_port, - StringSet &port_names) + set &port_names) { PortSeq *member_ports = new PortSeq; VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module,this); while (net_name_iter->hasNext()) { const char *net_name = net_name_iter->next(); - port_names.insert(stringCopy(net_name)); + port_names.insert(net_name); Port *port = makeCellPort(cell, module, net_name); member_ports->push_back(port); } delete net_name_iter; // Note that the bundle does NOT have a port declaration. - network_->makeBundlePort(cell, mod_port->name(), member_ports); + network_->makeBundlePort(cell, mod_port->name().c_str(), member_ports); } // Make sure each declaration appears in the module port list. void VerilogReader::checkModuleDcls(VerilogModule *module, - StringSet &port_names) + set &port_names) { VerilogDclMap::ConstIterator dcl_iter(module->declarationMap()); while (dcl_iter.hasNext()) { @@ -380,7 +380,7 @@ VerilogReader::checkModuleDcls(VerilogModule *module, if (dir->isInput() || dir->isOutput() || dir->isBidirect()) { - if (port_names.findKey(port_name) == nullptr) + if (port_names.find(port_name) == port_names.end()) linkWarn(197, module->filename(), module->line(), "module %s declared signal %s is not in the port list.", module->name(), @@ -457,10 +457,10 @@ VerilogDclArg * VerilogReader::makeDclArg(const char *net_vname) { dcl_arg_count_++; - const char *net_name = netVerilogToSta(net_vname); - VerilogDclArg *dcl =new VerilogDclArg(net_name); - stringDelete(net_vname); - return dcl; + string net_name = netVerilogToSta(net_vname); + VerilogDclArg *dcl =new VerilogDclArg(net_name.c_str()); + stringDelete(net_vname); + return dcl; } VerilogDclArg * @@ -478,8 +478,9 @@ VerilogReader::makeNetPartSelect(const char *net_vname, net_part_select_count_++; if (report_stmt_stats_) net_bus_names_ += strlen(net_vname) + 1; - const char *net_name = netVerilogToSta(net_vname); - VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name, from_index, + string net_name = netVerilogToSta(net_vname); + VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name.c_str(), + from_index, to_index); stringDelete(net_vname); return select; @@ -498,8 +499,8 @@ VerilogReader::makeNetScalar(const char *net_vname) net_scalar_count_++; if (report_stmt_stats_) net_scalar_names_ += strlen(net_vname) + 1; - const char *net_name = netVerilogToSta(net_vname); - VerilogNetScalar *scalar = new VerilogNetScalar(net_name); + string net_name = netVerilogToSta(net_vname); + VerilogNetScalar *scalar = new VerilogNetScalar(net_name.c_str()); stringDelete(net_vname); return scalar; } @@ -511,8 +512,8 @@ VerilogReader::makeNetBitSelect(const char *net_vname, net_bit_select_count_++; if (report_stmt_stats_) net_bus_names_ += strlen(net_vname) + 1; - const char *net_name = netVerilogToSta(net_vname); - VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name, index); + string net_name = netVerilogToSta(net_vname); + VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name.c_str(), index); stringDelete(net_vname); return select; } @@ -532,9 +533,9 @@ VerilogReader::makeModuleInst(const char *module_vname, VerilogNetSeq *pins, const int line) { - const char *module_name = moduleVerilogToSta(module_vname); - const char *inst_name = instanceVerilogToSta(inst_vname); - Cell *cell = network_->findAnyCell(module_name); + string module_name = moduleVerilogToSta(module_vname); + string inst_name = instanceVerilogToSta(inst_vname); + Cell *cell = network_->findAnyCell(module_name.c_str()); LibertyCell *liberty_cell = nullptr; if (cell) liberty_cell = network_->libertyCell(cell); @@ -549,7 +550,7 @@ VerilogReader::makeModuleInst(const char *module_vname, for (VerilogNet *vnet : *pins) { VerilogNetPortRefScalarNet *vpin = dynamic_cast(vnet); - const char *port_name = vpin->name(); + const char *port_name = vpin->name().c_str(); const char *net_name = vpin->netName(); // Steal the net name string. vpin->setNetName(nullptr); @@ -569,11 +570,11 @@ VerilogReader::makeModuleInst(const char *module_vname, delete vpin; net_port_ref_scalar_net_count_--; } - VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name, + VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name.c_str(), net_names, line); delete pins; if (report_stmt_stats_) { - inst_names_ += strlen(inst_name) + 1; + inst_names_ += inst_name.size() + 1; inst_lib_count_++; inst_lib_net_arrays_ += port_count; } @@ -582,10 +583,12 @@ VerilogReader::makeModuleInst(const char *module_vname, return inst; } else { - VerilogInst *inst = new VerilogModuleInst(module_name, inst_name, pins, line); + VerilogInst *inst = new VerilogModuleInst(module_name.c_str(), + inst_name.c_str(), + pins, line); if (report_stmt_stats_) { - inst_module_names_ += strlen(module_name) + 1; - inst_names_ += strlen(inst_name) + 1; + inst_module_names_ += module_name.size() + 1; + inst_names_ += inst_name.size() + 1; inst_mod_count_++; } stringDelete(module_vname); @@ -602,7 +605,7 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell, && pins->size() > 0 && (*pins)[0]->isNamedPortRef()) { for (VerilogNet *vpin : *pins) { - const char *port_name = vpin->name(); + const char *port_name = vpin->name().c_str(); LibertyPort *port = liberty_cell->findLibertyPort(port_name); if (port) { if (!(port->size() == 1 @@ -618,6 +621,18 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell, return false; } +VerilogNetPortRef * +VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname) +{ + net_port_ref_scalar_net_count_++; + if (report_stmt_stats_) + port_names_ += strlen(port_vname) + 1; + string port_name = portVerilogToSta(port_vname); + VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str()); + stringDelete(port_vname); + return ref; +} + VerilogNetPortRef * VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname, const char *net_vname) @@ -628,9 +643,10 @@ VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname, net_scalar_names_ += strlen(net_vname) + 1; port_names_ += strlen(port_vname) + 1; } - const char *port_name = portVerilogToSta(port_vname); - const char *net_name = netVerilogToSta(net_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name); + string port_name = portVerilogToSta(port_vname); + string net_name = netVerilogToSta(net_vname); + VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(), + net_name.c_str()); stringDelete(port_vname); stringDelete(net_vname); return ref; @@ -642,14 +658,15 @@ VerilogReader::makeNetNamedPortRefBitSelect(const char *port_vname, int index) { net_port_ref_scalar_net_count_++; - const char *bus_name = portVerilogToSta(bus_vname); - const char *net_name = verilogBusBitNameTmp(bus_name, index); + string bus_name = portVerilogToSta(bus_vname); + string net_name = verilogBusBitName(bus_name.c_str(), index); if (report_stmt_stats_) { - net_scalar_names_ += strlen(net_name) + 1; + net_scalar_names_ += net_name.length() + 1; port_names_ += strlen(port_vname) + 1; } - const char *port_name = portVerilogToSta(port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name); + string port_name = portVerilogToSta(port_vname); + VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(), + net_name.c_str()); stringDelete(port_vname); stringDelete(bus_vname); return ref; @@ -662,8 +679,8 @@ VerilogReader::makeNetNamedPortRefScalar(const char *port_vname, net_port_ref_scalar_count_++; if (report_stmt_stats_) port_names_ += strlen(port_vname) + 1; - const char *port_name = portVerilogToSta(port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name, net); + string port_name = portVerilogToSta(port_vname); + VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name.c_str(), net); stringDelete(port_vname); return ref; } @@ -674,8 +691,9 @@ VerilogReader::makeNetNamedPortRefBit(const char *port_vname, VerilogNet *net) { net_port_ref_bit_count_++; - const char *port_name = portVerilogToSta(port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name, index, net); + string port_name = portVerilogToSta(port_vname); + VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name.c_str(), + index, net); stringDelete(port_vname); return ref; } @@ -687,8 +705,9 @@ VerilogReader::makeNetNamedPortRefPart(const char *port_vname, VerilogNet *net) { net_port_ref_part_count_++; - const char *port_name = portVerilogToSta(port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name, from_index, + string port_name = portVerilogToSta(port_vname); + VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name.c_str(), + from_index, to_index, net); stringDelete(port_vname); return ref; @@ -776,20 +795,20 @@ VerilogReader::warn(int id, va_end(args); } -const char * +string VerilogReader::verilogName(VerilogModuleInst *mod_inst) { return sta::instanceVerilogName(mod_inst->instanceName(), network_->pathEscape()); } -const char * +string VerilogReader::instanceVerilogName(const char *inst_name) { return sta::netVerilogName(inst_name, network_->pathEscape()); } -const char * +string VerilogReader::netVerilogName(const char *net_name) { return sta::netVerilogName(net_name, network_->pathEscape()); @@ -862,11 +881,13 @@ VerilogModule::parseDcl(VerilogDcl *dcl, // supply0/supply1 dcl can be used as modifier for // input/output/inout dcls. dcl_map_[net_name] = dcl; - else if (!dcl->direction()->isInternal()) + else if (!dcl->direction()->isInternal()) { + string net_vname = reader->netVerilogName(net_name); reader->warn(18, filename_, dcl->line(), "signal %s previously declared on line %d.", - reader->netVerilogName(net_name), + net_vname.c_str(), existing_dcl->line()); + } } else dcl_map_[net_name] = dcl; @@ -890,9 +911,10 @@ VerilogModule::checkInstanceName(VerilogInst *inst, stringDelete(replacement_name); replacement_name = stringPrint("%s_%d", inst_name, i); } while (inst_names.findKey(replacement_name)); + string inst_vname = reader->instanceVerilogName(inst_name); reader->warn(19, filename_, inst->line(), "instance name %s duplicated - renamed to %s.", - reader->instanceVerilogName(inst_name), + inst_vname.c_str(), replacement_name); inst_name = replacement_name; inst->setInstanceName(inst_name); @@ -1078,7 +1100,7 @@ VerilogDclArg::netName() if (net_name_) return net_name_; else if (assign_) - return assign_->lhs()->name(); + return assign_->lhs()->name().c_str(); else return nullptr; } @@ -1112,6 +1134,7 @@ class VerilogOneNetNameIterator : public VerilogNetNameIterator { public: explicit VerilogOneNetNameIterator(const char *name); + explicit VerilogOneNetNameIterator(string name); virtual bool hasNext(); virtual const char *next(); @@ -1152,6 +1175,7 @@ protected: int from_index_; int to_index_; int index_; + string bit_name_; }; VerilogBusNetNameIterator::VerilogBusNetNameIterator(const char *bus_name, @@ -1176,19 +1200,21 @@ VerilogBusNetNameIterator::hasNext() const char * VerilogBusNetNameIterator::next() { - const char *bit_name = verilogBusBitNameTmp(bus_name_, index_); + bit_name_ = verilogBusBitName(bus_name_, index_); if (to_index_ > from_index_) index_++; else index_--; - return bit_name; + return bit_name_.c_str(); } -static const char * -verilogBusBitNameTmp(const char *bus_name, - int index) +static string +verilogBusBitName(const char *bus_name, + int index) { - return stringPrintTmp("%s[%d]", bus_name, index); + string bus_bit_name; + stringPrint(bus_bit_name, "%s[%d]", bus_name, index); + return bus_bit_name; } class VerilogConstantNetNameIterator : public VerilogNetNameIterator @@ -1291,21 +1317,27 @@ VerilogNetConcatNameIterator::next() //////////////////////////////////////////////////////////////// +const string VerilogNetUnnamed::null_; + VerilogNetNamed::VerilogNetNamed(const char *name) : VerilogNet(), - name_(stringCopy(name)) + name_(name) +{ +} + +VerilogNetNamed::VerilogNetNamed(const string &name) : + VerilogNet(), + name_(name) { } VerilogNetNamed::~VerilogNetNamed() { - stringDelete(name_); } void VerilogNetNamed::setName(const char *name) { - stringDelete(name_); name_ = name; } @@ -1329,7 +1361,7 @@ verilogNetScalarSize(const char *name, int VerilogNetScalar::size(VerilogModule *module) { - return verilogNetScalarSize(name_, module); + return verilogNetScalarSize(name_.c_str(), module); } static VerilogNetNameIterator * @@ -1354,22 +1386,16 @@ VerilogNetNameIterator * VerilogNetScalar::nameIterator(VerilogModule *module, VerilogReader *) { - return verilogNetScalarNameIterator(name_, module); + return verilogNetScalarNameIterator(name_.c_str(), module); } VerilogNetBitSelect::VerilogNetBitSelect(const char *name, int index) : - VerilogNetNamed(name), + VerilogNetNamed(verilogBusBitName(name, index)), index_(index) { } -const char * -VerilogNetBitSelect::name() -{ - return verilogBusBitNameTmp(name_, index_); -} - int VerilogNetBitSelect::size(VerilogModule *) { @@ -1380,7 +1406,7 @@ VerilogNetNameIterator * VerilogNetBitSelect::nameIterator(VerilogModule *, VerilogReader *) { - return new VerilogOneNetNameIterator(verilogBusBitNameTmp(name_, index_)); + return new VerilogOneNetNameIterator(name_.c_str()); } VerilogNetPartSelect::VerilogNetPartSelect(const char *name, @@ -1405,7 +1431,7 @@ VerilogNetNameIterator * VerilogNetPartSelect::nameIterator(VerilogModule *, VerilogReader *) { - return new VerilogBusNetNameIterator(name_, from_index_, to_index_); + return new VerilogBusNetNameIterator(name_.c_str(), from_index_, to_index_); } VerilogNetConstant::VerilogNetConstant(const char *constant, @@ -1583,6 +1609,12 @@ VerilogNetPortRef::VerilogNetPortRef(const char *name) : { } +VerilogNetPortRefScalarNet::VerilogNetPortRefScalarNet(const char *name) : + VerilogNetPortRef(name), + net_name_(nullptr) +{ +} + VerilogNetPortRefScalarNet::VerilogNetPortRefScalarNet(const char *name, const char *net_name) : VerilogNetPortRef(name), @@ -1651,16 +1683,10 @@ VerilogNetPortRefBit::VerilogNetPortRefBit(const char *name, int index, VerilogNet *net) : VerilogNetPortRefScalar(name, net), - index_(index) + bit_name_(verilogBusBitName(name, index)) { } -const char * -VerilogNetPortRefBit::name() -{ - return verilogBusBitNameTmp(name_, index_); -} - VerilogNetPortRefPart::VerilogNetPortRefPart(const char *name, int from_index, int to_index, @@ -1670,8 +1696,8 @@ VerilogNetPortRefPart::VerilogNetPortRefPart(const char *name, { } -const char * -VerilogNetPortRefPart::name() +const string & +VerilogNetPortRefPart::name() const { return name_; } @@ -1813,18 +1839,19 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, const char *module_name = mod_inst->moduleName(); Cell *cell = network_->findAnyCell(module_name); if (cell == nullptr) { + string inst_vname = verilogName(mod_inst); if (make_black_boxes) { cell = makeBlackBox(mod_inst, parent_module); linkWarn(198, parent_module->filename(), mod_inst->line(), "module %s not found. Creating black box for %s.", mod_inst->moduleName(), - verilogName(mod_inst)); + inst_vname.c_str()); } else linkError(199, parent_module->filename(), mod_inst->line(), "module %s not found for instance %s.", mod_inst->moduleName(), - verilogName(mod_inst)); + inst_vname.c_str()); } if (cell) { LibertyCell *lib_cell = network_->libertyCell(cell); @@ -1868,20 +1895,22 @@ VerilogReader::makeNamedInstPins(Cell *cell, VerilogBindingTbl *parent_bindings, bool is_leaf) { + string inst_vname = verilogName(mod_inst); VerilogNetSeq::Iterator pin_iter(mod_inst->pins()); while (pin_iter.hasNext()) { VerilogNetPortRef *vpin = dynamic_cast(pin_iter.next()); - const char *port_name = vpin->name(); + const char *port_name = vpin->name().c_str(); Port *port = network_->findPort(cell, port_name); if (port) { if (vpin->hasNet() - && network_->size(port) != vpin->size(parent_module)) + && network_->size(port) != vpin->size(parent_module)) { linkWarn(200, parent_module->filename(), mod_inst->line(), "instance %s port %s size %d does not match net size %d.", - verilogName(mod_inst), + inst_vname.c_str(), network_->name(port), network_->size(port), vpin->size(parent_module)); + } else { VerilogNetNameIterator *net_name_iter = vpin->nameIterator(parent_module, this); @@ -1907,11 +1936,12 @@ VerilogReader::makeNamedInstPins(Cell *cell, if (lib_cell) pg_port = lib_cell->findPgPort(port_name); // Do not warn about connections to pg ports (which are ignored). - if (pg_port == nullptr) + if (pg_port == nullptr) { linkWarn(201, parent_module->filename(), mod_inst->line(), "instance %s port %s not found.", - verilogName(mod_inst), + inst_vname.c_str(), port_name); + } } } } @@ -1931,13 +1961,15 @@ VerilogReader::makeOrderedInstPins(Cell *cell, while (pin_iter.hasNext() && port_iter->hasNext()) { VerilogNet *net = pin_iter.next(); Port *port = port_iter->next(); - if (network_->size(port) != net->size(parent_module)) + if (network_->size(port) != net->size(parent_module)) { + string inst_vname = verilogName(mod_inst); linkWarn(202, parent_module->filename(), mod_inst->line(), "instance %s port %s size %d does not match net size %d.", - verilogName(mod_inst), + inst_vname.c_str(), network_->name(port), network_->size(port), net->size(parent_module)); + } else { VerilogNetNameIterator *net_name_iter=net->nameIterator(parent_module, this); @@ -2027,9 +2059,8 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst, if (dcl && dcl->isBus()) { VerilogDclBus *dcl_bus = dynamic_cast(dcl); // Bus is only 1 bit wide. - const char *bus_name = verilogBusBitNameTmp(net_name, - dcl_bus->fromIndex()); - net = parent_bindings->ensureNetBinding(bus_name, parent, network_); + string bus_name = verilogBusBitName(net_name, dcl_bus->fromIndex()); + net = parent_bindings->ensureNetBinding(bus_name.c_str(), parent, network_); } else net = parent_bindings->ensureNetBinding(net_name, parent, network_); @@ -2066,7 +2097,7 @@ VerilogReader::makeBlackBoxNamedPorts(Cell *cell, VerilogNetSeq::Iterator pin_iter(mod_inst->pins()); while (pin_iter.hasNext()) { VerilogNetNamed *vpin = dynamic_cast(pin_iter.next()); - const char *port_name = vpin->name(); + const char *port_name = vpin->name().c_str(); size_t size = vpin->size(parent_module); Port *port = (size == 1) ? network_->makePort(cell, port_name) diff --git a/verilog/VerilogReaderPvt.hh b/verilog/VerilogReaderPvt.hh index 34818a9e..d5fc4423 100644 --- a/verilog/VerilogReaderPvt.hh +++ b/verilog/VerilogReaderPvt.hh @@ -32,6 +32,9 @@ VerilogParse_error(const char *msg); namespace sta { +using std::string; +using std::set; + class Debug; class Report; class VerilogReader; @@ -117,6 +120,7 @@ public: VerilogNet *rhs, int line); VerilogNetScalar *makeNetScalar(const char *name); + VerilogNetPortRef *makeNetNamedPortRefScalarNet(const char *port_vname); VerilogNetPortRef *makeNetNamedPortRefScalarNet(const char *port_name, const char *net_name); VerilogNetPortRef *makeNetNamedPortRefBitSelect(const char *port_name, @@ -160,11 +164,11 @@ public: void reportStmtCounts(); const char *constant10Max() const { return constant10_max_; } size_t constant10MaxLength() const { return constant10_max_length_; } - const char * + string verilogName(VerilogModuleInst *inst); - const char * + string instanceVerilogName(const char *inst_name); - const char * + string netVerilogName(const char *net_name); protected: @@ -178,9 +182,9 @@ protected: void makeNamedPortRefCellPorts(Cell *cell, VerilogModule *module, VerilogNet *mod_port, - StringSet &port_names); + set &port_names); void checkModuleDcls(VerilogModule *module, - StringSet &port_names); + set &port_names); void makeModuleInstBody(VerilogModule *module, Instance *inst, VerilogBindingTbl *bindings, @@ -488,8 +492,8 @@ class VerilogNet public: VerilogNet() {} virtual ~VerilogNet() {} - virtual bool isNamed() = 0; - virtual const char *name() = 0; + virtual bool isNamed() const = 0; + virtual const string &name() const = 0; virtual bool isNamedPortRef() { return false; } virtual bool isNamedPortRefScalarNet() const { return false; } virtual int size(VerilogModule *module) = 0; @@ -503,23 +507,27 @@ class VerilogNetUnnamed : public VerilogNet { public: VerilogNetUnnamed() {} - virtual bool isNamed() { return false; } - virtual const char *name() { return nullptr; } + bool isNamed() const override { return false; } + const string &name() const override { return null_; } + +private: + static const string null_; }; class VerilogNetNamed : public VerilogNet { public: explicit VerilogNetNamed(const char *name); + explicit VerilogNetNamed(const string &name); virtual ~VerilogNetNamed(); - virtual bool isNamed() { return true; } + bool isNamed() const override { return true; } virtual bool isScalar() const = 0; - virtual const char *name() { return name_; } - const char *baseName() { return name_; } + const string &name() const override { return name_; } + const string baseName() const { return name_; } void setName(const char *name); protected: - const char *name_; + string name_; }; // Named net reference, which could be the name of a scalar or bus signal. @@ -538,7 +546,6 @@ class VerilogNetBitSelect : public VerilogNetNamed public: VerilogNetBitSelect(const char *name, int index); - virtual const char *name(); int index() { return index_; } virtual bool isScalar() const { return false; } virtual int size(VerilogModule *module); @@ -620,6 +627,7 @@ public: class VerilogNetPortRefScalarNet : public VerilogNetPortRef { public: + VerilogNetPortRefScalarNet(const char *name); VerilogNetPortRefScalarNet(const char *name, const char *net_name); virtual ~VerilogNetPortRefScalarNet(); @@ -658,10 +666,10 @@ public: VerilogNetPortRefBit(const char *name, int index, VerilogNet *net); - virtual const char *name(); + const string &name() const override { return bit_name_; } private: - int index_; + string bit_name_; }; class VerilogNetPortRefPart : public VerilogNetPortRefBit @@ -671,7 +679,7 @@ public: int from_index, int to_index, VerilogNet *net); - virtual const char *name(); + const string &name() const override; int toIndex() const { return to_index_; } private: diff --git a/verilog/VerilogWriter.cc b/verilog/VerilogWriter.cc index a8586bbf..ca6a9478 100644 --- a/verilog/VerilogWriter.cc +++ b/verilog/VerilogWriter.cc @@ -159,8 +159,9 @@ VerilogWriter::writePorts(Cell *cell) || !network_->direction(port)->isPowerGround()) { if (!first) fprintf(stream_, ",\n "); - fprintf(stream_, "%s", portVerilogName(network_->name(port), - network_->pathEscape())); + string verillg_name = portVerilogName(network_->name(port), + network_->pathEscape()); + fprintf(stream_, "%s", verillg_name.c_str()); first = false; } } @@ -177,8 +178,8 @@ VerilogWriter::writePortDcls(Cell *cell) PortDirection *dir = network_->direction(port); if (include_pwr_gnd_ || !network_->direction(port)->isPowerGround()) { - const char *port_name = portVerilogName(network_->name(port), - network_->pathEscape()); + string port_vname = portVerilogName(network_->name(port), + network_->pathEscape()); const char *vtype = verilogPortDir(dir); if (vtype) { fprintf(stream_, " %s", vtype); @@ -186,14 +187,14 @@ VerilogWriter::writePortDcls(Cell *cell) fprintf(stream_, " [%d:%d]", network_->fromIndex(port), network_->toIndex(port)); - fprintf(stream_, " %s;\n", port_name); + fprintf(stream_, " %s;\n", port_vname.c_str()); if (dir->isTristate()) { fprintf(stream_, " tri"); if (network_->isBus(port)) fprintf(stream_, " [%d:%d]", network_->fromIndex(port), network_->toIndex(port)); - fprintf(stream_, " %s;\n", port_name); + fprintf(stream_, " %s;\n", port_vname.c_str()); } } } @@ -238,16 +239,18 @@ VerilogWriter::writeWireDcls(Instance *inst) const char *net_name = network_->name(net); if (network_->findPort(cell, net_name) == nullptr) { if (isBusName(net_name, '[', ']', escape)) { - char *bus_name; + bool is_bus; + string bus_name; int index; - parseBusName(net_name, '[', ']', escape, bus_name, index); - BusIndexRange &range = bus_ranges[bus_name]; + parseBusName(net_name, '[', ']', escape, is_bus, bus_name, index); + BusIndexRange &range = bus_ranges[bus_name.c_str()]; range.first = max(range.first, index); range.second = min(range.second, index); } - else - fprintf(stream_, " wire %s;\n", - netVerilogName(net_name, network_->pathEscape()));; + else { + string net_vname = netVerilogName(net_name, network_->pathEscape()); + fprintf(stream_, " wire %s;\n", net_vname.c_str());; + } } } delete net_iter; @@ -255,10 +258,11 @@ VerilogWriter::writeWireDcls(Instance *inst) for (auto name_range : bus_ranges) { const char *bus_name = name_range.first; const BusIndexRange &range = name_range.second; + string net_vname = netVerilogName(bus_name, network_->pathEscape()); fprintf(stream_, " wire [%d:%d] %s;\n", range.first, range.second, - netVerilogName(bus_name, network_->pathEscape()));; + net_vname.c_str());; } // Wire net dcls for writeInstBusPinBit. @@ -297,11 +301,10 @@ VerilogWriter::writeChild(Instance *child) Cell *child_cell = network_->cell(child); if (!remove_cells_.hasKey(child_cell)) { const char *child_name = network_->name(child); - const char *child_vname = instanceVerilogName(child_name, - network_->pathEscape()); + string child_vname = instanceVerilogName(child_name, network_->pathEscape()); fprintf(stream_, " %s %s (", network_->name(child_cell), - child_vname); + child_vname.c_str()); bool first_port = true; CellPortIterator *port_iter = network_->portIterator(child_cell); while (port_iter->hasNext()) { @@ -329,14 +332,14 @@ VerilogWriter::writeInstPin(Instance *inst, Net *net = network_->net(pin); if (net) { const char *net_name = network_->name(net); - const char *net_vname = netVerilogName(net_name, network_->pathEscape()); + string net_vname = netVerilogName(net_name, network_->pathEscape()); if (!first_port) fprintf(stream_, ",\n "); - const char *port_name = portVerilogName(network_->name(port), - network_->pathEscape()); + string port_vname = portVerilogName(network_->name(port), + network_->pathEscape()); fprintf(stream_, ".%s(%s)", - port_name, - net_vname); + port_vname.c_str(), + net_vname.c_str()); first_port = false; } } @@ -382,19 +385,17 @@ VerilogWriter::writeInstBusPinBit(Instance *inst, bool &first_member) { Pin *pin = network_->findPin(inst, port); - const char *net_name = nullptr; - if (pin) { - Net *net = network_->net(pin); - if (net) - net_name = network_->name(net); - } - if (net_name == nullptr) + Net *net = pin ? network_->net(pin) : nullptr; + string net_name; + if (net) + net_name = network_->name(net); + else // There is no verilog syntax to "skip" a bit in the concatentation. - net_name = stringPrintTmp("_NC%d", unconnected_net_index_++); - const char *net_vname = netVerilogName(net_name, network_->pathEscape()); + stringPrint(net_name, "_NC%d", unconnected_net_index_++); + string net_vname = netVerilogName(net_name.c_str(), network_->pathEscape()); if (!first_member) fprintf(stream_, ",\n "); - fprintf(stream_, "%s", net_vname); + fprintf(stream_, "%s", net_vname.c_str()); first_member = false; } @@ -414,11 +415,13 @@ VerilogWriter::writeAssigns(Instance *inst) && network_->direction(port)->isAnyOutput() && !stringEqual(network_->name(port), network_->name(net))) { // Port name is different from net name. + string port_vname = netVerilogName(network_->name(port), + network_->pathEscape()); + string net_vname = netVerilogName(network_->name(net), + network_->pathEscape()); fprintf(stream_, " assign %s = %s;\n", - netVerilogName(network_->name(port), - network_->pathEscape()), - netVerilogName(network_->name(net), - network_->pathEscape())); + port_vname.c_str(), + net_vname.c_str()); } } delete pin_iter;