Skip to content

Commit 952b2d7

Browse files
committed
vpr: analysis: use structs in --write_timing_usage
Signed-off-by: Pawel Czarnecki <[email protected]>
1 parent 11cec91 commit 952b2d7

File tree

3 files changed

+108
-41
lines changed

3 files changed

+108
-41
lines changed

vpr/src/base/read_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
24772477
.show_in(argparse::ShowIn::HELP_ONLY);
24782478

24792479
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.")
2480+
.help("Writes implemented design final timing summary to the specified JSON, XML or TXT file.")
24812481
.show_in(argparse::ShowIn::HELP_ONLY);
24822482

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

vpr/src/timing/timing_util.cpp

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

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";
194+
void TimingStats::writeHuman(std::ostream& output) const {
195+
output << prefix << "critical path delay (least slack): " << least_slack_cpd_delay << " ns";
204196

205-
fp << " \"cpd\": " << least_slack_cpd << ",\n";
206-
fp << " \"fmax\": " << fmax << ",\n";
197+
//Fmax is only meaningful for a single-clock circuit
198+
output << ", Fmax: " << fmax << " MHz";
199+
output << "\n";
207200

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";
201+
output << prefix << "setup Worst Negative Slack (sWNS): " << setup_worst_neg_slack << " ns\n";
202+
output << prefix << "setup Total Negative Slack (sTNS): " << setup_total_neg_slack << " ns\n";
203+
output << "\n";
204+
}
205+
void TimingStats::writeJSON(std::ostream& output) const {
206+
output << "{\n";
217207

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";
208+
output << " \"cpd\": " << least_slack_cpd_delay << ",\n";
209+
output << " \"fmax\": " << fmax << ",\n";
222210

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());
211+
output << " \"swns\": " << setup_worst_neg_slack << ",\n";
212+
output << " \"stns\": " << setup_total_neg_slack << "\n";
213+
output << "}\n";
214+
}
215+
216+
void TimingStats::writeXML(std::ostream& output) const {
217+
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
218+
output << "<timing_summary_report>\n";
219+
220+
output << " <cpd value=\"" << least_slack_cpd_delay << "\" unit=\"ns\" description=\"Final critical path delay\"></nets>\n";
221+
output << " <fmax value=\"" << fmax << "\" unit=\"MHz\" description=\"Max circuit frequency\"></fmax>\n";
222+
output << " <swns value=\"" << setup_worst_neg_slack << "\" unit=\"ns\" description=\"setup Worst Negative Slack (sWNS)\"></swns>\n";
223+
output << " <stns value=\"" << setup_total_neg_slack << "\" unit=\"ns\" description=\"setup Total Negative Slack (sTNS)\"></stns>\n";
224+
225+
output << "</block_usage_report>\n";
226+
}
227+
228+
TimingStats::TimingStats(std::string pref, double cpd, double f_max, double swns, double stns) {
229+
least_slack_cpd_delay = cpd;
230+
fmax = f_max;
231+
setup_worst_neg_slack = swns;
232+
setup_total_neg_slack = stns;
233+
prefix = pref;
234+
}
235+
236+
void TimingStats::write(OutputFormat fmt, std::ostream& output) const {
237+
switch (fmt) {
238+
case HumanReadable:
239+
writeHuman(output);
240+
break;
241+
case JSON:
242+
writeJSON(output);
243+
break;
244+
case XML:
245+
writeXML(output);
246+
break;
247+
default:
248+
VPR_FATAL_ERROR(VPR_ERROR_PACK,
249+
"Unknown extension on in timing summary file");
250+
break;
251+
}
252+
}
253+
254+
void write_setup_timing_summary(std::string timing_summary_filename, const TimingStats& stats) {
255+
if (timing_summary_filename.size() > 0) {
256+
TimingStats::OutputFormat fmt;
257+
258+
if (vtr::check_file_name_extension(timing_summary_filename.c_str(), ".json")) {
259+
fmt = TimingStats::OutputFormat::JSON;
260+
} else if (vtr::check_file_name_extension(timing_summary_filename.c_str(), ".xml")) {
261+
fmt = TimingStats::OutputFormat::XML;
262+
} else if (vtr::check_file_name_extension(timing_summary_filename.c_str(), ".txt")) {
263+
fmt = TimingStats::OutputFormat::HumanReadable;
264+
} else {
265+
VPR_FATAL_ERROR(VPR_ERROR_PACK, "Unknown extension on output %s", timing_summary_filename.c_str());
266+
}
267+
268+
std::fstream fp;
269+
270+
fp.open(timing_summary_filename, std::fstream::out | std::fstream::trunc);
271+
stats.write(fmt, fp);
272+
fp.close();
228273
}
229274
}
230275

