Skip to content

Commit 8c524bd

Browse files
authored
Merge pull request #1789 from antmicro/fix-post-synthesis-netlist
Add unconnected port options for Verilog netlist
2 parents 44f9683 + c425978 commit 8c524bd

9 files changed

+212
-31
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,26 @@ Analysis Options
12371237

12381238
**Default:** ``off``
12391239

1240+
.. option:: --post_synth_netlist_unconn_inputs { unconnected | nets | gnd | vcc }
1241+
1242+
Controls how unconnected input cell ports are handled in the post-synthesis netlist
1243+
1244+
* unconnected: leave unconnected
1245+
* nets: connect each unconnected input pin to its own separate undriven net named: ``__vpr__unconn<ID>``, where ``<ID>`` is index assigned to this occurrence of unconnected port in design
1246+
* gnd: tie all to ground (``1'b0``)
1247+
* vcc: tie all to VCC (``1'b1``)
1248+
1249+
**Default:** ``unconnected``
1250+
1251+
.. option:: --post_synth_netlist_unconn_outputs { unconnected | nets }
1252+
1253+
Controls how unconnected output cell ports are handled in the post-synthesis netlist
1254+
1255+
* unconnected: leave unconnected
1256+
* nets: connect each unconnected output pin to its own separate undriven net named: ``__vpr__unconn<ID>``, where ``<ID>`` is index assigned to this occurrence of unconnected port in design
1257+
1258+
**Default:** ``unconnected``
1259+
12401260
.. option:: --timing_report_npaths <int>
12411261

12421262
Controls how many timing paths are reported.

vpr/src/base/SetupVPR.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ static void SetupAnalysisOpts(const t_options& Options, t_analysis_opts& analysi
626626
analysis_opts.timing_report_skew = Options.timing_report_skew;
627627
analysis_opts.echo_dot_timing_graph_node = Options.echo_dot_timing_graph_node;
628628

629+
analysis_opts.post_synth_netlist_unconn_input_handling = Options.post_synth_netlist_unconn_input_handling;
630+
analysis_opts.post_synth_netlist_unconn_output_handling = Options.post_synth_netlist_unconn_output_handling;
631+
629632
analysis_opts.timing_update_type = Options.timing_update_type;
630633
}
631634

vpr/src/base/ShowSetup.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,31 @@ static void ShowAnalysisOpts(const t_analysis_opts& AnalysisOpts) {
604604
default:
605605
VPR_FATAL_ERROR(VPR_ERROR_UNKNOWN, "Unknown timing_report_detail\n");
606606
}
607+
608+
const auto opts = {
609+
std::make_tuple(&AnalysisOpts.post_synth_netlist_unconn_input_handling, "post_synth_netlist_unconn_input_handling"),
610+
std::make_tuple(&AnalysisOpts.post_synth_netlist_unconn_output_handling, "post_synth_netlist_unconn_output_handling"),
611+
};
612+
for (const auto& opt : opts) {
613+
auto value = *std::get<0>(opt);
614+
VTR_LOG("AnalysisOpts.%s: ", std::get<1>(opt));
615+
switch (value) {
616+
case e_post_synth_netlist_unconn_handling::UNCONNECTED:
617+
VTR_LOG("UNCONNECTED\n");
618+
break;
619+
case e_post_synth_netlist_unconn_handling::NETS:
620+
VTR_LOG("NETS\n");
621+
break;
622+
case e_post_synth_netlist_unconn_handling::GND:
623+
VTR_LOG("GND\n");
624+
break;
625+
case e_post_synth_netlist_unconn_handling::VCC:
626+
VTR_LOG("VCC\n");
627+
break;
628+
default:
629+
VPR_FATAL_ERROR(VPR_ERROR_UNKNOWN, "Unknown post_synth_netlist_unconn_handling\n");
630+
}
631+
}
607632
VTR_LOG("\n");
608633
}
609634

vpr/src/base/netlist_writer.cpp

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "vtr_version.h"
1919

2020
#include "vpr_error.h"
21+
#include "vpr_types.h"
2122

2223
#include "netlist_walker.h"
2324
#include "netlist_writer.h"
@@ -110,7 +111,7 @@ std::string indent(size_t depth);
110111
double get_delay_ps(double delay_sec);
111112

112113
void print_blif_port(std::ostream& os, size_t& unconn_count, const std::string& port_name, const std::vector<std::string>& nets, int depth);
113-
void print_verilog_port(std::ostream& os, const std::string& port_name, const std::vector<std::string>& nets, PortType type, int depth);
114+
void print_verilog_port(std::ostream& os, size_t& unconn_count, const std::string& port_name, const std::vector<std::string>& nets, PortType type, int depth, struct t_analysis_opts& opts);
114115

115116
std::string create_unconn_net(size_t& unconn_count);
116117
std::string escape_verilog_identifier(const std::string id);
@@ -187,7 +188,7 @@ class Instance {
187188
virtual void print_blif(std::ostream& os, size_t& unconn_count, int depth = 0) = 0;
188189

189190
///@brief Print the current instanse in Verilog, see print_blif() for argument descriptions
190-
virtual void print_verilog(std::ostream& os, int depth = 0) = 0;
191+
virtual void print_verilog(std::ostream& os, size_t& unconn_count, int depth = 0) = 0;
191192

192193
///@brief Print the current instanse in SDF, see print_blif() for argument descriptions
193194
virtual void print_sdf(std::ostream& os, int depth = 0) = 0;
@@ -200,13 +201,15 @@ class LutInst : public Instance {
200201
LogicVec lut_mask, ///<The LUT mask representing the logic function
201202
std::string inst_name, ///<The name of this instance
202203
std::map<std::string, std::vector<std::string>> port_conns, ///<The port connections of this instance. Key: port name, Value: connected nets
203-
std::vector<Arc> timing_arc_values) ///<The timing arcs of this instance
204+
std::vector<Arc> timing_arc_values, ///<The timing arcs of this instance
205+
struct t_analysis_opts opts)
204206
: type_("LUT_K")
205207
, lut_size_(lut_size)
206208
, lut_mask_(lut_mask)
207209
, inst_name_(inst_name)
208210
, port_conns_(port_conns)
209-
, timing_arcs_(timing_arc_values) {
211+
, timing_arcs_(timing_arc_values)
212+
, opts_(opts) {
210213
}
211214

212215
//Accessors
@@ -215,7 +218,7 @@ class LutInst : public Instance {
215218
std::string type() { return type_; }
216219

217220
public: //Instance interface method implementations
218-
void print_verilog(std::ostream& os, int depth) override {
221+
void print_verilog(std::ostream& os, size_t& unconn_count, int depth) override {
219222
//Instantiate the lut
220223
os << indent(depth) << type_ << " #(\n";
221224

@@ -231,10 +234,10 @@ class LutInst : public Instance {
231234
VTR_ASSERT(port_conns_.count("out"));
232235
VTR_ASSERT(port_conns_.size() == 2);
233236

234-
print_verilog_port(os, "in", port_conns_["in"], PortType::INPUT, depth + 1);
237+
print_verilog_port(os, unconn_count, "in", port_conns_["in"], PortType::INPUT, depth + 1, opts_);
235238
os << ","
236239
<< "\n";
237-
print_verilog_port(os, "out", port_conns_["out"], PortType::OUTPUT, depth + 1);
240+
print_verilog_port(os, unconn_count, "out", port_conns_["out"], PortType::OUTPUT, depth + 1, opts_);
238241
os << "\n";
239242

240243
os << indent(depth) << ");\n\n";
@@ -376,6 +379,7 @@ class LutInst : public Instance {
376379
std::string inst_name_;
377380
std::map<std::string, std::vector<std::string>> port_conns_;
378381
std::vector<Arc> timing_arcs_;
382+
struct t_analysis_opts opts_;
379383
};
380384

381385
class LatchInst : public Instance {
@@ -462,7 +466,7 @@ class LatchInst : public Instance {
462466
os << "\n";
463467
}
464468

465-
void print_verilog(std::ostream& os, int depth = 0) override {
469+
void print_verilog(std::ostream& os, size_t& /*unconn_count*/, int depth = 0) override {
466470
//Currently assume a standard DFF
467471
VTR_ASSERT(type_ == Type::RISING_EDGE);
468472

@@ -560,7 +564,8 @@ class BlackBoxInst : public Instance {
560564
std::vector<Arc> timing_arcs, ///<Combinational timing arcs
561565
std::map<std::string, sequential_port_delay_pair> ports_tsu, ///<Port setup checks
562566
std::map<std::string, sequential_port_delay_pair> ports_thld, ///<Port hold checks
563-
std::map<std::string, sequential_port_delay_pair> ports_tcq) ///<Port clock-to-q delays
567+
std::map<std::string, sequential_port_delay_pair> ports_tcq, ///<Port clock-to-q delays
568+
struct t_analysis_opts opts)
564569
: type_name_(type_name)
565570
, inst_name_(inst_name)
566571
, params_(params)
@@ -570,7 +575,8 @@ class BlackBoxInst : public Instance {
570575
, timing_arcs_(timing_arcs)
571576
, ports_tsu_(ports_tsu)
572577
, ports_thld_(ports_thld)
573-
, ports_tcq_(ports_tcq) {}
578+
, ports_tcq_(ports_tcq)
579+
, opts_(opts) {}
574580

575581
void print_blif(std::ostream& os, size_t& unconn_count, int depth = 0) override {
576582
os << indent(depth) << ".subckt " << type_name_ << " \\"
@@ -613,7 +619,7 @@ class BlackBoxInst : public Instance {
613619
os << "\n";
614620
}
615621

616-
void print_verilog(std::ostream& os, int depth = 0) override {
622+
void print_verilog(std::ostream& os, size_t& unconn_count, int depth = 0) override {
617623
//Instance type
618624
os << indent(depth) << type_name_ << " #(\n";
619625

@@ -633,7 +639,7 @@ class BlackBoxInst : public Instance {
633639
for (auto iter = input_port_conns_.begin(); iter != input_port_conns_.end(); ++iter) {
634640
auto& port_name = iter->first;
635641
auto& nets = iter->second;
636-
print_verilog_port(os, port_name, nets, PortType::INPUT, depth + 1);
642+
print_verilog_port(os, unconn_count, port_name, nets, PortType::INPUT, depth + 1, opts_);
637643
if (!(iter == --input_port_conns_.end() && output_port_conns_.empty())) {
638644
os << ",";
639645
}
@@ -644,7 +650,7 @@ class BlackBoxInst : public Instance {
644650
for (auto iter = output_port_conns_.begin(); iter != output_port_conns_.end(); ++iter) {
645651
auto& port_name = iter->first;
646652
auto& nets = iter->second;
647-
print_verilog_port(os, port_name, nets, PortType::OUTPUT, depth + 1);
653+
print_verilog_port(os, unconn_count, port_name, nets, PortType::OUTPUT, depth + 1, opts_);
648654
if (!(iter == --output_port_conns_.end())) {
649655
os << ",";
650656
}
@@ -755,6 +761,7 @@ class BlackBoxInst : public Instance {
755761
std::map<std::string, sequential_port_delay_pair> ports_tsu_;
756762
std::map<std::string, sequential_port_delay_pair> ports_thld_;
757763
std::map<std::string, sequential_port_delay_pair> ports_tcq_;
764+
struct t_analysis_opts opts_;
758765
};
759766

760767
/**
@@ -793,11 +800,13 @@ class NetlistWriterVisitor : public NetlistVisitor {
793800
NetlistWriterVisitor(std::ostream& verilog_os, ///<Output stream for verilog netlist
794801
std::ostream& blif_os, ///<Output stream for blif netlist
795802
std::ostream& sdf_os, ///<Output stream for SDF
796-
std::shared_ptr<const AnalysisDelayCalculator> delay_calc)
803+
std::shared_ptr<const AnalysisDelayCalculator> delay_calc,
804+
struct t_analysis_opts opts)
797805
: verilog_os_(verilog_os)
798806
, blif_os_(blif_os)
799807
, sdf_os_(sdf_os)
800-
, delay_calc_(delay_calc) {
808+
, delay_calc_(delay_calc)
809+
, opts_(opts) {
801810
auto& atom_ctx = g_vpr_ctx.atom();
802811

803812
//Initialize the pin to tnode look-up
@@ -903,8 +912,6 @@ class NetlistWriterVisitor : public NetlistVisitor {
903912
}
904913
}
905914

906-
verilog_os_ << indent(depth + 1) << "wire DummyOut;\n";
907-
908915
//connections between primary I/Os and their internal wires
909916
verilog_os_ << "\n";
910917
verilog_os_ << indent(depth + 1) << "//IO assignments\n";
@@ -931,10 +938,11 @@ class NetlistWriterVisitor : public NetlistVisitor {
931938
}
932939

933940
//All the cell instances
941+
size_t unconn_count = 0;
934942
verilog_os_ << "\n";
935943
verilog_os_ << indent(depth + 1) << "//Cell instances\n";
936944
for (auto& inst : cell_instances_) {
937-
inst->print_verilog(verilog_os_, depth + 1);
945+
inst->print_verilog(verilog_os_, unconn_count, depth + 1);
938946
}
939947

940948
verilog_os_ << "\n";
@@ -1213,7 +1221,7 @@ class NetlistWriterVisitor : public NetlistVisitor {
12131221
port_conns["out"].push_back(net);
12141222
}
12151223

1216-
auto inst = std::make_shared<LutInst>(lut_size, lut_mask, inst_name, port_conns, timing_arcs);
1224+
auto inst = std::make_shared<LutInst>(lut_size, lut_mask, inst_name, port_conns, timing_arcs, opts_);
12171225

12181226
return inst;
12191227
}
@@ -1413,7 +1421,7 @@ class NetlistWriterVisitor : public NetlistVisitor {
14131421
}
14141422
}
14151423

1416-
return std::make_shared<BlackBoxInst>(type, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq);
1424+
return std::make_shared<BlackBoxInst>(type, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq, opts_);
14171425
}
14181426

14191427
///@brief Returns an Instance object representing a Multiplier
@@ -1509,7 +1517,7 @@ class NetlistWriterVisitor : public NetlistVisitor {
15091517

15101518
VTR_ASSERT(pb_graph_node->num_clock_ports == 0); //No clocks
15111519

1512-
return std::make_shared<BlackBoxInst>(type_name, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq);
1520+
return std::make_shared<BlackBoxInst>(type_name, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq, opts_);
15131521
}
15141522

15151523
///@brief Returns an Instance object representing an Adder
@@ -1609,7 +1617,7 @@ class NetlistWriterVisitor : public NetlistVisitor {
16091617
}
16101618
}
16111619

1612-
return std::make_shared<BlackBoxInst>(type_name, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq);
1620+
return std::make_shared<BlackBoxInst>(type_name, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq, opts_);
16131621
}
16141622

16151623
std::shared_ptr<Instance> make_blackbox_instance(const t_pb* atom) {
@@ -1747,7 +1755,7 @@ class NetlistWriterVisitor : public NetlistVisitor {
17471755
attrs[attr.first] = attr.second;
17481756
}
17491757

1750-
return std::make_shared<BlackBoxInst>(type_name, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq);
1758+
return std::make_shared<BlackBoxInst>(type_name, inst_name, params, attrs, input_port_conns, output_port_conns, timing_arcs, ports_tsu, ports_thld, ports_tcq, opts_);
17511759
}
17521760

17531761
///@brief Returns the top level pb_route associated with the given pb
@@ -2067,14 +2075,15 @@ class NetlistWriterVisitor : public NetlistVisitor {
20672075
std::map<std::pair<ClusterBlockId, int>, tatum::NodeId> pin_id_to_tnode_lookup_;
20682076

20692077
std::shared_ptr<const AnalysisDelayCalculator> delay_calc_;
2078+
struct t_analysis_opts opts_;
20702079
};
20712080

20722081
//
20732082
// Externally Accessible Functions
20742083
//
20752084

20762085
///@brief Main routing for this file. See netlist_writer.h for details.
2077-
void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDelayCalculator> delay_calc) {
2086+
void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDelayCalculator> delay_calc, struct t_analysis_opts opts) {
20782087
std::string verilog_filename = basename + "_post_synthesis.v";
20792088
std::string blif_filename = basename + "_post_synthesis.blif";
20802089
std::string sdf_filename = basename + "_post_synthesis.sdf";
@@ -2087,7 +2096,7 @@ void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDe
20872096
std::ofstream blif_os(blif_filename);
20882097
std::ofstream sdf_os(sdf_filename);
20892098

2090-
NetlistWriterVisitor visitor(verilog_os, blif_os, sdf_os, delay_calc);
2099+
NetlistWriterVisitor visitor(verilog_os, blif_os, sdf_os, delay_calc, opts);
20912100

20922101
NetlistWalker nl_walker(visitor);
20932102

@@ -2159,7 +2168,7 @@ void print_blif_port(std::ostream& os, size_t& unconn_count, const std::string&
21592168
*
21602169
* Handles special cases like multi-bit and disconnected ports
21612170
*/
2162-
void print_verilog_port(std::ostream& os, const std::string& port_name, const std::vector<std::string>& nets, PortType type, int depth) {
2171+
void print_verilog_port(std::ostream& os, size_t& unconn_count, const std::string& port_name, const std::vector<std::string>& nets, PortType type, int depth, struct t_analysis_opts& opts) {
21632172
//Port name
21642173
os << indent(depth) << "." << port_name << "(";
21652174

@@ -2169,10 +2178,30 @@ void print_verilog_port(std::ostream& os, const std::string& port_name, const st
21692178
if (nets[0].empty()) {
21702179
//Disconnected
21712180
if (type == PortType::INPUT || type == PortType::CLOCK) {
2172-
os << "1'b0";
2181+
switch (opts.post_synth_netlist_unconn_input_handling) {
2182+
case e_post_synth_netlist_unconn_handling::GND:
2183+
os << "1'b0";
2184+
break;
2185+
case e_post_synth_netlist_unconn_handling::VCC:
2186+
os << "1'b1";
2187+
break;
2188+
case e_post_synth_netlist_unconn_handling::NETS:
2189+
os << create_unconn_net(unconn_count);
2190+
break;
2191+
case e_post_synth_netlist_unconn_handling::UNCONNECTED:
2192+
default:
2193+
os << "1'bX";
2194+
}
21732195
} else {
21742196
VTR_ASSERT(type == PortType::OUTPUT);
2175-
os << "DummyOut";
2197+
switch (opts.post_synth_netlist_unconn_output_handling) {
2198+
case e_post_synth_netlist_unconn_handling::NETS:
2199+
os << create_unconn_net(unconn_count);
2200+
break;
2201+
case e_post_synth_netlist_unconn_handling::UNCONNECTED:
2202+
default:
2203+
os << "1'bX";
2204+
}
21762205
}
21772206
} else {
21782207
//Connected
@@ -2191,7 +2220,7 @@ void print_verilog_port(std::ostream& os, const std::string& port_name, const st
21912220
os << "1'b0";
21922221
} else {
21932222
VTR_ASSERT(type == PortType::OUTPUT);
2194-
os << "DummyOut";
2223+
os << "";
21952224
}
21962225
} else {
21972226
//Connected

vpr/src/base/netlist_writer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
* All written filenames end in {basename}_post_synthesis.{fmt} where {basename} is the
1616
* basename argument and {fmt} is the file format (e.g. v, blif, sdf)
1717
*/
18-
void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDelayCalculator> delay_calc);
18+
void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDelayCalculator> delay_calc, struct t_analysis_opts opts);
1919

2020
#endif

0 commit comments

Comments
 (0)