3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-07 01:54:10 +00:00

flatten: preserve original object names via hdlname attribute.

This commit is contained in:
whitequark 2020-06-04 10:46:54 +00:00
parent 8d821dbbdb
commit fbb346ea91
5 changed files with 45 additions and 6 deletions

View file

@ -309,7 +309,9 @@ Verilog Attributes and non-standard features
that have ports with a width that depends on a parameter. that have ports with a width that depends on a parameter.
- The ``hdlname`` attribute is used by some passes to document the original - The ``hdlname`` attribute is used by some passes to document the original
(HDL) name of a module when renaming a module. (HDL) name of a module when renaming a module. It should contain a single
name, or, when describing a hierarchical name in a flattened design, multiple
names separated by a single space character.
- The ``keep`` attribute on cells and wires is used to mark objects that should - The ``keep`` attribute on cells and wires is used to mark objects that should
never be removed by the optimizer. This is used for example for cells that never be removed by the optimizer. This is used for example for cells that

View file

@ -339,6 +339,22 @@ pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const
return data; return data;
} }
void RTLIL::AttrObject::set_hdlname_attribute(const vector<string> &hierarchy)
{
string attrval;
for (const auto &ident : hierarchy) {
if (!attrval.empty())
attrval += " ";
attrval += ident;
}
set_string_attribute(ID::hdlname, attrval);
}
vector<string> RTLIL::AttrObject::get_hdlname_attribute() const
{
return split_tokens(get_string_attribute(ID::hdlname), " ");
}
bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const
{ {
if (full_selection) if (full_selection)

View file

@ -682,6 +682,9 @@ struct RTLIL::AttrObject
std::string get_src_attribute() const { std::string get_src_attribute() const {
return get_string_attribute(ID::src); return get_string_attribute(ID::src);
} }
void set_hdlname_attribute(const vector<string> &hierarchy);
vector<string> get_hdlname_attribute() const;
}; };
struct RTLIL::SigChunk struct RTLIL::SigChunk

View file

@ -193,6 +193,13 @@ Violating these rules results in a runtime error.
All RTLIL identifiers are case sensitive. All RTLIL identifiers are case sensitive.
Some transformations, such as flattening, may have to change identifiers provided by the user
to avoid name collisions. When that happens, attribute ``{\tt hdlname}`` is attached to the object
with the changed identifier. This attribute contains one name (if emitted directly by the frontend,
or is a result of disambiguation) or multiple names separated by spaces (if a result of flattening).
All names specified in the ``{\tt hdlname}`` attribute are public and do not include the leading
``\textbackslash``.
\subsection{RTLIL::Design and RTLIL::Module} \subsection{RTLIL::Design and RTLIL::Module}
The RTLIL::Design object is basically just a container for RTLIL::Module objects. In addition to The RTLIL::Design object is basically just a container for RTLIL::Module objects. In addition to

View file

@ -47,10 +47,21 @@ IdString map_name(RTLIL::Cell *cell, T *object)
} }
template<class T> template<class T>
void map_attributes(RTLIL::Cell *cell, T *object) void map_attributes(RTLIL::Cell *cell, T *object, IdString orig_object_name)
{ {
if (object->attributes.count(ID::src)) if (object->has_attribute(ID::src))
object->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); object->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
// Preserve original names via the hdlname attribute, but only for objects with a fully public name.
if (cell->name[0] == '\\' && (object->has_attribute(ID::hdlname) || orig_object_name[0] == '\\')) {
std::vector<std::string> hierarchy;
if (object->has_attribute(ID::hdlname))
hierarchy = object->get_hdlname_attribute();
else
hierarchy.push_back(orig_object_name.str().substr(1));
hierarchy.insert(hierarchy.begin(), cell->name.str().substr(1));
object->set_hdlname_attribute(hierarchy);
}
} }
void map_sigspec(const dict<RTLIL::Wire*, RTLIL::Wire*> &map, RTLIL::SigSpec &sig, RTLIL::Module *into = nullptr) void map_sigspec(const dict<RTLIL::Wire*, RTLIL::Wire*> &map, RTLIL::SigSpec &sig, RTLIL::Module *into = nullptr)
@ -81,7 +92,7 @@ struct FlattenWorker
dict<IdString, IdString> memory_map; dict<IdString, IdString> memory_map;
for (auto &tpl_memory_it : tpl->memories) { 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), tpl_memory_it.second);
map_attributes(cell, new_memory); map_attributes(cell, new_memory, tpl_memory_it.second->name);
memory_map[tpl_memory_it.first] = new_memory->name; memory_map[tpl_memory_it.first] = new_memory->name;
design->select(module, new_memory); design->select(module, new_memory);
} }
@ -111,14 +122,14 @@ struct FlattenWorker
new_wire->port_id = false; new_wire->port_id = false;
} }
map_attributes(cell, new_wire); map_attributes(cell, new_wire, tpl_wire->name);
wire_map[tpl_wire] = new_wire; wire_map[tpl_wire] = new_wire;
design->select(module, new_wire); design->select(module, new_wire);
} }
for (auto tpl_cell : tpl->cells()) { 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), tpl_cell);
map_attributes(cell, new_cell); map_attributes(cell, new_cell, tpl_cell->name);
if (new_cell->type.in(ID($memrd), ID($memwr), ID($meminit))) { if (new_cell->type.in(ID($memrd), ID($memwr), ID($meminit))) {
IdString memid = new_cell->getParam(ID::MEMID).decode_string(); IdString memid = new_cell->getParam(ID::MEMID).decode_string();
new_cell->setParam(ID::MEMID, Const(memory_map.at(memid).str())); new_cell->setParam(ID::MEMID, Const(memory_map.at(memid).str()));