@@ -127,6 +127,9 @@ std::string join_identifier(std::string lhs, std::string rhs);
127
127
//
128
128
//
129
129
130
+ // Unconnected net prefix
131
+ const std::string unconn_prefix = " __vpr__unconn" ;
132
+
130
133
// A combinational timing arc
131
134
class Arc {
132
135
public:
@@ -953,6 +956,16 @@ class NetlistWriterVisitor : public NetlistVisitor {
953
956
inst->print_verilog (verilog_os_, unconn_count, depth + 1 );
954
957
}
955
958
959
+ // Unconnected wires
960
+ if (unconn_count) {
961
+ verilog_os_ << " \n " ;
962
+ verilog_os_ << indent (depth + 1 ) << " //Unconnected wires\n " ;
963
+ for (size_t i = 0 ; i < unconn_count; ++i) {
964
+ auto name = unconn_prefix + std::to_string (i);
965
+ verilog_os_ << indent (depth + 1 ) << " wire " << escape_verilog_identifier (name) << " ;\n " ;
966
+ }
967
+ }
968
+
956
969
verilog_os_ << " \n " ;
957
970
verilog_os_ << indent (depth) << " endmodule\n " ;
958
971
}
@@ -2134,7 +2147,7 @@ double get_delay_ps(double delay_sec) {
2134
2147
std::string create_unconn_net (size_t & unconn_count) {
2135
2148
// We increment unconn_count by reference so each
2136
2149
// call generates a unique name
2137
- return " __vpr__unconn " + std::to_string (unconn_count++);
2150
+ return unconn_prefix + std::to_string (unconn_count++);
2138
2151
}
2139
2152
2140
2153
/* *
@@ -2177,6 +2190,30 @@ void print_blif_port(std::ostream& os, size_t& unconn_count, const std::string&
2177
2190
* Handles special cases like multi-bit and disconnected ports
2178
2191
*/
2179
2192
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) {
2193
+ auto unconn_inp_name = [&]() {
2194
+ switch (opts.post_synth_netlist_unconn_input_handling ) {
2195
+ case e_post_synth_netlist_unconn_handling::GND:
2196
+ return std::string (" 1'b0" );
2197
+ case e_post_synth_netlist_unconn_handling::VCC:
2198
+ return std::string (" 1'b1" );
2199
+ case e_post_synth_netlist_unconn_handling::NETS:
2200
+ return create_unconn_net (unconn_count);
2201
+ case e_post_synth_netlist_unconn_handling::UNCONNECTED:
2202
+ default :
2203
+ return std::string (" 1'bX" );
2204
+ }
2205
+ };
2206
+
2207
+ auto unconn_out_name = [&]() {
2208
+ switch (opts.post_synth_netlist_unconn_output_handling ) {
2209
+ case e_post_synth_netlist_unconn_handling::NETS:
2210
+ return create_unconn_net (unconn_count);
2211
+ case e_post_synth_netlist_unconn_handling::UNCONNECTED:
2212
+ default :
2213
+ return std::string ();
2214
+ }
2215
+ };
2216
+
2180
2217
// Port name
2181
2218
os << indent (depth) << " ." << port_name << " (" ;
2182
2219
@@ -2186,60 +2223,57 @@ void print_verilog_port(std::ostream& os, size_t& unconn_count, const std::strin
2186
2223
if (nets[0 ].empty ()) {
2187
2224
// Disconnected
2188
2225
if (type == PortType::INPUT || type == PortType::CLOCK) {
2189
- switch (opts.post_synth_netlist_unconn_input_handling ) {
2190
- case e_post_synth_netlist_unconn_handling::GND:
2191
- os << " 1'b0" ;
2192
- break ;
2193
- case e_post_synth_netlist_unconn_handling::VCC:
2194
- os << " 1'b1" ;
2195
- break ;
2196
- case e_post_synth_netlist_unconn_handling::NETS:
2197
- os << create_unconn_net (unconn_count);
2198
- break ;
2199
- case e_post_synth_netlist_unconn_handling::UNCONNECTED:
2200
- default :
2201
- os << " 1'bX" ;
2202
- }
2226
+ os << unconn_inp_name ();
2203
2227
} else {
2204
2228
VTR_ASSERT (type == PortType::OUTPUT);
2205
- switch (opts.post_synth_netlist_unconn_output_handling ) {
2206
- case e_post_synth_netlist_unconn_handling::NETS:
2207
- os << create_unconn_net (unconn_count);
2208
- break ;
2209
- case e_post_synth_netlist_unconn_handling::UNCONNECTED:
2210
- default :
2211
- os << " 1'bX" ;
2212
- }
2229
+ os << unconn_out_name ();
2213
2230
}
2214
2231
} else {
2215
2232
// Connected
2216
2233
os << escape_verilog_identifier (nets[0 ]);
2217
2234
}
2218
2235
} else {
2236
+ // Check if all pins are unconnected
2237
+ bool all_unconnected = true ;
2238
+ for (size_t i = 0 ; i < nets.size (); ++i) {
2239
+ if (!nets[i].empty ()) {
2240
+ all_unconnected = false ;
2241
+ break ;
2242
+ }
2243
+ }
2244
+
2219
2245
// A multi-bit port, we explicitly concat the single-bit nets to build the port,
2220
2246
// taking care to print MSB on left and LSB on right
2221
- os << " {"
2222
- << " \n " ;
2223
- for (int ipin = (int )nets.size () - 1 ; ipin >= 0 ; --ipin) { // Reverse order to match endianess
2224
- os << indent (depth + 1 );
2225
- if (nets[ipin].empty ()) {
2226
- // Disconnected
2227
- if (type == PortType::INPUT || type == PortType::CLOCK) {
2228
- os << " 1'b0" ;
2247
+ if (all_unconnected && type == PortType::OUTPUT && opts.post_synth_netlist_unconn_output_handling == e_post_synth_netlist_unconn_handling::UNCONNECTED) {
2248
+ // Empty connection
2249
+ } else {
2250
+ // Individual bits
2251
+ os << " {"
2252
+ << " \n " ;
2253
+ for (int ipin = (int )nets.size () - 1 ; ipin >= 0 ; --ipin) { // Reverse order to match endianess
2254
+ os << indent (depth + 1 );
2255
+ if (nets[ipin].empty ()) {
2256
+ // Disconnected
2257
+ if (type == PortType::INPUT || type == PortType::CLOCK) {
2258
+ os << unconn_inp_name ();
2259
+ } else {
2260
+ VTR_ASSERT (type == PortType::OUTPUT);
2261
+ // When concatenating output connection there cannot
2262
+ // be an empty placeholder so we have to create a
2263
+ // dummy net.
2264
+ os << create_unconn_net (unconn_count);
2265
+ }
2229
2266
} else {
2230
- VTR_ASSERT (type == PortType::OUTPUT);
2231
- os << " " ;
2267
+ // Connected
2268
+ os << escape_verilog_identifier (nets[ipin]);
2269
+ }
2270
+ if (ipin != 0 ) {
2271
+ os << " ," ;
2232
2272
}
2233
- } else {
2234
- // Connected
2235
- os << escape_verilog_identifier (nets[ipin]);
2236
- }
2237
- if (ipin != 0 ) {
2238
- os << " ," ;
2239
2273
os << " \n " ;
2240
2274
}
2275
+ os << indent (depth) + " }" ;
2241
2276
}
2242
- os << " }" ;
2243
2277
}
2244
2278
os << " )" ;
2245
2279
}
0 commit comments