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