report_parasitic_annotation

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-10-01 18:45:22 -07:00
parent af35dfb929
commit 60dcc75336
9 changed files with 218 additions and 3 deletions

View File

@ -116,6 +116,7 @@ set(STA_SOURCE
parasitics/NullParasitics.cc
parasitics/Parasitics.cc
parasitics/ReduceParasitics.cc
parasitics/ReportParasiticAnnotation.cc
parasitics/SpefNamespace.cc
parasitics/SpefReader.cc
parasitics/SpefReaderPvt.hh

View File

@ -3,6 +3,10 @@ OpenSTA Timing Analyzer Release Notes
This file summarizes user visible changes for each release.
The report_parasitics_annotation command reports SPEF annotation completeness.
report_parasitics_annotation [-report_unannotated]
Release 2.3.2 2022/07/03
-------------------------

View File

@ -39,10 +39,11 @@ typedef Iterator<ParasiticNode*> ParasiticNodeIterator;
// Parasitic annotation for a pin or net may exist for one analysis point
// and not another.
// If there is only one parasitic for both rise and fall transitions
// the sta parasitic readers will save it under the rise transition.
// the parasitic readers will save it under the rise transition.
class Parasitics : public StaState
{
public:
Parasitics(StaState *sta);
virtual ~Parasitics() {}
virtual bool haveParasitics() = 0;
// Clear all state.
@ -137,7 +138,7 @@ public:
virtual void poleResidue(const Parasitic *parasitic,
int pole_index,
ComplexFloat &pole,
ComplexFloat &residue) const=0;
ComplexFloat &residue) const = 0;
////////////////////////////////////////////////////////////////
// Parasitic Network (detailed parasitics).
@ -300,7 +301,6 @@ protected:
float fanout,
const ParasiticAnalysisPt *ap);
Parasitics(StaState *sta);
Net *findParasiticNet(const Pin *pin) const;
};

View File

