summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-11-24 05:03:43 +0100
committerClifford Wolf <clifford@clifford.at>2013-11-24 05:03:43 +0100
commit28093d9dd288484daa9df17585c1c9f174498359 (patch)
tree3940c6d3bd95f7c983c76cd6e54bd04216867f3d
parenta4edecb0cae0524b6f42d1a2c64af5a940c67a2f (diff)
Added "top" attribute to mark top module in hierarchy
-rw-r--r--README5
-rw-r--r--backends/blif/blif.cc5
-rw-r--r--backends/edif/edif.cc5
-rw-r--r--backends/spice/spice.cc5
-rw-r--r--passes/hierarchy/hierarchy.cc17
-rw-r--r--passes/techmap/techmap.cc29
6 files changed, 63 insertions, 3 deletions
diff --git a/README b/README
index cc451b2b..2277ef12 100644
--- 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
diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc
index 27f08774..f5a98276 100644
--- a/backends/blif/blif.cc
+++ b/backends/blif/blif.cc
@@ -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;
diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc
index c5977bb1..8843b394 100644
--- a/backends/edif/edif.cc
+++ b/backends/edif/edif.cc
@@ -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;
diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc
index 6c8a3ec9..e7926e90 100644
--- a/backends/spice/spice.cc
+++ b/backends/spice/spice.cc
@@ -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");
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index b98afcc1..d9b52c6d 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -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;
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index e273769d..7e3ba23e 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -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;
-
+