This commit is contained in:
James Cherry 2019-04-01 09:05:07 -07:00
parent ed3ad4fb30
commit fcfec7ae54
16 changed files with 172 additions and 124 deletions

View File

@ -16,7 +16,7 @@
cmake_minimum_required (VERSION 3.9) cmake_minimum_required (VERSION 3.9)
project(STA VERSION 2.0.12) project(STA VERSION 2.0.13)
set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)

View File

@ -16,6 +16,7 @@
#include "Machine.hh" #include "Machine.hh"
#include "StringUtil.hh" #include "StringUtil.hh"
#include "Corner.hh"
#include "DcalcAnalysisPt.hh" #include "DcalcAnalysisPt.hh"
namespace sta { namespace sta {
@ -23,19 +24,13 @@ namespace sta {
DcalcAnalysisPt::DcalcAnalysisPt(Corner *corner, DcalcAnalysisPt::DcalcAnalysisPt(Corner *corner,
DcalcAPIndex index, DcalcAPIndex index,
const OperatingConditions *op_cond, const OperatingConditions *op_cond,
const MinMax *cnst_min_max, const MinMax *min_max,
const MinMax *delay_min_max, const MinMax *check_clk_slew_min_max) :
const MinMax *slew_min_max,
const MinMax *check_clk_slew_min_max,
const ParasiticAnalysisPt *parasitic_ap) :
corner_(corner), corner_(corner),
index_(index), index_(index),
op_cond_(op_cond), op_cond_(op_cond),
cnst_min_max_(cnst_min_max), min_max_(min_max),
delay_min_max_(delay_min_max), check_clk_slew_min_max_(check_clk_slew_min_max)
slew_min_max_(slew_min_max),
check_clk_slew_min_max_(check_clk_slew_min_max),
parasitic_ap_(parasitic_ap)
{ {
} }
@ -45,11 +40,10 @@ DcalcAnalysisPt::setOperatingConditions(const OperatingConditions *op_cond)
op_cond_ = op_cond; op_cond_ = op_cond;
} }
void ParasiticAnalysisPt *
DcalcAnalysisPt:: DcalcAnalysisPt::parasiticAnalysisPt() const
setParasiticAnalysisPt(const ParasiticAnalysisPt *parasitic_ap)
{ {
parasitic_ap_ = parasitic_ap; return corner_->findParasiticAnalysisPt(min_max_);
} }
void void

View File

@ -39,11 +39,8 @@ public:
DcalcAnalysisPt(Corner *corner, DcalcAnalysisPt(Corner *corner,
DcalcAPIndex index, DcalcAPIndex index,
const OperatingConditions *op_cond, const OperatingConditions *op_cond,
const MinMax *cnst_min_max, const MinMax *min_max,
const MinMax *delay_min_max, const MinMax *check_clk_slew_min_max);
const MinMax *slew_min_max,
const MinMax *check_clk_slew_min_max,
const ParasiticAnalysisPt *parasitic_ap);
Corner *corner() const { return corner_; } Corner *corner() const { return corner_; }
// Which of the delay_count results this analysis point corresponds to. // Which of the delay_count results this analysis point corresponds to.
DcalcAPIndex index() const { return index_; } DcalcAPIndex index() const { return index_; }
@ -54,16 +51,15 @@ public:
// Slew min/max of timing check clock. // Slew min/max of timing check clock.
const MinMax *checkClkSlewMinMax() const { return check_clk_slew_min_max_; } const MinMax *checkClkSlewMinMax() const { return check_clk_slew_min_max_; }
// Constraint min/max values to use. // Constraint min/max values to use.
const MinMax *constraintMinMax() const { return cnst_min_max_; } const MinMax *constraintMinMax() const { return min_max_; }
// Constraints::operatingCondition(cnst_min_max_) // Constraints::operatingCondition(cnst_min_max_)
const OperatingConditions *operatingConditions() const { return op_cond_; } const OperatingConditions *operatingConditions() const { return op_cond_; }
void setOperatingConditions(const OperatingConditions *op_cond); void setOperatingConditions(const OperatingConditions *op_cond);
// Delay merging min/max operator (for wires). // Delay merging min/max operator (for wires).
const MinMax *delayMinMax() const { return delay_min_max_; } const MinMax *delayMinMax() const { return min_max_; }
// Merge min/max slews across timing arcs. // Merge min/max slews across timing arcs.
const MinMax *slewMinMax() const { return slew_min_max_; } const MinMax *slewMinMax() const { return min_max_; }
const ParasiticAnalysisPt *parasiticAnalysisPt()const{return parasitic_ap_;} ParasiticAnalysisPt *parasiticAnalysisPt() const;
void setParasiticAnalysisPt(const ParasiticAnalysisPt *parasitic_ap);
void setCheckClkSlewIndex(DcalcAPIndex index); void setCheckClkSlewIndex(DcalcAPIndex index);
int libertyIndex() const; int libertyIndex() const;
@ -74,11 +70,8 @@ private:
DcalcAPIndex index_; DcalcAPIndex index_;
DcalcAPIndex check_clk_slew_index_; DcalcAPIndex check_clk_slew_index_;
const OperatingConditions *op_cond_; const OperatingConditions *op_cond_;
const MinMax *cnst_min_max_; const MinMax *min_max_;
const MinMax *delay_min_max_;
const MinMax *slew_min_max_;
const MinMax *check_clk_slew_min_max_; const MinMax *check_clk_slew_min_max_;
const ParasiticAnalysisPt *parasitic_ap_;
}; };
} // namespace } // namespace

