aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-06-09 06:26:02 +0000
committerGitHub <noreply@github.com>2020-06-09 06:26:02 +0000
commit4351194e8ce94e7078b67a20e5fc92777d6cb3e6 (patch)
tree7d2027cda96eeb6c16506ca8b1c9df2fe475efa7
parent83f84afc0b617fe78fb7cfa31fb9d1cd202e22f2 (diff)
parent53688a24b531adcc99c091f728e9657d16010467 (diff)
downloadyosys-4351194e8ce94e7078b67a20e5fc92777d6cb3e6.tar.gz
yosys-4351194e8ce94e7078b67a20e5fc92777d6cb3e6.tar.bz2
yosys-4351194e8ce94e7078b67a20e5fc92777d6cb3e6.zip
Merge pull request #2107 from whitequark/flatten-hdlname
flatten: preserve original object names
-rw-r--r--README.md4
-rw-r--r--backends/cxxrtl/cxxrtl_backend.cc2
-rw-r--r--kernel/rtlil.cc20
-rw-r--r--kernel/rtlil.h3
-rw-r--r--manual/CHAPTER_Overview.tex7
-rw-r--r--passes/techmap/flatten.cc29
6 files changed, 54 insertions, 11 deletions
diff --git a/README.md b/README.md
index 770c62459..203a292d1 100644
--- a/README.md
+++ b/README.md
@@ -309,7 +309,9 @@ Verilog Attributes and non-standard features
that have ports with a width that depends on a parameter.
- 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
never be removed by the optimizer. This is used for example for cells that
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc
index b3aec2110..bf01b263a 100644
--- a/backends/cxxrtl/cxxrtl_backend.cc
+++ b/backends/cxxrtl/cxxrtl_backend.cc
@@ -508,7 +508,7 @@ std::string get_hdl_name(T *object)
if (object->has_attribute(ID::hdlname))
return object->get_string_attribute(ID::hdlname);
else
- return object->name.str();
+ return object->name.str().substr(1);
}
struct CxxrtlWorker {
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 109113370..b876862c8 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -319,7 +319,7 @@ void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<str
attrval += "|";
attrval += s;
}
- attributes[id] = RTLIL::Const(attrval);
+ set_string_attribute(id, attrval);
}
void RTLIL::AttrObject::add_strpool_attribute(RTLIL::IdString id, const pool<string> &data)
@@ -334,11 +334,27 @@ pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const
{
pool<string> data;
if (attributes.count(id) != 0)
- for (auto s : split_tokens(attributes.at(id).decode_string(), "|"))
+ for (auto s : split_tokens(get_string_attribute(id), "|"))
data.insert(s);
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
{
if (full_selection)
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 86b4e25b6..f751bdce4 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -682,6 +682,9 @@ struct RTLIL::AttrObject
std::string get_src_attribute() const {
return get_string_attribute(ID::src);
}
+
+ void set_hdlname_attribute(const vector<string> &hierarchy);
+ vector<string> get_hdlname_attribute() const;
};
struct RTLIL::SigChunk
diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex
index ac0f48e47..83cfa5cc4 100644
--- a/manual/CHAPTER_Overview.tex
+++ b/manual/CHAPTER_Overview.tex
@@ -193,6 +193,13 @@ Violating these rules results in a runtime error.
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}
The RTLIL::Design object is basically just a container for RTLIL::Module objects. In addition to
diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc
index 669159167..a2794541a 100644
--- a/passes/techmap/flatten.cc
+++ b/passes/techmap/flatten.cc
@@ -32,8 +32,12 @@ IdString concat_name(RTLIL::Cell *cell, IdString object_name)
{
if (object_name[0] == '\\')
return stringf("%s.%s", cell->name.c_str(), object_name.c_str() + 1);
- else
- return stringf("$flatten%s.%s", cell->name.c_str(), object_name.c_str());
+ 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());
+ }
}
template<class T>
@@ -43,10 +47,21 @@ IdString map_name(RTLIL::Cell *cell, T *object)
}
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));
+
+ // 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)
@@ -77,7 +92,7 @@ struct FlattenWorker
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);
- map_attributes(cell, new_memory);
+ map_attributes(cell, new_memory, tpl_memory_it.second->name);
memory_map[tpl_memory_it.first] = new_memory->name;
design->select(module, new_memory);
}
@@ -107,14 +122,14 @@ struct FlattenWorker
new_wire->port_id = false;
}
- map_attributes(cell, new_wire);
+ map_attributes(cell, new_wire, tpl_wire->name);
wire_map[tpl_wire] = new_wire;
design->select(module, new_wire);
}
for (auto tpl_cell : tpl->cells()) {
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))) {
IdString memid = new_cell->getParam(ID::MEMID).decode_string();
new_cell->setParam(ID::MEMID, Const(memory_map.at(memid).str()));