Merge pull request #154 from openroadie/master

Latest OpenSTA
This commit is contained in:
Harsh Vardhan 2023-03-28 18:32:10 -07:00 committed by GitHub
commit b7a94af32f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 1383 additions and 1361 deletions

View File

@ -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.

View File

@ -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 "";
}
////////////////////////////////////////////////////////////////

View File

@ -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,

View File

@ -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

View File

@ -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:

View File

@ -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 *

View File

@ -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

View File

@ -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();
}

View File

@ -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);

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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 *

View File

@ -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

View File

@ -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:

View File

@ -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();

View File

@ -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,

View File

@ -1106,7 +1106,7 @@ private:
LibertyCell *cell_;
};
const char *
string
portLibertyToSta(const char *port_name);
} // namespace

View File

@ -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_;
};

View File

@ -16,8 +16,12 @@
#pragma once
#include <string>
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,

View File

@ -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_; }

View File

@ -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,

View File

@ -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:

View File

@ -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

View File

@ -16,25 +16,29 @@
#pragma once
#include <string>
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

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 <multipler_digits><scale_suffix_char><unit_suffix>.
// 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

View File

@ -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_;

View File

@ -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

View File

@ -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

View File

@ -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<string, BusPort*> 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);
}
}
}

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -321,6 +321,7 @@ PropActivityVisitor::PropActivityVisitor(Power *power,
BfsFwdIterator *bfs) :
StaState(power),
visited_regs_(network_),
max_change_(0.0),
power_(power),
bfs_(bfs)
{

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 *

View File

@ -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<GateTableModel*>(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);

View File

@ -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);

View File

@ -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,

View File

@ -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 *

View File

@ -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"
}
}

View File

@ -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<char*>(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;
}

View File

@ -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
}

View File

@ -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
{

View File

@ -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 ']' ')'

View File

@ -36,9 +36,9 @@ namespace sta {
VerilogReader *verilog_reader;
static const char *unconnected_net_name = reinterpret_cast<const char*>(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<string> 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<string> &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<string> &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<VerilogNetPortRefScalarNet*>(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<VerilogNetPortRef*>(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<VerilogDclBus *>(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<VerilogNetNamed*>(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)

View File

@ -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<string> &port_names);
void checkModuleDcls(VerilogModule *module,
StringSet &port_names);
set<string> &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:

View File

@ -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;