View File

@ -848,7 +848,8 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
ocv_arc_depth_(0.0), ocv_arc_depth_(0.0),
ocv_derate_(nullptr), ocv_derate_(nullptr),
is_disabled_constraint_(false), is_disabled_constraint_(false),
leakage_power_(0.0) leakage_power_(0.0),
leakage_power_exists_(false)
{ {
} }
@ -1081,6 +1082,16 @@ void
LibertyCell::setLeakagePower(float leakage) LibertyCell::setLeakagePower(float leakage)
{ {
leakage_power_ = leakage; leakage_power_ = leakage;
leakage_power_exists_ = true;
}
void
LibertyCell::leakagePower(// Return values.
float &leakage,
bool &exists) const
{
leakage = leakage_power_;
exists = leakage_power_exists_;
} }
void void

View File

@ -429,7 +429,10 @@ public:
bool hasTimingArcs(LibertyPort *port) const; bool hasTimingArcs(LibertyPort *port) const;
InternalPowerSeq *internalPowers() { return &internal_powers_; } InternalPowerSeq *internalPowers() { return &internal_powers_; }
LeakagePowerSeq *leakagePowers() { return &leakage_powers_; } LeakagePowerSeq *leakagePowers() { return &leakage_powers_; }
float leakagePower() const { return leakage_power_; } void leakagePower(// Return values.
float &leakage,
bool &exists) const;
bool leakagePowerEx() const { return leakage_power_exists_; }
bool hasSequentials() const; bool hasSequentials() const;
void makeSequential(int size, void makeSequential(int size,
bool is_register, bool is_register,
@ -537,6 +540,7 @@ protected:
bool is_disabled_constraint_; bool is_disabled_constraint_;
Vector<LibertyCell*> corner_cells_; Vector<LibertyCell*> corner_cells_;
float leakage_power_; float leakage_power_;
bool leakage_power_exists_;
LibertyPgPortMap pg_port_map_; LibertyPgPortMap pg_port_map_;
private: private:

View File

@ -193,9 +193,17 @@ EstimateParasitics::estimatePiElmoreBalanced(const Pin *drvr_pin,
} }
delete load_iter; delete load_iter;
c1 = static_cast<float>(y2 * y2 / y3); if (y3 == 0) {
c2 = static_cast<float>(y1 - y2 * y2 / y3); // No loads.
rpi = static_cast<float>(-y3 * y3 / (y2 * y2 * y2)); c1 = 0.0;
c2 = 0.0;
rpi = 0.0;
}
else {
c1 = static_cast<float>(y2 * y2 / y3);
c2 = static_cast<float>(y1 - y2 * y2 / y3);
rpi = static_cast<float>(-y3 * y3 / (y2 * y2 * y2));
}
elmore_res = static_cast<float>(res_fanout); elmore_res = static_cast<float>(res_fanout);
elmore_cap = static_cast<float>(cap_fanout); elmore_cap = static_cast<float>(cap_fanout);
elmore_use_load_cap = true; elmore_use_load_cap = true;

View File

@ -253,7 +253,8 @@ LibertyPortPairNameLess::operator()(const LibertyPortPair *pair1,
} }
void void
sortLibertyPortPairSet(LibertyPortPairSet *sets, LibertyPortPairSeq &pairs) sortLibertyPortPairSet(LibertyPortPairSet *sets,
LibertyPortPairSeq &pairs)
{ {
LibertyPortPairSet::Iterator pair_iter(sets); LibertyPortPairSet::Iterator pair_iter(sets);
while (pair_iter.hasNext()) while (pair_iter.hasNext())

View File

@ -105,7 +105,8 @@ sortDisabledInstancePortsMap(DisabledInstancePortsMap *inst_map,
Network *network, Network *network,
DisabledInstancePortsSeq &disables); DisabledInstancePortsSeq &disables);
void void
sortLibertyPortPairSet(LibertyPortPairSet *sets, LibertyPortPairSeq &pairs); sortLibertyPortPairSet(LibertyPortPairSet *sets,
LibertyPortPairSeq &pairs);
} // namespace } // namespace
#endif #endif

