Skip to content

[Analysis] Printing Nets timing Information #3023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
72 changes: 72 additions & 0 deletions vpr/src/analysis/timing_reports.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#include "timing_reports.h"

#include <fstream>
#include <sstream>

#include "timing_reports.h"

#include "tatum/TimingReporter.hpp"

#include "vtr_version.h"
#include "vpr_types.h"
#include "globals.h"

Expand Down Expand Up @@ -61,3 +67,69 @@ void generate_hold_timing_stats(const std::string& prefix,

timing_reporter.report_unconstrained_hold(prefix + "report_unconstrained_timing.hold.rpt", *timing_info.hold_analyzer());
}

void generate_net_timing_report(const std::string& prefix,
const SetupHoldTimingInfo& timing_info,
const AnalysisDelayCalculator& delay_calc) {
/* Create a report file for net timing information */
std::ofstream os(prefix + "report_net_timing.rpt");
const auto& atom_netlist = g_vpr_ctx.atom().netlist();
const auto& atom_lookup = g_vpr_ctx.atom().lookup();

const auto& timing_ctx = g_vpr_ctx.timing();
const auto& timing_graph = timing_ctx.graph;

os << "# This file is generated by VTR" << std::endl;
os << "# Version: " << vtr::VERSION << std::endl;
os << "# Revision: " << vtr::VCS_REVISION << std::endl;
os << "# For each net, the timing information is reported in the following format:" << std::endl;
os << "# netname : Fanout : source_instance <slack_on source pin> : "
<< "<load pin name1> <slack on load pin name1> <net delay for this net> : "
<< "<load pin name2> <slack on load pin name2> <net delay for this net> : ..."
<< std::endl;

os << std::endl;

for (const auto& net : atom_netlist.nets()) {
/* Skip constant nets */
if (atom_netlist.net_is_constant(net)) {
continue;
}

const auto& net_name = atom_netlist.net_name(net);

/* Get source pin and its timing information */
const auto& source_pin = *atom_netlist.net_pins(net).begin();
auto source_pin_slack = timing_info.setup_pin_slack(source_pin);
/* Timing graph node id corresponding to the net's source pin */
auto tg_source_node = atom_lookup.atom_pin_tnode(source_pin);
VTR_ASSERT(tg_source_node.is_valid());

const size_t fanout = atom_netlist.net_sinks(net).size();
os << net_name << " : " << fanout << " : " << atom_netlist.pin_name(source_pin).c_str() << " " << source_pin_slack << " : ";

/* Iterate over all fanout pins and print their timing information */
for (size_t net_pin_index = 1; net_pin_index <= fanout; ++net_pin_index) {
const auto& pin = *(atom_netlist.net_pins(net).begin() + net_pin_index);

/* Get timing graph node id corresponding to the fanout pin */
const auto& tg_sink_node = atom_lookup.atom_pin_tnode(pin);
VTR_ASSERT(tg_sink_node.is_valid());

/* Get timing graph edge id between atom pins */
const auto& tg_edge_id = timing_graph->find_edge(tg_source_node, tg_sink_node);
VTR_ASSERT(tg_edge_id.is_valid());

/* Get timing information for the fanout pin */
const auto& pin_setup_slack = timing_info.setup_pin_slack(pin);
const auto& pin_delay = delay_calc.max_edge_delay(*timing_graph, tg_edge_id);

const auto& pin_name = atom_netlist.pin_name(pin);
os << pin_name << " " << std::scientific << pin_setup_slack << " " << pin_delay;
if (net_pin_index < fanout) {
os << " : ";
}
}
os << "," << std::endl;
}
}
15 changes: 15 additions & 0 deletions vpr/src/analysis/timing_reports.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,19 @@ void generate_hold_timing_stats(const std::string& prefix,
bool is_flat,
const BlkLocRegistry& blk_loc_registry);

/**
* @brief Generates timing information for each net in atom netlist. For each net, the timing information
* is reported in the following format:
* netname : Fanout : source_instance <slack_on source pin> :
* <load pin name1> <slack on load pin name1> <net delay for this net> :
* <load pin name2> <slack on load pin name2> <net delay for this net> : ...
*
* @param prefix The prefix for the report file to be added to filename: report_net_timing.rpt
* @param timing_info Updated timing information
* @param delay_calc Delay calculator
*/
void generate_net_timing_report(const std::string& prefix,
const SetupHoldTimingInfo& timing_info,
const AnalysisDelayCalculator& delay_calc);

#endif
1 change: 1 addition & 0 deletions vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,7 @@ static void SetupAnalysisOpts(const t_options& Options, t_analysis_opts& analysi

analysis_opts.timing_update_type = Options.timing_update_type;
analysis_opts.write_timing_summary = Options.write_timing_summary;
analysis_opts.generate_net_timing_report = Options.generate_net_timing_report;
}

static void SetupPowerOpts(const t_options& Options, t_power_opts* power_opts, t_arch* Arch) {
Expand Down
5 changes: 5 additions & 0 deletions vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3078,6 +3078,11 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.help("Writes implemented design final timing summary to the specified JSON, XML or TXT file.")
.show_in(argparse::ShowIn::HELP_ONLY);

analysis_grp.add_argument<bool, ParseOnOff>(args.generate_net_timing_report, "--generate_net_timing_report")
.help("Generates a net timing report for each net in the design.")
.default_value("off")
.show_in(argparse::ShowIn::HELP_ONLY);

auto& power_grp = parser.add_argument_group("power analysis options");

power_grp.add_argument<bool, ParseOnOff>(args.do_power, "--power")
Expand Down
1 change: 1 addition & 0 deletions vpr/src/base/read_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ struct t_options {
argparse::ArgValue<e_post_synth_netlist_unconn_handling> post_synth_netlist_unconn_output_handling;
argparse::ArgValue<bool> post_synth_netlist_module_parameters;
argparse::ArgValue<std::string> write_timing_summary;
argparse::ArgValue<bool> generate_net_timing_report;
};

argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_options& args);
Expand Down
4 changes: 4 additions & 0 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,10 @@ void vpr_analysis(const Netlist<>& net_list,
merged_netlist_writer(atom_ctx.netlist().netlist_name(), analysis_delay_calc, Arch.models, vpr_setup.AnalysisOpts);
}

if (vpr_setup.AnalysisOpts.generate_net_timing_report) {
generate_net_timing_report(/*prefix=*/"", *timing_info, *analysis_delay_calc);
}

//Do power analysis
// TODO: Still assumes that cluster net list is used
if (vpr_setup.PowerOpts.do_power) {
Expand Down
1 change: 1 addition & 0 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@ struct t_analysis_opts {
bool timing_report_skew;
std::string echo_dot_timing_graph_node;
std::string write_timing_summary;
bool generate_net_timing_report;

e_timing_update_type timing_update_type;
};
Expand Down