corner parasitics APs

This commit is contained in:
James Cherry 2021-05-15 16:55:10 -07:00
parent 8cf84facee
commit 9e27f27060
6 changed files with 111 additions and 72 deletions

View File

@ -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 &parasiticAnalysisPts();
@ -80,7 +77,6 @@ public:
protected:
void makeAnalysisPts();
void updateCornerParasiticAnalysisPts();
void makeDcalcAnalysisPts(Corner *corner);
DcalcAnalysisPt *makeDcalcAnalysisPt(Corner *corner,
const MinMax *min_max,

View File

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

View File

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

View File

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

View File

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

View File

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