Skip to content

Commit 0ea8a24

Browse files
committed
vpr: analysis: optionally write timing summary in JSON or XML file
Signed-off-by: Pawel Czarnecki <[email protected]>
1 parent f63d188 commit 0ea8a24

File tree

8 files changed

+72
-9
lines changed

8 files changed

+72
-9
lines changed

vpr/src/analysis/timing_reports.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void generate_setup_timing_stats(const std::string& prefix, const SetupTimingInf
1616
auto& timing_ctx = g_vpr_ctx.timing();
1717
auto& atom_ctx = g_vpr_ctx.atom();
1818

19-
print_setup_timing_summary(*timing_ctx.constraints, *timing_info.setup_analyzer(), "Final ");
19+
print_setup_timing_summary(*timing_ctx.constraints, *timing_info.setup_analyzer(), "Final ", analysis_opts.write_timing_summary);
2020

2121
VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc);
2222
resolver.set_detail_level(analysis_opts.timing_report_detail);

vpr/src/base/SetupVPR.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ static void SetupAnalysisOpts(const t_options& Options, t_analysis_opts& analysi
625625
analysis_opts.echo_dot_timing_graph_node = Options.echo_dot_timing_graph_node;
626626

627627
analysis_opts.timing_update_type = Options.timing_update_type;
628+
analysis_opts.write_timing_summary = Options.write_timing_summary;
628629
}
629630

630631
static void SetupPowerOpts(const t_options& Options, t_power_opts* power_opts, t_arch* Arch) {

vpr/src/base/read_options.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2476,6 +2476,10 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
24762476
.default_value("-1")
24772477
.show_in(argparse::ShowIn::HELP_ONLY);
24782478

2479+
analysis_grp.add_argument(args.write_timing_summary, "--write_timing_summary")
2480+
.help("Writes implemented design final timing summary to the specified JSON or XML file.")
2481+
.show_in(argparse::ShowIn::HELP_ONLY);
2482+
24792483
auto& power_grp = parser.add_argument_group("power analysis options");
24802484

24812485
power_grp.add_argument<bool, ParseOnOff>(args.do_power, "--power")

vpr/src/base/read_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ struct t_options {
210210
argparse::ArgValue<e_timing_report_detail> timing_report_detail;
211211
argparse::ArgValue<bool> timing_report_skew;
212212
argparse::ArgValue<std::string> echo_dot_timing_graph_node;
213+
argparse::ArgValue<std::string> write_timing_summary;
213214
};
214215

215216
argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& args);

vpr/src/base/vpr_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,7 @@ struct t_analysis_opts {
12921292
e_timing_report_detail timing_report_detail;
12931293
bool timing_report_skew;
12941294
std::string echo_dot_timing_graph_node;
1295+
std::string write_timing_summary;
12951296

12961297
e_timing_update_type timing_update_type;
12971298
};

vpr/src/place/place.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ void try_place(const t_placer_opts& placer_opts,
950950
/* Print critical path delay metrics */
951951
VTR_LOG("\n");
952952
print_setup_timing_summary(*timing_ctx.constraints,
953-
*timing_info->setup_analyzer(), "Placement estimated ");
953+
*timing_info->setup_analyzer(), "Placement estimated ", "");
954954
}
955955

