flatten, techmap: don't canonicalize tpl driven bits via sigmap.

For connection `assign a = b;`, `sigmap(a)` returns `b`. This is
exactly the opposite of the desired canonicalization for driven bits.
Consider the following code:

    module foo(inout a, b);
      assign a = b;
    endmodule
    module bar(output c);
      foo f(c, 1'b0);
    endmodule

Before this commit, the inout ports would be swapped after flattening
(and cause a crash while attempting to drive a constant value).

This issue was introduced in 9f772eb9.

Fixes #2183.
This commit is contained in:
whitequark 2020-08-26 16:20:32 +00:00
parent 08a226c9e7
commit 9f0892159e
3 changed files with 17 additions and 9 deletions

View File

@ -152,15 +152,14 @@ struct FlattenWorker
// Attach port connections of the flattened cell // Attach port connections of the flattened cell
SigMap tpl_sigmap(tpl);
pool<SigBit> tpl_driven; pool<SigBit> tpl_driven;
for (auto tpl_cell : tpl->cells()) for (auto tpl_cell : tpl->cells())
for (auto &tpl_conn : tpl_cell->connections()) for (auto &tpl_conn : tpl_cell->connections())
if (tpl_cell->output(tpl_conn.first)) if (tpl_cell->output(tpl_conn.first))
for (auto bit : tpl_sigmap(tpl_conn.second)) for (auto bit : tpl_conn.second)
tpl_driven.insert(bit); tpl_driven.insert(bit);
for (auto &tpl_conn : tpl->connections()) for (auto &tpl_conn : tpl->connections())
for (auto bit : tpl_sigmap(tpl_conn.first)) for (auto bit : tpl_conn.first)
tpl_driven.insert(bit); tpl_driven.insert(bit);
SigMap sigmap(module); SigMap sigmap(module);
@ -190,7 +189,7 @@ struct FlattenWorker
} else { } else {
SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second; SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second;
for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) {
if (tpl_driven.count(tpl_sigmap(sig_tpl[i]))) { if (tpl_driven.count(sig_tpl[i])) {
new_conn.first.append(sig_mod[i]); new_conn.first.append(sig_mod[i]);
new_conn.second.append(sig_tpl[i]); new_conn.second.append(sig_tpl[i]);
} else { } else {

View File

@ -233,16 +233,14 @@ struct TechmapWorker
} }
} }
SigMap tpl_sigmap(tpl);
pool<SigBit> tpl_written_bits; pool<SigBit> tpl_written_bits;
for (auto tpl_cell : tpl->cells()) for (auto tpl_cell : tpl->cells())
for (auto &conn : tpl_cell->connections()) for (auto &conn : tpl_cell->connections())
if (tpl_cell->output(conn.first)) if (tpl_cell->output(conn.first))
for (auto bit : tpl_sigmap(conn.second)) for (auto bit : conn.second)
tpl_written_bits.insert(bit); tpl_written_bits.insert(bit);
for (auto &conn : tpl->connections()) for (auto &conn : tpl->connections())
for (auto bit : tpl_sigmap(conn.first)) for (auto bit : conn.first)
tpl_written_bits.insert(bit); tpl_written_bits.insert(bit);
SigMap port_signal_map; SigMap port_signal_map;
@ -280,7 +278,7 @@ struct TechmapWorker
SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second; SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second;
apply_prefix(cell->name, sig_tpl_pf, module); apply_prefix(cell->name, sig_tpl_pf, module);
for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) {
if (tpl_written_bits.count(tpl_sigmap(sig_tpl[i]))) { if (tpl_written_bits.count(sig_tpl[i])) {
c.first.append(sig_mod[i]); c.first.append(sig_mod[i]);
c.second.append(sig_tpl_pf[i]); c.second.append(sig_tpl_pf[i]);
} else { } else {

11
tests/techmap/bug2183.ys Normal file
View File

@ -0,0 +1,11 @@
read_verilog <<EOT
module foo(inout a, b);
assign a = b;
endmodule
module bar(output c);
foo f(c, 1'b0);
endmodule
EOT
hierarchy -auto-top
flatten