corner parasitics APs
This commit is contained in:
parent
8cf84facee
commit
9e27f27060
|
|
@ -55,12 +55,9 @@ public:
|
||||||
void analysisTypeChanged();
|
void analysisTypeChanged();
|
||||||
void operatingConditionsChanged();
|
void operatingConditionsChanged();
|
||||||
|
|
||||||
// Make one parasitic analysis point shared by all corners.
|
// Make one parasitic analysis points.
|
||||||
void makeParasiticAnalysisPtsSingle();
|
void makeParasiticAnalysisPts(bool per_corner,
|
||||||
// Make min/max parasitic analysis points shared by all corners.
|
bool per_min_max);
|
||||||
void makeParasiticAnalysisPtsMinMax();
|
|
||||||
// Make one parasitic analysis point for each corner.
|
|
||||||
void makeCornerParasiticAnalysisPts();
|
|
||||||
int parasiticAnalysisPtCount() const;
|
int parasiticAnalysisPtCount() const;
|
||||||
ParasiticAnalysisPtSeq ¶siticAnalysisPts();
|
ParasiticAnalysisPtSeq ¶siticAnalysisPts();
|
||||||
|
|
||||||
|
|
@ -80,7 +77,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void makeAnalysisPts();
|
void makeAnalysisPts();
|
||||||
void updateCornerParasiticAnalysisPts();
|
|
||||||
void makeDcalcAnalysisPts(Corner *corner);
|
void makeDcalcAnalysisPts(Corner *corner);
|
||||||
DcalcAnalysisPt *makeDcalcAnalysisPt(Corner *corner,
|
DcalcAnalysisPt *makeDcalcAnalysisPt(Corner *corner,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
|
|
|
||||||
|
|
@ -1052,17 +1052,24 @@ public:
|
||||||
// Caller owns iterator and iterator->container().
|
// Caller owns iterator and iterator->container().
|
||||||
SlowDrvrIterator *slowDrvrIterator();
|
SlowDrvrIterator *slowDrvrIterator();
|
||||||
|
|
||||||
|
// Make parasitic analysis points.
|
||||||
|
// per_corner per_min_max ap_count
|
||||||
|
// false false 1
|
||||||
|
// false true 2
|
||||||
|
// true false corners
|
||||||
|
// true true corners*2
|
||||||
|
void setParasiticAnalysisPts(bool per_corner,
|
||||||
|
bool per_min_max);
|
||||||
// Annotate hierarchical "instance" with parasitics.
|
// Annotate hierarchical "instance" with parasitics.
|
||||||
// The parasitic analysis point is ap_name.
|
// The parasitic analysis point is ap_name.
|
||||||
// The parasitics are used by delay calculation analysis points
|
|
||||||
// specfied by min_max.
|
|
||||||
// The parasitic memory footprint is much smaller if parasitic
|
// The parasitic memory footprint is much smaller if parasitic
|
||||||
// networks (dspf) are reduced and deleted after reading each net
|
// networks (dspf) are reduced and deleted after reading each net
|
||||||
// with reduce_to and delete_after_reduce.
|
// with reduce_to and delete_after_reduce.
|
||||||
// Return true if successful.
|
// Return true if successful.
|
||||||
bool readSpef(const char *filename,
|
bool readSpef(const char *filename,
|
||||||
Instance *instance,
|
Instance *instance,
|
||||||
const MinMaxAll *min_max,
|
const Corner *corner,
|
||||||
|
const MinMaxAll *min_max,
|
||||||
bool increment,
|
bool increment,
|
||||||
bool pin_cap_included,
|
bool pin_cap_included,
|
||||||
bool keep_coupling_caps,
|
bool keep_coupling_caps,
|
||||||
|
|
@ -1343,6 +1350,7 @@ protected:
|
||||||
void sdcChangedGraph();
|
void sdcChangedGraph();
|
||||||
void ensureGraphSdcAnnotated();
|
void ensureGraphSdcAnnotated();
|
||||||
CornerSeq makeCornerSeq(Corner *corner) const;
|
CornerSeq makeCornerSeq(Corner *corner) const;
|
||||||
|
void makeParasiticAnalysisPts();
|
||||||
|
|
||||||
CmdNamespace cmd_namespace_;
|
CmdNamespace cmd_namespace_;
|
||||||
Instance *current_instance_;
|
Instance *current_instance_;
|
||||||
|
|
@ -1362,6 +1370,8 @@ protected:
|
||||||
bool update_genclks_;
|
bool update_genclks_;
|
||||||
EquivCells *equiv_cells_;
|
EquivCells *equiv_cells_;
|
||||||
bool graph_sdc_annotated_;
|
bool graph_sdc_annotated_;
|
||||||
|
bool parasitics_per_corner_;
|
||||||
|
bool parasitics_per_min_max_;
|
||||||
|
|
||||||
// Singleton sta used by tcl command interpreter.
|
// Singleton sta used by tcl command interpreter.
|
||||||
static Sta *sta_;
|
static Sta *sta_;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ using sta::TmpFloatSeq;
|
||||||
bool
|
bool
|
||||||
read_spef_cmd(const char *filename,
|
read_spef_cmd(const char *filename,
|
||||||
Instance *instance,
|
Instance *instance,
|
||||||
MinMaxAll *min_max,
|
const Corner *corner,
|
||||||
|
const MinMaxAll *min_max,
|
||||||
bool increment,
|
bool increment,
|
||||||
bool pin_cap_included,
|
bool pin_cap_included,
|
||||||
bool keep_coupling_caps,
|
bool keep_coupling_caps,
|
||||||
|
|
@ -46,7 +47,7 @@ read_spef_cmd(const char *filename,
|
||||||
bool quiet)
|
bool quiet)
|
||||||
{
|
{
|
||||||
cmdLinkedNetwork();
|
cmdLinkedNetwork();
|
||||||
return Sta::sta()->readSpef(filename, instance, min_max,
|
return Sta::sta()->readSpef(filename, instance, corner, min_max,
|
||||||
increment, pin_cap_included,
|
increment, pin_cap_included,
|
||||||
keep_coupling_caps, coupling_cap_factor,
|
keep_coupling_caps, coupling_cap_factor,
|
||||||
reduce_to, delete_after_reduce, quiet);
|
reduce_to, delete_after_reduce, quiet);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@
|
||||||
namespace eval sta {
|
namespace eval sta {
|
||||||
|
|
||||||
define_cmd_args "read_spef" \
|
define_cmd_args "read_spef" \
|
||||||
{[-min]\
|
{[-corner corner]\
|
||||||
|
[-min]\
|
||||||
[-max]\
|
[-max]\
|
||||||
[-path path]\
|
[-path path]\
|
||||||
[-increment]\
|
[-increment]\
|
||||||
|
|
@ -46,6 +47,7 @@ proc_redirect read_spef {
|
||||||
sta_error 433 "path instance '$path' not found."
|
sta_error 433 "path instance '$path' not found."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set corner [parse_corner_or_all keys]
|
||||||
set min_max [parse_min_max_all_flags flags]
|
set min_max [parse_min_max_all_flags flags]
|
||||||
set increment [info exists flags(-increment)]
|
set increment [info exists flags(-increment)]
|
||||||
set coupling_reduction_factor 1.0
|
set coupling_reduction_factor 1.0
|
||||||
|
|
@ -67,7 +69,7 @@ proc_redirect read_spef {
|
||||||
set quiet [info exists flags(-quiet)]
|
set quiet [info exists flags(-quiet)]
|
||||||
set save [info exists flags(-save)]
|
set save [info exists flags(-save)]
|
||||||
set filename [file nativename [lindex $args 0]]
|
set filename [file nativename [lindex $args 0]]
|
||||||
return [read_spef_cmd $filename $instance $min_max $increment \
|
return [read_spef_cmd $filename $instance $corner $min_max $increment \
|
||||||
$pin_cap_included $keep_coupling_caps $coupling_reduction_factor \
|
$pin_cap_included $keep_coupling_caps $coupling_reduction_factor \
|
||||||
$reduce_to $delete_after_reduce $quiet]
|
$reduce_to $delete_after_reduce $quiet]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,32 +114,58 @@ Corners::copy(Corners *corners)
|
||||||
}
|
}
|
||||||
makeAnalysisPts();
|
makeAnalysisPts();
|
||||||
|
|
||||||
parasitic_analysis_pts_.deleteContentsClear();
|
|
||||||
for (ParasiticAnalysisPt *orig_ap : corners->parasitic_analysis_pts_) {
|
for (ParasiticAnalysisPt *orig_ap : corners->parasitic_analysis_pts_) {
|
||||||
ParasiticAnalysisPt *ap = new ParasiticAnalysisPt(orig_ap->name(), orig_ap->index(),
|
ParasiticAnalysisPt *ap = new ParasiticAnalysisPt(orig_ap->name(), orig_ap->index(),
|
||||||
orig_ap->minMax());
|
orig_ap->minMax());
|
||||||
parasitic_analysis_pts_.push_back(ap);
|
parasitic_analysis_pts_.push_back(ap);
|
||||||
}
|
}
|
||||||
updateCornerParasiticAnalysisPts();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
int i = 0;
|
||||||
Corners::makeParasiticAnalysisPtsSingle()
|
for (Corner *orig : corners->corners_) {
|
||||||
{
|
Corner *corner = corners_[i];
|
||||||
if (parasitic_analysis_pts_.size() != 1) {
|
for (ParasiticAnalysisPt *ap : orig->parasitic_analysis_pts_)
|
||||||
parasitic_analysis_pts_.deleteContentsClear();
|
corner->addParasiticAP(parasitic_analysis_pts_[ap->index()]);
|
||||||
ParasiticAnalysisPt *ap = new ParasiticAnalysisPt("min_max", 0,
|
i++;
|
||||||
MinMax::max());
|
|
||||||
parasitic_analysis_pts_.push_back(ap);
|
|
||||||
updateCornerParasiticAnalysisPts();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Corners::makeParasiticAnalysisPtsMinMax()
|
Corners::makeParasiticAnalysisPts(bool per_corner,
|
||||||
|
bool per_min_max)
|
||||||
{
|
{
|
||||||
if (parasitic_analysis_pts_.size() != 2) {
|
parasitic_analysis_pts_.deleteContentsClear();
|
||||||
parasitic_analysis_pts_.deleteContentsClear();
|
if (per_corner && per_min_max) {
|
||||||
|
// each corner has min/max parasitics
|
||||||
|
parasitic_analysis_pts_.resize(corners_.size() * MinMax::index_count);
|
||||||
|
for (Corner *corner : corners_) {
|
||||||
|
corner->setParasiticAnalysisPtcount(1);
|
||||||
|
for (MinMax *min_max : MinMax::range()) {
|
||||||
|
int mm_index = min_max->index();
|
||||||
|
int ap_index = corner->index() * MinMax::index_count + mm_index;
|
||||||
|
string ap_name = corner->name();
|
||||||
|
ap_name += "_";
|
||||||
|
ap_name += min_max->asString();
|
||||||
|
ParasiticAnalysisPt *ap = new ParasiticAnalysisPt(ap_name.c_str(),
|
||||||
|
ap_index,
|
||||||
|
min_max);
|
||||||
|
parasitic_analysis_pts_.push_back(ap);
|
||||||
|
corner->addParasiticAP(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (per_corner && !per_min_max) {
|
||||||
|
// each corner has parasitics
|
||||||
|
parasitic_analysis_pts_.resize(corners_.size());
|
||||||
|
for (Corner *corner : corners_) {
|
||||||
|
corner->setParasiticAnalysisPtcount(1);
|
||||||
|
ParasiticAnalysisPt *ap = new ParasiticAnalysisPt("min_max", 0,
|
||||||
|
MinMax::max());
|
||||||
|
parasitic_analysis_pts_.push_back(ap);
|
||||||
|
corner->addParasiticAP(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!per_corner && per_min_max) {
|
||||||
|
// min/max parasitics shared by all corners
|
||||||
parasitic_analysis_pts_.resize(MinMax::index_count);
|
parasitic_analysis_pts_.resize(MinMax::index_count);
|
||||||
for (MinMax *min_max : MinMax::range()) {
|
for (MinMax *min_max : MinMax::range()) {
|
||||||
int mm_index = min_max->index();
|
int mm_index = min_max->index();
|
||||||
|
|
@ -148,35 +174,20 @@ Corners::makeParasiticAnalysisPtsMinMax()
|
||||||
min_max);
|
min_max);
|
||||||
parasitic_analysis_pts_[mm_index] = ap;
|
parasitic_analysis_pts_[mm_index] = ap;
|
||||||
}
|
}
|
||||||
updateCornerParasiticAnalysisPts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Corners::updateCornerParasiticAnalysisPts()
|
|
||||||
{
|
|
||||||
for (Corner *corner : corners_) {
|
|
||||||
corner->setParasiticAnalysisPtcount(parasitic_analysis_pts_.size());
|
|
||||||
for (ParasiticAnalysisPt *ap : parasitic_analysis_pts_)
|
|
||||||
corner->addParasiticAP(ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Corners::makeCornerParasiticAnalysisPts()
|
|
||||||
{
|
|
||||||
if (parasitic_analysis_pts_.size() != corners_.size()) {
|
|
||||||
parasitic_analysis_pts_.deleteContentsClear();
|
|
||||||
parasitic_analysis_pts_.resize(corners_.size());
|
|
||||||
MinMax *min_max = MinMax::max();
|
|
||||||
int ap_index = 0;
|
|
||||||
for (Corner *corner : corners_) {
|
for (Corner *corner : corners_) {
|
||||||
ParasiticAnalysisPt *ap = new ParasiticAnalysisPt(corner->name(),
|
corner->setParasiticAnalysisPtcount(2);
|
||||||
ap_index,
|
for (ParasiticAnalysisPt *ap : parasitic_analysis_pts_)
|
||||||
min_max);
|
corner->addParasiticAP(ap);
|
||||||
parasitic_analysis_pts_[ap_index] = ap;
|
}
|
||||||
|
}
|
||||||
|
else if (!per_corner && !per_min_max) {
|
||||||
|
// single parasitics shared by all corners
|
||||||
|
ParasiticAnalysisPt *ap = new ParasiticAnalysisPt("min_max", 0,
|
||||||
|
MinMax::max());
|
||||||
|
parasitic_analysis_pts_.push_back(ap);
|
||||||
|
for (Corner *corner : corners_) {
|
||||||
|
corner->setParasiticAnalysisPtcount(1);
|
||||||
corner->addParasiticAP(ap);
|
corner->addParasiticAP(ap);
|
||||||
ap_index++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,10 @@ Sta::Sta() :
|
||||||
link_make_black_boxes_(true),
|
link_make_black_boxes_(true),
|
||||||
update_genclks_(false),
|
update_genclks_(false),
|
||||||
equiv_cells_(nullptr),
|
equiv_cells_(nullptr),
|
||||||
graph_sdc_annotated_(false)
|
graph_sdc_annotated_(false),
|
||||||
|
// Default to same parasitics for each corner min/max.
|
||||||
|
parasitics_per_corner_(false),
|
||||||
|
parasitics_per_min_max_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,7 +302,7 @@ Sta::makeComponents()
|
||||||
|
|
||||||
makeObservers();
|
makeObservers();
|
||||||
// This must follow updateComponentsState.
|
// This must follow updateComponentsState.
|
||||||
corners_->makeParasiticAnalysisPtsSingle();
|
makeParasiticAnalysisPts();
|
||||||
setThreadCount(defaultThreadCount());
|
setThreadCount(defaultThreadCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2404,7 +2407,7 @@ Sta::makeCorners(StringSet *corner_names)
|
||||||
{
|
{
|
||||||
parasitics_->deleteParasitics();
|
parasitics_->deleteParasitics();
|
||||||
corners_->makeCorners(corner_names);
|
corners_->makeCorners(corner_names);
|
||||||
corners_->makeParasiticAnalysisPtsSingle();
|
makeParasiticAnalysisPts();
|
||||||
cmd_corner_ = corners_->findCorner(0);
|
cmd_corner_ = corners_->findCorner(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3653,6 +3656,7 @@ Sta::setResistance(Net *net,
|
||||||
bool
|
bool
|
||||||
Sta::readSpef(const char *filename,
|
Sta::readSpef(const char *filename,
|
||||||
Instance *instance,
|
Instance *instance,
|
||||||
|
const Corner *corner,
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
bool increment,
|
bool increment,
|
||||||
bool pin_cap_included,
|
bool pin_cap_included,
|
||||||
|
|
@ -3662,19 +3666,14 @@ Sta::readSpef(const char *filename,
|
||||||
bool delete_after_reduce,
|
bool delete_after_reduce,
|
||||||
bool quiet)
|
bool quiet)
|
||||||
{
|
{
|
||||||
Corner *corner = cmd_corner_;
|
setParasiticAnalysisPts(corner != nullptr,
|
||||||
const MinMax *cnst_min_max;
|
min_max != MinMaxAll::all());
|
||||||
ParasiticAnalysisPt *ap;
|
if (corner == nullptr)
|
||||||
if (min_max == MinMaxAll::all()) {
|
corner = cmd_corner_;
|
||||||
corners_->makeParasiticAnalysisPtsSingle();
|
const MinMax *cnst_min_max = (min_max == MinMaxAll::all())
|
||||||
ap = corner->findParasiticAnalysisPt(MinMax::max());
|
? cnst_min_max = MinMax::max()
|
||||||
cnst_min_max = MinMax::max();
|
: cnst_min_max = min_max->asMinMax();
|
||||||
}
|
ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(cnst_min_max);
|
||||||
else {
|
|
||||||
corners_->makeParasiticAnalysisPtsMinMax();
|
|
||||||
cnst_min_max = min_max->asMinMax();
|
|
||||||
ap = corner->findParasiticAnalysisPt(cnst_min_max);
|
|
||||||
}
|
|
||||||
const OperatingConditions *op_cond =
|
const OperatingConditions *op_cond =
|
||||||
sdc_->operatingConditions(cnst_min_max);
|
sdc_->operatingConditions(cnst_min_max);
|
||||||
bool success = readSpefFile(filename, instance, ap, increment,
|
bool success = readSpefFile(filename, instance, ap, increment,
|
||||||
|
|
@ -3688,6 +3687,26 @@ Sta::readSpef(const char *filename,
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Sta::setParasiticAnalysisPts(bool per_corner,
|
||||||
|
bool per_min_max)
|
||||||
|
{
|
||||||
|
if (per_corner != parasitics_per_corner_
|
||||||
|
|| per_min_max != parasitics_per_min_max_) {
|
||||||
|
deleteParasitics();
|
||||||
|
parasitics_per_corner_ = per_corner;
|
||||||
|
parasitics_per_min_max_ = per_min_max;
|
||||||
|
makeParasiticAnalysisPts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Sta::makeParasiticAnalysisPts()
|
||||||
|
{
|
||||||
|
corners_->makeParasiticAnalysisPts(parasitics_per_corner_,
|
||||||
|
parasitics_per_min_max_);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::findPiElmore(Pin *drvr_pin,
|
Sta::findPiElmore(Pin *drvr_pin,
|
||||||
const RiseFall *rf,
|
const RiseFall *rf,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue