mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Merge pull request #1763 from boqwxp/issue1762
Closes #1762. Adds warnings for `select` arguments not matching any object and for `add` command when no modules selected
This commit is contained in:
		
						commit
						3e46faa58c
					
				
					 8 changed files with 73 additions and 12 deletions
				
			
		
							
								
								
									
										1
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -716,6 +716,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) | ||||||
| 	+cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT) | 	+cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT) | ||||||
| 	+cd tests/bram && bash run-test.sh $(SEEDOPT) | 	+cd tests/bram && bash run-test.sh $(SEEDOPT) | ||||||
| 	+cd tests/various && bash run-test.sh | 	+cd tests/various && bash run-test.sh | ||||||
|  | 	+cd tests/select && bash run-test.sh | ||||||
| 	+cd tests/sat && bash run-test.sh | 	+cd tests/sat && bash run-test.sh | ||||||
| 	+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT) | 	+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT) | ||||||
| 	+cd tests/svtypes && bash run-test.sh $(SEEDOPT) | 	+cd tests/svtypes && bash run-test.sh $(SEEDOPT) | ||||||
|  |  | ||||||
|  | @ -206,6 +206,7 @@ struct AddPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
| 
 | 
 | ||||||
|  | 		bool selected_anything = false; | ||||||
| 		for (auto module : design->modules()) | 		for (auto module : design->modules()) | ||||||
| 		{ | 		{ | ||||||
| 			log_assert(module != nullptr); | 			log_assert(module != nullptr); | ||||||
|  | @ -214,11 +215,14 @@ struct AddPass : public Pass { | ||||||
| 			if (module->get_bool_attribute("\\blackbox")) | 			if (module->get_bool_attribute("\\blackbox")) | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
|  | 			selected_anything = true; | ||||||
| 			if (is_formal_celltype(command)) | 			if (is_formal_celltype(command)) | ||||||
| 				add_formal(module, command, arg_name, enable_name); | 				add_formal(module, command, arg_name, enable_name); | ||||||
| 			else if (command == "wire") | 			else if (command == "wire") | ||||||
| 				add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global); | 				add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global); | ||||||
| 		} | 		} | ||||||
|  | 		if (!selected_anything) | ||||||
|  | 			log_warning("No modules selected, or only blackboxes.  Nothing was added.\n"); | ||||||
| 	} | 	} | ||||||
| } AddPass; | } AddPass; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -625,9 +625,13 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void select_stmt(RTLIL::Design *design, std::string arg) | static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_empty_warning = false) | ||||||
| { | { | ||||||
| 	std::string arg_mod, arg_memb; | 	std::string arg_mod, arg_memb; | ||||||
|  | 	std::unordered_map<std::string, bool> arg_mod_found; | ||||||
|  | 	std::unordered_map<std::string, bool> arg_memb_found; | ||||||
|  | 	auto isalpha = [](const char &x) { return ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')); }; | ||||||
|  | 	bool prefixed = GetSize(arg) >= 2 && isalpha(arg[0]) && arg[1] == ':'; | ||||||
| 
 | 
 | ||||||
| 	if (arg.size() == 0) | 	if (arg.size() == 0) | ||||||
| 		return; | 		return; | ||||||
|  | @ -758,19 +762,21 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 	if (!design->selected_active_module.empty()) { | 	if (!design->selected_active_module.empty()) { | ||||||
| 		arg_mod = design->selected_active_module; | 		arg_mod = design->selected_active_module; | ||||||
| 		arg_memb = arg; | 		arg_memb = arg; | ||||||
|  | 		if (!prefixed) arg_memb_found[arg_memb] = false; | ||||||
| 	} else | 	} else | ||||||
| 	if (GetSize(arg) >= 2 && arg[0] >= 'a' && arg[0] <= 'z' && arg[1] == ':') { | 	if (prefixed && arg[0] >= 'a' && arg[0] <= 'z') { | ||||||
| 		arg_mod = "*", arg_memb = arg; | 		arg_mod = "*", arg_memb = arg; | ||||||
| 	} else { | 	} else { | ||||||
| 		size_t pos = arg.find('/'); | 		size_t pos = arg.find('/'); | ||||||
| 		if (pos == std::string::npos) { | 		if (pos == std::string::npos) { | ||||||
| 			if (arg.find(':') == std::string::npos || arg.compare(0, 1, "A") == 0) | 			arg_mod = arg; | ||||||
| 				arg_mod = arg; | 			if (!prefixed) arg_mod_found[arg_mod] = false; | ||||||
| 			else |  | ||||||
| 				arg_mod = "*", arg_memb = arg; |  | ||||||
| 		} else { | 		} else { | ||||||
| 			arg_mod = arg.substr(0, pos); | 			arg_mod = arg.substr(0, pos); | ||||||
|  | 			if (!prefixed) arg_mod_found[arg_mod] = false; | ||||||
| 			arg_memb = arg.substr(pos+1); | 			arg_memb = arg.substr(pos+1); | ||||||
|  | 			bool arg_memb_prefixed = GetSize(arg_memb) >= 2 && isalpha(arg_memb[0]) && arg_memb[1] == ':'; | ||||||
|  | 			if (!arg_memb_prefixed) arg_memb_found[arg_memb] = false; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -789,8 +795,14 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 			if (!match_attr(mod->attributes, arg_mod.substr(2))) | 			if (!match_attr(mod->attributes, arg_mod.substr(2))) | ||||||
| 				continue; | 				continue; | ||||||
| 		} else | 		} else | ||||||
|  | 		if (arg_mod.compare(0, 2, "N:") == 0) { | ||||||
|  | 			if (!match_ids(mod->name, arg_mod.substr(2))) | ||||||
|  | 				continue; | ||||||
|  | 		} else | ||||||
| 		if (!match_ids(mod->name, arg_mod)) | 		if (!match_ids(mod->name, arg_mod)) | ||||||
| 			continue; | 			continue; | ||||||
|  | 		else | ||||||
|  | 			arg_mod_found[arg_mod] = true; | ||||||
| 
 | 
 | ||||||
| 		if (arg_memb == "") { | 		if (arg_memb == "") { | ||||||
| 			sel.selected_modules.insert(mod->name); | 			sel.selected_modules.insert(mod->name); | ||||||
|  | @ -839,7 +851,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 				if (match_ids(it.first, arg_memb.substr(2))) | 				if (match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.compare(0, 2, "c:") ==0) { | 		if (arg_memb.compare(0, 2, "c:") == 0) { | ||||||
| 			for (auto cell : mod->cells()) | 			for (auto cell : mod->cells()) | ||||||
| 				if (match_ids(cell->name, arg_memb.substr(2))) | 				if (match_ids(cell->name, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(cell->name); | 					sel.selected_members[mod->name].insert(cell->name); | ||||||
|  | @ -873,24 +885,44 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 				if (match_attr(cell->parameters, arg_memb.substr(2))) | 				if (match_attr(cell->parameters, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(cell->name); | 					sel.selected_members[mod->name].insert(cell->name); | ||||||
| 		} else { | 		} else { | ||||||
|  | 			std::string orig_arg_memb = arg_memb; | ||||||
| 			if (arg_memb.compare(0, 2, "n:") == 0) | 			if (arg_memb.compare(0, 2, "n:") == 0) | ||||||
| 				arg_memb = arg_memb.substr(2); | 				arg_memb = arg_memb.substr(2); | ||||||
| 			for (auto wire : mod->wires()) | 			for (auto wire : mod->wires()) | ||||||
| 				if (match_ids(wire->name, arg_memb)) | 				if (match_ids(wire->name, arg_memb)) { | ||||||
| 					sel.selected_members[mod->name].insert(wire->name); | 					sel.selected_members[mod->name].insert(wire->name); | ||||||
|  | 					arg_memb_found[orig_arg_memb] = true; | ||||||
|  | 				} | ||||||
| 			for (auto &it : mod->memories) | 			for (auto &it : mod->memories) | ||||||
| 				if (match_ids(it.first, arg_memb)) | 				if (match_ids(it.first, arg_memb)) { | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
|  | 					arg_memb_found[orig_arg_memb] = true; | ||||||
|  | 				} | ||||||
| 			for (auto cell : mod->cells()) | 			for (auto cell : mod->cells()) | ||||||
| 				if (match_ids(cell->name, arg_memb)) | 				if (match_ids(cell->name, arg_memb)) { | ||||||
| 					sel.selected_members[mod->name].insert(cell->name); | 					sel.selected_members[mod->name].insert(cell->name); | ||||||
|  | 					arg_memb_found[orig_arg_memb] = true; | ||||||
|  | 				} | ||||||
| 			for (auto &it : mod->processes) | 			for (auto &it : mod->processes) | ||||||
| 				if (match_ids(it.first, arg_memb)) | 				if (match_ids(it.first, arg_memb)) { | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
|  | 					arg_memb_found[orig_arg_memb] = true; | ||||||
|  | 				} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	select_filter_active_mod(design, work_stack.back()); | 	select_filter_active_mod(design, work_stack.back()); | ||||||
|  | 
 | ||||||
|  | 	for (auto &it : arg_mod_found) { | ||||||
|  | 		if (it.second == false && !disable_empty_warning) { | ||||||
|  | 			log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	for (auto &it : arg_memb_found) { | ||||||
|  | 		if (it.second == false && !disable_empty_warning) { | ||||||
|  | 			log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel) | static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel) | ||||||
|  | @ -1074,6 +1106,10 @@ struct SelectPass : public Pass { | ||||||
| 		log("        all modules with an attribute matching the given pattern\n"); | 		log("        all modules with an attribute matching the given pattern\n"); | ||||||
| 		log("        in addition to = also <, <=, >=, and > are supported\n"); | 		log("        in addition to = also <, <=, >=, and > are supported\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    N:<pattern>\n"); | ||||||
|  | 		log("        all modules with a name matching the given pattern\n"); | ||||||
|  | 		log("        (i.e. 'N:' is optional as it is the default matching rule)\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("An <obj_pattern> can be an object name, wildcard expression, or one of\n"); | 		log("An <obj_pattern> can be an object name, wildcard expression, or one of\n"); | ||||||
| 		log("the following:\n"); | 		log("the following:\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -1276,7 +1312,8 @@ struct SelectPass : public Pass { | ||||||
| 			} | 			} | ||||||
| 			if (arg.size() > 0 && arg[0] == '-') | 			if (arg.size() > 0 && arg[0] == '-') | ||||||
| 				log_cmd_error("Unknown option %s.\n", arg.c_str()); | 				log_cmd_error("Unknown option %s.\n", arg.c_str()); | ||||||
| 			select_stmt(design, arg); | 			bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_count != -1) || (assert_max != -1) || (assert_min != -1); | ||||||
|  | 			select_stmt(design, arg, disable_empty_warning); | ||||||
| 			sel_str += " " + arg; | 			sel_str += " " + arg; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tests/select/no_warn_assert.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tests/select/no_warn_assert.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | logger -expect-no-warnings | ||||||
|  | select -assert-count 0 top/t:ff4 top/w:d0 %co:+[d] %i | ||||||
							
								
								
									
										5
									
								
								tests/select/no_warn_prefixed_arg_memb.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/select/no_warn_prefixed_arg_memb.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | logger -expect-no-warnings | ||||||
|  | read_verilog ../../examples/igloo2/example.v | ||||||
|  | hierarchy | ||||||
|  | proc | ||||||
|  | select example/t:$add | ||||||
							
								
								
									
										3
									
								
								tests/select/no_warn_prefixed_empty_select_arg.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/select/no_warn_prefixed_empty_select_arg.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | logger -expect-no-warnings | ||||||
|  | select n:foo/bar* | ||||||
|  | select t:$assert | ||||||
							
								
								
									
										6
									
								
								tests/select/run-test.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								tests/select/run-test.sh
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | set -e | ||||||
|  | for x in *.ys; do | ||||||
|  |   echo "Running $x.." | ||||||
|  |   ../../yosys -ql ${x%.ys}.log $x | ||||||
|  | done | ||||||
							
								
								
									
										3
									
								
								tests/select/warn_empty_select_arg.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/select/warn_empty_select_arg.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | logger -expect warning "did not match any module." 1 | ||||||
|  | logger -expect warning "did not match any object." 1 | ||||||
|  | select foo/bar | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue