Skip to content

Commit ab0c44d

Browse files
committed
Added %R select expression
1 parent 5e90a78 commit ab0c44d

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

passes/cmds/select.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,47 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs)
180180
lhs.selected_members.swap(new_sel.selected_members);
181181
}
182182

183+
static int my_xorshift32_rng() {
184+
static uint32_t x32 = 314159265;
185+
x32 ^= x32 << 13;
186+
x32 ^= x32 >> 17;
187+
x32 ^= x32 << 5;
188+
return x32 & 0x0fffffff;
189+
}
190+
191+
static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int count)
192+
{
193+
vector<pair<IdString, IdString>> objects;
194+
195+
for (auto mod : design->modules())
196+
{
197+
if (!lhs.selected_module(mod->name))
198+
continue;
199+
200+
for (auto cell : mod->cells()) {
201+
if (lhs.selected_member(mod->name, cell->name))
202+
objects.push_back(make_pair(mod->name, cell->name));
203+
}
204+
205+
for (auto wire : mod->wires()) {
206+
if (lhs.selected_member(mod->name, wire->name))
207+
objects.push_back(make_pair(mod->name, wire->name));
208+
}
209+
}
210+
211+
lhs = RTLIL::Selection(false);
212+
213+
while (!objects.empty() && count-- > 0)
214+
{
215+
int idx = my_xorshift32_rng() % GetSize(objects);
216+
lhs.selected_members[objects[idx].first].insert(objects[idx].second);
217+
objects[idx] = objects.back();
218+
objects.pop_back();
219+
}
220+
221+
lhs.optimize(design);
222+
}
223+
183224
static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
184225
{
185226
for (auto &mod_it : design->modules_)
@@ -634,6 +675,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
634675
select_op_intersect(design, work_stack[work_stack.size()-2], work_stack[work_stack.size()-1]);
635676
work_stack.pop_back();
636677
} else
678+
if (arg.size() >= 2 && arg[0] == '%' && arg[1] == 'R') {
679+
if (work_stack.size() < 1)
680+
log_cmd_error("Must have at least one element on the stack for operator %%R.\n");
681+
int count = arg.size() > 2 ? atoi(arg.c_str() + 2) : 1;
682+
select_op_random(design, work_stack[work_stack.size()-1], count);
683+
} else
637684
if (arg == "%s") {
638685
if (work_stack.size() < 1)
639686
log_cmd_error("Must have at least one element on the stack for operator %%s.\n");
@@ -1100,6 +1147,9 @@ struct SelectPass : public Pass {
11001147
log(" %%C\n");
11011148
log(" select cells that implement selected modules\n");
11021149
log("\n");
1150+
log(" %%R[<num>]\n");
1151+
log(" select <num> random objects from top selection (default 1)\n");
1152+
log("\n");
11031153
log("Example: the following command selects all wires that are connected to a\n");
11041154
log("'GATE' input of a 'SWITCH' cell:\n");
11051155
log("\n");

0 commit comments

Comments
 (0)