static std::vector<RTLIL::Selection> work_stack;
-static bool match_ids(RTLIL::IdString id, std::string pattern)
+static bool match_ids(RTLIL::IdString id, const std::string &pattern)
{
if (id == pattern)
return true;
- if (id.size() > 0 && id[0] == '\\' && id.compare(1, std::string::npos, pattern.c_str()) == 0)
+
+ const char *id_c = id.c_str();
+ const char *pat_c = pattern.c_str();
+ size_t id_size = strlen(id_c);
+ size_t pat_size = pattern.size();
+
+ if (*id_c == '\\' && id_size == 1 + pat_size && memcmp(id_c + 1, pat_c, pat_size) == 0)
return true;
- if (patmatch(pattern.c_str(), id.c_str()))
+ if (patmatch(pat_c, id_c))
return true;
- if (id.size() > 0 && id[0] == '\\' && patmatch(pattern.c_str(), id.substr(1).c_str()))
+ if (*id_c == '\\' && patmatch(pat_c, id_c + 1))
return true;
- if (id.size() > 0 && id[0] == '$' && pattern.size() > 0 && pattern[0] == '$') {
- const char *p = id.c_str();
- const char *q = strrchr(p, '$');
+ if (*id_c == '$' && *pat_c == '$') {
+ const char *q = strrchr(id_c, '$');
if (pattern == q)
return true;
}
return false;
}
-static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char match_op)
+static bool match_attr_val(const RTLIL::Const &value, const std::string &pattern, char match_op)
{
if (match_op == 0)
return true;
log_abort();
}
-static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, std::string name_pat, std::string value_pat, char match_op)
+static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, const std::string &name_pat, const std::string &value_pat, char match_op)
{
if (name_pat.find('*') != std::string::npos || name_pat.find('?') != std::string::npos || name_pat.find('[') != std::string::npos) {
for (auto &it : attributes) {
return false;
}
-static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, std::string match_expr)
+static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, const std::string &match_expr)
{
size_t pos = match_expr.find_first_of("<!=>");
};
}
-static int parse_comma_list(std::set<RTLIL::IdString> &tokens, std::string str, size_t pos, std::string stopchar)
+static int parse_comma_list(std::set<RTLIL::IdString> &tokens, const std::string &str, size_t pos, std::string stopchar)
{
stopchar += ',';
while (1) {
return sel_objects;
}
-static void select_op_expand(RTLIL::Design *design, std::string arg, char mode, bool eval_only)
+static void select_op_expand(RTLIL::Design *design, const std::string &arg, char mode, bool eval_only)
{
int pos = (mode == 'x' ? 2 : 3) + (eval_only ? 1 : 0);
int levels = 1, rem_objects = -1;
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] == ':';
+
+ auto isprefixed = [](const string &s) {
+ return GetSize(s) >= 2 && ((s[0] >= 'a' && s[0] <= 'z') || (s[0] >= 'A' && s[0] <= 'Z')) && s[1] == ':';
+ };
if (arg.size() == 0)
return;
return;
}
+ bool select_blackboxes = false;
+ if (arg.substr(0, 1) == "=") {
+ arg = arg.substr(1);
+ select_blackboxes = true;
+ }
+
if (!design->selected_active_module.empty()) {
arg_mod = design->selected_active_module;
arg_memb = arg;
- if (!prefixed) arg_memb_found[arg_memb] = false;
+ if (!isprefixed(arg_memb))
+ arg_memb_found[arg_memb] = false;
} else
- if (prefixed && arg[0] >= 'a' && arg[0] <= 'z') {
+ if (isprefixed(arg) && arg[0] >= 'a' && arg[0] <= 'z') {
arg_mod = "*", arg_memb = arg;
} else {
size_t pos = arg.find('/');
if (pos == std::string::npos) {
arg_mod = arg;
- if (!prefixed) arg_mod_found[arg_mod] = false;
+ if (!isprefixed(arg_mod))
+ arg_mod_found[arg_mod] = false;
} else {
arg_mod = arg.substr(0, pos);
- if (!prefixed) arg_mod_found[arg_mod] = false;
+ if (!isprefixed(arg_mod))
+ arg_mod_found[arg_mod] = false;
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;
+ if (!isprefixed(arg_memb))
+ arg_memb_found[arg_memb] = false;
}
}
work_stack.push_back(RTLIL::Selection());
RTLIL::Selection &sel = work_stack.back();
- if (arg == "*" && arg_mod == "*") {
+ if (arg == "*" && arg_mod == "*" && select_blackboxes) {
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())
+ continue;
+
if (arg_mod.compare(0, 2, "A:") == 0) {
if (!match_attr(mod->attributes, arg_mod.substr(2)))
continue;
YOSYS_NAMESPACE_BEGIN
// used in kernel/register.cc and maybe other locations, extern decl. in register.h
-void handle_extra_select_args(Pass *pass, vector<string> args, size_t argidx, size_t args_size, RTLIL::Design *design)
+void handle_extra_select_args(Pass *pass, const vector<string> &args, size_t argidx, size_t args_size, RTLIL::Design *design)
{
work_stack.clear();
for (; argidx < args_size; argidx++) {
struct SelectPass : public Pass {
SelectPass() : Pass("select", "modify and view the list of selected objects") { }
- void help() YS_OVERRIDE
+ void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" select [ -add | -del | -set <name> ] {-read <filename> | <selection>}\n");
+ log(" select [ -unset <name> ]\n");
log(" select [ <assert_option> ] {-read <filename> | <selection>}\n");
log(" select [ -list | -write <filename> | -count | -clear ]\n");
log(" select -module <modname>\n");
log(" under the given name (see @<name> below). to save the current selection,\n");
log(" use \"select -set <name> %%\"\n");
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("\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(" <obj_pattern>\n");
log(" select the specified object(s) from the current module\n");
log("\n");
+ log("By default, patterns will not match black/white-box modules or their");
+ log("contents. To include such objects, prefix the pattern with '='.\n");
+ log("\n");
log("A <mod_pattern> can be a module name, wildcard expression (*, ?, [..])\n");
log("matching module names, or one of the following:\n");
log("\n");
log(" select */t:SWITCH %%x:+[GATE] */t:SWITCH %%d\n");
log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
bool add_mode = false;
bool del_mode = false;
int assert_max = -1;
int assert_min = -1;
std::string write_file, read_file;
- std::string set_name, sel_str;
+ std::string set_name, unset_name, sel_str;
work_stack.clear();
set_name = RTLIL::escape_id(args[++argidx]);
continue;
}
+ if (arg == "-unset" && argidx+1 < args.size()) {
+ unset_name = RTLIL::escape_id(args[++argidx]);
+ continue;
+ }
if (arg.size() > 0 && arg[0] == '-')
log_cmd_error("Unknown option %s.\n", arg.c_str());
bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_count != -1) || (assert_max != -1) || (assert_min != -1);
if ((list_mode || !write_file.empty() || count_mode) && (add_mode || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0))
log_cmd_error("Options -list, -write and -count can not be combined with -add, -del, -assert-none, -assert-any, assert-count, -assert-max, or -assert-min.\n");
- if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0))
- log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -assert-none, -assert-any, -assert-count, -assert-max, or -assert-min.\n");
+ if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || !unset_name.empty() || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0))
+ log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -unset, -assert-none, -assert-any, -assert-count, -assert-max, or -assert-min.\n");
+
+ if (!unset_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || !set_name.empty() || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0))
+ log_cmd_error("Option -unset can not be combined with -list, -write, -count, -add, -del, -set, -assert-none, -assert-any, -assert-count, -assert-max, or -assert-min.\n");
if (work_stack.size() == 0 && got_module) {
RTLIL::Selection sel;
return;
}
+ if (!unset_name.empty())
+ {
+ if (!design->selection_vars.erase(unset_name))
+ log_error("Selection '%s' does not exist!\n", unset_name.c_str());
+ return;
+ }
+
if (work_stack.size() == 0) {
RTLIL::Selection &sel = design->selection_stack.back();
if (sel.full_selection)
struct CdPass : public Pass {
CdPass() : Pass("cd", "a shortcut for 'select -module <name>'") { }
- void help() YS_OVERRIDE
+ void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log("This is just a shortcut for 'select -clear'.\n");
log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
if (args.size() != 1 && args.size() != 2)
log_cmd_error("Invalid number of arguments.\n");
} CdPass;
template<typename T>
-static void log_matches(const char *title, Module *module, T list)
+static void log_matches(const char *title, Module *module, const T &list)
{
std::vector<IdString> matches;
struct LsPass : public Pass {
LsPass() : Pass("ls", "list modules or objects in modules") { }
- void help() YS_OVERRIDE
+ void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log("When an active module is selected, this prints a list of objects in the module.\n");
log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
size_t argidx = 1;
extra_args(args, argidx, design);