@ -1120,6 +1120,8 @@ public:
ReducedParasiticType reduce_to,
bool delete_after_reduce,
bool quiet);
void reportParasiticAnnotation(bool report_unannotated,
const Corner *corner);
// Parasitics.
void findPiElmore(Pin *drvr_pin,
const RiseFall *rf,

View File

@ -53,6 +53,14 @@ read_spef_cmd(const char *filename,
reduce_to, delete_after_reduce, quiet);
}
void
report_parasitic_annotation_cmd(bool report_unannotated,
const Corner *corner)
{
cmdLinkedNetwork();
Sta::sta()->reportParasiticAnnotation(report_unannotated, corner);
}
TmpFloatSeq *
find_pi_elmore(Pin *drvr_pin,
RiseFall *rf,

View File

@ -74,6 +74,17 @@ proc_redirect read_spef {
$reduce_to $delete_after_reduce $quiet]
}
define_cmd_args "report_parasitic_annotation" {}
proc_redirect report_parasitic_annotation {
parse_key_args "report_parasitic_annotation" args \
keys {} flags {-report_unannotated}
check_argc_eq0 "report_parasitic_annotation" $args
set report_unannotated [info exists flags(-report_unannotated)]
report_parasitic_annotation_cmd $report_unannotated [sta::cmd_corner]
}
# set_pi_model [-min] [-max] drvr_pin c2 rpi c1
proc set_pi_model { args } {
parse_key_args "set_pi_model" args keys {} flags {-max -min}

View File

@ -0,0 +1,151 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2022, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "ReportParasiticAnnotation.hh"
#include "Report.hh"
#include "Network.hh"
#include "Graph.hh"
#include "Corner.hh"
#include "Parasitics.hh"
#include "DcalcAnalysisPt.hh"
#include "ArcDelayCalc.hh"
namespace sta {
class ReportParasiticAnnotation : public StaState
{
public:
ReportParasiticAnnotation(bool report_unannotated,
const Corner *corner,
StaState *sta);
void report();
private:
void reportAnnotationCounts();
void findCounts();
void findCounts(Instance *inst);
void findCounts(Net *net);
bool report_unannotated_;
const Corner *corner_;
const MinMax *min_max_;
const DcalcAnalysisPt *dcalc_ap_;
const ParasiticAnalysisPt *parasitics_ap_;
NetSet unannotated_nets_;
VertexSet partially_annotated_drvrs_;
};
void
reportParasiticAnnotation(bool report_unannotated,
const Corner *corner,
StaState *sta)
{
ReportParasiticAnnotation report_annotation(report_unannotated, corner, sta);
report_annotation.report();
}
ReportParasiticAnnotation::ReportParasiticAnnotation(bool report_unannotated,
const Corner *corner,
StaState *sta) :
StaState(sta),
report_unannotated_(report_unannotated),
corner_(corner),
min_max_(MinMax::max()),
dcalc_ap_(corner_->findDcalcAnalysisPt(min_max_)),
parasitics_ap_(corner_->findParasiticAnalysisPt(min_max_)),
partially_annotated_drvrs_(graph_)
{
}
void
ReportParasiticAnnotation::report()
{
findCounts();
reportAnnotationCounts();
}
void
ReportParasiticAnnotation::reportAnnotationCounts()
{
report_->reportLine("Found %lu unannotated nets.", unannotated_nets_.size());
if (report_unannotated_) {
for (const Net *net : unannotated_nets_)
report_->reportLine(" %s", network_->pathName(net));
}
report_->reportLine("Found %lu partially unannotated nets.",
partially_annotated_drvrs_.size());
if (report_unannotated_) {
const RiseFall *rf = RiseFall::rise();
for (Vertex *vertex : partially_annotated_drvrs_) {
Pin *drvr_pin = vertex->pin();
Net *net = network_->isTopLevelPort(drvr_pin)
? network_->net(network_->term(drvr_pin))
: network_->net(drvr_pin);
report_->reportLine(" %s", network_->pathName(net));
Parasitic *parasitic = arc_delay_calc_->findParasitic(drvr_pin, rf, dcalc_ap_);
VertexOutEdgeIterator edge_iter(vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
Vertex *load_vertex = edge->to(graph_);
Pin *load_pin = load_vertex->pin();
bool elmore_exists = false;
float elmore = 0.0;
parasitics_->findElmore(parasitic, load_pin, elmore, elmore_exists);
if (!elmore_exists)
report_->reportLine(" %s", network_->pathName(load_pin));
}
}
}
}
void
ReportParasiticAnnotation::findCounts()
{
const RiseFall *rf = RiseFall::rise();
VertexIterator vertex_iter(graph_);
while (vertex_iter.hasNext()) {
Vertex *vertex = vertex_iter.next();
if (vertex->isDriver(network_)) {
Pin *drvr_pin = vertex->pin();
Parasitic *parasitic = arc_delay_calc_->findParasitic(drvr_pin, rf, dcalc_ap_);
if (parasitic) {
VertexOutEdgeIterator edge_iter(vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
Vertex *load_vertex = edge->to(graph_);
Pin *load_pin = load_vertex->pin();
bool elmore_exists = false;
float elmore = 0.0;
parasitics_->findElmore(parasitic, load_pin, elmore, elmore_exists);
if (!elmore_exists)
partially_annotated_drvrs_.insert(vertex);
}
}
else {
Net *net = network_->isTopLevelPort(drvr_pin)
? network_->net(network_->term(drvr_pin))
: network_->net(drvr_pin);
if (net)
unannotated_nets_.insert(net);
}
}
}
}
} // namespace

View File

@ -0,0 +1,29 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2022, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
namespace sta {
class StaState;
class Corner;
void
reportParasiticAnnotation(bool report_unannotated,
const Corner *corner,
StaState *sta);
} // namespace

View File

@ -41,6 +41,7 @@
#include "MakeConcreteParasitics.hh"
#include "Parasitics.hh"
#include "parasitics/SpefReader.hh"
#include "parasitics/ReportParasiticAnnotation.hh"
#include "DelayCalc.hh"
#include "ArcDelayCalc.hh"
#include "dcalc/GraphDelayCalc1.hh"
@ -3866,6 +3867,14 @@ Sta::makeParasiticAnalysisPts()
parasitics_per_min_max_);
}
void
Sta::reportParasiticAnnotation(bool report_unannotated,
const Corner *corner)
{
ensureGraph();
sta::reportParasiticAnnotation(report_unannotated, corner, this);
}
void
Sta::findPiElmore(Pin *drvr_pin,
const RiseFall *rf,