Added "submod -name ..." support

This commit is contained in:
Clifford Wolf 2013-04-15 11:58:24 +02:00
parent e0c408cb4a
commit 6626aad29a
1 changed files with 95 additions and 39 deletions

View File

@ -29,6 +29,7 @@ struct SubmodWorker
CellTypes ct; CellTypes ct;
RTLIL::Design *design; RTLIL::Design *design;
RTLIL::Module *module; RTLIL::Module *module;
std::string opt_name;
struct SubModule struct SubModule
{ {
@ -188,9 +189,9 @@ struct SubmodWorker
module->cells[new_cell->name] = new_cell; 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; return;
if (module->processes.size() > 0) { if (module->processes.size() > 0) {
@ -208,29 +209,47 @@ struct SubmodWorker
ct.setup_stdcells(); ct.setup_stdcells();
ct.setup_stdcells_mem(); ct.setup_stdcells_mem();
for (auto &it : module->wires) if (opt_name.empty())
it.second->attributes.erase("\\submod");
for (auto &it : module->cells)
{ {
RTLIL::Cell *cell = it.second; for (auto &it : module->wires)
if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].str.size() == 0) { 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"); cell->attributes.erase("\\submod");
continue;
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);
} }
std::string submod_str = cell->attributes["\\submod"].str; if (submodules.size() == 0)
cell->attributes.erase("\\submod"); log("Nothing selected -> do nothing.\n");
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);
} }
for (auto &it : submodules) 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("This pass only operates on completely selected modules with no processes\n");
log("or memories.\n"); log("or memories.\n");
log("\n"); log("\n");
log("\n");
log(" submod -name <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<std::string> args, RTLIL::Design *design) virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{ {
log_header("Executing SUBMOD pass (moving cells to submodules as requested).\n"); log_header("Executing SUBMOD pass (moving cells to submodules as requested).\n");
log_push(); log_push();
Pass::call(design, "opt_rmunused"); std::string opt_name;
log_header("Continuing SUBMOD pass.\n");
extra_args(args, 1, design); 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);
std::set<std::string> handled_modules; if (opt_name.empty())
{
Pass::call(design, "opt_rmunused");
log_header("Continuing SUBMOD pass.\n");
bool did_something = true; std::set<std::string> handled_modules;
while (did_something) {
did_something = false; bool did_something = true;
std::vector<std::string> queued_modules; while (did_something) {
for (auto &mod_it : design->modules) did_something = false;
if (handled_modules.count(mod_it.first) == 0) std::vector<std::string> queued_modules;
queued_modules.push_back(mod_it.first); for (auto &mod_it : design->modules)
for (auto &modname : queued_modules) if (handled_modules.count(mod_it.first) == 0 && design->selected_whole_module(mod_it.first))
if (design->modules.count(modname) != 0) { queued_modules.push_back(mod_it.first);
SubmodWorker worker(design, design->modules[modname]); for (auto &modname : queued_modules)
handled_modules.insert(modname); if (design->modules.count(modname) != 0) {
did_something = true; 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; } SubmodPass;