iopadmap: Fix z assignment to inout port

Fixes #1841.
This commit is contained in:
Marcin Kościelnicki 2020-03-30 15:35:31 +02:00 committed by Marcelina Kościelnicka
parent 22ef5701c0
commit 2d3753d730
2 changed files with 24 additions and 2 deletions

View File

@ -229,11 +229,13 @@ struct IopadmapPass : public Pass {
for (auto module : design->selected_modules()) for (auto module : design->selected_modules())
{ {
dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
pool<SigSig> remove_conns;
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
{ {
dict<SigBit, Cell *> tbuf_bits; dict<SigBit, Cell *> tbuf_bits;
pool<SigBit> driven_bits; pool<SigBit> driven_bits;
dict<SigBit, SigSig> z_conns;
// Gather tristate buffers and always-on drivers. // Gather tristate buffers and always-on drivers.
for (auto cell : module->cells()) for (auto cell : module->cells())
@ -252,8 +254,10 @@ struct IopadmapPass : public Pass {
for (int i = 0; i < GetSize(conn.first); i++) { for (int i = 0; i < GetSize(conn.first); i++) {
SigBit dstbit = conn.first[i]; SigBit dstbit = conn.first[i];
SigBit srcbit = conn.second[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; continue;
}
driven_bits.insert(dstbit); driven_bits.insert(dstbit);
} }
@ -302,6 +306,8 @@ struct IopadmapPass : public Pass {
// enable. // enable.
en_sig = SigBit(State::S0); en_sig = SigBit(State::S0);
data_sig = SigBit(State::Sx); data_sig = SigBit(State::Sx);
if (z_conns.count(wire_bit))
remove_conns.insert(z_conns[wire_bit]);
} }
if (wire->port_input) 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) { for (auto &it : rewrite_bits) {
RTLIL::Wire *wire = it.first; RTLIL::Wire *wire = it.first;
RTLIL::Wire *new_wire = module->addWire( RTLIL::Wire *new_wire = module->addWire(

View File

@ -55,13 +55,19 @@ obuf b (.i(i), .o(tmp));
assign o = tmp; assign o = tmp;
endmodule endmodule
module k(inout o, o2);
assign o = 1'bz;
endmodule
EOT EOT
opt_clean opt_clean
tribuf tribuf
simplemap simplemap
iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j k
opt_clean opt_clean
hierarchy -check
check
select -assert-count 1 a/t:ibuf select -assert-count 1 a/t:ibuf
select -assert-count 1 a/t:obuf select -assert-count 1 a/t:obuf
@ -140,6 +146,8 @@ select -assert-count 0 i/t:obuf
select -assert-count 1 j/t:ibuf select -assert-count 1 j/t:ibuf
select -assert-count 1 j/t:obuf select -assert-count 1 j/t:obuf
select -assert-count 2 k/t:iobuf
# Check that \init attributes get moved from output buffer # Check that \init attributes get moved from output buffer
# to buffer input # to buffer input