View File

@ -24,24 +24,23 @@
namespace sta { namespace sta {
Corners::Corners(StaState *sta) : Corners::Corners(StaState *sta) :
StaState(sta), StaState(sta)
default_corner_(nullptr)
{ {
} }
Corners::~Corners() Corners::~Corners()
{ {
clear(); clear();
parasitic_analysis_pts_.deleteContentsClear();
} }
void void
Corners::clear() Corners::clear()
{ {
corners_.deleteContentsClear(); corners_.deleteContentsClear();
corner_map_.clear();
dcalc_analysis_pts_.deleteContentsClear(); dcalc_analysis_pts_.deleteContentsClear();
path_analysis_pts_.deleteContentsClear(); path_analysis_pts_.deleteContentsClear();
default_corner_ = nullptr; parasitic_analysis_pts_.deleteContentsClear();
} }
int int
@ -59,13 +58,13 @@ Corners::multiCorner() const
Corner * Corner *
Corners::findCorner(const char *corner_name) Corners::findCorner(const char *corner_name)
{ {
return corners_.findKey(corner_name); return corner_map_.findKey(corner_name);
} }
Corner * Corner *
Corners::defaultCorner() Corners::findCorner(int corner_index)
{ {
return default_corner_; return corners_[corner_index];
} }
void void
@ -96,10 +95,9 @@ Corners::makeCorners(StringSet *corner_names)
while (name_iter.hasNext()) { while (name_iter.hasNext()) {
const char *name = name_iter.next(); const char *name = name_iter.next();
Corner *corner = new Corner(name, index); Corner *corner = new Corner(name, index);
corners_.push_back(corner);
// Use the copied name in the map. // Use the copied name in the map.
corners_[corner->name()] = corner; corner_map_[corner->name()] = corner;
if (default_corner_ == nullptr)
default_corner_ = corner;
index++; index++;
} }
updateCornerParasiticAnalysisPts(); updateCornerParasiticAnalysisPts();
@ -142,11 +140,11 @@ Corners::makeParasiticAnalysisPtsMinMax()
void void
Corners::updateCornerParasiticAnalysisPts() Corners::updateCornerParasiticAnalysisPts()
{ {
CornerMap::Iterator corner_iter(corners_); CornerSeq::Iterator corner_iter(corners_);
while (corner_iter.hasNext()) { while (corner_iter.hasNext()) {
Corner *corner = corner_iter.next(); Corner *corner = corner_iter.next();
corner->setParasiticAnalysisPtcount(parasitic_analysis_pts_.size()); corner->setParasiticAnalysisPtcount(parasitic_analysis_pts_.size());
ParasiticAnalysisPtIterator ap_iter(this); ParasiticAnalysisPtSeq::Iterator ap_iter(parasitic_analysis_pts_);
while (ap_iter.hasNext()) { while (ap_iter.hasNext()) {
ParasiticAnalysisPt *ap = ap_iter.next(); ParasiticAnalysisPt *ap = ap_iter.next();
corner->addParasiticAP(ap); corner->addParasiticAP(ap);
@ -160,7 +158,7 @@ Corners::makeAnalysisPts()
dcalc_analysis_pts_.deleteContentsClear(); dcalc_analysis_pts_.deleteContentsClear();
path_analysis_pts_.deleteContentsClear(); path_analysis_pts_.deleteContentsClear();
CornerMap::Iterator corner_iter(corners_); CornerSeq::Iterator corner_iter(corners_);
while (corner_iter.hasNext()) { while (corner_iter.hasNext()) {
Corner *corner = corner_iter.next(); Corner *corner = corner_iter.next();
makeDcalcAnalysisPts(corner); makeDcalcAnalysisPts(corner);
@ -200,13 +198,10 @@ Corners::makeDcalcAnalysisPt(Corner *corner,
const MinMax *check_clk_slew_min_max) const MinMax *check_clk_slew_min_max)
{ {
OperatingConditions *op_cond = sdc_->operatingConditions(min_max); OperatingConditions *op_cond = sdc_->operatingConditions(min_max);
ParasiticAnalysisPt *parasitic_ap = corner->findParasiticAnalysisPt(min_max);
DcalcAnalysisPt *dcalc_ap = new DcalcAnalysisPt(corner, DcalcAnalysisPt *dcalc_ap = new DcalcAnalysisPt(corner,
dcalc_analysis_pts_.size(), dcalc_analysis_pts_.size(),
op_cond, min_max, op_cond, min_max,
min_max, min_max, check_clk_slew_min_max);
check_clk_slew_min_max,
parasitic_ap);
dcalc_analysis_pts_.push_back(dcalc_ap); dcalc_analysis_pts_.push_back(dcalc_ap);
corner->addDcalcAP(dcalc_ap); corner->addDcalcAP(dcalc_ap);
return dcalc_ap; return dcalc_ap;

View File

@ -34,6 +34,7 @@ class Corner;
class Corners; class Corners;
class LibertyLibrary; class LibertyLibrary;
typedef Vector<Corner*> CornerSeq;
typedef Map<const char *, Corner*, CharPtrLess> CornerMap; typedef Map<const char *, Corner*, CharPtrLess> CornerMap;
typedef Vector<ParasiticAnalysisPt*> ParasiticAnalysisPtSeq; typedef Vector<ParasiticAnalysisPt*> ParasiticAnalysisPtSeq;
typedef Vector<DcalcAnalysisPt*> DcalcAnalysisPtSeq; typedef Vector<DcalcAnalysisPt*> DcalcAnalysisPtSeq;
@ -49,7 +50,7 @@ public:
int count() const; int count() const;
bool multiCorner() const; bool multiCorner() const;
Corner *findCorner(const char *corner); Corner *findCorner(const char *corner);
Corner *defaultCorner(); Corner *findCorner(int corner_index);
void makeCorners(StringSet *corner_names); void makeCorners(StringSet *corner_names);
void analysisTypeChanged(); void analysisTypeChanged();
void operatingConditionsChanged(); void operatingConditionsChanged();
@ -80,11 +81,11 @@ protected:
bool swap_clk_min_max, bool swap_clk_min_max,
DcalcAnalysisPt *dcalc_ap_min, DcalcAnalysisPt *dcalc_ap_min,
DcalcAnalysisPt *dcalc_ap_max); DcalcAnalysisPt *dcalc_ap_max);
CornerMap &corners() { return corners_; } CornerSeq &corners() { return corners_; }
private: private:
CornerMap corners_; CornerMap corner_map_;
Corner *default_corner_; CornerSeq corners_;
ParasiticAnalysisPtSeq parasitic_analysis_pts_; ParasiticAnalysisPtSeq parasitic_analysis_pts_;
DcalcAnalysisPtSeq dcalc_analysis_pts_; DcalcAnalysisPtSeq dcalc_analysis_pts_;
PathAnalysisPtSeq path_analysis_pts_; PathAnalysisPtSeq path_analysis_pts_;
@ -137,7 +138,7 @@ public:
virtual Corner *next(); virtual Corner *next();
protected: protected:
CornerMap::ConstIterator iter_; CornerSeq::ConstIterator iter_;
private: private:
DISALLOW_COPY_AND_ASSIGN(CornerIterator); DISALLOW_COPY_AND_ASSIGN(CornerIterator);

View File

@ -252,29 +252,59 @@ Power::loadCap(const Pin *to_pin,
} }
void void
Power::findLeakagePower(const Instance *inst, Power::findLeakagePower(const Instance *,
LibertyCell *cell, LibertyCell *cell,
// Return values. // Return values.
PowerResult &result) PowerResult &result)
{ {
float leakage = cell->leakagePower(); float cond_leakage = 0.0;
bool found_cond = false;
float default_leakage = 0.0;
bool found_default = false;
LibertyCellLeakagePowerIterator pwr_iter(cell); LibertyCellLeakagePowerIterator pwr_iter(cell);
while (pwr_iter.hasNext()) { while (pwr_iter.hasNext()) {
LeakagePower *leak = pwr_iter.next(); LeakagePower *leak = pwr_iter.next();
FuncExpr *when = leak->when(); FuncExpr *when = leak->when();
if (when) { if (when) {
LogicValue when_value = sim_->evalExpr(when, inst); FuncExprPortIterator port_iter(when);
switch (when_value) { float duty = 1.0;
case LogicValue::zero: while (port_iter.hasNext()) {
case LogicValue::one: auto port = port_iter.next();
leakage = max(leakage, leak->power()); if (port->direction()->isAnyInput())
break; duty *= .5;
case LogicValue::unknown:
default:
break;
} }
debugPrint4(debug_, "power", 2, "leakage %s %s %.3e * %.2f\n",
cell->name(),
when->asString(),
leak->power(),
duty);
cond_leakage += leak->power() * duty;
found_cond = true;
}
else {
debugPrint2(debug_, "power", 2, "leakage default %s %.3e\n",
cell->name(),
leak->power());
default_leakage += leak->power();
found_default = true;
} }
} }
float leakage = 0.0;
float leak;
bool exists;
cell->leakagePower(leak, exists);
if (exists) {
// Prefer cell_leakage_power until propagated activities exist.
debugPrint2(debug_, "power", 2, "leakage %s cell %.3e\n",
cell->name(),
leak);
leakage = leak;
}
// Ignore default leakages unless there are no conditional leakage groups.
else if (found_cond)
leakage = cond_leakage;
else if (found_default)
leakage = default_leakage;
result.setLeakage(leakage); result.setLeakage(leakage);
} }
@ -292,6 +322,15 @@ Power::findSwitchingPower(LibertyCell *cell,
result.setSwitching(switching); result.setSwitching(switching);
} }
float
Power::activity(const Pin *pin)
{
float activity1;
bool is_clk;
activity(pin, activity1, is_clk);
return activity1;
}
void void
Power::activity(const Pin *pin, Power::activity(const Pin *pin,
// Return values. // Return values.

View File

@ -78,6 +78,7 @@ protected:
// Return values. // Return values.
float &activity, float &activity,
bool &is_clk); bool &is_clk);
float activity(const Pin *pin);
float voltage(LibertyCell *cell, float voltage(LibertyCell *cell,
const LibertyPort *port, const LibertyPort *port,
const DcalcAnalysisPt *dcalc_ap); const DcalcAnalysisPt *dcalc_ap);

View File

@ -301,9 +301,8 @@ Sta::makeComponents()
updateComponentsState(); updateComponentsState();
makeObservers(); makeObservers();
// This must follow updateComponentsState.
corners_->makeParasiticAnalysisPtsSingle(); corners_->makeParasiticAnalysisPtsSingle();
makeDefaultCorners();
setThreadCount(defaultThreadCount()); setThreadCount(defaultThreadCount());
} }
@ -667,8 +666,7 @@ Sta::setMinLibrary(const char *min_filename,
{ {
LibertyLibrary *max_lib = network_->findLibertyFilename(max_filename); LibertyLibrary *max_lib = network_->findLibertyFilename(max_filename);
if (max_lib) { if (max_lib) {
LibertyLibrary *min_lib = readLibertyFile(min_filename, LibertyLibrary *min_lib = readLibertyFile(min_filename, cmd_corner_,
corners_->defaultCorner(),
MinMaxAll::min(), false, MinMaxAll::min(), false,
report_, debug_, network_); report_, debug_, network_);
return min_lib != nullptr; return min_lib != nullptr;
@ -2339,12 +2337,6 @@ Sta::setClkThruTristateEnabled(bool enable)
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
Corner *
Sta::defaultCorner()
{
return corners_->defaultCorner();
}
Corner * Corner *
Sta::findCorner(const char *corner_name) Sta::findCorner(const char *corner_name)
{ {
@ -2357,24 +2349,33 @@ Sta::multiCorner()
return corners_->multiCorner(); return corners_->multiCorner();
} }
// Init one corner named "default".
void void
Sta::makeCorners() Sta::makeCorners()
{ {
corners_ = new Corners(this); corners_ = new Corners(this);
StringSet corner_names;
corner_names.insert("default");
makeCorners(&corner_names);
} }
void void
Sta::makeCorners(StringSet *corner_names) Sta::makeCorners(StringSet *corner_names)
{ {
corners_->makeCorners(corner_names); corners_->makeCorners(corner_names);
cmd_corner_ = corners_->findCorner(0);
}
Corner *
Sta::cmdCorner() const
{
return cmd_corner_;
} }
void void
Sta::makeDefaultCorners() Sta::setCmdCorner(Corner *corner)
{ {
StringSet corner_names; cmd_corner_ = corner;
corner_names.insert("default");
corners_->makeCorners(&corner_names);
} }
void void
@ -3344,7 +3345,7 @@ Sta::setPortExtWireCap(Port *port,
const MinMaxAll *min_max, const MinMaxAll *min_max,
float cap) float cap)
{ {
Corner *corner = corners_->defaultCorner(); Corner *corner = cmd_corner_;
TransRiseFallIterator tr_iter(tr); TransRiseFallIterator tr_iter(tr);
while (tr_iter.hasNext()) { while (tr_iter.hasNext()) {
TransRiseFall *tr1 = tr_iter.next(); TransRiseFall *tr1 = tr_iter.next();
@ -3489,7 +3490,7 @@ Sta::readSpef(const char *filename,
bool save, bool save,
bool quiet) bool quiet)
{ {
Corner *corner = corners_->defaultCorner(); Corner *corner = cmd_corner_;
const MinMax *cnst_min_max; const MinMax *cnst_min_max;
ParasiticAnalysisPt *ap; ParasiticAnalysisPt *ap;
if (min_max == MinMaxAll::all()) { if (min_max == MinMaxAll::all()) {
@ -3510,27 +3511,9 @@ Sta::readSpef(const char *filename,
reduce_to, delete_after_reduce, reduce_to, delete_after_reduce,
op_cond, corner, cnst_min_max, save, quiet, op_cond, corner, cnst_min_max, save, quiet,
report_, network_, parasitics_); report_, network_, parasitics_);
parasiticsChangedAfter();
return success;
}
void
Sta::parasiticsChangedAfter()
{
// Update the delay calculation analysis points to use the parasitics.
CornerIterator corner_iter(sta_);
while (corner_iter.hasNext()) {
Corner *corner = corner_iter.next();
MinMaxIterator mm_iter;
while (mm_iter.hasNext()) {
MinMax *min_max = mm_iter.next();
ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(min_max);
DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
dcalc_ap->setParasiticAnalysisPt(ap);
}
}
graph_delay_calc_->delaysInvalid(); graph_delay_calc_->delaysInvalid();
search_->arrivalsInvalid(); search_->arrivalsInvalid();
return success;
} }
void void
@ -3542,7 +3525,7 @@ Sta::findPiElmore(Pin *drvr_pin,
float &c1, float &c1,
bool &exists) const bool &exists) const
{ {
Corner *corner = corners_->defaultCorner(); Corner *corner = cmd_corner_;
const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(min_max); const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(min_max);
if (parasitics_->hasPiElmore(drvr_pin, tr, ap)) { if (parasitics_->hasPiElmore(drvr_pin, tr, ap)) {
Parasitic *pi_elmore = parasitics_->findPiElmore(drvr_pin, tr, ap); Parasitic *pi_elmore = parasitics_->findPiElmore(drvr_pin, tr, ap);
@ -3561,7 +3544,7 @@ Sta::makePiElmore(Pin *drvr_pin,
float rpi, float rpi,
float c1) float c1)
{ {
Corner *corner = corners_->defaultCorner(); Corner *corner = cmd_corner_;
MinMaxIterator mm_iter(min_max); MinMaxIterator mm_iter(min_max);
while (mm_iter.hasNext()) { while (mm_iter.hasNext()) {
MinMax *mm = mm_iter.next(); MinMax *mm = mm_iter.next();
@ -3579,7 +3562,7 @@ Sta::findElmore(Pin *drvr_pin,
float &elmore, float &elmore,
bool &exists) const bool &exists) const
{ {
Corner *corner = corners_->defaultCorner(); Corner *corner = cmd_corner_;
const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(min_max); const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(min_max);
if (parasitics_->hasPiElmore(drvr_pin, tr, ap)) { if (parasitics_->hasPiElmore(drvr_pin, tr, ap)) {
Parasitic *pi_elmore = parasitics_->findPiElmore(drvr_pin, tr, ap); Parasitic *pi_elmore = parasitics_->findPiElmore(drvr_pin, tr, ap);
@ -3597,7 +3580,7 @@ Sta::setElmore(Pin *drvr_pin,
const MinMaxAll *min_max, const MinMaxAll *min_max,
float elmore) float elmore)
{ {
Corner *corner = corners_->defaultCorner(); Corner *corner = cmd_corner_;
MinMaxIterator mm_iter(min_max); MinMaxIterator mm_iter(min_max);
while (mm_iter.hasNext()) { while (mm_iter.hasNext()) {
MinMax *mm = mm_iter.next(); MinMax *mm = mm_iter.next();

View File

@ -1133,7 +1133,8 @@ public:
Tcl_Interp *tclInterp(); Tcl_Interp *tclInterp();
// Ensure that the timing graph has been built. // Ensure that the timing graph has been built.
Graph *ensureGraph(); Graph *ensureGraph();
Corner *defaultCorner(); Corner *cmdCorner() const;
void setCmdCorner(Corner *corner);
Corner *findCorner(const char *corner_name); Corner *findCorner(const char *corner_name);
bool multiCorner(); bool multiCorner();
void makeCorners(StringSet *corner_names); void makeCorners(StringSet *corner_names);
@ -1292,17 +1293,16 @@ protected:
void findRegisterPreamble(); void findRegisterPreamble();
bool crossesHierarchy(Edge *edge) const; bool crossesHierarchy(Edge *edge) const;
void deleteLeafInstanceBefore(Instance *inst); void deleteLeafInstanceBefore(Instance *inst);
void makeDefaultCorners();
void readLibertyAfter(LibertyLibrary *liberty, void readLibertyAfter(LibertyLibrary *liberty,
Corner *corner, Corner *corner,
const MinMax *min_max); const MinMax *min_max);
void parasiticsChangedAfter();
void powerPreamble(); void powerPreamble();
void disableFanoutCrprPruning(Vertex *vertex, void disableFanoutCrprPruning(Vertex *vertex,
int &fanou); int &fanou);
CmdNamespace cmd_namespace_; CmdNamespace cmd_namespace_;
Instance *current_instance_; Instance *current_instance_;
Corner *cmd_corner_;
CheckTiming *check_timing_; CheckTiming *check_timing_;
CheckSlewLimits *check_slew_limits_; CheckSlewLimits *check_slew_limits_;
CheckMinPulseWidths *check_min_pulse_widths_; CheckMinPulseWidths *check_min_pulse_widths_;

View File

@ -1255,7 +1255,7 @@ proc parse_corner { keys_var } {
} elseif { [multi_corner] } { } elseif { [multi_corner] } {
sta_error "-corner keyword required with multi-corner analysis." sta_error "-corner keyword required with multi-corner analysis."
} else { } else {
return [default_corner] return [cmd_corner]
} }
} }
@ -1289,7 +1289,7 @@ proc parse_corner_or_default { keys_var } {
return $corner return $corner
} }
} else { } else {
return [default_corner] return [cmd_corner]
} }
} }

View File

@ -1988,6 +1988,13 @@ private:
~OperatingConditions(); ~OperatingConditions();
}; };
class Corner
{
private:
Corner();
~Corner();
};
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// //
// C++ functions visible as TCL functions. // C++ functions visible as TCL functions.
@ -2735,10 +2742,24 @@ leaf_instance_iterator()
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
Corner * void
default_corner() define_corners_cmd(StringSet *corner_names)
{ {
return Sta::sta()->defaultCorner(); Sta *sta = Sta::sta();
sta->makeCorners(corner_names);
delete corner_names;
}
Corner *
cmd_corner()
{
return Sta::sta()->cmdCorner();
}
void
set_cmd_corner(Corner *corner)
{
Sta::sta()->setCmdCorner(corner);
} }
Corner * Corner *
@ -5169,14 +5190,6 @@ arrivals_invalid()
sta->arrivalsInvalid(); sta->arrivalsInvalid();
} }
void
define_corners_cmd(StringSet *corner_names)
{
Sta *sta = Sta::sta();
sta->makeCorners(corner_names);
delete corner_names;
}
%} // inline %} // inline
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -6133,6 +6146,10 @@ finish()
} }
%extend Corner {
const char *name() { return self->name(); }
}
// Local Variables: // Local Variables:
// mode:c++ // mode:c++
// End: // End: