report_checks -fileds hierarchical_pins resolves #136

commit bbcb5e6d69a7f01af186e1adf7aaff8bccada638
Author: James Cherry <cherry@parallaxsw.com>
Date:   Wed Dec 25 11:07:15 2024 -0700

    report hier pins factor

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 2b00bde920deb4f6f997f30f6f4d8ee41d2a686f
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Dec 24 18:35:24 2024 -0700

    report_checks hier pins

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit dd1a1b99d51f0adbedc6ef43b6b5e60fae075025
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Dec 24 11:22:17 2024 -0700

    report_checks error check fields

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit dc500534bddee9d514b4ed7ffb9d83289f0aaad5
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Dec 24 11:22:01 2024 -0700

    report_checks hierarchical_pins field

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit c6a4a12d9449773e677d2b12f1a41444a011b526
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Dec 24 09:56:33 2024 -0700

    report_checks hierarchical_pins field

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2024-12-25 17:44:28 -07:00
parent 3cf999c344
commit 26fccd8e7f
9 changed files with 208 additions and 64 deletions

View File

@ -33,6 +33,9 @@ is now supported by the the read_saif command.
The report_checks -group_count option has been renamed to -group_path_count. The report_checks -group_count option has been renamed to -group_path_count.
The report_checks -endpoing_count option has been renamed to -endpoint_path_count. The report_checks -endpoing_count option has been renamed to -endpoint_path_count.
The report_checks -field hierarchical_pins field reports hierarical pins between
a driver and a load in the path report.
Release 2.5.0 2024/01/17 Release 2.5.0 2024/01/17
------------------------- -------------------------

Binary file not shown.

Binary file not shown.

View File

