Fix iopadmap for loops between tristate IO buffers
authorClifford Wolf <clifford@clifford.at>
Tue, 15 May 2018 12:02:27 +0000 (14:02 +0200)
committerClifford Wolf <clifford@clifford.at>
Tue, 15 May 2018 12:02:27 +0000 (14:02 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
passes/techmap/iopadmap.cc

index c20081c649aa1b8c74b51b858f45a39fd6c34653..690ba87eda33459c212edf26b85e52230dfbf830 100644 (file)
@@ -175,6 +175,8 @@ struct IopadmapPass : public Pass {
                        if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
                        {
                                dict<SigBit, pair<IdString, pool<IdString>>> tbuf_bits;
+                               pool<pair<IdString, IdString>> norewrites;
+                               SigMap rewrites;
 
                                for (auto cell : module->cells())
                                        if (cell->type == "$_TBUF_") {
@@ -246,6 +248,9 @@ struct IopadmapPass : public Pass {
 
                                                        module->remove(tbuf_cell);
                                                        skip_wires[wire->name].insert(i);
+
+                                                       norewrites.insert(make_pair(cell->name, RTLIL::escape_id(tinoutpad_portname4)));
+                                                       rewrites.add(sigmap(wire_bit), owire);
                                                        continue;
                                                }
 
@@ -283,6 +288,22 @@ struct IopadmapPass : public Pass {
                                                }
                                        }
                                }
+
+                               if (GetSize(norewrites))
+                               {
+                                       for (auto cell : module->cells())
+                                       for (auto port : cell->connections())
+                                       {
+                                               if (norewrites.count(make_pair(cell->name, port.first)))
+                                                       continue;
+
+                                               SigSpec orig_sig = sigmap(port.second);
+                                               SigSpec new_sig = rewrites(orig_sig);
+
+                                               if (orig_sig != new_sig)
+                                                       cell->setPort(port.first, new_sig);
+                                       }
+                               }
                        }
 
                        for (auto wire : module->selected_wires())