-auto-top should check $abstract (deferred) modules with (* top *)
authorEddie Hung <eddie@fpgeh.com>
Thu, 29 Aug 2019 02:59:25 +0000 (19:59 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 29 Aug 2019 02:59:25 +0000 (19:59 -0700)
passes/hierarchy/hierarchy.cc

index fd95b94b2c5e19cd597f751405a8412b96e7cf3a..ad795c69fa69d6a89e25c77866055ff5be88c7a0 100644 (file)
@@ -808,6 +808,37 @@ struct HierarchyPass : public Pass {
                                if (mod_it.second->get_bool_attribute("\\top"))
                                        top_mod = mod_it.second;
 
+               if (top_mod != nullptr && auto_top_mode) {
+                       IdString abstract_id = top_mod->name;
+                       IdString top_name = abstract_id;
+                       if (top_name.begins_with("$abstract"))
+                               top_name = top_name.substr(strlen("$abstract"));
+                       top_mod = design->module(top_name);
+
+                       dict<RTLIL::IdString, RTLIL::Const> top_parameters;
+                       for (auto &para : parameters) {
+                               SigSpec sig_value;
+                               if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
+                                       log_cmd_error("Can't decode value '%s'!\n", para.second.c_str());
+                               top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const();
+                       }
+
+                       if (top_mod == nullptr && design->module(abstract_id))
+                               top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters));
+                       else if (top_mod != nullptr && !top_parameters.empty())
+                               top_mod = design->module(top_mod->derive(design, top_parameters));
+
+                       if (top_mod != nullptr && top_mod->name != top_name) {
+                               Module *m = top_mod->clone();
+                               m->name = top_name;
+                               Module *old_mod = design->module(top_name);
+                               if (old_mod)
+                                       design->remove(old_mod);
+                               design->add(m);
+                               top_mod = m;
+                       }
+               }
+
                if (top_mod == nullptr && auto_top_mode) {
                        log_header(design, "Finding top of design hierarchy..\n");
                        dict<Module*, int> db;