2.0.13
This commit is contained in:
parent
ed3ad4fb30
commit
fcfec7ae54
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
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_CXX_STANDARD 11)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "Machine.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "Corner.hh"
|
||||
#include "DcalcAnalysisPt.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -23,19 +24,13 @@ namespace sta {
|
|||
DcalcAnalysisPt::DcalcAnalysisPt(Corner *corner,
|
||||
DcalcAPIndex index,
|
||||
const OperatingConditions *op_cond,
|
||||
const MinMax *cnst_min_max,
|
||||
const MinMax *delay_min_max,
|
||||
const MinMax *slew_min_max,
|
||||
const MinMax *check_clk_slew_min_max,
|
||||
const ParasiticAnalysisPt *parasitic_ap) :
|
||||
const MinMax *min_max,
|
||||
const MinMax *check_clk_slew_min_max) :
|
||||
corner_(corner),
|
||||
index_(index),
|
||||
op_cond_(op_cond),
|
||||
cnst_min_max_(cnst_min_max),
|
||||
delay_min_max_(delay_min_max),
|
||||
slew_min_max_(slew_min_max),
|
||||
check_clk_slew_min_max_(check_clk_slew_min_max),
|
||||
parasitic_ap_(parasitic_ap)
|
||||
min_max_(min_max),
|
||||
check_clk_slew_min_max_(check_clk_slew_min_max)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -45,11 +40,10 @@ DcalcAnalysisPt::setOperatingConditions(const OperatingConditions *op_cond)
|
|||
op_cond_ = op_cond;
|
||||
}
|
||||
|
||||
void
|
||||
DcalcAnalysisPt::
|
||||
setParasiticAnalysisPt(const ParasiticAnalysisPt *parasitic_ap)
|
||||
ParasiticAnalysisPt *
|
||||
DcalcAnalysisPt::parasiticAnalysisPt() const
|
||||
{
|
||||
parasitic_ap_ = parasitic_ap;
|
||||
return corner_->findParasiticAnalysisPt(min_max_);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -39,11 +39,8 @@ public:
|
|||
DcalcAnalysisPt(Corner *corner,
|
||||
DcalcAPIndex index,
|
||||
const OperatingConditions *op_cond,
|
||||
const MinMax *cnst_min_max,
|
||||
const MinMax *delay_min_max,
|
||||
const MinMax *slew_min_max,
|
||||
const MinMax *check_clk_slew_min_max,
|
||||
const ParasiticAnalysisPt *parasitic_ap);
|
||||
const MinMax *min_max,
|
||||
const MinMax *check_clk_slew_min_max);
|
||||
Corner *corner() const { return corner_; }
|
||||
// Which of the delay_count results this analysis point corresponds to.
|
||||
DcalcAPIndex index() const { return index_; }
|
||||
|
|
@ -54,16 +51,15 @@ public:
|
|||
// Slew min/max of timing check clock.
|
||||
const MinMax *checkClkSlewMinMax() const { return check_clk_slew_min_max_; }
|
||||
// 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_)
|
||||
const OperatingConditions *operatingConditions() const { return op_cond_; }
|
||||
void setOperatingConditions(const OperatingConditions *op_cond);
|
||||
// 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.
|
||||
const MinMax *slewMinMax() const { return slew_min_max_; }
|
||||
const ParasiticAnalysisPt *parasiticAnalysisPt()const{return parasitic_ap_;}
|
||||
void setParasiticAnalysisPt(const ParasiticAnalysisPt *parasitic_ap);
|
||||
const MinMax *slewMinMax() const { return min_max_; }
|
||||
ParasiticAnalysisPt *parasiticAnalysisPt() const;
|
||||
void setCheckClkSlewIndex(DcalcAPIndex index);
|
||||
int libertyIndex() const;
|
||||
|
||||
|
|
@ -74,11 +70,8 @@ private:
|
|||
DcalcAPIndex index_;
|
||||
DcalcAPIndex check_clk_slew_index_;
|
||||
const OperatingConditions *op_cond_;
|
||||
const MinMax *cnst_min_max_;
|
||||
const MinMax *delay_min_max_;
|
||||
const MinMax *slew_min_max_;
|
||||
const MinMax *min_max_;
|
||||
const MinMax *check_clk_slew_min_max_;
|
||||
const ParasiticAnalysisPt *parasitic_ap_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -848,7 +848,8 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
|
|||
ocv_arc_depth_(0.0),
|
||||
ocv_derate_(nullptr),
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -429,7 +429,10 @@ public:
|
|||
bool hasTimingArcs(LibertyPort *port) const;
|
||||
InternalPowerSeq *internalPowers() { return &internal_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;
|
||||
void makeSequential(int size,
|
||||
bool is_register,
|
||||
|
|
@ -537,6 +540,7 @@ protected:
|
|||
bool is_disabled_constraint_;
|
||||
Vector<LibertyCell*> corner_cells_;
|
||||
float leakage_power_;
|
||||
bool leakage_power_exists_;
|
||||
LibertyPgPortMap pg_port_map_;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -193,9 +193,17 @@ EstimateParasitics::estimatePiElmoreBalanced(const Pin *drvr_pin,
|
|||
}
|
||||
delete load_iter;
|
||||
|
||||
c1 = static_cast<float>(y2 * y2 / y3);
|
||||
c2 = static_cast<float>(y1 - y2 * y2 / y3);
|
||||
rpi = static_cast<float>(-y3 * y3 / (y2 * y2 * y2));
|
||||
if (y3 == 0) {
|
||||
// No loads.
|
||||
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_cap = static_cast<float>(cap_fanout);
|
||||
elmore_use_load_cap = true;
|
||||
|
|
|
|||
|
|
@ -253,7 +253,8 @@ LibertyPortPairNameLess::operator()(const LibertyPortPair *pair1,
|
|||
}
|
||||
|
||||
void
|
||||
sortLibertyPortPairSet(LibertyPortPairSet *sets, LibertyPortPairSeq &pairs)
|
||||
sortLibertyPortPairSet(LibertyPortPairSet *sets,
|
||||
LibertyPortPairSeq &pairs)
|
||||
{
|
||||
LibertyPortPairSet::Iterator pair_iter(sets);
|
||||
while (pair_iter.hasNext())
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ sortDisabledInstancePortsMap(DisabledInstancePortsMap *inst_map,
|
|||
Network *network,
|
||||
DisabledInstancePortsSeq &disables);
|
||||
void
|
||||
sortLibertyPortPairSet(LibertyPortPairSet *sets, LibertyPortPairSeq &pairs);
|
||||
sortLibertyPortPairSet(LibertyPortPairSet *sets,
|
||||
LibertyPortPairSeq &pairs);
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,24 +24,23 @@
|
|||
namespace sta {
|
||||
|
||||
Corners::Corners(StaState *sta) :
|
||||
StaState(sta),
|
||||
default_corner_(nullptr)
|
||||
StaState(sta)
|
||||
{
|
||||
}
|
||||
|
||||
Corners::~Corners()
|
||||
{
|
||||
clear();
|
||||
parasitic_analysis_pts_.deleteContentsClear();
|
||||
}
|
||||
|
||||
void
|
||||
Corners::clear()
|
||||
{
|
||||
corners_.deleteContentsClear();
|
||||
corner_map_.clear();
|
||||
dcalc_analysis_pts_.deleteContentsClear();
|
||||
path_analysis_pts_.deleteContentsClear();
|
||||
default_corner_ = nullptr;
|
||||
parasitic_analysis_pts_.deleteContentsClear();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -59,13 +58,13 @@ Corners::multiCorner() const
|
|||
Corner *
|
||||
Corners::findCorner(const char *corner_name)
|
||||
{
|
||||
return corners_.findKey(corner_name);
|
||||
return corner_map_.findKey(corner_name);
|
||||
}
|
||||
|
||||
Corner *
|
||||
Corners::defaultCorner()
|
||||
Corners::findCorner(int corner_index)
|
||||
{
|
||||
return default_corner_;
|
||||
return corners_[corner_index];
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -96,10 +95,9 @@ Corners::makeCorners(StringSet *corner_names)
|
|||
while (name_iter.hasNext()) {
|
||||
const char *name = name_iter.next();
|
||||
Corner *corner = new Corner(name, index);
|
||||
corners_.push_back(corner);
|
||||
// Use the copied name in the map.
|
||||
corners_[corner->name()] = corner;
|
||||
if (default_corner_ == nullptr)
|
||||
default_corner_ = corner;
|
||||
corner_map_[corner->name()] = corner;
|
||||
index++;
|
||||
}
|
||||
updateCornerParasiticAnalysisPts();
|
||||
|
|
@ -142,11 +140,11 @@ Corners::makeParasiticAnalysisPtsMinMax()
|
|||
void
|
||||
Corners::updateCornerParasiticAnalysisPts()
|
||||
{
|
||||
CornerMap::Iterator corner_iter(corners_);
|
||||
CornerSeq::Iterator corner_iter(corners_);
|
||||
while (corner_iter.hasNext()) {
|
||||
Corner *corner = corner_iter.next();
|
||||
corner->setParasiticAnalysisPtcount(parasitic_analysis_pts_.size());
|
||||
ParasiticAnalysisPtIterator ap_iter(this);
|
||||
ParasiticAnalysisPtSeq::Iterator ap_iter(parasitic_analysis_pts_);
|
||||
while (ap_iter.hasNext()) {
|
||||
ParasiticAnalysisPt *ap = ap_iter.next();
|
||||
corner->addParasiticAP(ap);
|
||||
|
|
@ -160,7 +158,7 @@ Corners::makeAnalysisPts()
|
|||
dcalc_analysis_pts_.deleteContentsClear();
|
||||
path_analysis_pts_.deleteContentsClear();
|
||||
|
||||
CornerMap::Iterator corner_iter(corners_);
|
||||
CornerSeq::Iterator corner_iter(corners_);
|
||||
while (corner_iter.hasNext()) {
|
||||
Corner *corner = corner_iter.next();
|
||||
makeDcalcAnalysisPts(corner);
|
||||
|
|
@ -200,13 +198,10 @@ Corners::makeDcalcAnalysisPt(Corner *corner,
|
|||
const MinMax *check_clk_slew_min_max)
|
||||
{
|
||||
OperatingConditions *op_cond = sdc_->operatingConditions(min_max);
|
||||
ParasiticAnalysisPt *parasitic_ap = corner->findParasiticAnalysisPt(min_max);
|
||||
DcalcAnalysisPt *dcalc_ap = new DcalcAnalysisPt(corner,
|
||||
dcalc_analysis_pts_.size(),
|
||||
op_cond, min_max,
|
||||
min_max, min_max,
|
||||
check_clk_slew_min_max,
|
||||
parasitic_ap);
|
||||
check_clk_slew_min_max);
|
||||
dcalc_analysis_pts_.push_back(dcalc_ap);
|
||||
corner->addDcalcAP(dcalc_ap);
|
||||
return dcalc_ap;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class Corner;
|
|||
class Corners;
|
||||
class LibertyLibrary;
|
||||
|
||||
typedef Vector<Corner*> CornerSeq;
|
||||
typedef Map<const char *, Corner*, CharPtrLess> CornerMap;
|
||||
typedef Vector<ParasiticAnalysisPt*> ParasiticAnalysisPtSeq;
|
||||
typedef Vector<DcalcAnalysisPt*> DcalcAnalysisPtSeq;
|
||||
|
|
@ -49,7 +50,7 @@ public:
|
|||
int count() const;
|
||||
bool multiCorner() const;
|
||||
Corner *findCorner(const char *corner);
|
||||
Corner *defaultCorner();
|
||||
Corner *findCorner(int corner_index);
|
||||
void makeCorners(StringSet *corner_names);
|
||||
void analysisTypeChanged();
|
||||
void operatingConditionsChanged();
|
||||
|
|
@ -80,11 +81,11 @@ protected:
|
|||
bool swap_clk_min_max,
|
||||
DcalcAnalysisPt *dcalc_ap_min,
|
||||
DcalcAnalysisPt *dcalc_ap_max);
|
||||
CornerMap &corners() { return corners_; }
|
||||
CornerSeq &corners() { return corners_; }
|
||||
|
||||
private:
|
||||
CornerMap corners_;
|
||||
Corner *default_corner_;
|
||||
CornerMap corner_map_;
|
||||
CornerSeq corners_;
|
||||
ParasiticAnalysisPtSeq parasitic_analysis_pts_;
|
||||
DcalcAnalysisPtSeq dcalc_analysis_pts_;
|
||||
PathAnalysisPtSeq path_analysis_pts_;
|
||||
|
|
@ -137,7 +138,7 @@ public:
|
|||
virtual Corner *next();
|
||||
|
||||
protected:
|
||||
CornerMap::ConstIterator iter_;
|
||||
CornerSeq::ConstIterator iter_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CornerIterator);
|
||||
|
|
|
|||
|
|
@ -252,29 +252,59 @@ Power::loadCap(const Pin *to_pin,
|
|||
}
|
||||
|
||||
void
|
||||
Power::findLeakagePower(const Instance *inst,
|
||||
Power::findLeakagePower(const Instance *,
|
||||
LibertyCell *cell,
|
||||
// Return values.
|
||||
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);
|
||||
while (pwr_iter.hasNext()) {
|
||||
LeakagePower *leak = pwr_iter.next();
|
||||
FuncExpr *when = leak->when();
|
||||
if (when) {
|
||||
LogicValue when_value = sim_->evalExpr(when, inst);
|
||||
switch (when_value) {
|
||||
case LogicValue::zero:
|
||||
case LogicValue::one:
|
||||
leakage = max(leakage, leak->power());
|
||||
break;
|
||||
case LogicValue::unknown:
|
||||
default:
|
||||
break;
|
||||
FuncExprPortIterator port_iter(when);
|
||||
float duty = 1.0;
|
||||
while (port_iter.hasNext()) {
|
||||
auto port = port_iter.next();
|
||||
if (port->direction()->isAnyInput())
|
||||
duty *= .5;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -292,6 +322,15 @@ Power::findSwitchingPower(LibertyCell *cell,
|
|||
result.setSwitching(switching);
|
||||
}
|
||||
|
||||
float
|
||||
Power::activity(const Pin *pin)
|
||||
{
|
||||
float activity1;
|
||||
bool is_clk;
|
||||
activity(pin, activity1, is_clk);
|
||||
return activity1;
|
||||
}
|
||||
|
||||
void
|
||||
Power::activity(const Pin *pin,
|
||||
// Return values.
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ protected:
|
|||
// Return values.
|
||||
float &activity,
|
||||
bool &is_clk);
|
||||
float activity(const Pin *pin);
|
||||
float voltage(LibertyCell *cell,
|
||||
const LibertyPort *port,
|
||||
const DcalcAnalysisPt *dcalc_ap);
|
||||
|
|
|
|||
|
|
@ -301,9 +301,8 @@ Sta::makeComponents()
|
|||
updateComponentsState();
|
||||
|
||||
makeObservers();
|
||||
|
||||
// This must follow updateComponentsState.
|
||||
corners_->makeParasiticAnalysisPtsSingle();
|
||||
makeDefaultCorners();
|
||||
setThreadCount(defaultThreadCount());
|
||||
}
|
||||
|
||||
|
|
@ -667,8 +666,7 @@ Sta::setMinLibrary(const char *min_filename,
|
|||
{
|
||||
LibertyLibrary *max_lib = network_->findLibertyFilename(max_filename);
|
||||
if (max_lib) {
|
||||
LibertyLibrary *min_lib = readLibertyFile(min_filename,
|
||||
corners_->defaultCorner(),
|
||||
LibertyLibrary *min_lib = readLibertyFile(min_filename, cmd_corner_,
|
||||
MinMaxAll::min(), false,
|
||||
report_, debug_, network_);
|
||||
return min_lib != nullptr;
|
||||
|
|
@ -2339,12 +2337,6 @@ Sta::setClkThruTristateEnabled(bool enable)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Corner *
|
||||
Sta::defaultCorner()
|
||||
{
|
||||
return corners_->defaultCorner();
|
||||
}
|
||||
|
||||
Corner *
|
||||
Sta::findCorner(const char *corner_name)
|
||||
{
|
||||
|
|
@ -2357,24 +2349,33 @@ Sta::multiCorner()
|
|||
return corners_->multiCorner();
|
||||
}
|
||||
|
||||
// Init one corner named "default".
|
||||
void
|
||||
Sta::makeCorners()
|
||||
{
|
||||
corners_ = new Corners(this);
|
||||
StringSet corner_names;
|
||||
corner_names.insert("default");
|
||||
makeCorners(&corner_names);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::makeCorners(StringSet *corner_names)
|
||||
{
|
||||
corners_->makeCorners(corner_names);
|
||||
cmd_corner_ = corners_->findCorner(0);
|
||||
}
|
||||
|
||||
Corner *
|
||||
Sta::cmdCorner() const
|
||||
{
|
||||
return cmd_corner_;
|
||||
}
|
||||
|
||||
void
|
||||
Sta::makeDefaultCorners()
|
||||
Sta::setCmdCorner(Corner *corner)
|
||||
{
|
||||
StringSet corner_names;
|
||||
corner_names.insert("default");
|
||||
corners_->makeCorners(&corner_names);
|
||||
cmd_corner_ = corner;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3344,7 +3345,7 @@ Sta::setPortExtWireCap(Port *port,
|
|||
const MinMaxAll *min_max,
|
||||
float cap)
|
||||
{
|
||||
Corner *corner = corners_->defaultCorner();
|
||||
Corner *corner = cmd_corner_;
|
||||
TransRiseFallIterator tr_iter(tr);
|
||||
while (tr_iter.hasNext()) {
|
||||
TransRiseFall *tr1 = tr_iter.next();
|
||||
|
|
@ -3489,7 +3490,7 @@ Sta::readSpef(const char *filename,
|
|||
bool save,
|
||||
bool quiet)
|
||||
{
|
||||
Corner *corner = corners_->defaultCorner();
|
||||
Corner *corner = cmd_corner_;
|
||||
const MinMax *cnst_min_max;
|
||||
ParasiticAnalysisPt *ap;
|
||||
if (min_max == MinMaxAll::all()) {
|
||||
|
|
@ -3510,27 +3511,9 @@ Sta::readSpef(const char *filename,
|
|||
reduce_to, delete_after_reduce,
|
||||
op_cond, corner, cnst_min_max, save, quiet,
|
||||
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();
|
||||
search_->arrivalsInvalid();
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3542,7 +3525,7 @@ Sta::findPiElmore(Pin *drvr_pin,
|
|||
float &c1,
|
||||
bool &exists) const
|
||||
{
|
||||
Corner *corner = corners_->defaultCorner();
|
||||
Corner *corner = cmd_corner_;
|
||||
const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(min_max);
|
||||
if (parasitics_->hasPiElmore(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 c1)
|
||||
{
|
||||
Corner *corner = corners_->defaultCorner();
|
||||
Corner *corner = cmd_corner_;
|
||||
MinMaxIterator mm_iter(min_max);
|
||||
while (mm_iter.hasNext()) {
|
||||
MinMax *mm = mm_iter.next();
|
||||
|
|
@ -3579,7 +3562,7 @@ Sta::findElmore(Pin *drvr_pin,
|
|||
float &elmore,
|
||||
bool &exists) const
|
||||
{
|
||||
Corner *corner = corners_->defaultCorner();
|
||||
Corner *corner = cmd_corner_;
|
||||
const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(min_max);
|
||||
if (parasitics_->hasPiElmore(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,
|
||||
float elmore)
|
||||
{
|
||||
Corner *corner = corners_->defaultCorner();
|
||||
Corner *corner = cmd_corner_;
|
||||
MinMaxIterator mm_iter(min_max);
|
||||
while (mm_iter.hasNext()) {
|
||||
MinMax *mm = mm_iter.next();
|
||||
|
|
|
|||
|
|
@ -1133,7 +1133,8 @@ public:
|
|||
Tcl_Interp *tclInterp();
|
||||
// Ensure that the timing graph has been built.
|
||||
Graph *ensureGraph();
|
||||
Corner *defaultCorner();
|
||||
Corner *cmdCorner() const;
|
||||
void setCmdCorner(Corner *corner);
|
||||
Corner *findCorner(const char *corner_name);
|
||||
bool multiCorner();
|
||||
void makeCorners(StringSet *corner_names);
|
||||
|
|
@ -1292,17 +1293,16 @@ protected:
|
|||
void findRegisterPreamble();
|
||||
bool crossesHierarchy(Edge *edge) const;
|
||||
void deleteLeafInstanceBefore(Instance *inst);
|
||||
void makeDefaultCorners();
|
||||
void readLibertyAfter(LibertyLibrary *liberty,
|
||||
Corner *corner,
|
||||
const MinMax *min_max);
|
||||
void parasiticsChangedAfter();
|
||||
void powerPreamble();
|
||||
void disableFanoutCrprPruning(Vertex *vertex,
|
||||
int &fanou);
|
||||
|
||||
CmdNamespace cmd_namespace_;
|
||||
Instance *current_instance_;
|
||||
Corner *cmd_corner_;
|
||||
CheckTiming *check_timing_;
|
||||
CheckSlewLimits *check_slew_limits_;
|
||||
CheckMinPulseWidths *check_min_pulse_widths_;
|
||||
|
|
|
|||
|
|
@ -1255,7 +1255,7 @@ proc parse_corner { keys_var } {
|
|||
} elseif { [multi_corner] } {
|
||||
sta_error "-corner keyword required with multi-corner analysis."
|
||||
} else {
|
||||
return [default_corner]
|
||||
return [cmd_corner]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1289,7 +1289,7 @@ proc parse_corner_or_default { keys_var } {
|
|||
return $corner
|
||||
}
|
||||
} else {
|
||||
return [default_corner]
|
||||
return [cmd_corner]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
39
tcl/StaTcl.i
39
tcl/StaTcl.i
|
|
@ -1988,6 +1988,13 @@ private:
|
|||
~OperatingConditions();
|
||||
};
|
||||
|
||||
class Corner
|
||||
{
|
||||
private:
|
||||
Corner();
|
||||
~Corner();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// C++ functions visible as TCL functions.
|
||||
|
|
@ -2735,10 +2742,24 @@ leaf_instance_iterator()
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Corner *
|
||||
default_corner()
|
||||
void
|
||||
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 *
|
||||
|
|
@ -5169,14 +5190,6 @@ arrivals_invalid()
|
|||
sta->arrivalsInvalid();
|
||||
}
|
||||
|
||||
void
|
||||
define_corners_cmd(StringSet *corner_names)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
sta->makeCorners(corner_names);
|
||||
delete corner_names;
|
||||
}
|
||||
|
||||
%} // inline
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -6133,6 +6146,10 @@ finish()
|
|||
|
||||
}
|
||||
|
||||
%extend Corner {
|
||||
const char *name() { return self->name(); }
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode:c++
|
||||
// End:
|
||||
|
|
|
|||
Loading…
Reference in New Issue