mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Fixed and improved #x selection operator
This commit is contained in:
		
							parent
							
								
									b96ffed69b
								
							
						
					
					
						commit
						0be19f6ca7
					
				
					 1 changed files with 44 additions and 14 deletions
				
			
		|  | @ -243,7 +243,7 @@ static int parse_comma_list(std::set<RTLIL::IdString> &tokens, std::string str, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector<expand_rule_t> &rules) | static void select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector<expand_rule_t> &rules, std::set<RTLIL::IdString> &limits) | ||||||
| { | { | ||||||
| 	for (auto &mod_it : design->modules) | 	for (auto &mod_it : design->modules) | ||||||
| 	{ | 	{ | ||||||
|  | @ -254,7 +254,7 @@ static void select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std:: | ||||||
| 		std::set<RTLIL::Wire*> selected_wires; | 		std::set<RTLIL::Wire*> selected_wires; | ||||||
| 
 | 
 | ||||||
| 		for (auto &it : mod->wires) | 		for (auto &it : mod->wires) | ||||||
| 			if (lhs.selected_member(mod_it.first, it.first)) | 			if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0) | ||||||
| 				selected_wires.insert(it.second); | 				selected_wires.insert(it.second); | ||||||
| 
 | 
 | ||||||
| 		for (auto &cell : mod->cells) | 		for (auto &cell : mod->cells) | ||||||
|  | @ -263,9 +263,9 @@ static void select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std:: | ||||||
| 			char last_mode = '-'; | 			char last_mode = '-'; | ||||||
| 			for (auto &rule : rules) { | 			for (auto &rule : rules) { | ||||||
| 				last_mode = rule.mode; | 				last_mode = rule.mode; | ||||||
| 				if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type)) | 				if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type) == 0) | ||||||
| 					continue; | 					continue; | ||||||
| 				if (rule.port_names.size() > 0 && rule.port_names.count(cell.first)) | 				if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0) | ||||||
| 					continue; | 					continue; | ||||||
| 				if (rule.mode == '+') | 				if (rule.mode == '+') | ||||||
| 					goto include_match; | 					goto include_match; | ||||||
|  | @ -279,7 +279,7 @@ static void select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std:: | ||||||
| 				if (chunk.wire != NULL) { | 				if (chunk.wire != NULL) { | ||||||
| 					if (selected_wires.count(chunk.wire) > 0) | 					if (selected_wires.count(chunk.wire) > 0) | ||||||
| 						lhs.selected_members[mod->name].insert(cell.first); | 						lhs.selected_members[mod->name].insert(cell.first); | ||||||
| 					if (lhs.selected_members[mod->name].count(cell.first) > 0) | 					if (lhs.selected_members[mod->name].count(cell.first) > 0 && limits.count(cell.first) == 0) | ||||||
| 						lhs.selected_members[mod->name].insert(chunk.wire->name); | 						lhs.selected_members[mod->name].insert(chunk.wire->name); | ||||||
| 				} | 				} | ||||||
| 		exclude_match:; | 		exclude_match:; | ||||||
|  | @ -359,6 +359,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 				log_cmd_error("Must have at least one element on stack for operator #x.\n"); | 				log_cmd_error("Must have at least one element on stack for operator #x.\n"); | ||||||
| 			size_t pos = 2, levels = 1; | 			size_t pos = 2, levels = 1; | ||||||
| 			std::vector<expand_rule_t> rules; | 			std::vector<expand_rule_t> rules; | ||||||
|  | 			std::set<RTLIL::IdString> limits; | ||||||
| 			if (pos < arg.size() && '0' <= arg[pos] && arg[pos] <= '9') { | 			if (pos < arg.size() && '0' <= arg[pos] && arg[pos] <= '9') { | ||||||
| 				size_t endpos = arg.find_first_not_of("0123456789", pos); | 				size_t endpos = arg.find_first_not_of("0123456789", pos); | ||||||
| 				if (endpos == std::string::npos) | 				if (endpos == std::string::npos) | ||||||
|  | @ -368,25 +369,53 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 			} | 			} | ||||||
| 			while (pos < arg.size()) { | 			while (pos < arg.size()) { | ||||||
| 				if (arg[pos] != ':' || pos+1 == arg.size()) | 				if (arg[pos] != ':' || pos+1 == arg.size()) | ||||||
| 					goto syntax_error_x; | 					log_cmd_error("Syntax error in expand operator '%s'.\n", arg.c_str()); | ||||||
| 				pos++; | 				pos++; | ||||||
| 				if (arg[pos] == '+' || arg[pos] == '-') { | 				if (arg[pos] == '+' || arg[pos] == '-') { | ||||||
| 					expand_rule_t rule; | 					expand_rule_t rule; | ||||||
| 					rule.mode = arg[pos++]; | 					rule.mode = arg[pos++]; | ||||||
| 					pos = parse_comma_list(rule.cell_types, arg, pos, "[:"); | 					pos = parse_comma_list(rule.cell_types, arg, pos, "[:"); | ||||||
| 					if (pos < arg.size() && arg[pos] == '[') { | 					if (pos < arg.size() && arg[pos] == '[') { | ||||||
| 						pos = parse_comma_list(rule.port_names, arg, pos, "]:"); | 						pos = parse_comma_list(rule.port_names, arg, pos+1, "]:"); | ||||||
| 						if (pos < arg.size() && arg[pos] == ']') | 						if (pos < arg.size() && arg[pos] == ']') | ||||||
| 							pos++; | 							pos++; | ||||||
| 					} | 					} | ||||||
| 				} else | 					rules.push_back(rule); | ||||||
| 			syntax_error_x: | 				} else { | ||||||
| 					log_cmd_error("Syntax error in expand operator '%s'.\n", arg.c_str()); | 					size_t endpos = arg.find(':', pos); | ||||||
|  | 					if (endpos == std::string::npos) | ||||||
|  | 						endpos = arg.size(); | ||||||
|  | 					if (endpos > pos) | ||||||
|  | 						limits.insert(RTLIL::escape_id(arg.substr(pos, endpos-pos))); | ||||||
|  | 					pos = endpos; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			if (arg.size() > 3) | 		#if 0 | ||||||
| 				levels = std::max(atoi(arg.substr(3).c_str()), 1); | 			log("expand by %d levels:\n", int(levels)); | ||||||
|  | 			for (auto &rule : rules) { | ||||||
|  | 				log("  rule (%c):\n", rule.mode); | ||||||
|  | 				if (rule.cell_types.size() > 0) { | ||||||
|  | 					log("    cell types:"); | ||||||
|  | 					for (auto &it : rule.cell_types) | ||||||
|  | 						log(" %s", it.c_str()); | ||||||
|  | 					log("\n"); | ||||||
|  | 				} | ||||||
|  | 				if (rule.port_names.size() > 0) { | ||||||
|  | 					log("    port names:"); | ||||||
|  | 					for (auto &it : rule.port_names) | ||||||
|  | 						log(" %s", it.c_str()); | ||||||
|  | 					log("\n"); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if (limits.size() > 0) { | ||||||
|  | 				log("  limits:"); | ||||||
|  | 				for (auto &it : limits) | ||||||
|  | 					log(" %s", it.c_str()); | ||||||
|  | 				log("\n"); | ||||||
|  | 			} | ||||||
|  | 		#endif | ||||||
| 			while (levels-- > 0) | 			while (levels-- > 0) | ||||||
| 				select_op_expand(design, work_stack.back(), rules); | 				select_op_expand(design, work_stack.back(), rules, limits); | ||||||
| 		} else | 		} else | ||||||
| 			log_cmd_error("Unknown selection operator '%s'.\n", arg.c_str()); | 			log_cmd_error("Unknown selection operator '%s'.\n", arg.c_str()); | ||||||
| 		select_filter_active_mod(design, work_stack.back()); | 		select_filter_active_mod(design, work_stack.back()); | ||||||
|  | @ -645,7 +674,8 @@ struct SelectPass : public Pass { | ||||||
| 		log("        ports to use for this. the syntax for a rule is a '-' for exclusion\n"); | 		log("        ports to use for this. the syntax for a rule is a '-' for exclusion\n"); | ||||||
| 		log("        and a '+' for inclusion, followed by an optional comma seperated\n"); | 		log("        and a '+' for inclusion, followed by an optional comma seperated\n"); | ||||||
| 		log("        list of cell types followed by an optional comma seperated list of\n"); | 		log("        list of cell types followed by an optional comma seperated list of\n"); | ||||||
| 		log("        cell ports in square brackets.\n"); | 		log("        cell ports in square brackets. a rule can also be just a cell or wire\n"); | ||||||
|  | 		log("        name that limits the expansion (is included but does not go beyond).\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("Example: the following command selects all wires that are connected to a\n"); | 		log("Example: the following command selects all wires that are connected to a\n"); | ||||||
| 		log("'GATE' input of a 'SWITCH' cell:\n"); | 		log("'GATE' input of a 'SWITCH' cell:\n"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue