Added "top" attribute to mark top module in hierarchy
authorClifford Wolf <clifford@clifford.at>
Sun, 24 Nov 2013 04:03:43 +0000 (05:03 +0100)
committerClifford Wolf <clifford@clifford.at>
Sun, 24 Nov 2013 04:03:43 +0000 (05:03 +0100)
README
backends/blif/blif.cc
backends/edif/edif.cc
backends/spice/spice.cc
passes/hierarchy/hierarchy.cc
passes/techmap/techmap.cc

diff --git a/README b/README
index cc451b2b930e8534d1373a8b000d0b49ce11ce53..2277ef129f210ba996d830f023499e618578821d 100644 (file)
--- a/README
+++ b/README
@@ -262,6 +262,11 @@ Verilog Attributes and non-standard features
   initialized "FPGA-style" with 'reg foo = val'. It can be used during synthesis
   to add the necessary reset logic.
 
+- The "top" attribute on a module marks this module as the top of the
+  design hierarchy. The "hierarchy" command sets this attribute when called
+  with "-top". Other commands, such as "flatten" and various backends
+  use this attribute to determine the top module.
+
 - In addition to the (* ... *) attribute syntax, yosys supports
   the non-standard {* ... *} attribute syntax to set default attributes
   for everything that comes after the {* ... *} statement. (Reset
index 27f087746bad05d811b5ecd407dd610305b9d71e..f5a982760010b832ca67f8c3506699ee0dc56c14 100644 (file)
@@ -293,6 +293,11 @@ struct BlifBackend : public Backend {
                }
                extra_args(f, filename, args, argidx);
 
+               if (top_module_name.empty())
+                       for (auto & mod_it:design->modules)
+                               if (mod_it.second->get_bool_attribute("\\top"))
+                                       top_module_name = mod_it.first;
+
                fprintf(f, "# Generated by %s\n", yosys_version_str);
 
                std::vector<RTLIL::Module*> mod_list;
index c5977bb1d3b618117027782d14254f01ae38c285..8843b3946f182065e597ddc754a0cf1f93fdb322 100644 (file)
@@ -118,6 +118,11 @@ struct EdifBackend : public Backend {
                }
                extra_args(f, filename, args, argidx);
 
+               if (top_module_name.empty())
+                       for (auto & mod_it:design->modules)
+                               if (mod_it.second->get_bool_attribute("\\top"))
+                                       top_module_name = mod_it.first;
+
                for (auto module_it : design->modules)
                {
                        RTLIL::Module *module = module_it.second;
index 6c8a3ec980d3c5e0dfffe0024cc5eaa6c8d63f2d..e7926e90e72dbfa2660c40e5dfb548b151c5896f 100644 (file)
@@ -172,6 +172,11 @@ struct SpiceBackend : public Backend {
                }
                extra_args(f, filename, args, argidx);
 
+               if (top_module_name.empty())
+                       for (auto & mod_it:design->modules)
+                               if (mod_it.second->get_bool_attribute("\\top"))
+                                       top_module_name = mod_it.first;
+
                fprintf(f, "* SPICE netlist generated by %s\n", yosys_version_str);
                fprintf(f, "\n");
 
index b98afcc1c13b0e20d5bc851d254f5c91f70e0825..d9b52c6d00f8ad924a0f21cf825b78133c294529 100644 (file)
@@ -280,6 +280,10 @@ struct HierarchyPass : public Pass {
                log("        use the specified top module to built a design hierarchy. modules\n");
                log("        outside this tree (unused modules) are removed.\n");
                log("\n");
+               log("        when the -top option is used, the 'top' attribute will be set on the\n");
+               log("        specified top module. otherwise a module with the 'top' attribute set\n");
+               log("        will implicitly be used as top module, if such a module exists.\n");
+               log("\n");
                log("In -generate mode this pass generates blackbox modules for the given cell\n");
                log("types (wildcards supported). For this the design is searched for cells that\n");
                log("match the given types and then the given port declarations are used to\n");
@@ -381,6 +385,11 @@ struct HierarchyPass : public Pass {
 
                log_push();
 
+               if (top_mod == NULL)
+                       for (auto &mod_it : design->modules)
+                               if (mod_it.second->get_bool_attribute("\\top"))
+                                       top_mod = mod_it.second;
+
                if (top_mod != NULL)
                        hierarchy(design, top_mod);
 
@@ -407,6 +416,14 @@ struct HierarchyPass : public Pass {
                        hierarchy(design, top_mod);
                }
 
+               if (top_mod != NULL) {
+                       for (auto &mod_it : design->modules)
+                               if (mod_it.second == top_mod)
+                                       mod_it.second->attributes["\\top"] = RTLIL::Const(1);
+                               else
+                                       mod_it.second->attributes.erase("\\top");
+               }
+
                if (!keep_positionals)
                {
                        std::set<RTLIL::Module*> pos_mods;
index e273769d1a42b26f783147cac95da925b7a30452..7e3ba23ec71aa73f4fe31949faf6abf9bcde56fb 100644 (file)
@@ -500,19 +500,42 @@ struct FlattenPass : public Pass {
                for (auto &it : design->modules)
                        celltypeMap[it.first].insert(it.first);
 
+               RTLIL::Module *top_mod = NULL;
+               for (auto &mod_it : design->modules)
+                       if (mod_it.second->get_bool_attribute("\\top"))
+                               top_mod = mod_it.second;
+
                bool did_something = true;
                std::set<RTLIL::Cell*> handled_cells;
                while (did_something) {
                        did_something = false;
-                       for (auto &mod_it : design->modules)
-                               if (techmap_module(design, mod_it.second, design, handled_cells, celltypeMap, true))
+                       if (top_mod != NULL) {
+                               if (techmap_module(design, top_mod, design, handled_cells, celltypeMap, true))
                                        did_something = true;
+                       } else {
+                               for (auto &mod_it : design->modules)
+                                       if (techmap_module(design, mod_it.second, design, handled_cells, celltypeMap, true))
+                                               did_something = true;
+                       }
                }
 
                log("No more expansions possible.\n");
+
+               if (top_mod != NULL) {
+                       std::map<RTLIL::IdString, RTLIL::Module*> new_modules;
+                       for (auto &mod_it : design->modules)
+                               if (mod_it.second == top_mod) {
+                                       new_modules[mod_it.first] = mod_it.second;
+                               } else {
+                                       log("Deleting now unused module %s.\n", RTLIL::id2cstr(mod_it.first));
+                                       delete mod_it.second;
+                               }
+                       design->modules.swap(new_modules);
+               }
+
                techmap_cache.clear();
                techmap_do_cache.clear();
                log_pop();
        }
 } FlattenPass;
+