Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option for a custom flatten block separator char #4839

Merged
merged 1 commit into from
Jan 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions passes/techmap/flatten.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

IdString concat_name(RTLIL::Cell *cell, IdString object_name)
IdString concat_name(RTLIL::Cell *cell, IdString object_name, const std::string &separator = ".")
{
if (object_name[0] == '\\')
return stringf("%s.%s", cell->name.c_str(), object_name.c_str() + 1);
return stringf("%s%s%s", cell->name.c_str(), separator.c_str(), object_name.c_str() + 1);
else {
std::string object_name_str = object_name.str();
if (object_name_str.substr(0, 8) == "$flatten")
object_name_str.erase(0, 8);
return stringf("$flatten%s.%s", cell->name.c_str(), object_name_str.c_str());
return stringf("$flatten%s%s%s", cell->name.c_str(), separator.c_str(), object_name_str.c_str());
}
}

template<class T>
IdString map_name(RTLIL::Cell *cell, T *object)
IdString map_name(RTLIL::Cell *cell, T *object, const std::string &separator = ".")
{
return cell->module->uniquify(concat_name(cell, object->name));
return cell->module->uniquify(concat_name(cell, object->name, separator));
}

void map_sigspec(const dict<RTLIL::Wire*, RTLIL::Wire*> &map, RTLIL::SigSpec &sig, RTLIL::Module *into = nullptr)
Expand All @@ -60,6 +60,7 @@ struct FlattenWorker
bool ignore_wb = false;
bool create_scopeinfo = true;
bool create_scopename = false;
std::string separator = ".";

template<class T>
void map_attributes(RTLIL::Cell *cell, T *object, IdString orig_object_name)
Expand Down Expand Up @@ -107,13 +108,13 @@ struct FlattenWorker
}
}

void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, SigMap &sigmap, std::vector<RTLIL::Cell*> &new_cells)
void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, SigMap &sigmap, std::vector<RTLIL::Cell*> &new_cells, const std::string &separator)
{
// Copy the contents of the flattened cell

dict<IdString, IdString> memory_map;
for (auto &tpl_memory_it : tpl->memories) {
RTLIL::Memory *new_memory = module->addMemory(map_name(cell, tpl_memory_it.second), tpl_memory_it.second);
RTLIL::Memory *new_memory = module->addMemory(map_name(cell, tpl_memory_it.second, separator), tpl_memory_it.second);
map_attributes(cell, new_memory, tpl_memory_it.second->name);
memory_map[tpl_memory_it.first] = new_memory->name;
design->select(module, new_memory);
Expand All @@ -127,7 +128,7 @@ struct FlattenWorker

RTLIL::Wire *new_wire = nullptr;
if (tpl_wire->name[0] == '\\') {
RTLIL::Wire *hier_wire = module->wire(concat_name(cell, tpl_wire->name));
RTLIL::Wire *hier_wire = module->wire(concat_name(cell, tpl_wire->name, separator));
if (hier_wire != nullptr && hier_wire->get_bool_attribute(ID::hierconn)) {
hier_wire->attributes.erase(ID::hierconn);
if (GetSize(hier_wire) < GetSize(tpl_wire)) {
Expand All @@ -139,7 +140,7 @@ struct FlattenWorker
}
}
if (new_wire == nullptr) {
new_wire = module->addWire(map_name(cell, tpl_wire), tpl_wire);
new_wire = module->addWire(map_name(cell, tpl_wire, separator), tpl_wire);
new_wire->port_input = new_wire->port_output = false;
new_wire->port_id = false;
}
Expand All @@ -150,7 +151,7 @@ struct FlattenWorker
}

for (auto &tpl_proc_it : tpl->processes) {
RTLIL::Process *new_proc = module->addProcess(map_name(cell, tpl_proc_it.second), tpl_proc_it.second);
RTLIL::Process *new_proc = module->addProcess(map_name(cell, tpl_proc_it.second, separator), tpl_proc_it.second);
map_attributes(cell, new_proc, tpl_proc_it.second->name);
for (auto new_proc_sync : new_proc->syncs)
for (auto &memwr_action : new_proc_sync->mem_write_actions)
Expand All @@ -161,14 +162,14 @@ struct FlattenWorker
}

for (auto tpl_cell : tpl->cells()) {
RTLIL::Cell *new_cell = module->addCell(map_name(cell, tpl_cell), tpl_cell);
RTLIL::Cell *new_cell = module->addCell(map_name(cell, tpl_cell, separator), tpl_cell);
map_attributes(cell, new_cell, tpl_cell->name);
if (new_cell->has_memid()) {
IdString memid = new_cell->getParam(ID::MEMID).decode_string();
new_cell->setParam(ID::MEMID, Const(memory_map.at(memid).str()));
} else if (new_cell->is_mem_cell()) {
IdString memid = new_cell->getParam(ID::MEMID).decode_string();
new_cell->setParam(ID::MEMID, Const(concat_name(cell, memid).str()));
new_cell->setParam(ID::MEMID, Const(concat_name(cell, memid, separator).str()));
}
auto rewriter = [&](RTLIL::SigSpec &sig) { map_sigspec(wire_map, sig); };
new_cell->rewrite_sigspecs(rewriter);
Expand Down Expand Up @@ -279,7 +280,7 @@ struct FlattenWorker
module->rename(scopeinfo, cell_name);
}

void flatten_module(RTLIL::Design *design, RTLIL::Module *module, pool<RTLIL::Module*> &used_modules)
void flatten_module(RTLIL::Design *design, RTLIL::Module *module, pool<RTLIL::Module*> &used_modules, const std::string &separator)
{
if (!design->selected(module) || module->get_blackbox_attribute(ignore_wb))
return;
Expand Down Expand Up @@ -308,7 +309,7 @@ struct FlattenWorker
// If a design is fully selected and has a top module defined, topological sorting ensures that all cells
// added during flattening are black boxes, and flattening is finished in one pass. However, when flattening
// individual modules, this isn't the case, and the newly added cells might have to be flattened further.
flatten_cell(design, module, cell, tpl, sigmap, worklist);
flatten_cell(design, module, cell, tpl, sigmap, worklist, separator);
}
}
};
Expand Down Expand Up @@ -345,6 +346,9 @@ struct FlattenPass : public Pass {
log(" with a public name the enclosing scope can be found via their\n");
log(" 'hdlname' attribute.\n");
log("\n");
log(" -separator <char>\n");
log(" Use this separator char instead of '.' when concatenating design levels.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
Expand All @@ -367,6 +371,10 @@ struct FlattenPass : public Pass {
worker.create_scopename = true;
continue;
}
if (args[argidx] == "-separator" && argidx + 1 < args.size()) {
worker.separator = args[++argidx];
continue;
}
break;
}
extra_args(args, argidx, design);
Expand Down Expand Up @@ -401,7 +409,7 @@ struct FlattenPass : public Pass {
log_error("Cannot flatten a design containing recursive instantiations.\n");

for (auto module : topo_modules.sorted)
worker.flatten_module(design, module, used_modules);
worker.flatten_module(design, module, used_modules, worker.separator);

if (top != nullptr)
for (auto module : design->modules().to_vector())
Expand Down
Loading