Rename conflicting wires on flatten/techmap, add "hierconn" attribute, fixes #1220
authorClifford Wolf <clifford@clifford.at>
Thu, 5 Sep 2019 11:51:53 +0000 (13:51 +0200)
committerClifford Wolf <clifford@clifford.at>
Thu, 5 Sep 2019 11:51:53 +0000 (13:51 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
README.md
passes/techmap/techmap.cc

index e0a95a9d5c604859fd467f76e4ebba381f05ddcc..a39737c08c9ca914cf2c46e20e003a06409d1b7b 100644 (file)
--- a/README.md
+++ b/README.md
@@ -332,6 +332,9 @@ Verilog Attributes and non-standard features
   that represent module parameters or localparams (when the HDL front-end
   is run in ``-pwires`` mode).
 
+- Wires marked with the ``hierconn`` attribute are connected to wires with the
+  same name when they are imported from sub-modules by ``flatten``.
+
 - The ``clkbuf_driver`` attribute can be set on an output port of a blackbox
   module to mark it as a clock buffer output, and thus prevent ``clkbufmap``
   from inserting another clock buffer on a net driven by such output.
index cb01cadb126afe0aef77702419a8ed5f32e84a62..5ce1bf7d68c32caec13f4f5d6a66f911cbbf7c92 100644 (file)
@@ -205,6 +205,7 @@ struct TechmapWorker
                }
 
                std::map<RTLIL::IdString, RTLIL::IdString> positional_ports;
+               dict<Wire*, IdString> temp_renamed_wires;
 
                for (auto &it : tpl->wires_) {
                        if (it.second->port_id > 0)
@@ -213,15 +214,20 @@ struct TechmapWorker
                        apply_prefix(cell->name, w_name);
                        RTLIL::Wire *w = module->wire(w_name);
                        if (w != nullptr) {
-                               if (!flatten_mode)
-                                       log_error("Signal %s.%s conflicts with %s.%s (via %s.%s).\n", log_id(module), log_id(w),
-                                                       log_id(tpl), log_id(it.second), log_id(module), log_id(cell));
-                               if (GetSize(w) < GetSize(it.second)) {
-                                       log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w),
-                                                       log_id(tpl), log_id(it.second), log_id(module), log_id(cell));
-                                       w->width = GetSize(it.second);
+                               if (!flatten_mode || !w->get_bool_attribute(ID(hierconn))) {
+                                       temp_renamed_wires[w] = w->name;
+                                       module->rename(w, NEW_ID);
+                                       w = nullptr;
+                               } else {
+                                       w->attributes.erase(ID(hierconn));
+                                       if (GetSize(w) < GetSize(it.second)) {
+                                               log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w),
+                                                               log_id(tpl), log_id(it.second), log_id(module), log_id(cell));
+                                               w->width = GetSize(it.second);
+                                       }
                                }
-                       } else {
+                       }
+                       if (w == nullptr) {
                                w = module->addWire(w_name, it.second);
                                w->port_input = false;
                                w->port_output = false;
@@ -392,6 +398,16 @@ struct TechmapWorker
                }
 
                module->remove(cell);
+
+               for (auto &it : temp_renamed_wires)
+               {
+                       Wire *w = it.first;
+                       IdString name = it.second;
+                       IdString altname = module->uniquify(name);
+                       Wire *other_w = module->wire(name);
+                       module->rename(other_w, altname);
+                       module->rename(w, name);
+               }
        }
 
        bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set<RTLIL::Cell*> &handled_cells,