mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	Refactor full_selection
The `Design::selected_*()` methods no longer unconditionally skip boxed modules.  Instead, selections are now box and design aware.
The selection constructor now optionally takes a design pointer, and has a new `selects_boxes` flag.  If the selection has an assigned design, then `Selection::selected_*()` will only return true for boxed modules if the selects_boxes flag is set.  A warning is raised if a selection is checked and no design is set.  Selections can change design via the `Selection::optimize()` method.
Most places that iterate over `Design::modules()` and check `Selection::selected_module()` should instead use `Design::selected_modules()`.
Since boxed modules should only ever be selected explicitly, and `full_selection` (now) refers to all non-boxed modules, `Selection::optimize()` will clear the `full_selection` flag if the `selects_boxes` flag is enabled, and instead explicitly selects all modules (including boxed modules).  This also means that `full_selection` will only get automatically applied to a design without any boxed modules.
These changes necessitated a number of changes to `select.cc` in order to support this functionality when operating on selections, in particular when combining selections (e.g. by union or difference).
To minimize redundancy, a number of places that previously iterated over `design->modules()` now push the current selection to the design, use `design->selected_modules()`, and then pop the selection when done.
Introduce `RTLIL::NamedObject`, to allow for iterating over all members of a module with a single iterator instead of needing to iterate over wires, cells, memories, and processes separately.
Also implement `Module::selected_{memories, processes, members}()` to match wires and cells methods.  The `selected_members()` method combines each of the other `selected_*()` methods into a single list.
			
			
This commit is contained in:
		
							parent
							
								
									e44d1d404a
								
							
						
					
					
						commit
						398afd102e
					
				
					 3 changed files with 197 additions and 114 deletions
				
			
		|  | @ -766,8 +766,21 @@ vector<int> RTLIL::AttrObject::get_intvec_attribute(const RTLIL::IdString &id) c | |||
