edif: more resilience to mismatched port connection sizes.

Fixes #1653.
This commit is contained in:
Marcin Kościelnicki 2020-02-01 15:27:27 +01:00 committed by Marcelina Kościelnicka
parent d44848328b
commit 8f559b070a
1 changed files with 27 additions and 16 deletions

View File

@ -246,19 +246,25 @@ struct EdifBackend : public Backend {
else if (!ct.cell_input(cell_it.first, port_it.first)) else if (!ct.cell_input(cell_it.first, port_it.first))
dir = "OUTPUT"; dir = "OUTPUT";
} }
if (port_it.second == 1) int width = port_it.second;
*f << stringf(" (port %s (direction %s))\n", EDIF_DEF(port_it.first), dir); int start = 0;
else { bool upto = false;
int b[2] = {port_it.second-1, 0};
auto m = design->module(cell_it.first); auto m = design->module(cell_it.first);
if (m) { if (m) {
auto w = m->wire(port_it.first); auto w = m->wire(port_it.first);
if (w) { if (w) {
b[w->upto ? 0 : 1] = w->start_offset; width = GetSize(w);
b[w->upto ? 1 : 0] = w->start_offset+GetSize(w)-1; start = w->start_offset;
upto = w->upto;
} }
} }
*f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(port_it.first, port_rename, b[0], b[1]), port_it.second, dir); if (width == 1)
*f << stringf(" (port %s (direction %s))\n", EDIF_DEF(port_it.first), dir);
else {
int b[2];
b[upto ? 0 : 1] = start;
b[upto ? 1 : 0] = start+width-1;
*f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(port_it.first, port_rename, b[0], b[1]), width, dir);
} }
} }
*f << stringf(" )\n"); *f << stringf(" )\n");
@ -390,21 +396,26 @@ struct EdifBackend : public Backend {
if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1) if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1)
log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n", log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n",
i, log_id(module), log_id(cell), log_id(p.first), log_signal(sig[i])); i, log_id(module), log_id(cell), log_id(p.first), log_signal(sig[i]));
else if (sig.size() == 1)
net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
else { else {
int member_idx = GetSize(sig)-i-1; int member_idx = GetSize(sig)-i-1;
auto m = design->module(cell->type); auto m = design->module(cell->type);
int width = sig.size();
if (m) { if (m) {
auto w = m->wire(p.first); auto w = m->wire(p.first);
if (w) if (w) {
member_idx = GetSize(w)-i-1; member_idx = GetSize(w)-i-1;
width = GetSize(w);
} }
}
if (width == 1)
net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
else {
net_join_db[sig[i]].insert(make_pair(stringf("(portRef (member %s %d) (instanceRef %s))", net_join_db[sig[i]].insert(make_pair(stringf("(portRef (member %s %d) (instanceRef %s))",
EDIF_REF(p.first), member_idx, EDIF_REF(cell->name)), cell->output(p.first))); EDIF_REF(p.first), member_idx, EDIF_REF(cell->name)), cell->output(p.first)));
} }
} }
} }
}
for (auto &it : net_join_db) { for (auto &it : net_join_db) {
RTLIL::SigBit sig = it.first; RTLIL::SigBit sig = it.first;
if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) { if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) {