Correct handling of unconnected ports in output Verilog netlist...

...so that outputs are not connected to constants.

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
Maciej Kurc 2022-06-30 12:57:05 +02:00 committed by Paweł Czarnecki
parent 782cdfd8e1
commit 721ac99696
1 changed files with 80 additions and 45 deletions

View File

@ -125,6 +125,9 @@ std::string join_identifier(std::string lhs, std::string rhs);
//
//
// Unconnected net prefix
const std::string unconn_prefix = "__vpr__unconn";
//A combinational timing arc
class Arc {
public:
@ -945,6 +948,16 @@ class NetlistWriterVisitor : public NetlistVisitor {
inst->print_verilog(verilog_os_, unconn_count, depth + 1);
}
//Unconnected wires
if (unconn_count) {
verilog_os_ << "\n";
verilog_os_ << indent(depth + 1) << "//Unconnected wires\n";
for (size_t i = 0; i < unconn_count; ++i) {
auto name = unconn_prefix + std::to_string(i);
verilog_os_ << indent(depth + 1) << "wire " << escape_verilog_identifier(name) << ";\n";
}
}
verilog_os_ << "\n";
verilog_os_ << indent(depth) << "endmodule\n";
}
@ -2126,7 +2139,7 @@ double get_delay_ps(double delay_sec) {
std::string create_unconn_net(size_t& unconn_count) {
//We increment unconn_count by reference so each
//call generates a unique name
return "__vpr__unconn" + std::to_string(unconn_count++);
return unconn_prefix + std::to_string(unconn_count++);
}
/**
@ -2169,6 +2182,30 @@ void print_blif_port(std::ostream& os, size_t& unconn_count, const std::string&
* Handles special cases like multi-bit and disconnected ports
*/
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) {
auto unconn_inp_name = [&]() {
switch (opts.post_synth_netlist_unconn_input_handling) {
case e_post_synth_netlist_unconn_handling::GND:
return std::string("1'b0");
case e_post_synth_netlist_unconn_handling::VCC:
return std::string("1'b1");
case e_post_synth_netlist_unconn_handling::NETS:
return create_unconn_net(unconn_count);
case e_post_synth_netlist_unconn_handling::UNCONNECTED:
default:
return std::string("1'bX");
}
};
auto unconn_out_name = [&]() {
switch (opts.post_synth_netlist_unconn_output_handling) {
case e_post_synth_netlist_unconn_handling::NETS:
return create_unconn_net(unconn_count);
case e_post_synth_netlist_unconn_handling::UNCONNECTED:
default:
return std::string();
}
};
//Port name
os << indent(depth) << "." << port_name << "(";
@ -2178,38 +2215,32 @@ void print_verilog_port(std::ostream& os, size_t& unconn_count, const std::strin
if (nets[0].empty()) {
//Disconnected
if (type == PortType::INPUT || type == PortType::CLOCK) {
switch (opts.post_synth_netlist_unconn_input_handling) {
case e_post_synth_netlist_unconn_handling::GND:
os << "1'b0";
break;
case e_post_synth_netlist_unconn_handling::VCC:
os << "1'b1";
break;
case e_post_synth_netlist_unconn_handling::NETS:
os << create_unconn_net(unconn_count);
break;
case e_post_synth_netlist_unconn_handling::UNCONNECTED:
default:
os << "1'bX";
}
os << unconn_inp_name();
} else {
VTR_ASSERT(type == PortType::OUTPUT);
switch (opts.post_synth_netlist_unconn_output_handling) {
case e_post_synth_netlist_unconn_handling::NETS:
os << create_unconn_net(unconn_count);
break;
case e_post_synth_netlist_unconn_handling::UNCONNECTED:
default:
os << "1'bX";
}
os << unconn_out_name();
}
} else {
//Connected
os << escape_verilog_identifier(nets[0]);
}
} else {
// Check if all pins are unconnected
bool all_unconnected = true;
for (size_t i = 0; i < nets.size(); ++i) {
if (!nets[i].empty()) {
all_unconnected = false;
break;
}
}
//A multi-bit port, we explicitly concat the single-bit nets to build the port,
//taking care to print MSB on left and LSB on right
if (all_unconnected && type == PortType::OUTPUT && opts.post_synth_netlist_unconn_output_handling == e_post_synth_netlist_unconn_handling::UNCONNECTED) {
// Empty connection
} else {
// Individual bits
os << "{"
<< "\n";
for (int ipin = (int)nets.size() - 1; ipin >= 0; --ipin) { //Reverse order to match endianess
@ -2217,10 +2248,13 @@ void print_verilog_port(std::ostream& os, size_t& unconn_count, const std::strin
if (nets[ipin].empty()) {
//Disconnected
if (type == PortType::INPUT || type == PortType::CLOCK) {
os << "1'b0";
os << unconn_inp_name();
} else {
VTR_ASSERT(type == PortType::OUTPUT);
os << "";
// When concatenating output connection there cannot
// be an empty placeholder so we have to create a
// dummy net.
os << create_unconn_net(unconn_count);
}
} else {
//Connected
@ -2228,10 +2262,11 @@ void print_verilog_port(std::ostream& os, size_t& unconn_count, const std::strin
}
if (ipin != 0) {
os << ",";
}
os << "\n";
}
os << indent(depth) + " }";
}
os << "}";
}
os << ")";
}