mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	
						commit
						edb95c69a9
					
				
					 20 changed files with 976 additions and 21 deletions
				
			
		|  | @ -35,10 +35,12 @@ struct keep_cache_t | |||
| { | ||||
| 	Design *design; | ||||
| 	dict<Module*, bool> cache; | ||||
| 	bool purge_mode = false; | ||||
| 
 | ||||
| 	void reset(Design *design = nullptr) | ||||
| 	void reset(Design *design = nullptr, bool purge_mode = false) | ||||
| 	{ | ||||
| 		this->design = design; | ||||
| 		this->purge_mode = purge_mode; | ||||
| 		cache.clear(); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -88,6 +90,9 @@ struct keep_cache_t | |||
| 		if (cell->has_keep_attr()) | ||||
| 			return true; | ||||
| 
 | ||||
| 		if (!purge_mode && cell->type == ID($scopeinfo)) | ||||
| 			return true; | ||||
| 
 | ||||
| 		if (cell->module && cell->module->design) | ||||
| 			return query(cell->module->design->module(cell->type)); | ||||
| 
 | ||||
|  | @ -236,6 +241,8 @@ int count_nontrivial_wire_attrs(RTLIL::Wire *w) | |||
| { | ||||
| 	int count = w->attributes.size(); | ||||
| 	count -= w->attributes.count(ID::src); | ||||
| 	count -= w->attributes.count(ID::hdlname); | ||||
| 	count -= w->attributes.count(ID(scopename)); | ||||
| 	count -= w->attributes.count(ID::unused_bits); | ||||
| 	return count; | ||||
| } | ||||
|  | @ -661,7 +668,7 @@ struct OptCleanPass : public Pass { | |||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		keep_cache.reset(design); | ||||
| 		keep_cache.reset(design, purge_mode); | ||||
| 
 | ||||
| 		ct_reg.setup_internals_mem(); | ||||
| 		ct_reg.setup_internals_anyinit(); | ||||
|  |  | |||
|  | @ -272,6 +272,9 @@ struct OptMergeWorker | |||
| 				if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) | ||||
| 					continue; | ||||
| 
 | ||||
| 				if (cell->type == ID($scopeinfo)) | ||||
| 					continue; | ||||
| 
 | ||||
| 				uint64_t hash = hash_cell_parameters_and_connections(cell); | ||||
| 				auto r = sharemap.insert(std::make_pair(hash, cell)); | ||||
| 				if (!r.second) { | ||||
|  |  | |||
|  | @ -46,24 +46,6 @@ IdString map_name(RTLIL::Cell *cell, T *object) | |||
| 	return cell->module->uniquify(concat_name(cell, object->name)); | ||||
| } | ||||
| 
 | ||||
| template<class T> | ||||
| void map_attributes(RTLIL::Cell *cell, T *object, IdString orig_object_name) | ||||
| { | ||||
| 	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) | ||||
| { | ||||
| 	vector<SigChunk> chunks = sig; | ||||
|  | @ -76,6 +58,54 @@ void map_sigspec(const dict<RTLIL::Wire*, RTLIL::Wire*> &map, RTLIL::SigSpec &si | |||
| struct FlattenWorker | ||||
| { | ||||
| 	bool ignore_wb = false; | ||||
| 	bool create_scopeinfo = true; | ||||
| 	bool create_scopename = false; | ||||
| 
 | ||||
| 	template<class T> | ||||
| 	void map_attributes(RTLIL::Cell *cell, T *object, IdString orig_object_name) | ||||
| 	{ | ||||
| 		if (!create_scopeinfo && 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 the '-scopename' option is used, also preserve the containing scope of private objects if their scope is fully public.
 | ||||
| 		if (cell->name[0] == '\\') { | ||||
| 			if (object->has_attribute(ID::hdlname) || orig_object_name[0] == '\\') { | ||||
| 				std::string new_hdlname; | ||||
| 
 | ||||
| 				if (cell->has_attribute(ID::hdlname)) { | ||||
| 					new_hdlname = cell->get_string_attribute(ID(hdlname)); | ||||
| 				} else { | ||||
| 					log_assert(!cell->name.empty()); | ||||
| 					new_hdlname = cell->name.c_str() + 1; | ||||
| 				} | ||||
| 				new_hdlname += ' '; | ||||
| 
 | ||||
| 				if (object->has_attribute(ID::hdlname)) { | ||||
| 					new_hdlname += object->get_string_attribute(ID(hdlname)); | ||||
| 				} else { | ||||
| 					log_assert(!orig_object_name.empty()); | ||||
| 					new_hdlname += orig_object_name.c_str() + 1; | ||||
| 				} | ||||
| 				object->set_string_attribute(ID(hdlname), new_hdlname); | ||||
| 			} else if (object->has_attribute(ID(scopename))) { | ||||
| 				std::string new_scopename; | ||||
| 
 | ||||
| 				if (cell->has_attribute(ID::hdlname)) { | ||||
| 					new_scopename = cell->get_string_attribute(ID(hdlname)); | ||||
| 				} else { | ||||
| 					log_assert(!cell->name.empty()); | ||||
| 					new_scopename = cell->name.c_str() + 1; | ||||
| 				} | ||||
| 				new_scopename += ' '; | ||||
| 				new_scopename += object->get_string_attribute(ID(scopename)); | ||||
| 				object->set_string_attribute(ID(scopename), new_scopename); | ||||
| 			} else if (create_scopename) { | ||||
| 				log_assert(!cell->name.empty()); | ||||
| 				object->set_string_attribute(ID(scopename), cell->name.c_str() + 1); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, SigMap &sigmap, std::vector<RTLIL::Cell*> &new_cells) | ||||
| 	{ | ||||
|  | @ -220,7 +250,33 @@ struct FlattenWorker | |||
| 			sigmap.add(new_conn.first, new_conn.second); | ||||
| 		} | ||||
| 
 | ||||
| 		RTLIL::Cell *scopeinfo = nullptr; | ||||
| 		RTLIL::IdString cell_name = cell->name; | ||||
| 
 | ||||
| 		if (create_scopeinfo && cell_name.isPublic()) | ||||
| 		{ | ||||
| 			// The $scopeinfo's name will be changed below after removing the flattened cell
 | ||||
| 			scopeinfo = module->addCell(NEW_ID, ID($scopeinfo)); | ||||
| 			scopeinfo->setParam(ID::TYPE, RTLIL::Const("module")); | ||||
| 
 | ||||
| 			for (auto const &attr : cell->attributes) | ||||
| 			{ | ||||
| 				if (attr.first == ID::hdlname) | ||||
| 					scopeinfo->attributes.insert(attr); | ||||
| 				else | ||||
| 					scopeinfo->attributes.emplace(stringf("\\cell_%s", RTLIL::unescape_id(attr.first).c_str()), attr.second); | ||||
| 			} | ||||
| 
 | ||||
| 			for (auto const &attr : tpl->attributes) | ||||
| 				scopeinfo->attributes.emplace(stringf("\\module_%s", RTLIL::unescape_id(attr.first).c_str()), attr.second); | ||||
| 
 | ||||
| 			scopeinfo->attributes.emplace(ID(module), RTLIL::unescape_id(tpl->name)); | ||||
| 		} | ||||
| 
 | ||||
| 		module->remove(cell); | ||||
| 
 | ||||
| 		if (scopeinfo != nullptr) | ||||
| 			module->rename(scopeinfo, cell_name); | ||||
| 	} | ||||
| 
 | ||||
| 	void flatten_module(RTLIL::Design *design, RTLIL::Module *module, pool<RTLIL::Module*> &used_modules) | ||||
|  | @ -275,6 +331,20 @@ struct FlattenPass : public Pass { | |||
| 		log("    -wb\n"); | ||||
| 		log("        Ignore the 'whitebox' attribute on cell implementations.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -noscopeinfo\n"); | ||||
| 		log("        Do not create '$scopeinfo' cells that preserve attributes of cells and\n"); | ||||
| 		log("        modules that were removed during flattening. With this option, the\n"); | ||||
| 		log("        'src' attribute of a given cell is merged into all objects replacing\n"); | ||||
| 		log("        that cell, with multiple distinct 'src' locations separated by '|'.\n"); | ||||
| 		log("        Without this option these 'src' locations can be found via the\n"); | ||||
| 		log("        cell_src' and 'module_src' attribute of '$scopeinfo' cells.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -scopename\n"); | ||||
| 		log("        Create 'scopename' attributes for objects with a private name. This\n"); | ||||
| 		log("        attribute records the 'hdlname' of the enclosing scope. For objects\n"); | ||||
| 		log("        with a public name the enclosing scope can be found via their\n"); | ||||
| 		log("        'hdlname' attribute.\n"); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) override | ||||
| 	{ | ||||
|  | @ -289,6 +359,14 @@ struct FlattenPass : public Pass { | |||
| 				worker.ignore_wb = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-noscopeinfo") { | ||||
| 				worker.create_scopeinfo = false; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-scopename") { | ||||
| 				worker.create_scopename = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue