report_parasitic_annotation
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
af35dfb929
commit
60dcc75336
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
-------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue