mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +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
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…
Reference in a new issue