@@ -243,6 +288,11 @@ void print_setup_timing_summary(const tatum::TimingConstraints& constraints,
243288
double setup_worst_neg_slack = sec_to_nanosec(find_setup_worst_negative_slack(setup_analyzer));
244289
double setup_total_neg_slack = sec_to_nanosec(find_setup_total_negative_slack(setup_analyzer));
245290

291+
const auto stats = TimingStats(prefix, least_slack_cpd_delay, fmax,
292+
setup_worst_neg_slack, setup_total_neg_slack);
293+
if (!timing_summary_filename.empty())
294+
write_setup_timing_summary(timing_summary_filename, stats);
295+
246296
VTR_LOG("%scritical path delay (least slack): %g ns", prefix.c_str(), least_slack_cpd_delay);
247297

248298
if (crit_paths.size() == 1) {
@@ -258,10 +308,6 @@ void print_setup_timing_summary(const tatum::TimingConstraints& constraints,
258308
VTR_LOG("%ssetup slack histogram:\n", prefix.c_str());
259309
print_histogram(create_setup_slack_histogram(setup_analyzer));
260310

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-
265311
if (crit_paths.size() > 1) {
266312
//Multi-clock
267313
VTR_LOG("\n");

vpr/src/timing/timing_util.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ std::vector<HistogramBucket> create_criticality_histogram(const SetupTimingInfo&
5050
//Print a useful summary of timing information
5151
void print_setup_timing_summary(const tatum::TimingConstraints& constraints, const tatum::SetupTimingAnalyzer& setup_analyzer, std::string prefix, std::string timing_summary_filename);
5252

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);
5953
/*
6054
* Hold-time related statistics
6155
*/
@@ -219,4 +213,31 @@ tatum::NodeId pin_name_to_tnode(std::string name);
219213
void write_setup_timing_graph_dot(std::string filename, SetupTimingInfo& timing_info, tatum::NodeId debug_node = tatum::NodeId::INVALID());
220214
void write_hold_timing_graph_dot(std::string filename, HoldTimingInfo& timing_info, tatum::NodeId debug_node = tatum::NodeId::INVALID());
221215

216+
struct TimingStats {
217+
private:
218+
void writeHuman(std::ostream& output) const;
219+
void writeJSON(std::ostream& output) const;
220+
void writeXML(std::ostream& output) const;
221+
222+
public:
223+
TimingStats(std::string prefix, double least_slack_cpd_delay, double fmax, double setup_worst_neg_slack, double setup_total_neg_slack);
224+
225+
enum OutputFormat {
226+
HumanReadable,
227+
JSON,
228+
XML
229+
};
230+
231+
double least_slack_cpd_delay;
232+
double fmax;
233+
double setup_worst_neg_slack;
234+
double setup_total_neg_slack;
235+
std::string prefix;
236+
237+
void write(OutputFormat fmt, std::ostream& output) const;
238+
};
239+
240+
//Write a useful summary of timing information to JSON file
241+
void write_setup_timing_summary(std::string timing_summary_filename, const TimingStats& stats);
242+
222243
#endif

0 commit comments

Comments
 (0)