summaryrefslogtreecommitdiff
path: root/passes/cmds/select.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-12-20 13:35:58 +0100
committerClifford Wolf <clifford@clifford.at>2015-12-20 13:35:58 +0100
commitab0c44d3ed81f71cb0c6ff844679110cc27b38ad (patch)
tree5deff3288c2df8c4b4ee66f67b99849de90af65a /passes/cmds/select.cc
parent5e90a78466bf072c68cae36d218974cd7d184c88 (diff)
Added %R select expression
Diffstat (limited to 'passes/cmds/select.cc')
-rw-r--r--passes/cmds/select.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc
index d05000eb..3e64dd84 100644
--- a/passes/cmds/select.cc
+++ b/passes/cmds/select.cc
@@ -180,6 +180,47 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs)
lhs.selected_members.swap(new_sel.selected_members);
}
+static int my_xorshift32_rng() {
+ static uint32_t x32 = 314159265;
+ x32 ^= x32 << 13;
+ x32 ^= x32 >> 17;
+ x32 ^= x32 << 5;
+ return x32 & 0x0fffffff;
+}
+
+static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int count)
+{
+ vector<pair<IdString, IdString>> objects;
+
+ for (auto mod : design->modules())
+ {
+ if (!lhs.selected_module(mod->name))
+ continue;
+
+ for (auto cell : mod->cells()) {
+ if (lhs.selected_member(mod->name, cell->name))
+ objects.push_back(make_pair(mod->name, cell->name));
+ }
+
+ for (auto wire : mod->wires()) {
+ if (lhs.selected_member(mod->name, wire->name))
+ objects.push_back(make_pair(mod->name, wire->name));
+ }
+ }
+
+ lhs = RTLIL::Selection(false);
+
+ while (!objects.empty() && count-- > 0)
+ {
+ int idx = my_xorshift32_rng() % GetSize(objects);
+ lhs.selected_members[objects[idx].first].insert(objects[idx].second);
+ objects[idx] = objects.back();
+ objects.pop_back();
+ }
+
+ lhs.optimize(design);
+}
+
static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
{
for (auto &mod_it : design->modules_)
@@ -634,6 +675,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
select_op_intersect(design, work_stack[work_stack.size()-2], work_stack[work_stack.size()-1]);
work_stack.pop_back();
} else
+ if (arg.size() >= 2 && arg[0] == '%' && arg[1] == 'R') {
+ if (work_stack.size() < 1)
+ log_cmd_error("Must have at least one element on the stack for operator %%R.\n");
+ int count = arg.size() > 2 ? atoi(arg.c_str() + 2) : 1;
+ select_op_random(design, work_stack[work_stack.size()-1], count);
+ } else
if (arg == "%s") {
if (work_stack.size() < 1)
log_cmd_error("Must have at least one element on the stack for operator %%s.\n");
@@ -1100,6 +1147,9 @@ struct SelectPass : public Pass {
log(" %%C\n");
log(" select cells that implement selected modules\n");
log("\n");
+ log(" %%R[<num>]\n");
+ log(" select <num> random objects from top selection (default 1)\n");
+ log("\n");
log("Example: the following command selects all wires that are connected to a\n");
log("'GATE' input of a 'SWITCH' cell:\n");
log("\n");