From 60dcc75336cbfbb6300e5c494596e194f9f815aa Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 1 Oct 2022 18:45:22 -0700 Subject: [PATCH] report_parasitic_annotation Signed-off-by: James Cherry --- CMakeLists.txt | 1 + doc/ChangeLog.txt | 4 + include/sta/Parasitics.hh | 6 +- include/sta/Sta.hh | 2 + parasitics/Parasitics.i | 8 ++ parasitics/Parasitics.tcl | 11 ++ parasitics/ReportParasiticAnnotation.cc | 151 ++++++++++++++++++++++++ parasitics/ReportParasiticAnnotation.hh | 29 +++++ search/Sta.cc | 9 ++ 9 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 parasitics/ReportParasiticAnnotation.cc create mode 100644 parasitics/ReportParasiticAnnotation.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e47f123..3d86545b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/doc/ChangeLog.txt b/doc/ChangeLog.txt index 3b5951e6..14101458 100644 --- a/doc/ChangeLog.txt +++ b/doc/ChangeLog.txt @@ -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 ------------------------- diff --git a/include/sta/Parasitics.hh b/include/sta/Parasitics.hh index 63cbc33e..276098ca 100644 --- a/include/sta/Parasitics.hh +++ b/include/sta/Parasitics.hh @@ -39,10 +39,11 @@ typedef Iterator 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; }; diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index ec2e9cf7..f01d538b 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -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, diff --git a/parasitics/Parasitics.i b/parasitics/Parasitics.i index 4344fbe5..6d178a06 100644 --- a/parasitics/Parasitics.i +++ b/parasitics/Parasitics.i @@ -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, diff --git a/parasitics/Parasitics.tcl b/parasitics/Parasitics.tcl index eb628759..b316d578 100644 --- a/parasitics/Parasitics.tcl +++ b/parasitics/Parasitics.tcl @@ -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} diff --git a/parasitics/ReportParasiticAnnotation.cc b/parasitics/ReportParasiticAnnotation.cc new file mode 100644 index 00000000..442f284a --- /dev/null +++ b/parasitics/ReportParasiticAnnotation.cc @@ -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 . + +#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 diff --git a/parasitics/ReportParasiticAnnotation.hh b/parasitics/ReportParasiticAnnotation.hh new file mode 100644 index 00000000..8e711c0c --- /dev/null +++ b/parasitics/ReportParasiticAnnotation.hh @@ -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 . + +#pragma once + +namespace sta { + +class StaState; +class Corner; + +void +reportParasiticAnnotation(bool report_unannotated, + const Corner *corner, + StaState *sta); + +} // namespace diff --git a/search/Sta.cc b/search/Sta.cc index f5ffb127..a6402e3c 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -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,