diff options
| author | whitequark <whitequark@whitequark.org> | 2020-06-09 06:26:02 +0000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-09 06:26:02 +0000 | 
| commit | 4351194e8ce94e7078b67a20e5fc92777d6cb3e6 (patch) | |
| tree | 7d2027cda96eeb6c16506ca8b1c9df2fe475efa7 | |
| parent | 83f84afc0b617fe78fb7cfa31fb9d1cd202e22f2 (diff) | |
| parent | 53688a24b531adcc99c091f728e9657d16010467 (diff) | |
| download | yosys-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.md | 4 | ||||
| -rw-r--r-- | backends/cxxrtl/cxxrtl_backend.cc | 2 | ||||
| -rw-r--r-- | kernel/rtlil.cc | 20 | ||||
| -rw-r--r-- | kernel/rtlil.h | 3 | ||||
| -rw-r--r-- | manual/CHAPTER_Overview.tex | 7 | ||||
| -rw-r--r-- | passes/techmap/flatten.cc | 29 | 
6 files changed, 54 insertions, 11 deletions
| @@ -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())); | 
