flatten, techmap: don't canonicalize tpl driven bits via sigmap.
authorwhitequark <whitequark@whitequark.org>
Wed, 26 Aug 2020 16:20:32 +0000 (16:20 +0000)
committerwhitequark <whitequark@whitequark.org>
Wed, 26 Aug 2020 16:29:42 +0000 (16:29 +0000)
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.

passes/techmap/flatten.cc
passes/techmap/techmap.cc
tests/techmap/bug2183.ys [new file with mode: 0644]

index b5f55cffaf801aa75ff3a76d2e1cea3552241f5d..08978f4469231c196a484a49de983cd393765eed 100644 (file)
@@ -152,15 +152,14 @@ struct FlattenWorker
 
                // Attach port connections of the flattened cell
 
-               SigMap tpl_sigmap(tpl);
                pool<SigBit> tpl_driven;
                for (auto tpl_cell : tpl->cells())
                        for (auto &tpl_conn : tpl_cell->connections())
                                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);
                for (auto &tpl_conn : tpl->connections())
-                       for (auto bit : tpl_sigmap(tpl_conn.first))
+                       for (auto bit : tpl_conn.first)
                                tpl_driven.insert(bit);
 
                SigMap sigmap(module);
@@ -190,7 +189,7 @@ struct FlattenWorker
                        } else {
                                SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second;
                                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.second.append(sig_tpl[i]);
                                        } else {
index 4a1a74ce93bda4385ab35793f32501d11094102a..136c95d8ee079c4c23ff127f845e4d352abc14c3 100644 (file)
@@ -233,16 +233,14 @@ struct TechmapWorker
                        }
                }
 
-               SigMap tpl_sigmap(tpl);
                pool<SigBit> tpl_written_bits;
-
                for (auto tpl_cell : tpl->cells())
                for (auto &conn : tpl_cell->connections())
                        if (tpl_cell->output(conn.first))
-                               for (auto bit : tpl_sigmap(conn.second))
+                               for (auto bit : conn.second)
                                        tpl_written_bits.insert(bit);
                for (auto &conn : tpl->connections())
-                       for (auto bit : tpl_sigmap(conn.first))
+                       for (auto bit : conn.first)
                                tpl_written_bits.insert(bit);
 
                SigMap port_signal_map;
@@ -280,7 +278,7 @@ struct TechmapWorker
                                SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second;
                                apply_prefix(cell->name, sig_tpl_pf, module);
                                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.second.append(sig_tpl_pf[i]);
                                        } else {
diff --git a/tests/techmap/bug2183.ys b/tests/techmap/bug2183.ys
new file mode 100644 (file)
index 0000000..8dd0945
--- /dev/null
@@ -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