From 6626aad29a75cc9e14507f235d555d17a8d96cfc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Apr 2013 11:58:24 +0200 Subject: [PATCH] Added "submod -name ..." support --- passes/submod/submod.cc | 136 ++++++++++++++++++++++++++++------------ 1 file changed, 96 insertions(+), 40 deletions(-) diff --git a/passes/submod/submod.cc b/passes/submod/submod.cc index f91d1ec3a..98854da23 100644 --- a/passes/submod/submod.cc +++ b/passes/submod/submod.cc @@ -29,6 +29,7 @@ struct SubmodWorker CellTypes ct; RTLIL::Design *design; RTLIL::Module *module; + std::string opt_name; struct SubModule { @@ -188,9 +189,9 @@ struct SubmodWorker module->cells[new_cell->name] = new_cell; } - SubmodWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module) + SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, std::string opt_name = std::string()) : design(design), module(module), opt_name(opt_name) { - if (!design->selected_whole_module(module->name)) + if (!design->selected_whole_module(module->name) && opt_name.empty()) return; if (module->processes.size() > 0) { @@ -208,29 +209,47 @@ struct SubmodWorker ct.setup_stdcells(); ct.setup_stdcells_mem(); - for (auto &it : module->wires) - it.second->attributes.erase("\\submod"); - - for (auto &it : module->cells) + if (opt_name.empty()) { - RTLIL::Cell *cell = it.second; - if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].str.size() == 0) { + for (auto &it : module->wires) + it.second->attributes.erase("\\submod"); + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].str.size() == 0) { + cell->attributes.erase("\\submod"); + continue; + } + + std::string submod_str = cell->attributes["\\submod"].str; cell->attributes.erase("\\submod"); - continue; - } - std::string submod_str = cell->attributes["\\submod"].str; - cell->attributes.erase("\\submod"); + if (submodules.count(submod_str) == 0) { + submodules[submod_str].name = submod_str; + submodules[submod_str].full_name = module->name + "_" + submod_str; + while (design->modules.count(submodules[submod_str].full_name) != 0 || + module->count_id(submodules[submod_str].full_name) != 0) + submodules[submod_str].full_name += "_"; + } - if (submodules.count(submod_str) == 0) { - submodules[submod_str].name = submod_str; - submodules[submod_str].full_name = module->name + "_" + submod_str; - while (design->modules.count(submodules[submod_str].full_name) != 0 || - module->count_id(submodules[submod_str].full_name) != 0) - submodules[submod_str].full_name += "_"; + submodules[submod_str].cells.insert(cell); + } + } + else + { + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + if (!design->selected(module, cell)) + continue; + submodules[opt_name].name = opt_name; + submodules[opt_name].full_name = RTLIL::escape_id(opt_name); + submodules[opt_name].cells.insert(cell); } - submodules[submod_str].cells.insert(cell); + if (submodules.size() == 0) + log("Nothing selected -> do nothing.\n"); } for (auto &it : submodules) @@ -256,35 +275,72 @@ struct SubmodPass : public Pass { log("This pass only operates on completely selected modules with no processes\n"); log("or memories.\n"); log("\n"); + log("\n"); + log(" submod -name [selection]\n"); + log("\n"); + log("As above, but don't use the 'submod' attribute but instead use the selection.\n"); + log("Only objects from one module might be selected. The value of the -name option\n"); + log("is used as the value of the 'submod' attribute above.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing SUBMOD pass (moving cells to submodules as requested).\n"); log_push(); - Pass::call(design, "opt_rmunused"); - log_header("Continuing SUBMOD pass.\n"); - - extra_args(args, 1, design); - - std::set handled_modules; - - bool did_something = true; - while (did_something) { - did_something = false; - std::vector queued_modules; - for (auto &mod_it : design->modules) - if (handled_modules.count(mod_it.first) == 0) - queued_modules.push_back(mod_it.first); - for (auto &modname : queued_modules) - if (design->modules.count(modname) != 0) { - SubmodWorker worker(design, design->modules[modname]); - handled_modules.insert(modname); - did_something = true; - } + std::string opt_name; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-name" && argidx+1 < args.size()) { + opt_name = args[++argidx]; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (opt_name.empty()) + { + Pass::call(design, "opt_rmunused"); + log_header("Continuing SUBMOD pass.\n"); + + std::set handled_modules; + + bool did_something = true; + while (did_something) { + did_something = false; + std::vector queued_modules; + for (auto &mod_it : design->modules) + if (handled_modules.count(mod_it.first) == 0 && design->selected_whole_module(mod_it.first)) + queued_modules.push_back(mod_it.first); + for (auto &modname : queued_modules) + if (design->modules.count(modname) != 0) { + SubmodWorker worker(design, design->modules[modname]); + handled_modules.insert(modname); + did_something = true; + } + } + + Pass::call(design, "opt_rmunused"); + } + else + { + RTLIL::Module *module = NULL; + for (auto &mod_it : design->modules) { + if (!design->selected_module(mod_it.first)) + continue; + if (module != NULL) + log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod_it.first.c_str()); + module = mod_it.second; + } + if (module == NULL) + log("Nothing selected -> do nothing.\n"); + else + SubmodWorker worker(design, module, opt_name); } - Pass::call(design, "opt_rmunused"); + log_pop(); } } SubmodPass; -- 2.30.2