@@ -180,6 +180,47 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs)
180
180
lhs.selected_members .swap (new_sel.selected_members );
181
181
}
182
182
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
+
183
224
static void select_op_submod (RTLIL::Design *design, RTLIL::Selection &lhs)
184
225
{
185
226
for (auto &mod_it : design->modules_ )
@@ -634,6 +675,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
634
675
select_op_intersect (design, work_stack[work_stack.size ()-2 ], work_stack[work_stack.size ()-1 ]);
635
676
work_stack.pop_back ();
636
677
} 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
637
684
if (arg == " %s" ) {
638
685
if (work_stack.size () < 1 )
639
686
log_cmd_error (" Must have at least one element on the stack for operator %%s.\n " );
@@ -1100,6 +1147,9 @@ struct SelectPass : public Pass {
1100
1147
log (" %%C\n " );
1101
1148
log (" select cells that implement selected modules\n " );
1102
1149
log (" \n " );
1150
+ log (" %%R[<num>]\n " );
1151
+ log (" select <num> random objects from top selection (default 1)\n " );
1152
+ log (" \n " );
1103
1153
log (" Example: the following command selects all wires that are connected to a\n " );
1104
1154
log (" 'GATE' input of a 'SWITCH' cell:\n " );
1105
1155
log (" \n " );
0 commit comments