mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	flatten: preserve original object names via hdlname attribute.
This commit is contained in:
		
							parent
							
								
									8d821dbbdb
								
							
						
					
					
						commit
						fbb346ea91
					
				
					 5 changed files with 45 additions and 6 deletions
				
			
		|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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())); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue