2018-09-28 17:54:21 +02:00
|
|
|
// OpenSTA, Static Timing Analyzer
|
2025-01-22 02:54:33 +01:00
|
|
|
// Copyright (c) 2025, Parallax Software, Inc.
|
2018-09-28 17:54:21 +02:00
|
|
|
//
|
|
|
|
|
// 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
|
2022-01-04 18:17:08 +01:00
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2018-09-28 17:54:21 +02:00
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
2022-01-04 18:17:08 +01:00
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2025-01-22 02:54:33 +01:00
|
|
|
//
|
|
|
|
|
// The origin of this software must not be misrepresented; you must not
|
|
|
|
|
// claim that you wrote the original software.
|
|
|
|
|
//
|
|
|
|
|
// Altered source versions must be plainly marked as such, and must not be
|
|
|
|
|
// misrepresented as being the original software.
|
|
|
|
|
//
|
|
|
|
|
// This notice may not be removed or altered from any source distribution.
|
2018-09-28 17:54:21 +02:00
|
|
|
|
2020-04-05 20:35:51 +02:00
|
|
|
#include "sdf/ReportAnnotation.hh"
|
|
|
|
|
|
2020-04-05 23:53:44 +02:00
|
|
|
#include "StringUtil.hh"
|
|
|
|
|
#include "Report.hh"
|
|
|
|
|
#include "TimingRole.hh"
|
|
|
|
|
#include "TimingArc.hh"
|
|
|
|
|
#include "Liberty.hh"
|
|
|
|
|
#include "Network.hh"
|
|
|
|
|
#include "Graph.hh"
|
|
|
|
|
#include "GraphCmp.hh"
|
|
|
|
|
#include "Sdc.hh"
|
|
|
|
|
#include "DcalcAnalysisPt.hh"
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
namespace sta {
|
|
|
|
|
|
|
|
|
|
class ReportAnnotated : public StaState
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
ReportAnnotated(bool report_cells,
|
|
|
|
|
bool report_nets,
|
|
|
|
|
bool report_in_ports,
|
|
|
|
|
bool report_out_ports,
|
|
|
|
|
int max_lines,
|
|
|
|
|
bool list_annotated,
|
|
|
|
|
bool list_unannotated,
|
|
|
|
|
bool constant_arcs,
|
|
|
|
|
StaState *sta);
|
|
|
|
|
ReportAnnotated(bool report_setup,
|
|
|
|
|
bool report_hold,
|
|
|
|
|
bool report_recovery,
|
|
|
|
|
bool report_removal,
|
|
|
|
|
bool report_nochange,
|
|
|
|
|
bool report_width,
|
|
|
|
|
bool report_period,
|
|
|
|
|
bool report_max_skew,
|
|
|
|
|
int max_lines,
|
|
|
|
|
bool list_annotated,
|
|
|
|
|
bool list_unannotated,
|
|
|
|
|
bool constant_arcs,
|
|
|
|
|
StaState *sta);
|
|
|
|
|
void reportDelayAnnotation();
|
|
|
|
|
void reportCheckAnnotation();
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
enum CountIndex {
|
|
|
|
|
count_internal_net = TimingRole::index_max,
|
|
|
|
|
count_input_net,
|
|
|
|
|
count_output_net,
|
|
|
|
|
count_index_max
|
|
|
|
|
};
|
|
|
|
|
static int count_delay;
|
|
|
|
|
|
|
|
|
|
void init();
|
|
|
|
|
void findCounts();
|
2024-04-17 20:49:19 +02:00
|
|
|
void findPeriodCount(Pin *pin);
|
2018-09-28 17:54:21 +02:00
|
|
|
void reportDelayCounts();
|
|
|
|
|
void reportCheckCounts();
|
|
|
|
|
void reportArcs();
|
|
|
|
|
void reportArcs(const char *header,
|
|
|
|
|
bool report_annotated,
|
|
|
|
|
PinSet &pins);
|
|
|
|
|
void reportArcs(Vertex *vertex,
|
|
|
|
|
bool report_annotated,
|
|
|
|
|
int &i);
|
2024-04-17 20:49:19 +02:00
|
|
|
void reportPeriodArcs(const Pin *pin,
|
|
|
|
|
bool report_annotated,
|
|
|
|
|
int &i);
|
2018-09-28 17:54:21 +02:00
|
|
|
void reportCount(const char *title,
|
|
|
|
|
int index,
|
|
|
|
|
int &total,
|
|
|
|
|
int &annotated_total);
|
2025-03-31 00:27:53 +02:00
|
|
|
void reportCheckCount(const TimingRole *role,
|
2018-09-28 17:54:21 +02:00
|
|
|
int &total,
|
|
|
|
|
int &annotated_total);
|
|
|
|
|
int roleIndex(const TimingRole *role,
|
|
|
|
|
const Pin *from_pin,
|
|
|
|
|
const Pin *to_pin);
|
|
|
|
|
|
|
|
|
|
int max_lines_;
|
|
|
|
|
bool list_annotated_;
|
|
|
|
|
bool list_unannotated_;
|
|
|
|
|
bool report_constant_arcs_;
|
|
|
|
|
|
|
|
|
|
int edge_count_[count_index_max];
|
|
|
|
|
int edge_annotated_count_[count_index_max];
|
|
|
|
|
int edge_constant_count_[count_index_max];
|
|
|
|
|
int edge_constant_annotated_count_[count_index_max];
|
|
|
|
|
bool report_role_[count_index_max];
|
|
|
|
|
PinSet unannotated_pins_;
|
|
|
|
|
PinSet annotated_pins_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ReportAnnotated::count_delay;
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
reportAnnotatedDelay(bool report_cells,
|
|
|
|
|
bool report_nets,
|
|
|
|
|
bool from_in_ports,
|
|
|
|
|
bool to_out_ports,
|
|
|
|
|
int max_lines,
|
|
|
|
|
bool list_annotated,
|
|
|
|
|
bool list_unannotated,
|
|
|
|
|
bool report_constant_arcs,
|
|
|
|
|
StaState *sta)
|
|
|
|
|
{
|
|
|
|
|
ReportAnnotated report_annotated(report_cells, report_nets,
|
|
|
|
|
from_in_ports, to_out_ports,
|
|
|
|
|
max_lines, list_annotated, list_unannotated,
|
|
|
|
|
report_constant_arcs, sta);
|
|
|
|
|
report_annotated.reportDelayAnnotation();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReportAnnotated::ReportAnnotated(bool report_cells,
|
|
|
|
|
bool report_nets,
|
|
|
|
|
bool report_in_ports,
|
|
|
|
|
bool report_out_ports,
|
|
|
|
|
int max_lines,
|
|
|
|
|
bool list_annotated,
|
|
|
|
|
bool list_unannotated,
|
|
|
|
|
bool report_constant_arcs,
|
|
|
|
|
StaState *sta) :
|
|
|
|
|
StaState(sta),
|
|
|
|
|
max_lines_(max_lines),
|
|
|
|
|
list_annotated_(list_annotated),
|
|
|
|
|
list_unannotated_(list_unannotated),
|
2023-01-19 19:23:45 +01:00
|
|
|
report_constant_arcs_(report_constant_arcs),
|
|
|
|
|
unannotated_pins_(sta->network()),
|
|
|
|
|
annotated_pins_(sta->network())
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
init();
|
|
|
|
|
report_role_[TimingRole::sdfIopath()->index()] = report_cells;
|
|
|
|
|
report_role_[count_internal_net] = report_nets;
|
|
|
|
|
report_role_[count_input_net] = report_in_ports;
|
|
|
|
|
report_role_[count_output_net] = report_out_ports;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportDelayAnnotation()
|
|
|
|
|
{
|
|
|
|
|
findCounts();
|
|
|
|
|
reportDelayCounts();
|
|
|
|
|
reportArcs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportDelayCounts()
|
|
|
|
|
{
|
2020-12-29 03:04:49 +01:00
|
|
|
report_->reportLine(" Not ");
|
|
|
|
|
report_->reportLine("Delay type Total Annotated Annotated");
|
|
|
|
|
report_->reportLine("----------------------------------------------------------------");
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
int total = 0;
|
|
|
|
|
int annotated_total = 0;
|
|
|
|
|
reportCount("cell arcs", count_delay, total, annotated_total);
|
|
|
|
|
reportCount("internal net arcs", count_internal_net, total, annotated_total);
|
|
|
|
|
reportCount("net arcs from primary inputs", count_input_net,
|
|
|
|
|
total, annotated_total);
|
|
|
|
|
reportCount("net arcs to primary outputs", count_output_net,
|
|
|
|
|
total, annotated_total);
|
2020-12-28 18:04:57 +01:00
|
|
|
report_->reportLine("----------------------------------------------------------------");
|
|
|
|
|
report_->reportLine("%-28s %10u %10u %10u",
|
|
|
|
|
" ",
|
|
|
|
|
total,
|
|
|
|
|
annotated_total,
|
|
|
|
|
total - annotated_total);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
reportAnnotatedCheck(bool report_setup,
|
|
|
|
|
bool report_hold,
|
|
|
|
|
bool report_recovery,
|
|
|
|
|
bool report_removal,
|
|
|
|
|
bool report_nochange,
|
|
|
|
|
bool report_width,
|
|
|
|
|
bool report_period,
|
|
|
|
|
bool report_max_skew,
|
|
|
|
|
int max_lines,
|
|
|
|
|
bool list_annotated,
|
|
|
|
|
bool list_unannotated,
|
|
|
|
|
bool report_constant_arcs,
|
|
|
|
|
StaState *sta)
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
ReportAnnotated report_annotated(report_setup, report_hold,
|
|
|
|
|
report_recovery, report_removal,
|
|
|
|
|
report_nochange, report_width,
|
|
|
|
|
report_period, report_max_skew,
|
|
|
|
|
max_lines, list_annotated, list_unannotated,
|
|
|
|
|
report_constant_arcs, sta);
|
|
|
|
|
report_annotated.reportCheckAnnotation();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReportAnnotated::ReportAnnotated(bool report_setup,
|
|
|
|
|
bool report_hold,
|
|
|
|
|
bool report_recovery,
|
|
|
|
|
bool report_removal,
|
|
|
|
|
bool report_nochange,
|
|
|
|
|
bool report_width,
|
|
|
|
|
bool report_period,
|
|
|
|
|
bool report_max_skew,
|
|
|
|
|
int max_lines,
|
|
|
|
|
bool list_annotated,
|
|
|
|
|
bool list_unannotated,
|
|
|
|
|
bool report_constant_arcs,
|
|
|
|
|
StaState *sta) :
|
|
|
|
|
StaState(sta),
|
|
|
|
|
max_lines_(max_lines),
|
|
|
|
|
list_annotated_(list_annotated),
|
|
|
|
|
list_unannotated_(list_unannotated),
|
2023-01-19 19:23:45 +01:00
|
|
|
report_constant_arcs_(report_constant_arcs),
|
|
|
|
|
unannotated_pins_(sta->network()),
|
|
|
|
|
annotated_pins_(sta->network())
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
init();
|
|
|
|
|
report_role_[TimingRole::setup()->index()] = report_setup;
|
|
|
|
|
report_role_[TimingRole::hold()->index()] = report_hold;
|
|
|
|
|
report_role_[TimingRole::recovery()->index()] = report_recovery;
|
|
|
|
|
report_role_[TimingRole::removal()->index()] = report_removal;
|
|
|
|
|
report_role_[TimingRole::nochange()->index()] = report_nochange;
|
|
|
|
|
report_role_[TimingRole::width()->index()] = report_width;
|
|
|
|
|
report_role_[TimingRole::period()->index()] = report_period;
|
|
|
|
|
report_role_[TimingRole::skew()->index()] = report_max_skew;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportCheckAnnotation()
|
|
|
|
|
{
|
|
|
|
|
findCounts();
|
|
|
|
|
reportCheckCounts();
|
|
|
|
|
reportArcs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportCheckCounts()
|
|
|
|
|
{
|
2020-12-29 03:04:49 +01:00
|
|
|
report_->reportLine(" Not ");
|
|
|
|
|
report_->reportLine("Check type Total Annotated Annotated");
|
|
|
|
|
report_->reportLine("----------------------------------------------------------------");
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
int total = 0;
|
|
|
|
|
int annotated_total = 0;
|
|
|
|
|
reportCheckCount(TimingRole::setup(), total, annotated_total);
|
|
|
|
|
reportCheckCount(TimingRole::hold(), total, annotated_total);
|
|
|
|
|
reportCheckCount(TimingRole::recovery(), total, annotated_total);
|
|
|
|
|
reportCheckCount(TimingRole::removal(), total, annotated_total);
|
|
|
|
|
reportCheckCount(TimingRole::nochange(), total, annotated_total);
|
|
|
|
|
reportCheckCount(TimingRole::width(), total, annotated_total);
|
|
|
|
|
reportCheckCount(TimingRole::period(), total, annotated_total);
|
|
|
|
|
reportCheckCount(TimingRole::skew(), total, annotated_total);
|
|
|
|
|
|
2020-12-28 18:04:57 +01:00
|
|
|
report_->reportLine("----------------------------------------------------------------");
|
|
|
|
|
report_->reportLine("%-28s %10u %10u %10u",
|
|
|
|
|
" ",
|
|
|
|
|
total,
|
|
|
|
|
annotated_total,
|
|
|
|
|
total - annotated_total);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2025-03-31 00:27:53 +02:00
|
|
|
ReportAnnotated::reportCheckCount(const TimingRole *role,
|
2018-09-28 17:54:21 +02:00
|
|
|
int &total,
|
|
|
|
|
int &annotated_total)
|
|
|
|
|
{
|
|
|
|
|
int index = role->index();
|
|
|
|
|
if (edge_count_[index] > 0) {
|
2025-04-12 01:59:48 +02:00
|
|
|
std::string title;
|
2025-03-31 00:27:53 +02:00
|
|
|
stringPrint(title, "cell %s arcs", role->to_string().c_str());
|
2019-01-17 00:37:31 +01:00
|
|
|
reportCount(title.c_str(), index, total, annotated_total);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::init()
|
|
|
|
|
{
|
|
|
|
|
count_delay = TimingRole::sdfIopath()->index();
|
|
|
|
|
for (int i = 0; i < count_index_max; i++) {
|
|
|
|
|
edge_count_[i] = 0;
|
|
|
|
|
edge_annotated_count_[i] = 0;
|
|
|
|
|
edge_constant_count_[i] = 0;
|
|
|
|
|
edge_constant_annotated_count_[i] = 0;
|
|
|
|
|
report_role_[i] = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::findCounts()
|
|
|
|
|
{
|
|
|
|
|
VertexIterator vertex_iter(graph_);
|
|
|
|
|
while (vertex_iter.hasNext()) {
|
|
|
|
|
Vertex *from_vertex = vertex_iter.next();
|
|
|
|
|
Pin *from_pin = from_vertex->pin();
|
|
|
|
|
LogicValue from_logic_value;
|
|
|
|
|
bool from_logic_value_exists;
|
|
|
|
|
sdc_->logicValue(from_pin, from_logic_value,
|
2018-11-09 19:04:16 +01:00
|
|
|
from_logic_value_exists);
|
2018-09-28 17:54:21 +02:00
|
|
|
VertexOutEdgeIterator edge_iter(from_vertex, graph_);
|
|
|
|
|
while (edge_iter.hasNext()) {
|
|
|
|
|
Edge *edge = edge_iter.next();
|
|
|
|
|
const TimingRole *role = edge->role();
|
|
|
|
|
Vertex *to_vertex = edge->to(graph_);
|
|
|
|
|
Pin *to_pin = to_vertex->pin();
|
|
|
|
|
int index = roleIndex(role, from_pin, to_pin);
|
|
|
|
|
LogicValue to_logic_value;
|
|
|
|
|
bool to_logic_value_exists;
|
|
|
|
|
sdc_->logicValue(to_pin, to_logic_value,
|
2018-11-09 19:04:16 +01:00
|
|
|
to_logic_value_exists);
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
edge_count_[index]++;
|
|
|
|
|
|
|
|
|
|
if (from_logic_value_exists || to_logic_value_exists)
|
|
|
|
|
edge_constant_count_[index]++;
|
|
|
|
|
if (report_role_[index]) {
|
2018-11-09 19:04:16 +01:00
|
|
|
if (graph_->delayAnnotated(edge)) {
|
2018-09-28 17:54:21 +02:00
|
|
|
edge_annotated_count_[index]++;
|
|
|
|
|
if (from_logic_value_exists || to_logic_value_exists)
|
|
|
|
|
edge_constant_annotated_count_[index]++;
|
|
|
|
|
if (list_annotated_)
|
|
|
|
|
annotated_pins_.insert(from_pin);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (list_unannotated_)
|
|
|
|
|
unannotated_pins_.insert(from_pin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-17 20:49:19 +02:00
|
|
|
findPeriodCount(from_pin);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
ReportAnnotated::roleIndex(const TimingRole *role,
|
|
|
|
|
const Pin *from_pin,
|
|
|
|
|
const Pin *to_pin)
|
|
|
|
|
{
|
|
|
|
|
if (role == TimingRole::wire()) {
|
|
|
|
|
if (network_->isTopLevelPort(from_pin))
|
|
|
|
|
return count_input_net;
|
|
|
|
|
else if (network_->isTopLevelPort(to_pin))
|
|
|
|
|
return count_output_net;
|
|
|
|
|
else
|
|
|
|
|
return count_internal_net;
|
|
|
|
|
}
|
|
|
|
|
else if (role->sdfRole() == TimingRole::sdfIopath())
|
|
|
|
|
return count_delay;
|
|
|
|
|
else {
|
|
|
|
|
if (role->isTimingCheck()
|
|
|
|
|
&& (role == TimingRole::latchSetup()
|
|
|
|
|
|| role == TimingRole::latchHold()))
|
|
|
|
|
role = role->genericRole();
|
|
|
|
|
return role->index();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Width and period checks are not edges in the graph so
|
|
|
|
|
// they require special handling.
|
|
|
|
|
void
|
2024-04-17 20:49:19 +02:00
|
|
|
ReportAnnotated::findPeriodCount(Pin *pin)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
LibertyPort *port = network_->libertyPort(pin);
|
|
|
|
|
if (port) {
|
|
|
|
|
DcalcAPIndex ap_index = 0;
|
|
|
|
|
float value;
|
|
|
|
|
bool exists, annotated;
|
|
|
|
|
int period_index = TimingRole::period()->index();
|
|
|
|
|
if (report_role_[period_index]) {
|
|
|
|
|
port->minPeriod(value, exists);
|
|
|
|
|
if (exists) {
|
|
|
|
|
edge_count_[period_index]++;
|
|
|
|
|
graph_->periodCheckAnnotation(pin, ap_index, value, annotated);
|
|
|
|
|
if (annotated) {
|
|
|
|
|
edge_annotated_count_[period_index]++;
|
|
|
|
|
if (list_annotated_)
|
|
|
|
|
annotated_pins_.insert(pin);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (list_unannotated_)
|
|
|
|
|
unannotated_pins_.insert(pin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportCount(const char *title,
|
|
|
|
|
int index,
|
|
|
|
|
int &total,
|
|
|
|
|
int &annotated_total)
|
|
|
|
|
{
|
|
|
|
|
if (report_role_[index]) {
|
|
|
|
|
int count = edge_count_[index];
|
|
|
|
|
int annotated_count = edge_annotated_count_[index];
|
2020-12-28 18:04:57 +01:00
|
|
|
report_->reportLine("%-28s %10u %10u %10u",
|
|
|
|
|
title,
|
|
|
|
|
count,
|
|
|
|
|
annotated_count,
|
|
|
|
|
count - annotated_count);
|
2018-09-28 17:54:21 +02:00
|
|
|
if (report_constant_arcs_) {
|
|
|
|
|
int const_count = edge_constant_count_[index];
|
|
|
|
|
int const_annotated_count = edge_constant_annotated_count_[index];
|
2020-12-28 18:04:57 +01:00
|
|
|
report_->reportLine("%-28s %10s %10u %10u",
|
|
|
|
|
"constant arcs",
|
|
|
|
|
"",
|
|
|
|
|
const_annotated_count,
|
|
|
|
|
const_count - const_annotated_count);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
total += count;
|
|
|
|
|
annotated_total += annotated_count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportArcs()
|
|
|
|
|
{
|
|
|
|
|
if (list_annotated_)
|
|
|
|
|
reportArcs("Annotated Arcs", true, annotated_pins_);
|
|
|
|
|
if (list_unannotated_)
|
|
|
|
|
reportArcs("Unannotated Arcs", false, unannotated_pins_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportArcs(const char *header,
|
|
|
|
|
bool report_annotated,
|
|
|
|
|
PinSet &pins)
|
|
|
|
|
{
|
2021-01-05 03:14:04 +01:00
|
|
|
report_->reportBlankLine();
|
2020-12-31 04:51:50 +01:00
|
|
|
report_->reportLineString(header);
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSeq pins1 = sortByPathName(&pins, network_);
|
2018-09-28 17:54:21 +02:00
|
|
|
int i = 0;
|
2023-01-19 19:23:45 +01:00
|
|
|
for (const Pin *pin : pins1) {
|
2018-09-28 17:54:21 +02:00
|
|
|
Vertex *vertex, *bidirect_drvr_vertex;
|
|
|
|
|
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
|
|
|
|
reportArcs(vertex, report_annotated, i);
|
|
|
|
|
if (bidirect_drvr_vertex)
|
|
|
|
|
reportArcs(bidirect_drvr_vertex, report_annotated, i);
|
2024-04-17 20:49:19 +02:00
|
|
|
reportPeriodArcs(pin, report_annotated, i);
|
2023-01-19 19:23:45 +01:00
|
|
|
if (max_lines_ != 0 && i > max_lines_)
|
|
|
|
|
break;
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ReportAnnotated::reportArcs(Vertex *vertex,
|
|
|
|
|
bool report_annotated,
|
|
|
|
|
int &i)
|
|
|
|
|
{
|
|
|
|
|
const Pin *from_pin = vertex->pin();
|
|
|
|
|
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
|
|
|
|
while (edge_iter.hasNext()
|
|
|
|
|
&& (max_lines_ == 0 || i < max_lines_)) {
|
|
|
|
|
Edge *edge = edge_iter.next();
|
2025-03-31 00:27:53 +02:00
|
|
|
const TimingRole *role = edge->role();
|
2018-09-28 17:54:21 +02:00
|
|
|
const Pin *to_pin = edge->to(graph_)->pin();
|
2018-11-09 19:04:16 +01:00
|
|
|
if (graph_->delayAnnotated(edge) == report_annotated
|
2018-09-28 17:54:21 +02:00
|
|
|
&& report_role_[roleIndex(role, from_pin, to_pin)]) {
|
|
|
|
|
const char *role_name;
|
|
|
|
|
if (role->isTimingCheck())
|
2025-03-31 00:27:53 +02:00
|
|
|
role_name = role->to_string().c_str();
|
2018-09-28 17:54:21 +02:00
|
|
|
else if (role->isWire()) {
|
|
|
|
|
if (network_->isTopLevelPort(from_pin))
|
|
|
|
|
role_name = "primary input net";
|
|
|
|
|
else if (network_->isTopLevelPort(to_pin))
|
|
|
|
|
role_name = "primary output net";
|
|
|
|
|
else
|
|
|
|
|
role_name = "internal net";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
role_name = "delay";
|
|
|
|
|
const char *cond = edge->timingArcSet()->sdfCond();
|
2020-12-28 18:04:57 +01:00
|
|
|
report_->reportLine(" %-18s %s -> %s %s",
|
|
|
|
|
role_name,
|
|
|
|
|
network_->pathName(from_pin),
|
|
|
|
|
network_->pathName(to_pin),
|
|
|
|
|
cond ? cond : "");
|
2018-09-28 17:54:21 +02:00
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2024-04-17 20:49:19 +02:00
|
|
|
ReportAnnotated::reportPeriodArcs(const Pin *pin,
|
|
|
|
|
bool report_annotated,
|
|
|
|
|
int &i)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
LibertyPort *port = network_->libertyPort(pin);
|
|
|
|
|
if (port) {
|
|
|
|
|
DcalcAPIndex ap_index = 0;
|
|
|
|
|
int period_index = TimingRole::period()->index();
|
|
|
|
|
if (report_role_[period_index]
|
|
|
|
|
&& (max_lines_ == 0 || i < max_lines_)) {
|
|
|
|
|
float value;
|
|
|
|
|
bool exists, annotated;
|
|
|
|
|
port->minPeriod(value, exists);
|
|
|
|
|
if (exists) {
|
|
|
|
|
edge_count_[period_index]++;
|
|
|
|
|
graph_->periodCheckAnnotation(pin, ap_index, value, annotated);
|
|
|
|
|
if (annotated == report_annotated) {
|
2020-12-28 18:04:57 +01:00
|
|
|
report_->reportLine(" %-18s %s",
|
|
|
|
|
"period",
|
|
|
|
|
network_->pathName(pin));
|
2018-09-28 17:54:21 +02:00
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|