diff options
author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2022-06-07 02:18:08 +0200 |
---|---|---|
committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2022-06-07 04:10:50 +0200 |
commit | 9e8a2ac0511a59762306f75fc9c5267c25d23caf (patch) | |
tree | 796190e3831c3d14ff09976752e940d884e42819 /passes | |
parent | aa0b47c74a44ea3fd95e200e46bb858f68081aeb (diff) | |
download | yosys-9e8a2ac0511a59762306f75fc9c5267c25d23caf.tar.gz yosys-9e8a2ac0511a59762306f75fc9c5267c25d23caf.tar.bz2 yosys-9e8a2ac0511a59762306f75fc9c5267c25d23caf.zip |
iopadmap: Fix z assignment removal.
Fixes #3360.
Diffstat (limited to 'passes')
-rw-r--r-- | passes/techmap/iopadmap.cc | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 437ad5156..322eb7779 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -240,13 +240,13 @@ struct IopadmapPass : public Pass { for (auto module : design->selected_modules()) { dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; - pool<SigSig> remove_conns; + dict<SigSig, pool<int>> remove_conns; if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) { dict<SigBit, Cell *> tbuf_bits; pool<SigBit> driven_bits; - dict<SigBit, SigSig> z_conns; + dict<SigBit, std::pair<SigSig, int>> z_conns; // Gather tristate buffers and always-on drivers. for (auto cell : module->cells()) @@ -266,7 +266,7 @@ struct IopadmapPass : public Pass { SigBit dstbit = conn.first[i]; SigBit srcbit = conn.second[i]; if (!srcbit.wire && srcbit.data == State::Sz) { - z_conns[dstbit] = conn; + z_conns[dstbit] = {conn, i}; continue; } driven_bits.insert(dstbit); @@ -317,8 +317,9 @@ 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]); + auto it = z_conns.find(wire_bit); + if (it != z_conns.end()) + remove_conns[it->second.first].insert(it->second.second); } if (wire->port_input) @@ -477,9 +478,22 @@ struct IopadmapPass : public Pass { if (!remove_conns.empty()) { std::vector<SigSig> new_conns; - for (auto &conn : module->connections()) - if (!remove_conns.count(conn)) + for (auto &conn : module->connections()) { + auto it = remove_conns.find(conn); + if (it == remove_conns.end()) { new_conns.push_back(conn); + } else { + SigSpec lhs, rhs; + for (int i = 0; i < GetSize(conn.first); i++) { + if (!it->second.count(i)) { + lhs.append(conn.first[i]); + rhs.append(conn.second[i]); + } + } + new_conns.push_back(SigSig(lhs, rhs)); + + } + } module->new_connections(new_conns); } |