956956
sprintf(msg,

vpr/src/timing/timing_util.cpp

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,27 +191,77 @@ std::vector<HistogramBucket> create_criticality_histogram(const SetupTimingInfo&
191191
return histogram;
192192
}
193193

194-
void print_setup_timing_summary(const tatum::TimingConstraints& constraints, const tatum::SetupTimingAnalyzer& setup_analyzer, std::string prefix) {
194+
void write_setup_timing_summary(std::string timing_summary_filename,
195+
double least_slack_cpd,
196+
double fmax,
197+
double setup_worst_neg_slack,
198+
double setup_total_neg_slack) {
199+
if (vtr::check_file_name_extension(timing_summary_filename.c_str(), ".json")) {
200+
// write report in JSON format
201+
std::fstream fp;
202+
fp.open(timing_summary_filename, std::fstream::out | std::fstream::trunc);
203+
fp << "{\n";
204+
205+
fp << " \"cpd\": " << least_slack_cpd << ",\n";
206+
fp << " \"fmax\": " << fmax << ",\n";
207+
208+
fp << " \"swns\": " << setup_worst_neg_slack << ",\n";
209+
fp << " \"stns\": " << setup_total_neg_slack << "\n";
210+
fp << "}\n";
211+
} else if (vtr::check_file_name_extension(timing_summary_filename.c_str(), ".xml")) {
212+
// write report in XML format
213+
std::fstream fp;
214+
fp.open(timing_summary_filename, std::fstream::out | std::fstream::trunc);
215+
fp << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
216+
fp << "<timing_summary_report>\n";
217+
218+
fp << " <cpd value=\"" << least_slack_cpd << "\" unit=\"ns\" description=\"Final critical path delay\"></nets>\n";
219+
fp << " <fmax value=\"" << fmax << "\" unit=\"MHz\" description=\"Max circuit frequency\"></fmax>\n";
220+
fp << " <swns value=\"" << setup_worst_neg_slack << "\" unit=\"ns\" description=\"setup Worst Negative Slack (sWNS)\"></swns>\n";
221+
fp << " <stns value=\"" << setup_total_neg_slack << "\" unit=\"ns\" description=\"setup Total Negative Slack (sTNS)\"></stns>\n";
222+
223+
fp << "</block_usage_report>\n";
224+
} else {
225+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
226+
"Unknown extension on output %s",
227+
timing_summary_filename.c_str());
228+
}
229+
}
230+
231+
void print_setup_timing_summary(const tatum::TimingConstraints& constraints,
232+
const tatum::SetupTimingAnalyzer& setup_analyzer,
233+
std::string prefix,
234+
std::string timing_summary_filename) {
195235
auto& timing_ctx = g_vpr_ctx.timing();
196236

197237
auto crit_paths = tatum::find_critical_paths(*timing_ctx.graph, constraints, setup_analyzer);
198238

199239
auto least_slack_cpd = find_least_slack_critical_path_delay(constraints, setup_analyzer);
200-
VTR_LOG("%scritical path delay (least slack): %g ns", prefix.c_str(), sec_to_nanosec(least_slack_cpd.delay()));
240+
241+
double least_slack_cpd_delay = sec_to_nanosec(least_slack_cpd.delay());
242+
double fmax = sec_to_mhz(least_slack_cpd.delay());
243+
double setup_worst_neg_slack = sec_to_nanosec(find_setup_worst_negative_slack(setup_analyzer));
244+
double setup_total_neg_slack = sec_to_nanosec(find_setup_total_negative_slack(setup_analyzer));
245+
246+
VTR_LOG("%scritical path delay (least slack): %g ns", prefix.c_str(), least_slack_cpd_delay);
201247

202248
if (crit_paths.size() == 1) {
203249
//Fmax is only meaningful for a single-clock circuit
204-
VTR_LOG(", Fmax: %g MHz", sec_to_mhz(least_slack_cpd.delay()));
250+
VTR_LOG(", Fmax: %g MHz", fmax);
205251
}
206252
VTR_LOG("\n");
207253

208-
VTR_LOG("%ssetup Worst Negative Slack (sWNS): %g ns\n", prefix.c_str(), sec_to_nanosec(find_setup_worst_negative_slack(setup_analyzer)));
209-
VTR_LOG("%ssetup Total Negative Slack (sTNS): %g ns\n", prefix.c_str(), sec_to_nanosec(find_setup_total_negative_slack(setup_analyzer)));
254+
VTR_LOG("%ssetup Worst Negative Slack (sWNS): %g ns\n", prefix.c_str(), setup_worst_neg_slack);
255+
VTR_LOG("%ssetup Total Negative Slack (sTNS): %g ns\n", prefix.c_str(), setup_total_neg_slack);
210256
VTR_LOG("\n");
211257

212258
VTR_LOG("%ssetup slack histogram:\n", prefix.c_str());
213259
print_histogram(create_setup_slack_histogram(setup_analyzer));
214260

261+
if (!timing_summary_filename.empty())
262+
write_setup_timing_summary(timing_summary_filename, least_slack_cpd_delay,
263+
fmax, setup_worst_neg_slack, setup_total_neg_slack);
264+
215265
if (crit_paths.size() > 1) {
216266
//Multi-clock
217267
VTR_LOG("\n");

vpr/src/timing/timing_util.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,14 @@ std::vector<HistogramBucket> create_criticality_histogram(const SetupTimingInfo&
4848
size_t num_bins = 10);
4949

5050
//Print a useful summary of timing information
51-
void print_setup_timing_summary(const tatum::TimingConstraints& constraints, const tatum::SetupTimingAnalyzer& setup_analyzer, std::string prefix);
52-
51+
void print_setup_timing_summary(const tatum::TimingConstraints& constraints, const tatum::SetupTimingAnalyzer& setup_analyzer, std::string prefix, std::string timing_summary_filename);
52+
53+
//Write a useful summary of timing information to JSON file
54+
void write_setup_timing_summary(std::string timing_summary_filename,
55+
double least_slack_cpd,
56+
double fmax,
57+
double setup_worst_neg_slack,
58+
double setup_total_neg_slack);
5359
/*
5460
* Hold-time related statistics
5561
*/

0 commit comments

Comments
 (0)