Skip to content

Commit d16820f

Browse files
[STA] Updated How Un-Initialized Delay Triples are Handled
Thank you to Fred Tombs for pointing out this issue!
1 parent 60bffac commit d16820f

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

vpr/src/base/netlist_writer.cpp

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include <cmath>
6363
#include <fstream>
6464
#include <iostream>
65+
#include <limits>
6566
#include <map>
6667
#include <memory>
6768
#include <regex>
@@ -107,11 +108,21 @@ struct DelayTriple {
107108
, maximum(maximum_sec) {}
108109

109110
/// @brief The minimum delay along a timing edge.
110-
double minimum;
111+
double minimum = std::numeric_limits<double>::quiet_NaN();
111112
/// @brief The typical delay along a timing edge.
112-
double typical;
113+
double typical = std::numeric_limits<double>::quiet_NaN();
113114
/// @brief The maximum delay along a timing edge.
114-
double maximum;
115+
double maximum = std::numeric_limits<double>::quiet_NaN();
116+
117+
/**
118+
* @brief Returns true if the minimum, typical, and maximum delay values have
119+
* been assigned a number.
120+
*
121+
* These values are defaulted to NaN, so this checks if the values have changed.
122+
*/
123+
inline bool has_value() const {
124+
return !std::isnan(minimum) && !std::isnan(typical) && !std::isnan(maximum);
125+
}
115126

116127
/**
117128
* @brief Convert the triple into a string. This string will be of the form:
@@ -123,6 +134,9 @@ struct DelayTriple {
123134
* print method converts the output into picoseconds.
124135
*/
125136
inline std::string str() const {
137+
VTR_ASSERT_MSG(has_value(),
138+
"Cannot create a non-initialized delay triple string");
139+
126140
// Convert the delays to picoseconds for printing.
127141
double minimum_ps = minimum * 1e12;
128142
double typical_ps = typical * 1e12;
@@ -479,22 +493,13 @@ class LatchInst : public Instance {
479493
}
480494

481495
public:
482-
// When a delay is unspecified in the constructor of this class, need to set
483-
// the delay to a value we can check for so we can ignore it when printing
484-
// the SDF file. For now, we set the triple to be all NaNs which can be
485-
// checked for when printing.
486-
// TODO: Should -1 be used instead? Is it possible for delay to be negative?
487-
static constexpr DelayTriple undefined_delay = DelayTriple(std::numeric_limits<double>::quiet_NaN(),
488-
std::numeric_limits<double>::quiet_NaN(),
489-
std::numeric_limits<double>::quiet_NaN());
490-
491496
LatchInst(std::string inst_name, ///<Name of this instance
492497
std::map<std::string, std::string> port_conns, ///<Instance's port-to-net connections
493498
Type type, ///<Type of this latch
494499
vtr::LogicValue init_value, ///<Initial value of the latch
495-
DelayTriple tcq = undefined_delay, ///<Clock-to-Q delay
496-
DelayTriple tsu = undefined_delay, ///<Setup time
497-
DelayTriple thld = undefined_delay) ///<Hold time
500+
DelayTriple tcq = DelayTriple(), ///<Clock-to-Q delay
501+
DelayTriple tsu = DelayTriple(), ///<Setup time
502+
DelayTriple thld = DelayTriple()) ///<Hold time
498503
: instance_name_(inst_name)
499504
, port_connections_(port_conns)
500505
, type_(type)
@@ -570,7 +575,7 @@ class LatchInst : public Instance {
570575
os << indent(depth + 1) << "(INSTANCE " << escape_sdf_identifier(instance_name_) << ")\n";
571576

572577
//Clock to Q
573-
if (!std::isnan(tcq_delay_triple_.maximum)) {
578+
if (tcq_delay_triple_.has_value()) {
574579
os << indent(depth + 1) << "(DELAY\n";
575580
os << indent(depth + 2) << "(ABSOLUTE\n";
576581
os << indent(depth + 3) << "(IOPATH "
@@ -580,12 +585,12 @@ class LatchInst : public Instance {
580585
}
581586

582587
//Setup/Hold
583-
if (!std::isnan(tsu_delay_triple_.maximum) || !std::isnan(thld_delay_triple_.maximum)) {
588+
if (tsu_delay_triple_.has_value() || thld_delay_triple_.has_value()) {
584589
os << indent(depth + 1) << "(TIMINGCHECK\n";
585-
if (!std::isnan(tsu_delay_triple_.maximum)) {
590+
if (tsu_delay_triple_.has_value()) {
586591
os << indent(depth + 2) << "(SETUP D (posedge clock) " << tsu_delay_triple_.str() << ")\n";
587592
}
588-
if (!std::isnan(thld_delay_triple_.maximum)) {
593+
if (thld_delay_triple_.has_value()) {
589594
os << indent(depth + 2) << "(HOLD D (posedge clock) " << thld_delay_triple_.str() << ")\n";
590595
}
591596
}
@@ -2346,8 +2351,8 @@ DelayTriple get_pin_tco_delay_triple(const t_pb_graph_pin& pin) {
23462351
DelayTriple delay_triple;
23472352
delay_triple.minimum = pin.tco_min;
23482353
delay_triple.maximum = pin.tco_max;
2349-
// TODO: VPR does not have typical values for delays (as far as I can tell),
2350-
// is it reasonable to take the average of min and max?
2354+
// Since Tatum does not provide typical delays, set it to be the average
2355+
// of min and max.
23512356
delay_triple.typical = (pin.tco_min + pin.tco_max) / 2.0;
23522357
return delay_triple;
23532358
}
@@ -2361,8 +2366,8 @@ DelayTriple get_edge_delay_triple(tatum::EdgeId edge_id,
23612366
DelayTriple delay_triple;
23622367
delay_triple.minimum = min_edge_delay;
23632368
delay_triple.maximum = max_edge_delay;
2364-
// TODO: VPR does not have typical values for delays (as far as I can tell),
2365-
// is it reasonable to take the average of min and max?
2369+
// Since Tatum does not provide typical delays, set it to be the average
2370+
// of min and max.
23662371
delay_triple.typical = (min_edge_delay + max_edge_delay) / 2.0;
23672372
return delay_triple;
23682373
}
@@ -2614,7 +2619,7 @@ void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDe
26142619
void merged_netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDelayCalculator> delay_calc, struct t_analysis_opts opts) {
26152620
std::string verilog_filename = basename + "_merged_post_implementation.v";
26162621

2617-
VTR_LOG("Writing Implementation Netlist: %s\n", verilog_filename.c_str());
2622+
VTR_LOG("Writing Merged Implementation Netlist: %s\n", verilog_filename.c_str());
26182623

26192624
std::ofstream verilog_os(verilog_filename);
26202625
// Don't write blif and sdf, pass dummy streams

vpr/src/base/netlist_writer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
* @brief Writes out the post-synthesis implementation netlists in BLIF and Verilog formats,
99
* along with an SDF for delay annotations.
1010
*
11+
* Here, post-synthesis implementation netlist is the netlist as it appears after
12+
* routing (i.e. implementation is complete).
13+
*
1114
* All written filenames end in {basename}_post_synthesis.{fmt} where {basename} is the
1215
* basename argument and {fmt} is the file format (e.g. v, blif, sdf)
1316
*/
@@ -17,6 +20,9 @@ void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDe
1720
* @brief Writes out the post implementation netlist in Verilog format.
1821
* It has its top module ports merged into multi-bit ones.
1922
*
23+
* Here, post-synthesis implementation netlist is the netlist as it appears after
24+
* routing (i.e. implementation is complete).
25+
*
2026
* Written filename ends in {basename}_merged_post_implementation.v where {basename} is the
2127
* basename argument.
2228
*/

0 commit comments

Comments
 (0)