@ -889,6 +889,7 @@ public:
void setReportPathFormat(ReportPathFormat format); void setReportPathFormat(ReportPathFormat format);
void setReportPathFieldOrder(StringSeq *field_names); void setReportPathFieldOrder(StringSeq *field_names);
void setReportPathFields(bool report_input_pin, void setReportPathFields(bool report_input_pin,
bool report_hier_pins,
bool report_net, bool report_net,
bool report_cap, bool report_cap,
bool report_slew, bool report_slew,

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <algorithm> // reverse
#include "ReportPath.hh" #include "ReportPath.hh"
#include "Report.hh" #include "Report.hh"
@ -53,6 +55,11 @@
namespace sta { namespace sta {
static PinSeq
hierPinsThruEdge(const Edge *edge,
const Network *network,
const Graph *graph);
ReportField::ReportField(const char *name, ReportField::ReportField(const char *name,
const char *title, const char *title,
int width, int width,
@ -122,7 +129,7 @@ ReportPath::ReportPath(StaState *sta) :
{ {
setDigits(2); setDigits(2);
makeFields(); makeFields();
setReportFields(false, false, false, false, false, false); setReportFields(false, false, false, false, false, false, false);
} }
ReportPath::~ReportPath() ReportPath::~ReportPath()
@ -225,6 +232,7 @@ ReportPath::setReportFieldOrder(StringSeq *field_names)
void void
ReportPath::setReportFields(bool report_input_pin, ReportPath::setReportFields(bool report_input_pin,
bool report_hier_pins,
bool report_net, bool report_net,
bool report_cap, bool report_cap,
bool report_slew, bool report_slew,
@ -232,6 +240,7 @@ ReportPath::setReportFields(bool report_input_pin,
bool report_src_attr) bool report_src_attr)
{ {
report_input_pin_ = report_input_pin; report_input_pin_ = report_input_pin;
report_hier_pins_ = report_hier_pins;
report_net_ = report_net; report_net_ = report_net;
field_capacitance_->setEnabled(report_cap); field_capacitance_->setEnabled(report_cap);
@ -2402,7 +2411,7 @@ ReportPath::reportPathLine(const Path *path,
{ {
Vertex *vertex = path->vertex(this); Vertex *vertex = path->vertex(this);
Pin *pin = vertex->pin(); Pin *pin = vertex->pin();
auto what = descriptionField(vertex); const string what = descriptionField(vertex);
const RiseFall *rf = path->transition(this); const RiseFall *rf = path->transition(this);
bool is_driver = network_->isDriver(pin); bool is_driver = network_->isDriver(pin);
PathAnalysisPt *path_ap = path->pathAnalysisPt(this); PathAnalysisPt *path_ap = path->pathAnalysisPt(this);
@ -2761,52 +2770,39 @@ ReportPath::reportPath5(const Path *path,
incr = delayIncr(time, prev_time, min_max); incr = delayIncr(time, prev_time, min_max);
line_case = "normal"; line_case = "normal";
} }
if (report_input_pin_
|| (i == path_last_index) if (vertex->isDriver(network_)) {
|| is_clk_start float cap = field_blank_;
|| (prev_arc == nullptr)
// Filter wire edges from report unless reporting
// input pins.
|| (prev_arc
&& !prev_arc->role()->isWire())) {
bool is_driver = network_->isDriver(pin);
float cap = field_blank_;
float fanout = field_blank_; float fanout = field_blank_;
// Don't show capacitance field for input pins. if (field_capacitance_->enabled())
if (is_driver && field_capacitance_->enabled())
cap = graph_delay_calc_->loadCap(pin, rf, dcalc_ap); cap = graph_delay_calc_->loadCap(pin, rf, dcalc_ap);
// Don't show fanout field for input pins. if (field_fanout_->enabled())
if (is_driver && field_fanout_->enabled()) fanout = drvrFanout(vertex, dcalc_ap->corner(), min_max);
fanout = drvrFanout(vertex, dcalc_ap->corner(), min_max); const string what = descriptionField(vertex);
auto what = descriptionField(vertex); reportLine(what.c_str(), cap, slew, fanout,
if (report_net_ && is_driver) { incr, time, false, min_max, rf, src_attr,
reportLine(what.c_str(), cap, slew, fanout, line_case);
incr, time, false, min_max, rf,
src_attr, line_case); if (report_net_) {
string what2; const string what2 = descriptionNet(pin);
if (network_->isTopLevelPort(pin)) { reportLine(what2.c_str(), field_blank_, field_blank_, field_blank_,
const char *pin_name = cmd_network_->pathName(pin); field_blank_, field_blank_, false, min_max,
what2 = stdstrPrint("%s (net)", pin_name); nullptr, src_attr, "");
} }
else { prev_time = time;
Net *net = network_->net(pin); }
if (net) { else {
Net *highest_net = network_->highestNetAbove(net); reportHierPinsThru(path1, prev_arc);
const char *net_name = cmd_network_->pathName(highest_net); if (report_input_pin_
what2 = stdstrPrint("%s (net)", net_name); || (i == 0)
} || (i == path_last_index)
else || is_clk_start) {
what2 = "(unconnected)"; const string what = descriptionField(vertex);
} reportLine(what.c_str(), field_blank_, slew, field_blank_,
reportLine(what2.c_str(), field_blank_, field_blank_, field_blank_, incr, time, false, min_max, rf, src_attr,
field_blank_, field_blank_, false, min_max, line_case);
nullptr, src_attr, line_case); prev_time = time;
} }
else
reportLine(what.c_str(), cap, slew, fanout,
incr, time, false, min_max, rf, src_attr,
line_case);
prev_time = time;
} }
} }
else else
@ -2814,6 +2810,23 @@ ReportPath::reportPath5(const Path *path,
} }
} }
void
ReportPath::reportHierPinsThru(const Path *path,
const TimingArc *prev_arc)
{
if (report_hier_pins_) {
const Edge *prev_edge = path->prevEdge(prev_arc, this);
if (prev_edge && prev_edge->isWire()) {
for (const Pin *hpin : hierPinsThruEdge(prev_edge, network_, graph_)) {
const string what = descriptionField(hpin);
reportLine(what.c_str(), field_blank_, field_blank_, field_blank_,
field_blank_, field_blank_, false, path->minMax(this),
nullptr, "", "");
}
}
}
}
Delay Delay
ReportPath::delayIncr(Delay time, ReportPath::delayIncr(Delay time,
Delay prev, Delay prev,
@ -2839,7 +2852,12 @@ ReportPath::nextArcAnnotated(const PathRef *next_path,
string string
ReportPath::descriptionField(Vertex *vertex) ReportPath::descriptionField(Vertex *vertex)
{ {
Pin *pin = vertex->pin(); return descriptionField(vertex->pin());
}
string
ReportPath::descriptionField(const Pin *pin)
{
const char *pin_name = cmd_network_->pathName(pin); const char *pin_name = cmd_network_->pathName(pin);
const char *name2; const char *name2;
if (network_->isTopLevelPort(pin)) { if (network_->isTopLevelPort(pin)) {
@ -2863,6 +2881,25 @@ ReportPath::descriptionField(Vertex *vertex)
return stdstrPrint("%s (%s)", pin_name, name2); return stdstrPrint("%s (%s)", pin_name, name2);
} }
string
ReportPath::descriptionNet(const Pin *pin)
{
if (network_->isTopLevelPort(pin)) {
const char *pin_name = cmd_network_->pathName(pin);
return stdstrPrint("%s (net)", pin_name);
}
else {
Net *net = network_->net(pin);
if (net) {
Net *highest_net = network_->highestNetAbove(net);
const char *net_name = cmd_network_->pathName(highest_net);
return stdstrPrint("%s (net)", net_name);
}
else
return "(unconnected)";
}
}
float float
ReportPath::drvrFanout(Vertex *drvr, ReportPath::drvrFanout(Vertex *drvr,
const Corner *corner, const Corner *corner,
@ -3442,4 +3479,85 @@ ReportPath::latchDesc(const RiseFall *clk_rf) const
: "negative level-sensitive latch"; : "negative level-sensitive latch";
} }
////////////////////////////////////////////////////////////////
static void
hierPinsAbove(const Net *net,
const Network *network,
PinSeq &pins_above);
static void
hierPinsAbove(const Pin *pin,
const Network *network,
PinSeq &pins_above);
static PinSeq
hierPinsThruEdge(const Edge *edge,
const Network *network,
const Graph *graph)
{
const Pin *drvr_pin = edge->from(graph)->pin();
const Pin *load_pin = edge->to(graph)->pin();
PinSeq drvr_hpins;
PinSeq load_hpins;
hierPinsAbove(drvr_pin, network, drvr_hpins);
hierPinsAbove(load_pin, network, load_hpins);
if (drvr_hpins.empty()) {
std::reverse(load_hpins.begin(), load_hpins.end());
return load_hpins;
}
if (load_hpins.empty())
return drvr_hpins;
for (size_t l1 = 0; l1 < load_hpins.size(); l1++) {
const Pin *load_hpin = load_hpins[l1];
const Net *load_net = network->net(load_hpin);
for (size_t d1 = 0; d1 < drvr_hpins.size(); d1++) {
const Pin *drvr_hpin = drvr_hpins[d1];
const Net *drvr_net = network->net(drvr_hpin);
if (load_net == drvr_net) {
PinSeq hpins_thru;
for (size_t d2 = 0; d2 < d1; d2++) {
const Pin *drvr_hpin2 = drvr_hpins[d2];
hpins_thru.push_back(drvr_hpin2);
}
hpins_thru.push_back(drvr_hpin);
hpins_thru.push_back(load_hpin);
for (size_t l2 = 0; l2 < l1; l2++) {
const Pin *load_hpin2 = load_hpins[l2];
hpins_thru.push_back(load_hpin2);
}
return hpins_thru;
}
}
}
return PinSeq();
}
static void
hierPinsAbove(const Pin *pin,
const Network *network,
PinSeq &pins_above)
{
const Net *net = network->net(pin);
hierPinsAbove(net, network, pins_above);
}
static void
hierPinsAbove(const Net *net,
const Network *network,
PinSeq &pins_above)
{
if (net) {
NetTermIterator *term_iter = network->termIterator(net);
while (term_iter->hasNext()) {
const Term *term = term_iter->next();
const Pin *net_pin = network->pin(term);
if (network->isHierarchical(net_pin))
pins_above.push_back(net_pin);
const Net *hpin_net = network->net(net_pin);
if (hpin_net)
hierPinsAbove(hpin_net, network, pins_above);
}
}
}
} // namespace } // namespace

View File

@ -41,6 +41,7 @@ public:
void setPathFormat(ReportPathFormat format); void setPathFormat(ReportPathFormat format);
void setReportFieldOrder(StringSeq *field_names); void setReportFieldOrder(StringSeq *field_names);
void setReportFields(bool report_input_pin, void setReportFields(bool report_input_pin,
bool report_hier_pins,
bool report_net, bool report_net,
bool report_cap, bool report_cap,
bool report_slew, bool report_slew,
@ -316,6 +317,8 @@ protected:
bool report_clk_path, bool report_clk_path,
Arrival prev_time, Arrival prev_time,
float time_offset); float time_offset);
void reportHierPinsThru(const Path *path,
const TimingArc *prev_arc);
void reportInputExternalDelay(const Path *path, void reportInputExternalDelay(const Path *path,
float time_offset); float time_offset);
void reportLine(const char *what, void reportLine(const char *what,
@ -401,6 +404,8 @@ protected:
void reportDashLine(int line_width); void reportDashLine(int line_width);
void reportBlankLine(); void reportBlankLine();
string descriptionField(Vertex *vertex); string descriptionField(Vertex *vertex);
string descriptionField(const Pin *pin);
string descriptionNet(const Pin *pin);
bool reportClkPath() const; bool reportClkPath() const;
string clkName(const Clock *clk, string clkName(const Clock *clk,
bool inverted); bool inverted);
@ -455,6 +460,7 @@ protected:
ReportPathFormat format_; ReportPathFormat format_;
ReportFieldSeq fields_; ReportFieldSeq fields_;
bool report_input_pin_; bool report_input_pin_;
bool report_hier_pins_;
bool report_net_; bool report_net_;
bool no_split_; bool no_split_;
int digits_; int digits_;

View File

@ -437,6 +437,7 @@ set_report_path_field_order(StringSeq *field_names)
void void
set_report_path_fields(bool report_input_pin, set_report_path_fields(bool report_input_pin,
bool report_hier_pins,
bool report_net, bool report_net,
bool report_cap, bool report_cap,
bool report_slew, bool report_slew,
@ -444,6 +445,7 @@ set_report_path_fields(bool report_input_pin,
bool report_src_attr) bool report_src_attr)
{ {
Sta::sta()->setReportPathFields(report_input_pin, Sta::sta()->setReportPathFields(report_input_pin,
report_hier_pins,
report_net, report_net,
report_cap, report_cap,
report_slew, report_slew,

View File

@ -907,23 +907,35 @@ proc parse_report_path_options { cmd args_var default_format
set_report_path_field_width $field $field_width set_report_path_field_width $field $field_width
} }
set report_input_pin 0
set report_hier_pins 0
set report_cap 0
set report_net 0
set report_slew 0
set report_fanout 0
set report_src_attr 0
if { [info exists path_options(-fields)] } { if { [info exists path_options(-fields)] } {
set fields $path_options(-fields) foreach field $path_options(-fields) {
set report_input_pin [expr [lsearch $fields "input*"] != -1] if { [string match "input*" $field] } {
set report_cap [expr [lsearch $fields "cap*"] != -1] set report_input_pin 1
set report_net [expr [lsearch $fields "net*"] != -1] } elseif { [string match "hier*" $field] } {
set report_slew [expr [lsearch $fields "slew*"] != -1] set report_hier_pins 1
set report_fanout [expr [lsearch $fields "fanout*"] != -1] } elseif { [string match "cap*" $field] } {
set report_src_attr [expr [lsearch $fields "src_attr*"] != -1] set report_cap 1
} else { } elseif { [string match "net" $field] } {
set report_input_pin 0 set report_net 1
set report_cap 0 } elseif { [string match "slew" $field] } {
set report_net 0 set report_slew 1
set report_slew 0 } elseif { [string match "fanout" $field] } {
set report_fanout 0 set report_fanout 1
set report_src_attr 0 } elseif { [string match "src*" $field] } {
set report_src_attr 1
} else {
sta_warn 166 "unknown field $field."
}
}
} }
set_report_path_fields $report_input_pin $report_net \ set_report_path_fields $report_input_pin $report_hier_pins $report_net \
$report_cap $report_slew $report_fanout $report_src_attr $report_cap $report_slew $report_fanout $report_src_attr
set_report_path_no_split [info exists path_options(-no_line_splits)] set_report_path_no_split [info exists path_options(-no_line_splits)]

View File

@ -2481,14 +2481,16 @@ Sta::setReportPathFieldOrder(StringSeq *field_names)
void void
Sta::setReportPathFields(bool report_input_pin, Sta::setReportPathFields(bool report_input_pin,
bool report_hier_pins,
bool report_net, bool report_net,
bool report_cap, bool report_cap,
bool report_slew, bool report_slew,
bool report_fanout, bool report_fanout,
bool report_src_attr) bool report_src_attr)
{ {
report_path_->setReportFields(report_input_pin, report_net, report_cap, report_path_->setReportFields(report_input_pin, report_hier_pins, report_net,
report_slew, report_fanout, report_src_attr); report_cap, report_slew, report_fanout,
report_src_attr);
} }
ReportField * ReportField *