summaryrefslogtreecommitdiff
path: root/passes/hierarchy
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-03-18 08:33:40 +0100
committerClifford Wolf <clifford@clifford.at>2015-03-18 08:33:40 +0100
commitaed4d763cf40c6341f5a53eb856a940ace4b15e7 (patch)
tree00abe2c5beb649d408c7a45de7386fcce87283c0 /passes/hierarchy
parent67e6dcd34a3cb1373a9c64d30a29ec807158af38 (diff)
Added hierarchy -auto-top
Diffstat (limited to 'passes/hierarchy')
-rw-r--r--passes/hierarchy/hierarchy.cc34
1 files changed, 33 insertions, 1 deletions
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index 40fc9ae9..155d4e46 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -321,6 +321,17 @@ bool set_keep_assert(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
return cache[mod];
}
+int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db)
+{
+ if (db.count(module) == 0) {
+ db[module] = 0;
+ for (auto cell : module->cells())
+ if (design->module(cell->type))
+ db[module] = std::max(db[module], find_top_mod_score(design, design->module(cell->type), db) + 1);
+ }
+ return db.at(module);
+}
+
struct HierarchyPass : public Pass {
HierarchyPass() : Pass("hierarchy", "check, expand and clean up design hierarchy") { }
virtual void help()
@@ -365,6 +376,9 @@ struct HierarchyPass : public Pass {
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(" -auto-top\n");
+ log(" automatically determine the top of the design hierarchy and mark it.\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");
@@ -391,6 +405,7 @@ struct HierarchyPass : public Pass {
RTLIL::Module *top_mod = NULL;
std::vector<std::string> libdirs;
+ bool auto_top_mode = false;
bool generate_mode = false;
bool keep_positionals = false;
bool nokeep_asserts = false;
@@ -472,6 +487,10 @@ struct HierarchyPass : public Pass {
log_cmd_error("Module `%s' not found!\n", args[argidx].c_str());
continue;
}
+ if (args[argidx] == "-auto-top") {
+ auto_top_mode = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design, false);
@@ -483,11 +502,24 @@ struct HierarchyPass : public Pass {
log_push();
- if (top_mod == NULL)
+ if (top_mod == nullptr)
for (auto &mod_it : design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
top_mod = mod_it.second;
+ if (top_mod == nullptr && auto_top_mode) {
+ log_header("Finding top of design hierarchy..\n");
+ dict<Module*, int> db;
+ for (Module *mod : design->modules()) {
+ int score = find_top_mod_score(design, mod, db);
+ log("root of %3d design levels: %-20s\n", score, log_id(mod));
+ if (!top_mod || score > db[top_mod])
+ top_mod = mod;
+ }
+ if (top_mod != nullptr)
+ log("Automatically selected %s as design top module.\n", log_id(top_mod));
+ }
+
bool did_something = true;
while (did_something)
{