diff options
Diffstat (limited to 'kernel/select.cc')
-rw-r--r-- | kernel/select.cc | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/kernel/select.cc b/kernel/select.cc index a6e675c88..fa1c3db02 100644 --- a/kernel/select.cc +++ b/kernel/select.cc @@ -346,8 +346,18 @@ static void select_op_expand(RTLIL::Design *design, std::string arg, char mode) size_t endpos = arg.find(':', pos); if (endpos == std::string::npos) endpos = arg.size(); - if (int(endpos) > pos) - limits.insert(RTLIL::escape_id(arg.substr(pos, endpos-pos))); + if (int(endpos) > pos) { + std::string str = arg.substr(pos, endpos-pos); + if (str[0] == '@') { + str = RTLIL::escape_id(str.substr(1)); + if (design->selection_vars.count(str) > 0) { + for (auto i1 : design->selection_vars.at(str).selected_members) + for (auto i2 : i1.second) + limits.insert(i2); + } + } else + limits.insert(RTLIL::escape_id(str)); + } pos = endpos; } } @@ -471,7 +481,8 @@ static void select_stmt(RTLIL::Design *design, std::string arg) select_op_expand(design, arg, 'o'); } else log_cmd_error("Unknown selection operator '%s'.\n", arg.c_str()); - select_filter_active_mod(design, work_stack.back()); + if (work_stack.size() >= 1) + select_filter_active_mod(design, work_stack.back()); return; } @@ -585,20 +596,27 @@ static void select_stmt(RTLIL::Design *design, std::string arg) select_filter_active_mod(design, work_stack.back()); } -// used in kernel/register.cc -void handle_extra_select_args(Pass *pass, std::vector<std::string> args, size_t argidx, RTLIL::Design *design) +// used in kernel/register.cc and maybe other locations, extern decl. in register.h +void handle_extra_select_args(Pass *pass, std::vector<std::string> args, size_t argidx, size_t args_size, RTLIL::Design *design) { work_stack.clear(); - for (; argidx < args.size(); argidx++) { - if (args[argidx].substr(0, 1) == "-") - pass->cmd_error(args, argidx, "Unexpected option in selection arguments."); + for (; argidx < args_size; argidx++) { + if (args[argidx].substr(0, 1) == "-") { + if (pass != NULL) + pass->cmd_error(args, argidx, "Unexpected option in selection arguments."); + else + log_cmd_error("Unexpected option in selection arguments."); + } select_stmt(design, args[argidx]); } while (work_stack.size() > 1) { select_op_union(design, work_stack.front(), work_stack.back()); work_stack.pop_back(); } - design->selection_stack.push_back(work_stack.back()); + if (work_stack.size() > 0) + design->selection_stack.push_back(work_stack.back()); + else + design->selection_stack.push_back(RTLIL::Selection(false)); } struct SelectPass : public Pass { |