| 	return data; | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Selection::boxed_module(const RTLIL::IdString &mod_name) const | ||||
| { | ||||
| 	if (current_design != nullptr) { | ||||
| 		auto module = current_design->module(mod_name); | ||||
| 		return module && module->get_blackbox_attribute(); | ||||
| 	} else { | ||||
| 		log_warning("Unable to check if module is boxed for null design.\n"); | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const | ||||
| { | ||||
| 	if (!selects_boxes && boxed_module(mod_name)) | ||||
| 		return false; | ||||
| 	if (full_selection) | ||||
| 		return true; | ||||
| 	if (selected_modules.count(mod_name) > 0) | ||||
|  | @ -779,6 +792,8 @@ bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const | |||
| 
 | ||||
| bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) const | ||||
| { | ||||
| 	if (!selects_boxes && boxed_module(mod_name)) | ||||
| 		return false; | ||||
| 	if (full_selection) | ||||
| 		return true; | ||||
| 	if (selected_modules.count(mod_name) > 0) | ||||
|  | @ -788,6 +803,8 @@ bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) co | |||
| 
 | ||||
| bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const | ||||
| { | ||||
| 	if (!selects_boxes && boxed_module(mod_name)) | ||||
| 		return false; | ||||
| 	if (full_selection) | ||||
| 		return true; | ||||
| 	if (selected_modules.count(mod_name) > 0) | ||||
|  | @ -800,6 +817,19 @@ bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RT | |||
| 
 | ||||
| void RTLIL::Selection::optimize(RTLIL::Design *design) | ||||
| { | ||||
| 	if (design != current_design) { | ||||
| 		current_design = design; | ||||
| 	} | ||||
| 
 | ||||
| 	if (selects_boxes && full_selection) { | ||||
| 		selected_modules.clear(); | ||||
| 		selected_members.clear(); | ||||
| 		full_selection = false; | ||||
| 		for (auto mod : current_design->modules()) { | ||||
| 			selected_modules.insert(mod->name); | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| 	if (full_selection) { | ||||
| 		selected_modules.clear(); | ||||
| 		selected_members.clear(); | ||||
|  | @ -810,7 +840,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) | |||
| 
 | ||||
| 	del_list.clear(); | ||||
| 	for (auto mod_name : selected_modules) { | ||||
| 		if (design->modules_.count(mod_name) == 0) | ||||
| 		if (current_design->modules_.count(mod_name) == 0) | ||||
| 			del_list.push_back(mod_name); | ||||
| 		selected_members.erase(mod_name); | ||||
| 	} | ||||
|  | @ -819,7 +849,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) | |||
| 
 | ||||
| 	del_list.clear(); | ||||
| 	for (auto &it : selected_members) | ||||
| 		if (design->modules_.count(it.first) == 0) | ||||
| 		if (current_design->modules_.count(it.first) == 0) | ||||
| 			del_list.push_back(it.first); | ||||
| 	for (auto mod_name : del_list) | ||||
| 		selected_members.erase(mod_name); | ||||
|  | @ -827,7 +857,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) | |||
| 	for (auto &it : selected_members) { | ||||
| 		del_list.clear(); | ||||
| 		for (auto memb_name : it.second) | ||||
| 			if (design->modules_[it.first]->count_id(memb_name) == 0) | ||||
| 			if (current_design->modules_[it.first]->count_id(memb_name) == 0) | ||||
| 				del_list.push_back(memb_name); | ||||
| 		for (auto memb_name : del_list) | ||||
| 			it.second.erase(memb_name); | ||||
|  | @ -838,8 +868,8 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) | |||
| 	for (auto &it : selected_members) | ||||
| 		if (it.second.size() == 0) | ||||
| 			del_list.push_back(it.first); | ||||
| 		else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() + | ||||
| 				design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size()) | ||||
| 		else if (it.second.size() == current_design->modules_[it.first]->wires_.size() + current_design->modules_[it.first]->memories.size() + | ||||
| 				current_design->modules_[it.first]->cells_.size() + current_design->modules_[it.first]->processes.size()) | ||||
| 			add_list.push_back(it.first); | ||||
| 	for (auto mod_name : del_list) | ||||
| 		selected_members.erase(mod_name); | ||||
|  | @ -848,7 +878,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) | |||
| 		selected_modules.insert(mod_name); | ||||
| 	} | ||||
| 
 | ||||
| 	if (selected_modules.size() == design->modules_.size()) { | ||||
| 	if (!selects_boxes && selected_modules.size() == current_design->modules_.size()) { | ||||
| 		full_selection = true; | ||||
| 		selected_modules.clear(); | ||||
| 		selected_members.clear(); | ||||
|  | @ -863,7 +893,7 @@ RTLIL::Design::Design() | |||
| 	hashidx_ = hashidx_count; | ||||
| 
 | ||||
| 	refcount_modules_ = 0; | ||||
| 	selection_stack.push_back(RTLIL::Selection()); | ||||
| 	selection_stack.push_back(RTLIL::Selection(true, false, this)); | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this)); | ||||
|  | @ -1127,7 +1157,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const | |||
| 	std::vector<RTLIL::Module*> result; | ||||
| 	result.reserve(modules_.size()); | ||||
| 	for (auto &it : modules_) | ||||
| 		if (selected_module(it.first) && !it.second->get_blackbox_attribute()) | ||||
| 		if (selected_module(it.first)) | ||||
| 			result.push_back(it.second); | ||||
| 	return result; | ||||
| } | ||||
|  | @ -1137,7 +1167,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const | |||
| 	std::vector<RTLIL::Module*> result; | ||||
| 	result.reserve(modules_.size()); | ||||
| 	for (auto &it : modules_) | ||||
| 		if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute()) | ||||
| 		if (selected_whole_module(it.first)) | ||||
| 			result.push_back(it.second); | ||||
| 	return result; | ||||
| } | ||||
|  | @ -1146,13 +1176,13 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn(bool incl | |||
| { | ||||
| 	std::vector<RTLIL::Module*> result; | ||||
| 	result.reserve(modules_.size()); | ||||
| 	for (auto &it : modules_) | ||||
| 		if (it.second->get_blackbox_attribute(include_wb)) | ||||
| 			continue; | ||||
| 		else if (selected_whole_module(it.first)) | ||||
| 	for (auto &it : modules_) { | ||||
| 		log_assert(selection_stack.size() > 0 || !it.second->get_blackbox_attribute(include_wb)); | ||||
| 		if (selected_whole_module(it.first)) | ||||
| 			result.push_back(it.second); | ||||
| 		else if (selected_module(it.first)) | ||||
| 			log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  | @ -2431,6 +2461,40 @@ std::vector<RTLIL::Cell*> RTLIL::Module::selected_cells() const | |||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| std::vector<RTLIL::Memory*> RTLIL::Module::selected_memories() const | ||||
| { | ||||
| 	std::vector<RTLIL::Memory*> result; | ||||
| 	result.reserve(memories.size()); | ||||
| 	for (auto &it : memories) | ||||
| 		if (design->selected(this, it.second)) | ||||
| 			result.push_back(it.second); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| std::vector<RTLIL::Process*> RTLIL::Module::selected_processes() const | ||||
| { | ||||
| 	std::vector<RTLIL::Process*> result; | ||||
| 	result.reserve(processes.size()); | ||||
| 	for (auto &it : processes) | ||||
| 		if (design->selected(this, it.second)) | ||||
| 			result.push_back(it.second); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| std::vector<RTLIL::NamedObject*> RTLIL::Module::selected_members() const | ||||
| { | ||||
| 	std::vector<RTLIL::NamedObject*> result; | ||||
| 	auto cells = selected_cells(); | ||||
| 	auto memories = selected_memories(); | ||||
| 	auto wires = selected_wires(); | ||||
| 	auto processes = selected_processes(); | ||||
| 	result.insert(result.end(), cells.begin(), cells.end()); | ||||
| 	result.insert(result.end(), memories.begin(), memories.end()); | ||||
| 	result.insert(result.end(), wires.begin(), wires.end()); | ||||
| 	result.insert(result.end(), processes.begin(), processes.end()); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| void RTLIL::Module::add(RTLIL::Wire *wire) | ||||
| { | ||||
| 	log_assert(!wire->name.empty()); | ||||
|  |  | |||
|  | @ -58,6 +58,7 @@ namespace RTLIL | |||
| 
 | ||||
| 	struct Const; | ||||
| 	struct AttrObject; | ||||
| 	struct NamedObject; | ||||
| 	struct Selection; | ||||
| 	struct Monitor; | ||||
| 	struct Design; | ||||
|  | @ -869,6 +870,11 @@ struct RTLIL::AttrObject | |||
| 	vector<int> get_intvec_attribute(const RTLIL::IdString &id) const; | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::NamedObject : public RTLIL::AttrObject | ||||
| { | ||||
| 	RTLIL::IdString name; | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::SigChunk | ||||
| { | ||||
| 	RTLIL::Wire *wire; | ||||
|  | @ -1135,11 +1141,14 @@ public: | |||
| struct RTLIL::Selection | ||||
| { | ||||
| 	bool full_selection; | ||||
| 	bool selects_boxes; | ||||
| 	pool<RTLIL::IdString> selected_modules; | ||||
| 	dict<RTLIL::IdString, pool<RTLIL::IdString>> selected_members; | ||||
| 	RTLIL::Design *current_design; | ||||
| 
 | ||||
| 	Selection(bool full = true) : full_selection(full) { } | ||||
| 	Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : full_selection(full), selects_boxes(boxes), current_design(design) { } | ||||
| 
 | ||||
| 	bool boxed_module(const RTLIL::IdString &mod_name) const; | ||||
| 	bool selected_module(const RTLIL::IdString &mod_name) const; | ||||
| 	bool selected_whole_module(const RTLIL::IdString &mod_name) const; | ||||
| 	bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; | ||||
|  | @ -1290,7 +1299,7 @@ struct RTLIL::Design | |||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Module : public RTLIL::AttrObject | ||||
| struct RTLIL::Module : public RTLIL::NamedObject | ||||
| { | ||||
| 	Hasher::hash_t hashidx_; | ||||
| 	[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } | ||||
|  | @ -1313,7 +1322,6 @@ public: | |||
| 	std::vector<RTLIL::SigSig>   connections_; | ||||
| 	std::vector<RTLIL::Binding*> bindings_; | ||||
| 
 | ||||
| 	RTLIL::IdString name; | ||||
| 	idict<RTLIL::IdString> avail_parameters; | ||||
| 	dict<RTLIL::IdString, RTLIL::Const> parameter_default_values; | ||||
| 	dict<RTLIL::IdString, RTLIL::Memory*> memories; | ||||
|  | @ -1360,6 +1368,9 @@ public: | |||
| 
 | ||||
| 	std::vector<RTLIL::Wire*> selected_wires() const; | ||||
| 	std::vector<RTLIL::Cell*> selected_cells() const; | ||||
| 	std::vector<RTLIL::Memory*> selected_memories() const; | ||||
| 	std::vector<RTLIL::Process*> selected_processes() const; | ||||
| 	std::vector<RTLIL::NamedObject*> selected_members() const; | ||||
| 
 | ||||
| 	template<typename T> bool selected(T *member) const { | ||||
| 		return design->selected_member(name, member->name); | ||||
|  | @ -1645,7 +1656,7 @@ namespace RTLIL_BACKEND { | |||
| void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); | ||||
| } | ||||
| 
 | ||||
| struct RTLIL::Wire : public RTLIL::AttrObject | ||||
| struct RTLIL::Wire : public RTLIL::NamedObject | ||||
| { | ||||
| 	Hasher::hash_t hashidx_; | ||||
| 	[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } | ||||
|  | @ -1668,7 +1679,6 @@ public: | |||
| 	void operator=(RTLIL::Wire &other) = delete; | ||||
| 
 | ||||
| 	RTLIL::Module *module; | ||||
| 	RTLIL::IdString name; | ||||
| 	int width, start_offset, port_id; | ||||
| 	bool port_input, port_output, upto, is_signed; | ||||
| 
 | ||||
|  | @ -1697,14 +1707,13 @@ inline int GetSize(RTLIL::Wire *wire) { | |||
| 	return wire->width; | ||||
| } | ||||
| 
 | ||||
| struct RTLIL::Memory : public RTLIL::AttrObject | ||||
| struct RTLIL::Memory : public RTLIL::NamedObject | ||||
| { | ||||
| 	Hasher::hash_t hashidx_; | ||||
| 	[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } | ||||
| 
 | ||||
| 	Memory(); | ||||
| 
 | ||||
| 	RTLIL::IdString name; | ||||
| 	int width, start_offset, size; | ||||
| #ifdef WITH_PYTHON | ||||
| 	~Memory(); | ||||
|  | @ -1712,7 +1721,7 @@ struct RTLIL::Memory : public RTLIL::AttrObject | |||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Cell : public RTLIL::AttrObject | ||||
| struct RTLIL::Cell : public RTLIL::NamedObject | ||||
| { | ||||
| 	Hasher::hash_t hashidx_; | ||||
| 	[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } | ||||
|  | @ -1729,7 +1738,6 @@ public: | |||
| 	void operator=(RTLIL::Cell &other) = delete; | ||||
| 
 | ||||
| 	RTLIL::Module *module; | ||||
| 	RTLIL::IdString name; | ||||
| 	RTLIL::IdString type; | ||||
| 	dict<RTLIL::IdString, RTLIL::SigSpec> connections_; | ||||
| 	dict<RTLIL::IdString, RTLIL::Const> parameters; | ||||
|  | @ -1822,7 +1830,7 @@ struct RTLIL::SyncRule | |||
| 	RTLIL::SyncRule *clone() const; | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Process : public RTLIL::AttrObject | ||||
| struct RTLIL::Process : public RTLIL::NamedObject | ||||
| { | ||||
| 	Hasher::hash_t hashidx_; | ||||
| 	[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } | ||||
|  | @ -1834,7 +1842,6 @@ protected: | |||
| 	~Process(); | ||||
| 
 | ||||
| public: | ||||
| 	RTLIL::IdString name; | ||||
| 	RTLIL::Module *module; | ||||
| 	RTLIL::CaseRule root_case; | ||||
| 	std::vector<RTLIL::SyncRule*> syncs; | ||||
|  |  | |||
|  | @ -141,6 +141,20 @@ static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, co | |||
| 	return match_attr(attributes, match_expr, std::string(), 0); | ||||
| } | ||||
| 
 | ||||
| static void full_select_no_box(RTLIL::Design *design, RTLIL::Selection &lhs) | ||||
| { | ||||
| 	if (!lhs.full_selection) | ||||
| 		return; | ||||
| 
 | ||||
| 	lhs.current_design = design; | ||||
| 	lhs.selected_modules.clear(); | ||||
| 	for (auto mod : design->modules()) { | ||||
| 		if (mod->get_blackbox_attribute()) | ||||
| 			continue; | ||||
| 		lhs.selected_modules.insert(mod->name); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) | ||||
| { | ||||
| 	if (lhs.full_selection) { | ||||
|  | @ -150,7 +164,7 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { | ||||
| 	if (!lhs.selects_boxes && lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { | ||||
| 		lhs.full_selection = true; | ||||
| 		return; | ||||
| 	} | ||||
|  | @ -159,6 +173,8 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) | |||
| 
 | ||||
| 	for (auto mod : design->modules()) | ||||
| 	{ | ||||
| 		if (!lhs.selects_boxes && mod->get_blackbox_attribute()) | ||||
| 			continue; | ||||
| 		if (lhs.selected_whole_module(mod->name)) | ||||
| 			continue; | ||||
| 		if (!lhs.selected_module(mod->name)) { | ||||
|  | @ -212,7 +228,7 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	lhs = RTLIL::Selection(false); | ||||
| 	lhs = RTLIL::Selection(false, false, design); | ||||
| 
 | ||||
| 	while (!objects.empty() && count-- > 0) | ||||
| 	{ | ||||
|  | @ -243,7 +259,7 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) | |||
| 
 | ||||
| static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &lhs) | ||||
| { | ||||
| 	RTLIL::Selection new_sel(false); | ||||
| 	RTLIL::Selection new_sel(false, lhs.selects_boxes, design); | ||||
| 	for (auto mod : design->modules()) | ||||
| 		if (lhs.selected_module(mod->name)) | ||||
| 			for (auto cell : mod->cells()) | ||||
|  | @ -254,7 +270,7 @@ static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection & | |||
| 
 | ||||
| static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs) | ||||
| { | ||||
| 	RTLIL::Selection new_sel(false); | ||||
| 	RTLIL::Selection new_sel(false, lhs.selects_boxes, design); | ||||
| 	for (auto mod : design->modules()) | ||||
| 		for (auto cell : mod->cells()) | ||||
| 			if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type)) | ||||
|  | @ -274,6 +290,8 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) | |||
| { | ||||
| 	for (auto mod : design->modules()) | ||||
| 	{ | ||||
| 		if (!lhs.selects_boxes && mod->get_blackbox_attribute()) | ||||
| 			continue; | ||||
| 		if (lhs.selected_whole_module(mod->name)) | ||||
| 			continue; | ||||
| 		if (!lhs.selected_module(mod->name)) | ||||
|  | @ -292,18 +310,32 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) | ||||
| static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) | ||||
| { | ||||
| 	if (rhs.selects_boxes) { | ||||
| 		if (lhs.full_selection) { | ||||
| 			full_select_no_box(design, lhs); | ||||
| 			lhs.full_selection = false; | ||||
| 		} | ||||
| 		lhs.selects_boxes = true; | ||||
| 	} | ||||
| 	else if (lhs.full_selection) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (rhs.full_selection) { | ||||
| 		lhs.full_selection = true; | ||||
| 		lhs.selected_modules.clear(); | ||||
| 		lhs.selected_members.clear(); | ||||
| 		if (lhs.selects_boxes) { | ||||
| 			auto new_rhs = RTLIL::Selection(rhs); | ||||
| 			full_select_no_box(design, new_rhs); | ||||
| 			for (auto mod : new_rhs.selected_modules) | ||||
| 				lhs.selected_modules.insert(mod); | ||||
| 		} else { | ||||
| 			lhs.full_selection = true; | ||||
| 			lhs.selected_modules.clear(); | ||||
| 			lhs.selected_members.clear(); | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (lhs.full_selection) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (auto &it : rhs.selected_members) | ||||
| 		for (auto &it2 : it.second) | ||||
| 			lhs.selected_members[it.first].insert(it2); | ||||
|  | @ -317,18 +349,26 @@ static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL:: | |||
| static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) | ||||
| { | ||||
| 	if (rhs.full_selection) { | ||||
| 		lhs.full_selection = false; | ||||
| 		lhs.selected_modules.clear(); | ||||
| 		lhs.selected_members.clear(); | ||||
| 		if (lhs.selects_boxes) { | ||||
| 			auto new_rhs = RTLIL::Selection(rhs); | ||||
| 			full_select_no_box(design, new_rhs); | ||||
| 			for (auto mod : new_rhs.selected_modules) { | ||||
| 				lhs.selected_modules.erase(mod); | ||||
| 				lhs.selected_members.erase(mod); | ||||
| 			} | ||||
| 		} else { | ||||
| 			lhs.full_selection = false; | ||||
| 			lhs.selected_modules.clear(); | ||||
| 			lhs.selected_members.clear(); | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (lhs.full_selection) { | ||||
| 		if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) | ||||
| 		if (rhs.empty()) | ||||
| 			return; | ||||
| 		full_select_no_box(design, lhs); | ||||
| 		lhs.full_selection = false; | ||||
| 		for (auto mod : design->modules()) | ||||
| 			lhs.selected_modules.insert(mod->name); | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto &it : rhs.selected_modules) { | ||||
|  | @ -366,7 +406,7 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R | |||
| 
 | ||||
| static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) | ||||
| { | ||||
| 	if (rhs.full_selection) | ||||
| 	if (rhs.full_selection && !lhs.selects_boxes) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (lhs.full_selection) { | ||||
|  | @ -377,27 +417,28 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co | |||
| 
 | ||||
| 	std::vector<RTLIL::IdString> del_list; | ||||
| 
 | ||||
| 	for (auto &it : lhs.selected_modules) | ||||
| 		if (rhs.selected_modules.count(it) == 0) { | ||||
| 			if (rhs.selected_members.count(it) > 0) | ||||
| 				for (auto &it2 : rhs.selected_members.at(it)) | ||||
| 					lhs.selected_members[it].insert(it2); | ||||
| 			del_list.push_back(it); | ||||
| 		} | ||||
| 	for (auto mod_name : lhs.selected_modules) { | ||||
| 		if (rhs.selected_whole_module(mod_name)) | ||||
| 			continue; | ||||
| 		if (rhs.selected_module(mod_name)) | ||||
| 			for (auto memb_name : rhs.selected_members.at(mod_name)) | ||||
| 				lhs.selected_members[mod_name].insert(memb_name); | ||||
| 		del_list.push_back(mod_name); | ||||
| 	} | ||||
| 	for (auto &it : del_list) | ||||
| 		lhs.selected_modules.erase(it); | ||||
| 
 | ||||
| 	del_list.clear(); | ||||
| 	for (auto &it : lhs.selected_members) { | ||||
| 		if (rhs.selected_modules.count(it.first) > 0) | ||||
| 		if (rhs.selected_whole_module(it.first)) | ||||
| 			continue; | ||||
| 		if (rhs.selected_members.count(it.first) == 0) { | ||||
| 		if (!rhs.selected_module(it.first)) { | ||||
| 			del_list.push_back(it.first); | ||||
| 			continue; | ||||
| 		} | ||||
| 		std::vector<RTLIL::IdString> del_list2; | ||||
| 		for (auto &it2 : it.second) | ||||
| 			if (rhs.selected_members.at(it.first).count(it2) == 0) | ||||
| 			if (!rhs.selected_member(it.first, it2)) | ||||
| 				del_list2.push_back(it2); | ||||
| 		for (auto &it2 : del_list2) | ||||
| 			it.second.erase(it2); | ||||
|  | @ -796,15 +837,16 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	work_stack.push_back(RTLIL::Selection()); | ||||
| 	bool full_selection = (arg == "*" && arg_mod == "*"); | ||||
| 	work_stack.push_back(RTLIL::Selection(full_selection, select_blackboxes, design)); | ||||
| 	RTLIL::Selection &sel = work_stack.back(); | ||||
| 
 | ||||
| 	if (arg == "*" && arg_mod == "*" && select_blackboxes) { | ||||
| 	if (sel.full_selection) { | ||||
| 		if (sel.selects_boxes) sel.optimize(design); | ||||
| 		select_filter_active_mod(design, work_stack.back()); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	sel.full_selection = false; | ||||
| 	for (auto mod : design->modules()) | ||||
| 	{ | ||||
| 		if (!select_blackboxes && mod->get_blackbox_attribute()) | ||||
|  | @ -958,24 +1000,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp | |||
| static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel, bool whole_modules = false) | ||||
| { | ||||
| 	std::string desc = "Selection contains:\n"; | ||||
| 	for (auto mod : design->modules()) | ||||
| 	for (auto mod : design->selected_modules()) | ||||
| 	{ | ||||
| 		if (sel->selected_module(mod->name)) { | ||||
| 			if (whole_modules && sel->selected_whole_module(mod->name)) | ||||
| 					desc += stringf("%s\n", id2cstr(mod->name)); | ||||
| 			for (auto wire : mod->wires()) | ||||
| 				if (sel->selected_member(mod->name, wire->name)) | ||||
| 					desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)); | ||||
| 			for (auto &it : mod->memories) | ||||
| 				if (sel->selected_member(mod->name, it.first)) | ||||
| 					desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); | ||||
| 			for (auto cell : mod->cells()) | ||||
| 				if (sel->selected_member(mod->name, cell->name)) | ||||
| 					desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)); | ||||
| 			for (auto &it : mod->processes) | ||||
| 				if (sel->selected_member(mod->name, it.first)) | ||||
| 					desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); | ||||
| 		} | ||||
| 		if (whole_modules && sel->selected_whole_module(mod->name)) | ||||
| 			desc += stringf("%s\n", id2cstr(mod->name)); | ||||
| 		for (auto it : mod->selected_members()) | ||||
| 			desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)); | ||||
| 	} | ||||
| 	return desc; | ||||
| } | ||||
|  | @ -1001,7 +1031,7 @@ void handle_extra_select_args(Pass *pass, const vector<string> &args, size_t arg | |||
| 		work_stack.pop_back(); | ||||
| 	} | ||||
| 	if (work_stack.empty()) | ||||
| 		design->selection_stack.push_back(RTLIL::Selection(false)); | ||||
| 		design->selection_stack.push_back(RTLIL::Selection(false, false, design)); | ||||
| 	else | ||||
| 		design->selection_stack.push_back(work_stack.back()); | ||||
| } | ||||
|  | @ -1017,7 +1047,7 @@ RTLIL::Selection eval_select_args(const vector<string> &args, RTLIL::Design *des | |||
| 		work_stack.pop_back(); | ||||
| 	} | ||||
| 	if (work_stack.empty()) | ||||
| 		return RTLIL::Selection(false); | ||||
| 		return RTLIL::Selection(false, false, design); | ||||
| 	return work_stack.back(); | ||||
| } | ||||
| 
 | ||||
|  | @ -1444,13 +1474,13 @@ struct SelectPass : public Pass { | |||
| 		log_assert(design->selection_stack.size() > 0); | ||||
| 
 | ||||
| 		if (clear_mode) { | ||||
| 			design->selection_stack.back() = RTLIL::Selection(true); | ||||
| 			design->selection_stack.back() = RTLIL::Selection(true, false, design); | ||||
| 			design->selected_active_module = std::string(); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (none_mode) { | ||||
| 			design->selection_stack.back() = RTLIL::Selection(false); | ||||
| 			design->selection_stack.back() = RTLIL::Selection(false, false, design); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -1465,28 +1495,17 @@ struct SelectPass : public Pass { | |||
| 				if (f == nullptr) | ||||
| 					log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); | ||||
| 			} | ||||
| 			RTLIL::Selection *sel = &design->selection_stack.back(); | ||||
| 			if (work_stack.size() > 0) | ||||
| 				sel = &work_stack.back(); | ||||
| 				design->selection_stack.push_back(work_stack.back()); | ||||
| 			RTLIL::Selection *sel = &design->selection_stack.back(); | ||||
| 			sel->optimize(design); | ||||
| 			for (auto mod : design->modules()) | ||||
| 			for (auto mod : design->selected_modules()) | ||||
| 			{ | ||||
| 				if (sel->selected_whole_module(mod->name) && list_mode) | ||||
| 					log("%s\n", id2cstr(mod->name)); | ||||
| 				if (sel->selected_module(mod->name) && !list_mod_mode) { | ||||
| 					for (auto wire : mod->wires()) | ||||
| 						if (sel->selected_member(mod->name, wire->name)) | ||||
| 							LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)) | ||||
| 					for (auto &it : mod->memories) | ||||
| 						if (sel->selected_member(mod->name, it.first)) | ||||
| 							LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) | ||||
| 					for (auto cell : mod->cells()) | ||||
| 						if (sel->selected_member(mod->name, cell->name)) | ||||
| 							LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)) | ||||
| 					for (auto &it : mod->processes) | ||||
| 						if (sel->selected_member(mod->name, it.first)) | ||||
| 							LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) | ||||
| 				} | ||||
| 				if (!list_mod_mode) | ||||
| 					for (auto it : mod->selected_members()) | ||||
| 						LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)) | ||||
| 			} | ||||
| 			if (count_mode) | ||||
| 			{ | ||||
|  | @ -1495,6 +1514,8 @@ struct SelectPass : public Pass { | |||
| 			} | ||||
| 			if (f != nullptr) | ||||
| 				fclose(f); | ||||
| 			if (work_stack.size() > 0) | ||||
| 				design->selection_stack.pop_back(); | ||||
| 		#undef LOG_OBJECT | ||||
| 			return; | ||||
| 		} | ||||
|  | @ -1553,23 +1574,13 @@ struct SelectPass : public Pass { | |||
| 			if (work_stack.size() == 0) | ||||
| 				log_cmd_error("No selection to check.\n"); | ||||
| 			RTLIL::Selection *sel = &work_stack.back(); | ||||
| 			design->selection_stack.push_back(*sel); | ||||
| 			sel->optimize(design); | ||||
| 			for (auto mod : design->modules()) | ||||
| 				if (sel->selected_module(mod->name)) { | ||||
| 					module_count++; | ||||
| 					for (auto wire : mod->wires()) | ||||
| 						if (sel->selected_member(mod->name, wire->name)) | ||||
| 							total_count++; | ||||
| 					for (auto &it : mod->memories) | ||||
| 						if (sel->selected_member(mod->name, it.first)) | ||||
| 							total_count++; | ||||
| 					for (auto cell : mod->cells()) | ||||
| 						if (sel->selected_member(mod->name, cell->name)) | ||||
| 							total_count++; | ||||
| 					for (auto &it : mod->processes) | ||||
| 						if (sel->selected_member(mod->name, it.first)) | ||||
| 							total_count++; | ||||
| 				} | ||||
| 			for (auto mod : design->selected_modules()) { | ||||
| 				module_count++; | ||||
| 				for ([[maybe_unused]] auto member_name : mod->selected_members()) | ||||
| 					total_count++; | ||||
| 			} | ||||
| 			if (assert_modcount >= 0 && assert_modcount != module_count) | ||||
| 			{ | ||||
| 				log_error("Assertion failed: selection contains %d modules instead of the asserted %d:%s\n", | ||||
|  | @ -1593,13 +1604,14 @@ struct SelectPass : public Pass { | |||
| 				log_error("Assertion failed: selection contains %d elements, less than the minimum number %d:%s\n%s", | ||||
| 						total_count, assert_min, sel_str.c_str(), desc.c_str()); | ||||
| 			} | ||||
| 			design->selection_stack.pop_back(); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!set_name.empty()) | ||||
| 		{ | ||||
| 			if (work_stack.size() == 0) | ||||
| 				design->selection_vars[set_name] = RTLIL::Selection(false); | ||||
| 				design->selection_vars[set_name] = RTLIL::Selection(false, false, design); | ||||
| 			else | ||||
| 				design->selection_vars[set_name] = work_stack.back(); | ||||
| 			return; | ||||
|  | @ -1665,7 +1677,7 @@ struct CdPass : public Pass { | |||
| 			log_cmd_error("Invalid number of arguments.\n"); | ||||
| 
 | ||||
| 		if (args.size() == 1 || args[1] == "/") { | ||||
| 			design->selection_stack.back() = RTLIL::Selection(true); | ||||
| 			design->selection_stack.back() = RTLIL::Selection(true, false, design); | ||||
| 			design->selected_active_module = std::string(); | ||||
| 			return; | ||||
| 		} | ||||
|  | @ -1674,7 +1686,7 @@ struct CdPass : public Pass { | |||
| 		{ | ||||
| 			string modname = design->selected_active_module; | ||||
| 
 | ||||
| 			design->selection_stack.back() = RTLIL::Selection(true); | ||||
| 			design->selection_stack.back() = RTLIL::Selection(true, false, design); | ||||
| 			design->selected_active_module = std::string(); | ||||
| 
 | ||||
| 			while (1) | ||||
|  | @ -1691,7 +1703,7 @@ struct CdPass : public Pass { | |||
| 					continue; | ||||
| 
 | ||||
| 				design->selected_active_module = modname; | ||||
| 				design->selection_stack.back() = RTLIL::Selection(); | ||||
| 				design->selection_stack.back() = RTLIL::Selection(true, false, design); | ||||
| 				select_filter_active_mod(design, design->selection_stack.back()); | ||||
| 				design->selection_stack.back().optimize(design); | ||||
| 				return; | ||||
|  | @ -1710,7 +1722,7 @@ struct CdPass : public Pass { | |||
| 
 | ||||
| 		if (design->module(modname) != nullptr) { | ||||
| 			design->selected_active_module = modname; | ||||
| 			design->selection_stack.back() = RTLIL::Selection(); | ||||
| 			design->selection_stack.back() = RTLIL::Selection(true, false, design); | ||||
| 			select_filter_active_mod(design, design->selection_stack.back()); | ||||
| 			design->selection_stack.back().optimize(design); | ||||
| 			return; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue