select: Fix -assert-none and -assert-any error output and docs
authorJannis Harder <me@jix.one>
Thu, 19 May 2022 11:58:46 +0000 (13:58 +0200)
committerJannis Harder <me@jix.one>
Thu, 19 May 2022 12:07:34 +0000 (14:07 +0200)
Both of these options consider a selection containing only empty modules
as non-empty. This wasn't mentioned in the documentation nor did the
error message when using `select -assert-none` list those empty modules,
which produced a very confusing error message complaining about a
non-empty selection followed by an empty listing of the selection.

This fixes the documentation and changes the `-assert-none` and
`-assert-any` assertion error messages to also output fully selected
modules (this includes selected empty modules).

It doesn't change the messages for `-assert-count` etc. as they don't
count modules.

passes/cmds/select.cc

index bb7b78cfed5cce6b36f8e618b00d24b8415dc17f..d609c8d0fef3accf7a6cc4814bdd50cc4341258f 100644 (file)
@@ -944,12 +944,14 @@ 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)
+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())
        {
                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));
@@ -1051,17 +1053,17 @@ struct SelectPass : public Pass {
                log("\n");
                log("    -unset <name>\n");
                log("        do not modify the current selection. instead remove a previously saved\n");
-               log("        selection under the given name (see @<name> below).");
+               log("        selection under the given name (see @<name> below).\n");
                log("\n");
                log("    -assert-none\n");
                log("        do not modify the current selection. instead assert that the given\n");
-               log("        selection is empty. i.e. produce an error if any object matching the\n");
-               log("        selection is found.\n");
+               log("        selection is empty. i.e. produce an error if any object or module\n");
+               log("        matching the selection is found.\n");
                log("\n");
                log("    -assert-any\n");
                log("        do not modify the current selection. instead assert that the given\n");
-               log("        selection is non-empty. i.e. produce an error if no object matching\n");
-               log("        the selection is found.\n");
+               log("        selection is non-empty. i.e. produce an error if no object or module\n");
+               log("        matching the selection is found.\n");
                log("\n");
                log("    -assert-count N\n");
                log("        do not modify the current selection. instead assert that the given\n");
@@ -1488,7 +1490,7 @@ struct SelectPass : public Pass {
                        {
                                RTLIL::Selection *sel = &work_stack.back();
                                sel->optimize(design);
-                               std::string desc = describe_selection_for_assert(design, sel);
+                               std::string desc = describe_selection_for_assert(design, sel, true);
                                log_error("Assertion failed: selection is not empty:%s\n%s", sel_str.c_str(), desc.c_str());
                        }
                        return;
@@ -1503,7 +1505,7 @@ struct SelectPass : public Pass {
                        {
                                RTLIL::Selection *sel = &work_stack.back();
                                sel->optimize(design);
-                               std::string desc = describe_selection_for_assert(design, sel);
+                               std::string desc = describe_selection_for_assert(design, sel, true);
                                log_error("Assertion failed: selection is empty:%s\n%s", sel_str.c_str(), desc.c_str());
                        }
                        return;