diff options
Diffstat (limited to 'passes/techmap/iopadmap.cc')
-rw-r--r-- | passes/techmap/iopadmap.cc | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 8b1862237..a18d02652 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -203,7 +203,7 @@ struct IopadmapPass : public Pass { // Collect explicitly-marked already-buffered SigBits. for (auto wire : module->wires()) - if (wire->get_bool_attribute("\\iopad_external_pin") || ignore.count(make_pair(module->name, wire->name))) + if (wire->get_bool_attribute(ID::iopad_external_pin) || ignore.count(make_pair(module->name, wire->name))) for (int i = 0; i < GetSize(wire); i++) buf_bits.insert(sigmap(SigBit(wire, i))); @@ -229,11 +229,13 @@ struct IopadmapPass : public Pass { for (auto module : design->selected_modules()) { dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; + pool<SigSig> remove_conns; if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) { dict<SigBit, Cell *> tbuf_bits; pool<SigBit> driven_bits; + dict<SigBit, SigSig> z_conns; // Gather tristate buffers and always-on drivers. for (auto cell : module->cells()) @@ -252,8 +254,10 @@ struct IopadmapPass : public Pass { for (int i = 0; i < GetSize(conn.first); i++) { SigBit dstbit = conn.first[i]; SigBit srcbit = conn.second[i]; - if (!srcbit.wire && srcbit.data == State::Sz) + if (!srcbit.wire && srcbit.data == State::Sz) { + z_conns[dstbit] = conn; continue; + } driven_bits.insert(dstbit); } @@ -287,7 +291,7 @@ struct IopadmapPass : public Pass { if (tbuf_cell != nullptr) { // Found a tristate buffer — use it. - en_sig = tbuf_cell->getPort(ID(E)).as_bit(); + en_sig = tbuf_cell->getPort(ID::E).as_bit(); data_sig = tbuf_cell->getPort(ID::A).as_bit(); } else if (is_driven) { // No tristate buffer, but an always-on driver is present. @@ -302,6 +306,8 @@ struct IopadmapPass : public Pass { // enable. en_sig = SigBit(State::S0); data_sig = SigBit(State::Sx); + if (z_conns.count(wire_bit)) + remove_conns.insert(z_conns[wire_bit]); } if (wire->port_input) @@ -454,6 +460,14 @@ struct IopadmapPass : public Pass { } } + if (!remove_conns.empty()) { + std::vector<SigSig> new_conns; + for (auto &conn : module->connections()) + if (!remove_conns.count(conn)) + new_conns.push_back(conn); + module->new_connections(new_conns); + } + for (auto &it : rewrite_bits) { RTLIL::Wire *wire = it.first; RTLIL::Wire *new_wire = module->addWire( @@ -476,10 +490,10 @@ struct IopadmapPass : public Pass { } if (wire->port_output) { - auto jt = new_wire->attributes.find(ID(init)); + auto jt = new_wire->attributes.find(ID::init); // For output ports, move \init attributes from old wire to new wire if (jt != new_wire->attributes.end()) { - wire->attributes[ID(init)] = std::move(jt->second); + wire->attributes[ID::init] = std::move(jt->second); new_wire->attributes.erase(jt); } } |