Moved patmatch() to yosys.cc
[yosys.git] / passes / cmds / select.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20 #include "kernel/yosys.h"
21 #include "kernel/celltypes.h"
22 #include "kernel/sigtools.h"
23 #include <string.h>
24 #include <errno.h>
25
26 USING_YOSYS_NAMESPACE
27 PRIVATE_NAMESPACE_BEGIN
28
29 using RTLIL::id2cstr;
30
31 static std::vector<RTLIL::Selection> work_stack;
32
33 static bool match_ids(RTLIL::IdString id, std::string pattern)
34 {
35 if (id == pattern)
36 return true;
37 if (id.size() > 0 && id[0] == '\\' && id.substr(1) == pattern)
38 return true;
39 if (patmatch(pattern.c_str(), id.c_str()))
40 return true;
41 if (id.size() > 0 && id[0] == '\\' && patmatch(pattern.c_str(), id.substr(1).c_str()))
42 return true;
43 if (id.size() > 0 && id[0] == '$' && pattern.size() > 0 && pattern[0] == '$') {
44 const char *p = id.c_str();
45 const char *q = strrchr(p, '$');
46 if (pattern == q)
47 return true;
48 }
49 return false;
50 }
51
52 static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char match_op)
53 {
54 if (match_op == 0)
55 return true;
56
57 if ((value.flags & RTLIL::CONST_FLAG_STRING) == 0)
58 {
59 RTLIL::SigSpec sig_value;
60
61 if (!RTLIL::SigSpec::parse(sig_value, NULL, pattern))
62 return false;
63
64 RTLIL::Const pattern_value = sig_value.as_const();
65
66 if (match_op == '=')
67 return value == pattern_value;
68 if (match_op == '!')
69 return value != pattern_value;
70 if (match_op == '<')
71 return value.as_int() < pattern_value.as_int();
72 if (match_op == '>')
73 return value.as_int() > pattern_value.as_int();
74 if (match_op == '[')
75 return value.as_int() <= pattern_value.as_int();
76 if (match_op == ']')
77 return value.as_int() >= pattern_value.as_int();
78 }
79 else
80 {
81 std::string value_str = value.decode_string();
82
83 if (match_op == '=')
84 if (patmatch(pattern.c_str(), value.decode_string().c_str()))
85 return true;
86
87 if (match_op == '=')
88 return value_str == pattern;
89 if (match_op == '!')
90 return value_str != pattern;
91 if (match_op == '<')
92 return value_str < pattern;
93 if (match_op == '>')
94 return value_str > pattern;
95 if (match_op == '[')
96 return value_str <= pattern;
97 if (match_op == ']')
98 return value_str >= pattern;
99 }
100
101 log_abort();
102 }
103
104 static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes, std::string name_pat, std::string value_pat, char match_op)
105 {
106 if (name_pat.find('*') != std::string::npos || name_pat.find('?') != std::string::npos || name_pat.find('[') != std::string::npos) {
107 for (auto &it : attributes) {
108 if (patmatch(name_pat.c_str(), it.first.c_str()) && match_attr_val(it.second, value_pat, match_op))
109 return true;
110 if (it.first.size() > 0 && it.first[0] == '\\' && patmatch(name_pat.c_str(), it.first.substr(1).c_str()) && match_attr_val(it.second, value_pat, match_op))
111 return true;
112 }
113 } else {
114 if (name_pat.size() > 0 && (name_pat[0] == '\\' || name_pat[0] == '$') && attributes.count(name_pat) && match_attr_val(attributes.at(name_pat), value_pat, match_op))
115 return true;
116 if (attributes.count("\\" + name_pat) && match_attr_val(attributes.at("\\" + name_pat), value_pat, match_op))
117 return true;
118 }
119 return false;
120 }
121
122 static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes, std::string match_expr)
123 {
124 size_t pos = match_expr.find_first_of("<!=>");
125
126 if (pos != std::string::npos) {
127 if (match_expr.substr(pos, 2) == "!=")
128 return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '!');
129 if (match_expr.substr(pos, 2) == "<=")
130 return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '[');
131 if (match_expr.substr(pos, 2) == ">=")
132 return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), ']');
133 return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+1), match_expr[pos]);
134 }
135
136 return match_attr(attributes, match_expr, std::string(), 0);
137 }
138
139 static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs)
140 {
141 if (lhs.full_selection) {
142 lhs.full_selection = false;
143 lhs.selected_modules.clear();
144 lhs.selected_members.clear();
145 return;
146 }
147
148 if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) {
149 lhs.full_selection = true;
150 return;
151 }
152
153 RTLIL::Selection new_sel(false);
154
155 for (auto &mod_it : design->modules_)
156 {
157 if (lhs.selected_whole_module(mod_it.first))
158 continue;
159 if (!lhs.selected_module(mod_it.first)) {
160 new_sel.selected_modules.insert(mod_it.first);
161 continue;
162 }
163
164 RTLIL::Module *mod = mod_it.second;
165 for (auto &it : mod->wires_)
166 if (!lhs.selected_member(mod_it.first, it.first))
167 new_sel.selected_members[mod->name].insert(it.first);
168 for (auto &it : mod->memories)
169 if (!lhs.selected_member(mod_it.first, it.first))
170 new_sel.selected_members[mod->name].insert(it.first);
171 for (auto &it : mod->cells_)
172 if (!lhs.selected_member(mod_it.first, it.first))
173 new_sel.selected_members[mod->name].insert(it.first);
174 for (auto &it : mod->processes)
175 if (!lhs.selected_member(mod_it.first, it.first))
176 new_sel.selected_members[mod->name].insert(it.first);
177 }
178
179 lhs.selected_modules.swap(new_sel.selected_modules);
180 lhs.selected_members.swap(new_sel.selected_members);
181 }
182
183 static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
184 {
185 for (auto &mod_it : design->modules_)
186 {
187 if (lhs.selected_whole_module(mod_it.first))
188 {
189 for (auto &cell_it : mod_it.second->cells_)
190 {
191 if (design->modules_.count(cell_it.second->type) == 0)
192 continue;
193 lhs.selected_modules.insert(cell_it.second->type);
194 }
195 }
196 }
197 }
198
199 static void select_op_fullmod(RTLIL::Design *design, RTLIL::Selection &lhs)
200 {
201 lhs.optimize(design);
202 for (auto &it : lhs.selected_members)
203 lhs.selected_modules.insert(it.first);
204 lhs.selected_members.clear();
205 }
206
207 static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs)
208 {
209 for (auto &mod_it : design->modules_)
210 {
211 if (lhs.selected_whole_module(mod_it.first))
212 continue;
213 if (!lhs.selected_module(mod_it.first))
214 continue;
215
216 SigMap sigmap(mod_it.second);
217 SigPool selected_bits;
218
219 for (auto &it : mod_it.second->wires_)
220 if (lhs.selected_member(mod_it.first, it.first))
221 selected_bits.add(sigmap(it.second));
222
223 for (auto &it : mod_it.second->wires_)
224 if (!lhs.selected_member(mod_it.first, it.first) && selected_bits.check_any(sigmap(it.second)))
225 lhs.selected_members[mod_it.first].insert(it.first);
226 }
227 }
228
229 static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL::Selection &rhs)
230 {
231 if (rhs.full_selection) {
232 lhs.full_selection = true;
233 lhs.selected_modules.clear();
234 lhs.selected_members.clear();
235 return;
236 }
237
238 if (lhs.full_selection)
239 return;
240
241 for (auto &it : rhs.selected_members)
242 for (auto &it2 : it.second)
243 lhs.selected_members[it.first].insert(it2);
244
245 for (auto &it : rhs.selected_modules) {
246 lhs.selected_modules.insert(it);
247 lhs.selected_members.erase(it);
248 }
249 }
250
251 static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs)
252 {
253 if (rhs.full_selection) {
254 lhs.full_selection = false;
255 lhs.selected_modules.clear();
256 lhs.selected_members.clear();
257 return;
258 }
259
260 if (lhs.full_selection) {
261 if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0)
262 return;
263 lhs.full_selection = false;
264 for (auto &it : design->modules_)
265 lhs.selected_modules.insert(it.first);
266 }
267
268 for (auto &it : rhs.selected_modules) {
269 lhs.selected_modules.erase(it);
270 lhs.selected_members.erase(it);
271 }
272
273 for (auto &it : rhs.selected_members)
274 {
275 if (design->modules_.count(it.first) == 0)
276 continue;
277
278 RTLIL::Module *mod = design->modules_[it.first];
279
280 if (lhs.selected_modules.count(mod->name) > 0)
281 {
282 for (auto &it : mod->wires_)
283 lhs.selected_members[mod->name].insert(it.first);
284 for (auto &it : mod->memories)
285 lhs.selected_members[mod->name].insert(it.first);
286 for (auto &it : mod->cells_)
287 lhs.selected_members[mod->name].insert(it.first);
288 for (auto &it : mod->processes)
289 lhs.selected_members[mod->name].insert(it.first);
290 lhs.selected_modules.erase(mod->name);
291 }
292
293 if (lhs.selected_members.count(mod->name) == 0)
294 continue;
295
296 for (auto &it2 : it.second)
297 lhs.selected_members[mod->name].erase(it2);
298 }
299 }
300
301 static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs)
302 {
303 if (rhs.full_selection)
304 return;
305
306 if (lhs.full_selection) {
307 lhs.full_selection = false;
308 for (auto &it : design->modules_)
309 lhs.selected_modules.insert(it.first);
310 }
311
312 std::vector<RTLIL::IdString> del_list;
313
314 for (auto &it : lhs.selected_modules)
315 if (rhs.selected_modules.count(it) == 0) {
316 if (rhs.selected_members.count(it) > 0)
317 for (auto &it2 : rhs.selected_members.at(it))
318 lhs.selected_members[it].insert(it2);
319 del_list.push_back(it);
320 }
321 for (auto &it : del_list)
322 lhs.selected_modules.erase(it);
323
324 del_list.clear();
325 for (auto &it : lhs.selected_members) {
326 if (rhs.selected_modules.count(it.first) > 0)
327 continue;
328 if (rhs.selected_members.count(it.first) == 0) {
329 del_list.push_back(it.first);
330 continue;
331 }
332 std::vector<RTLIL::IdString> del_list2;
333 for (auto &it2 : it.second)
334 if (rhs.selected_members.at(it.first).count(it2) == 0)
335 del_list2.push_back(it2);
336 for (auto &it2 : del_list2)
337 it.second.erase(it2);
338 if (it.second.size() == 0)
339 del_list.push_back(it.first);
340 }
341 for (auto &it : del_list)
342 lhs.selected_members.erase(it);
343 }
344
345 namespace {
346 struct expand_rule_t {
347 char mode;
348 std::set<RTLIL::IdString> cell_types, port_names;
349 };
350 }
351
352 static int parse_comma_list(std::set<RTLIL::IdString> &tokens, std::string str, size_t pos, std::string stopchar)
353 {
354 stopchar += ',';
355 while (1) {
356 size_t endpos = str.find_first_of(stopchar, pos);
357 if (endpos == std::string::npos)
358 endpos = str.size();
359 if (endpos != pos)
360 tokens.insert(RTLIL::escape_id(str.substr(pos, endpos-pos)));
361 pos = endpos;
362 if (pos == str.size() || str[pos] != ',')
363 return pos;
364 pos++;
365 }
366 }
367
368 static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector<expand_rule_t> &rules, std::set<RTLIL::IdString> &limits, int max_objects, char mode, CellTypes &ct)
369 {
370 int sel_objects = 0;
371 bool is_input, is_output;
372 for (auto &mod_it : design->modules_)
373 {
374 if (lhs.selected_whole_module(mod_it.first) || !lhs.selected_module(mod_it.first))
375 continue;
376
377 RTLIL::Module *mod = mod_it.second;
378 std::set<RTLIL::Wire*> selected_wires;
379
380 for (auto &it : mod->wires_)
381 if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0)
382 selected_wires.insert(it.second);
383
384 for (auto &conn : mod->connections())
385 {
386 std::vector<RTLIL::SigBit> conn_lhs = conn.first.to_sigbit_vector();
387 std::vector<RTLIL::SigBit> conn_rhs = conn.second.to_sigbit_vector();
388
389 for (size_t i = 0; i < conn_lhs.size(); i++) {
390 if (conn_lhs[i].wire == NULL || conn_rhs[i].wire == NULL)
391 continue;
392 if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && lhs.selected_members[mod->name].count(conn_lhs[i].wire->name) == 0)
393 lhs.selected_members[mod->name].insert(conn_lhs[i].wire->name), sel_objects++, max_objects--;
394 if (mode != 'o' && selected_wires.count(conn_lhs[i].wire) && lhs.selected_members[mod->name].count(conn_rhs[i].wire->name) == 0)
395 lhs.selected_members[mod->name].insert(conn_rhs[i].wire->name), sel_objects++, max_objects--;
396 }
397 }
398
399 for (auto &cell : mod->cells_)
400 for (auto &conn : cell.second->connections())
401 {
402 char last_mode = '-';
403 for (auto &rule : rules) {
404 last_mode = rule.mode;
405 if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type) == 0)
406 continue;
407 if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0)
408 continue;
409 if (rule.mode == '+')
410 goto include_match;
411 else
412 goto exclude_match;
413 }
414 if (last_mode == '+')
415 goto exclude_match;
416 include_match:
417 is_input = mode == 'x' || ct.cell_input(cell.second->type, conn.first);
418 is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first);
419 for (auto &chunk : conn.second.chunks())
420 if (chunk.wire != NULL) {
421 if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && lhs.selected_members[mod->name].count(cell.first) == 0)
422 if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input))
423 lhs.selected_members[mod->name].insert(cell.first), sel_objects++, max_objects--;
424 if (max_objects != 0 && lhs.selected_members[mod->name].count(cell.first) > 0 && limits.count(cell.first) == 0 && lhs.selected_members[mod->name].count(chunk.wire->name) == 0)
425 if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output))
426 lhs.selected_members[mod->name].insert(chunk.wire->name), sel_objects++, max_objects--;
427 }
428 exclude_match:;
429 }
430 }
431
432 return sel_objects;
433 }
434
435 static void select_op_expand(RTLIL::Design *design, std::string arg, char mode)
436 {
437 int pos = mode == 'x' ? 2 : 3, levels = 1, rem_objects = -1;
438 std::vector<expand_rule_t> rules;
439 std::set<RTLIL::IdString> limits;
440
441 CellTypes ct;
442
443 if (mode != 'x')
444 ct.setup(design);
445
446 if (pos < int(arg.size()) && arg[pos] == '*') {
447 levels = 1000000;
448 pos++;
449 } else
450 if (pos < int(arg.size()) && '0' <= arg[pos] && arg[pos] <= '9') {
451 size_t endpos = arg.find_first_not_of("0123456789", pos);
452 if (endpos == std::string::npos)
453 endpos = arg.size();
454 levels = atoi(arg.substr(pos, endpos-pos).c_str());
455 pos = endpos;
456 }
457
458 if (pos < int(arg.size()) && arg[pos] == '.') {
459 size_t endpos = arg.find_first_not_of("0123456789", ++pos);
460 if (endpos == std::string::npos)
461 endpos = arg.size();
462 if (int(endpos) > pos)
463 rem_objects = atoi(arg.substr(pos, endpos-pos).c_str());
464 pos = endpos;
465 }
466
467 while (pos < int(arg.size())) {
468 if (arg[pos] != ':' || pos+1 == int(arg.size()))
469 log_cmd_error("Syntax error in expand operator '%s'.\n", arg.c_str());
470 pos++;
471 if (arg[pos] == '+' || arg[pos] == '-') {
472 expand_rule_t rule;
473 rule.mode = arg[pos++];
474 pos = parse_comma_list(rule.cell_types, arg, pos, "[:");
475 if (pos < int(arg.size()) && arg[pos] == '[') {
476 pos = parse_comma_list(rule.port_names, arg, pos+1, "]:");
477 if (pos < int(arg.size()) && arg[pos] == ']')
478 pos++;
479 }
480 rules.push_back(rule);
481 } else {
482 size_t endpos = arg.find(':', pos);
483 if (endpos == std::string::npos)
484 endpos = arg.size();
485 if (int(endpos) > pos) {
486 std::string str = arg.substr(pos, endpos-pos);
487 if (str[0] == '@') {
488 str = RTLIL::escape_id(str.substr(1));
489 if (design->selection_vars.count(str) > 0) {
490 for (auto i1 : design->selection_vars.at(str).selected_members)
491 for (auto i2 : i1.second)
492 limits.insert(i2);
493 } else
494 log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str).c_str());
495 } else
496 limits.insert(RTLIL::escape_id(str));
497 }
498 pos = endpos;
499 }
500 }
501
502 #if 0
503 log("expand by %d levels (max. %d objects):\n", levels, rem_objects);
504 for (auto &rule : rules) {
505 log(" rule (%c):\n", rule.mode);
506 if (rule.cell_types.size() > 0) {
507 log(" cell types:");
508 for (auto &it : rule.cell_types)
509 log(" %s", it.c_str());
510 log("\n");
511 }
512 if (rule.port_names.size() > 0) {
513 log(" port names:");
514 for (auto &it : rule.port_names)
515 log(" %s", it.c_str());
516 log("\n");
517 }
518 }
519 if (limits.size() > 0) {
520 log(" limits:");
521 for (auto &it : limits)
522 log(" %s", it.c_str());
523 log("\n");
524 }
525 #endif
526
527 while (levels-- > 0 && rem_objects != 0) {
528 int num_objects = select_op_expand(design, work_stack.back(), rules, limits, rem_objects, mode, ct);
529 if (num_objects == 0)
530 break;
531 rem_objects -= num_objects;
532 }
533
534 if (rem_objects == 0)
535 log("Warning: reached configured limit at `%s'.\n", arg.c_str());
536 }
537
538 static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &sel)
539 {
540 if (design->selected_active_module.empty())
541 return;
542
543 if (sel.full_selection) {
544 sel.full_selection = false;
545 sel.selected_modules.clear();
546 sel.selected_members.clear();
547 sel.selected_modules.insert(design->selected_active_module);
548 return;
549 }
550
551 std::vector<RTLIL::IdString> del_list;
552 for (auto mod_name : sel.selected_modules)
553 if (mod_name != design->selected_active_module)
554 del_list.push_back(mod_name);
555 for (auto &it : sel.selected_members)
556 if (it.first != design->selected_active_module)
557 del_list.push_back(it.first);
558 for (auto mod_name : del_list) {
559 sel.selected_modules.erase(mod_name);
560 sel.selected_members.erase(mod_name);
561 }
562 }
563
564 static void select_stmt(RTLIL::Design *design, std::string arg)
565 {
566 std::string arg_mod, arg_memb;
567
568 if (arg.size() == 0)
569 return;
570
571 if (arg[0] == '%') {
572 if (arg == "%") {
573 if (design->selection_stack.size() > 0)
574 work_stack.push_back(design->selection_stack.back());
575 } else
576 if (arg == "%%") {
577 while (work_stack.size() > 1) {
578 select_op_union(design, work_stack.front(), work_stack.back());
579 work_stack.pop_back();
580 }
581 } else
582 if (arg == "%n") {
583 if (work_stack.size() < 1)
584 log_cmd_error("Must have at least one element on the stack for operator %%n.\n");
585 select_op_neg(design, work_stack[work_stack.size()-1]);
586 } else
587 if (arg == "%u") {
588 if (work_stack.size() < 2)
589 log_cmd_error("Must have at least two elements on the stack for operator %%u.\n");
590 select_op_union(design, work_stack[work_stack.size()-2], work_stack[work_stack.size()-1]);
591 work_stack.pop_back();
592 } else
593 if (arg == "%d") {
594 if (work_stack.size() < 2)
595 log_cmd_error("Must have at least two elements on the stack for operator %%d.\n");
596 select_op_diff(design, work_stack[work_stack.size()-2], work_stack[work_stack.size()-1]);
597 work_stack.pop_back();
598 } else
599 if (arg == "%D") {
600 if (work_stack.size() < 2)
601 log_cmd_error("Must have at least two elements on the stack for operator %%d.\n");
602 select_op_diff(design, work_stack[work_stack.size()-1], work_stack[work_stack.size()-2]);
603 work_stack[work_stack.size()-2] = work_stack[work_stack.size()-1];
604 work_stack.pop_back();
605 } else
606 if (arg == "%i") {
607 if (work_stack.size() < 2)
608 log_cmd_error("Must have at least two elements on the stack for operator %%i.\n");
609 select_op_intersect(design, work_stack[work_stack.size()-2], work_stack[work_stack.size()-1]);
610 work_stack.pop_back();
611 } else
612 if (arg == "%s") {
613 if (work_stack.size() < 1)
614 log_cmd_error("Must have at least one element on the stack for operator %%s.\n");
615 select_op_submod(design, work_stack[work_stack.size()-1]);
616 } else
617 if (arg == "%c") {
618 if (work_stack.size() < 1)
619 log_cmd_error("Must have at least one element on the stack for operator %%c.\n");
620 work_stack.push_back(work_stack.back());
621 } else
622 if (arg == "%m") {
623 if (work_stack.size() < 1)
624 log_cmd_error("Must have at least one element on the stack for operator %%m.\n");
625 select_op_fullmod(design, work_stack[work_stack.size()-1]);
626 } else
627 if (arg == "%a") {
628 if (work_stack.size() < 1)
629 log_cmd_error("Must have at least one element on the stack for operator %%a.\n");
630 select_op_alias(design, work_stack[work_stack.size()-1]);
631 } else
632 if (arg == "%x" || (arg.size() > 2 && arg.substr(0, 2) == "%x" && (arg[2] == ':' || arg[2] == '*' || arg[2] == '.' || ('0' <= arg[2] && arg[2] <= '9')))) {
633 if (work_stack.size() < 1)
634 log_cmd_error("Must have at least one element on the stack for operator %%x.\n");
635 select_op_expand(design, arg, 'x');
636 } else
637 if (arg == "%ci" || (arg.size() > 3 && arg.substr(0, 3) == "%ci" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) {
638 if (work_stack.size() < 1)
639 log_cmd_error("Must have at least one element on the stack for operator %%ci.\n");
640 select_op_expand(design, arg, 'i');
641 } else
642 if (arg == "%co" || (arg.size() > 3 && arg.substr(0, 3) == "%co" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) {
643 if (work_stack.size() < 1)
644 log_cmd_error("Must have at least one element on the stack for operator %%co.\n");
645 select_op_expand(design, arg, 'o');
646 } else
647 log_cmd_error("Unknown selection operator '%s'.\n", arg.c_str());
648 if (work_stack.size() >= 1)
649 select_filter_active_mod(design, work_stack.back());
650 return;
651 }
652
653 if (arg[0] == '@') {
654 std::string set_name = RTLIL::escape_id(arg.substr(1));
655 if (design->selection_vars.count(set_name) > 0)
656 work_stack.push_back(design->selection_vars[set_name]);
657 else
658 log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name).c_str());
659 select_filter_active_mod(design, work_stack.back());
660 return;
661 }
662
663 if (!design->selected_active_module.empty()) {
664 arg_mod = design->selected_active_module;
665 arg_memb = arg;
666 } else {
667 size_t pos = arg.find('/');
668 if (pos == std::string::npos) {
669 if (arg.find(':') == std::string::npos || arg.substr(0, 1) == "A")
670 arg_mod = arg;
671 else
672 arg_mod = "*", arg_memb = arg;
673 } else {
674 arg_mod = arg.substr(0, pos);
675 arg_memb = arg.substr(pos+1);
676 }
677 }
678
679 work_stack.push_back(RTLIL::Selection());
680 RTLIL::Selection &sel = work_stack.back();
681
682 if (arg == "*" && arg_mod == "*") {
683 select_filter_active_mod(design, work_stack.back());
684 return;
685 }
686
687 sel.full_selection = false;
688 for (auto &mod_it : design->modules_)
689 {
690 if (arg_mod.substr(0, 2) == "A:") {
691 if (!match_attr(mod_it.second->attributes, arg_mod.substr(2)))
692 continue;
693 } else
694 if (!match_ids(mod_it.first, arg_mod))
695 continue;
696
697 if (arg_memb == "") {
698 sel.selected_modules.insert(mod_it.first);
699 continue;
700 }
701
702 RTLIL::Module *mod = mod_it.second;
703 if (arg_memb.substr(0, 2) == "w:") {
704 for (auto &it : mod->wires_)
705 if (match_ids(it.first, arg_memb.substr(2)))
706 sel.selected_members[mod->name].insert(it.first);
707 } else
708 if (arg_memb.substr(0, 2) == "i:") {
709 for (auto &it : mod->wires_)
710 if (it.second->port_input && match_ids(it.first, arg_memb.substr(2)))
711 sel.selected_members[mod->name].insert(it.first);
712 } else
713 if (arg_memb.substr(0, 2) == "o:") {
714 for (auto &it : mod->wires_)
715 if (it.second->port_output && match_ids(it.first, arg_memb.substr(2)))
716 sel.selected_members[mod->name].insert(it.first);
717 } else
718 if (arg_memb.substr(0, 2) == "x:") {
719 for (auto &it : mod->wires_)
720 if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2)))
721 sel.selected_members[mod->name].insert(it.first);
722 } else
723 if (arg_memb.substr(0, 2) == "s:") {
724 size_t delim = arg_memb.substr(2).find(':');
725 if (delim == std::string::npos) {
726 int width = atoi(arg_memb.substr(2).c_str());
727 for (auto &it : mod->wires_)
728 if (it.second->width == width)
729 sel.selected_members[mod->name].insert(it.first);
730 } else {
731 std::string min_str = arg_memb.substr(2, delim);
732 std::string max_str = arg_memb.substr(2+delim+1);
733 int min_width = min_str.empty() ? 0 : atoi(min_str.c_str());
734 int max_width = max_str.empty() ? -1 : atoi(max_str.c_str());
735 for (auto &it : mod->wires_)
736 if (min_width <= it.second->width && (it.second->width <= max_width || max_width == -1))
737 sel.selected_members[mod->name].insert(it.first);
738 }
739 } else
740 if (arg_memb.substr(0, 2) == "m:") {
741 for (auto &it : mod->memories)
742 if (match_ids(it.first, arg_memb.substr(2)))
743 sel.selected_members[mod->name].insert(it.first);
744 } else
745 if (arg_memb.substr(0, 2) == "c:") {
746 for (auto &it : mod->cells_)
747 if (match_ids(it.first, arg_memb.substr(2)))
748 sel.selected_members[mod->name].insert(it.first);
749 } else
750 if (arg_memb.substr(0, 2) == "t:") {
751 for (auto &it : mod->cells_)
752 if (match_ids(it.second->type, arg_memb.substr(2)))
753 sel.selected_members[mod->name].insert(it.first);
754 } else
755 if (arg_memb.substr(0, 2) == "p:") {
756 for (auto &it : mod->processes)
757 if (match_ids(it.first, arg_memb.substr(2)))
758 sel.selected_members[mod->name].insert(it.first);
759 } else
760 if (arg_memb.substr(0, 2) == "a:") {
761 for (auto &it : mod->wires_)
762 if (match_attr(it.second->attributes, arg_memb.substr(2)))
763 sel.selected_members[mod->name].insert(it.first);
764 for (auto &it : mod->memories)
765 if (match_attr(it.second->attributes, arg_memb.substr(2)))
766 sel.selected_members[mod->name].insert(it.first);
767 for (auto &it : mod->cells_)
768 if (match_attr(it.second->attributes, arg_memb.substr(2)))
769 sel.selected_members[mod->name].insert(it.first);
770 for (auto &it : mod->processes)
771 if (match_attr(it.second->attributes, arg_memb.substr(2)))
772 sel.selected_members[mod->name].insert(it.first);
773 } else
774 if (arg_memb.substr(0, 2) == "r:") {
775 for (auto &it : mod->cells_)
776 if (match_attr(it.second->parameters, arg_memb.substr(2)))
777 sel.selected_members[mod->name].insert(it.first);
778 } else {
779 if (arg_memb.substr(0, 2) == "n:")
780 arg_memb = arg_memb.substr(2);
781 for (auto &it : mod->wires_)
782 if (match_ids(it.first, arg_memb))
783 sel.selected_members[mod->name].insert(it.first);
784 for (auto &it : mod->memories)
785 if (match_ids(it.first, arg_memb))
786 sel.selected_members[mod->name].insert(it.first);
787 for (auto &it : mod->cells_)
788 if (match_ids(it.first, arg_memb))
789 sel.selected_members[mod->name].insert(it.first);
790 for (auto &it : mod->processes)
791 if (match_ids(it.first, arg_memb))
792 sel.selected_members[mod->name].insert(it.first);
793 }
794 }
795
796 select_filter_active_mod(design, work_stack.back());
797 }
798
799 PRIVATE_NAMESPACE_END
800 YOSYS_NAMESPACE_BEGIN
801
802 // used in kernel/register.cc and maybe other locations, extern decl. in register.h
803 void handle_extra_select_args(Pass *pass, std::vector<std::string> args, size_t argidx, size_t args_size, RTLIL::Design *design)
804 {
805 work_stack.clear();
806 for (; argidx < args_size; argidx++) {
807 if (args[argidx].substr(0, 1) == "-") {
808 if (pass != NULL)
809 pass->cmd_error(args, argidx, "Unexpected option in selection arguments.");
810 else
811 log_cmd_error("Unexpected option in selection arguments.");
812 }
813 select_stmt(design, args[argidx]);
814 }
815 while (work_stack.size() > 1) {
816 select_op_union(design, work_stack.front(), work_stack.back());
817 work_stack.pop_back();
818 }
819 if (work_stack.size() > 0)
820 design->selection_stack.push_back(work_stack.back());
821 else
822 design->selection_stack.push_back(RTLIL::Selection(false));
823 }
824
825 YOSYS_NAMESPACE_END
826 PRIVATE_NAMESPACE_BEGIN
827
828 struct SelectPass : public Pass {
829 SelectPass() : Pass("select", "modify and view the list of selected objects") { }
830 virtual void help()
831 {
832 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
833 log("\n");
834 log(" select [ -add | -del | -set <name> ] <selection>\n");
835 log(" select [ -assert-none | -assert-any ] <selection>\n");
836 log(" select [ -list | -write <filename> | -count | -clear ]\n");
837 log(" select -module <modname>\n");
838 log("\n");
839 log("Most commands use the list of currently selected objects to determine which part\n");
840 log("of the design to operate on. This command can be used to modify and view this\n");
841 log("list of selected objects.\n");
842 log("\n");
843 log("Note that many commands support an optional [selection] argument that can be\n");
844 log("used to override the global selection for the command. The syntax of this\n");
845 log("optional argument is identical to the syntax of the <selection> argument\n");
846 log("described here.\n");
847 log("\n");
848 log(" -add, -del\n");
849 log(" add or remove the given objects to the current selection.\n");
850 log(" without this options the current selection is replaced.\n");
851 log("\n");
852 log(" -set <name>\n");
853 log(" do not modify the current selection. instead save the new selection\n");
854 log(" under the given name (see @<name> below). to save the current selection,\n");
855 log(" use \"select -set <name> %%\"\n");
856 log("\n");
857 log(" -assert-none\n");
858 log(" do not modify the current selection. instead assert that the given\n");
859 log(" selection is empty. i.e. produce an error if any object matching the\n");
860 log(" selection is found.\n");
861 log("\n");
862 log(" -assert-any\n");
863 log(" do not modify the current selection. instead assert that the given\n");
864 log(" selection is non-empty. i.e. produce an error if no object matching\n");
865 log(" the selection is found.\n");
866 log("\n");
867 log(" -assert-count N\n");
868 log(" do not modify the current selection. instead assert that the given\n");
869 log(" selection contains exactly N objects.\n");
870 log("\n");
871 log(" -list\n");
872 log(" list all objects in the current selection\n");
873 log("\n");
874 log(" -write <filename>\n");
875 log(" like -list but write the output to the specified file\n");
876 log("\n");
877 log(" -count\n");
878 log(" count all objects in the current selection\n");
879 log("\n");
880 log(" -clear\n");
881 log(" clear the current selection. this effectively selects the whole\n");
882 log(" design. it also resets the selected module (see -module). use the\n");
883 log(" command 'select *' to select everything but stay in the current module.\n");
884 log("\n");
885 log(" -none\n");
886 log(" create an empty selection. the current module is unchanged.\n");
887 log("\n");
888 log(" -module <modname>\n");
889 log(" limit the current scope to the specified module.\n");
890 log(" the difference between this and simply selecting the module\n");
891 log(" is that all object names are interpreted relative to this\n");
892 log(" module after this command until the selection is cleared again.\n");
893 log("\n");
894 log("When this command is called without an argument, the current selection\n");
895 log("is displayed in a compact form (i.e. only the module name when a whole module\n");
896 log("is selected).\n");
897 log("\n");
898 log("The <selection> argument itself is a series of commands for a simple stack\n");
899 log("machine. Each element on the stack represents a set of selected objects.\n");
900 log("After this commands have been executed, the union of all remaining sets\n");
901 log("on the stack is computed and used as selection for the command.\n");
902 log("\n");
903 log("Pushing (selecting) object when not in -module mode:\n");
904 log("\n");
905 log(" <mod_pattern>\n");
906 log(" select the specified module(s)\n");
907 log("\n");
908 log(" <mod_pattern>/<obj_pattern>\n");
909 log(" select the specified object(s) from the module(s)\n");
910 log("\n");
911 log("Pushing (selecting) object when in -module mode:\n");
912 log("\n");
913 log(" <obj_pattern>\n");
914 log(" select the specified object(s) from the current module\n");
915 log("\n");
916 log("A <mod_pattern> can be a module name, wildcard expression (*, ?, [..])\n");
917 log("matching module names, or one of the following:\n");
918 log("\n");
919 log(" A:<pattern>, A:<pattern>=<pattern>\n");
920 log(" all modules with an attribute matching the given pattern\n");
921 log(" in addition to = also <, <=, >=, and > are supported\n");
922 log("\n");
923 log("An <obj_pattern> can be an object name, wildcard expression, or one of\n");
924 log("the following:\n");
925 log("\n");
926 log(" w:<pattern>\n");
927 log(" all wires with a name matching the given wildcard pattern\n");
928 log("\n");
929 log(" i:<pattern>, o:<pattern>, x:<pattern>\n");
930 log(" all inputs (i:), outputs (o:) or any ports (x:) with matching names\n");
931 log("\n");
932 log(" s:<size>, s:<min>:<max>\n");
933 log(" all wires with a matching width\n");
934 log("\n");
935 log(" m:<pattern>\n");
936 log(" all memories with a name matching the given pattern\n");
937 log("\n");
938 log(" c:<pattern>\n");
939 log(" all cells with a name matching the given pattern\n");
940 log("\n");
941 log(" t:<pattern>\n");
942 log(" all cells with a type matching the given pattern\n");
943 log("\n");
944 log(" p:<pattern>\n");
945 log(" all processes with a name matching the given pattern\n");
946 log("\n");
947 log(" a:<pattern>\n");
948 log(" all objects with an attribute name matching the given pattern\n");
949 log("\n");
950 log(" a:<pattern>=<pattern>\n");
951 log(" all objects with a matching attribute name-value-pair.\n");
952 log(" in addition to = also <, <=, >=, and > are supported\n");
953 log("\n");
954 log(" r:<pattern>, r:<pattern>=<pattern>\n");
955 log(" cells with matching parameters. also with <, <=, >= and >.\n");
956 log("\n");
957 log(" n:<pattern>\n");
958 log(" all objects with a name matching the given pattern\n");
959 log(" (i.e. 'n:' is optional as it is the default matching rule)\n");
960 log("\n");
961 log(" @<name>\n");
962 log(" push the selection saved prior with 'select -set <name> ...'\n");
963 log("\n");
964 log("The following actions can be performed on the top sets on the stack:\n");
965 log("\n");
966 log(" %%\n");
967 log(" push a copy of the current selection to the stack\n");
968 log("\n");
969 log(" %%%%\n");
970 log(" replace the stack with a union of all elements on it\n");
971 log("\n");
972 log(" %%n\n");
973 log(" replace top set with its invert\n");
974 log("\n");
975 log(" %%u\n");
976 log(" replace the two top sets on the stack with their union\n");
977 log("\n");
978 log(" %%i\n");
979 log(" replace the two top sets on the stack with their intersection\n");
980 log("\n");
981 log(" %%d\n");
982 log(" pop the top set from the stack and subtract it from the new top\n");
983 log("\n");
984 log(" %%D\n");
985 log(" like %%d but swap the roles of two top sets on the stack\n");
986 log("\n");
987 log(" %%c\n");
988 log(" create a copy of the top set rom the stack and push it\n");
989 log("\n");
990 log(" %%x[<num1>|*][.<num2>][:<rule>[:<rule>..]]\n");
991 log(" expand top set <num1> num times according to the specified rules.\n");
992 log(" (i.e. select all cells connected to selected wires and select all\n");
993 log(" wires connected to selected cells) The rules specify which cell\n");
994 log(" ports to use for this. the syntax for a rule is a '-' for exclusion\n");
995 log(" and a '+' for inclusion, followed by an optional comma separated\n");
996 log(" list of cell types followed by an optional comma separated list of\n");
997 log(" cell ports in square brackets. a rule can also be just a cell or wire\n");
998 log(" name that limits the expansion (is included but does not go beyond).\n");
999 log(" select at most <num2> objects. a warning message is printed when this\n");
1000 log(" limit is reached. When '*' is used instead of <num1> then the process\n");
1001 log(" is repeated until no further object are selected.\n");
1002 log("\n");
1003 log(" %%ci[<num1>|*][.<num2>][:<rule>[:<rule>..]]\n");
1004 log(" %%co[<num1>|*][.<num2>][:<rule>[:<rule>..]]\n");
1005 log(" simmilar to %%x, but only select input (%%ci) or output cones (%%co)\n");
1006 log("\n");
1007 log(" %%a\n");
1008 log(" expand top set by selecting all wires that are (at least in part)\n");
1009 log(" aliases for selected wires.\n");
1010 log("\n");
1011 log(" %%s\n");
1012 log(" expand top set by adding all modules of instantiated cells in selected\n");
1013 log(" modules\n");
1014 log("\n");
1015 log(" %%m\n");
1016 log(" expand top set by selecting all modules that contain selected objects\n");
1017 log("\n");
1018 log("Example: the following command selects all wires that are connected to a\n");
1019 log("'GATE' input of a 'SWITCH' cell:\n");
1020 log("\n");
1021 log(" select */t:SWITCH %%x:+[GATE] */t:SWITCH %%d\n");
1022 log("\n");
1023 }
1024 virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
1025 {
1026 bool add_mode = false;
1027 bool del_mode = false;
1028 bool clear_mode = false;
1029 bool none_mode = false;
1030 bool list_mode = false;
1031 bool count_mode = false;
1032 bool got_module = false;
1033 bool assert_none = false;
1034 bool assert_any = false;
1035 int assert_count = -1;
1036 std::string write_file;
1037 std::string set_name;
1038 std::string sel_str;
1039
1040 work_stack.clear();
1041
1042 size_t argidx;
1043 for (argidx = 1; argidx < args.size(); argidx++)
1044 {
1045 std::string arg = args[argidx];
1046 if (arg == "-add") {
1047 add_mode = true;
1048 continue;
1049 }
1050 if (arg == "-del") {
1051 del_mode = true;
1052 continue;
1053 }
1054 if (arg == "-assert-none") {
1055 assert_none = true;
1056 continue;
1057 }
1058 if (arg == "-assert-any") {
1059 assert_any = true;
1060 continue;
1061 }
1062 if (arg == "-assert-count" && argidx+1 < args.size()) {
1063 assert_count = atoi(args[++argidx].c_str());
1064 continue;
1065 }
1066 if (arg == "-clear") {
1067 clear_mode = true;
1068 continue;
1069 }
1070 if (arg == "-none") {
1071 none_mode = true;
1072 continue;
1073 }
1074 if (arg == "-list") {
1075 list_mode = true;
1076 continue;
1077 }
1078 if (arg == "-write" && argidx+1 < args.size()) {
1079 write_file = args[++argidx];
1080 continue;
1081 }
1082 if (arg == "-count") {
1083 count_mode = true;
1084 continue;
1085 }
1086 if (arg == "-module" && argidx+1 < args.size()) {
1087 RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]);
1088 if (design->modules_.count(mod_name) == 0)
1089 log_cmd_error("No such module: %s\n", id2cstr(mod_name));
1090 design->selected_active_module = mod_name.str();
1091 got_module = true;
1092 continue;
1093 }
1094 if (arg == "-set" && argidx+1 < args.size()) {
1095 set_name = RTLIL::escape_id(args[++argidx]);
1096 continue;
1097 }
1098 if (arg.size() > 0 && arg[0] == '-')
1099 log_cmd_error("Unknown option %s.\n", arg.c_str());
1100 select_stmt(design, arg);
1101 sel_str += " " + arg;
1102 }
1103
1104 if (clear_mode && args.size() != 2)
1105 log_cmd_error("Option -clear can not be combined with any other options.\n");
1106
1107 if (none_mode && args.size() != 2)
1108 log_cmd_error("Option -none can not be combined with any other options.\n");
1109
1110 if (add_mode + del_mode + assert_none + assert_any + (assert_count >= 0) > 1)
1111 log_cmd_error("Options -add, -del, -assert-none, -assert-any or -assert-count can not be combined.\n");
1112
1113 if ((list_mode || !write_file.empty() || count_mode) && (add_mode || del_mode || assert_none || assert_any || assert_count >= 0))
1114 log_cmd_error("Options -list, -write and -count can not be combined with -add, -del, -assert-none, -assert-any or -assert-count.\n");
1115
1116 if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || del_mode || assert_none || assert_any || assert_count >= 0))
1117 log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -assert-none, -assert-any or -assert-count.\n");
1118
1119 if (work_stack.size() == 0 && got_module) {
1120 RTLIL::Selection sel;
1121 select_filter_active_mod(design, sel);
1122 work_stack.push_back(sel);
1123 }
1124
1125 while (work_stack.size() > 1) {
1126 select_op_union(design, work_stack.front(), work_stack.back());
1127 work_stack.pop_back();
1128 }
1129
1130 log_assert(design->selection_stack.size() > 0);
1131
1132 if (clear_mode) {
1133 design->selection_stack.back() = RTLIL::Selection(true);
1134 design->selected_active_module = std::string();
1135 return;
1136 }
1137
1138 if (none_mode) {
1139 design->selection_stack.back() = RTLIL::Selection(false);
1140 return;
1141 }
1142
1143 if (list_mode || count_mode || !write_file.empty())
1144 {
1145 #define LOG_OBJECT(...) do { if (list_mode) log(__VA_ARGS__); if (f != NULL) fprintf(f, __VA_ARGS__); total_count++; } while (0)
1146 int total_count = 0;
1147 FILE *f = NULL;
1148 if (!write_file.empty()) {
1149 f = fopen(write_file.c_str(), "w");
1150 if (f == NULL)
1151 log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno));
1152 }
1153 RTLIL::Selection *sel = &design->selection_stack.back();
1154 if (work_stack.size() > 0)
1155 sel = &work_stack.back();
1156 sel->optimize(design);
1157 for (auto mod_it : design->modules_)
1158 {
1159 if (sel->selected_whole_module(mod_it.first) && list_mode)
1160 log("%s\n", id2cstr(mod_it.first));
1161 if (sel->selected_module(mod_it.first)) {
1162 for (auto &it : mod_it.second->wires_)
1163 if (sel->selected_member(mod_it.first, it.first))
1164 LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
1165 for (auto &it : mod_it.second->memories)
1166 if (sel->selected_member(mod_it.first, it.first))
1167 LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
1168 for (auto &it : mod_it.second->cells_)
1169 if (sel->selected_member(mod_it.first, it.first))
1170 LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
1171 for (auto &it : mod_it.second->processes)
1172 if (sel->selected_member(mod_it.first, it.first))
1173 LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
1174 }
1175 }
1176 if (count_mode)
1177 log("%d objects.\n", total_count);
1178 if (f != NULL)
1179 fclose(f);
1180 #undef LOG_OBJECT
1181 return;
1182 }
1183
1184 if (add_mode)
1185 {
1186 if (work_stack.size() == 0)
1187 log_cmd_error("Nothing to add to selection.\n");
1188 select_op_union(design, design->selection_stack.back(), work_stack.back());
1189 design->selection_stack.back().optimize(design);
1190 return;
1191 }
1192
1193 if (del_mode)
1194 {
1195 if (work_stack.size() == 0)
1196 log_cmd_error("Nothing to delete from selection.\n");
1197 select_op_diff(design, design->selection_stack.back(), work_stack.back());
1198 design->selection_stack.back().optimize(design);
1199 return;
1200 }
1201
1202 if (assert_none)
1203 {
1204 if (work_stack.size() == 0)
1205 log_cmd_error("No selection to check.\n");
1206 if (!work_stack.back().empty())
1207 log_error("Assertation failed: selection is not empty:%s\n", sel_str.c_str());
1208 return;
1209 }
1210
1211 if (assert_any)
1212 {
1213 if (work_stack.size() == 0)
1214 log_cmd_error("No selection to check.\n");
1215 if (work_stack.back().empty())
1216 log_error("Assertation failed: selection is empty:%s\n", sel_str.c_str());
1217 return;
1218 }
1219
1220 if (assert_count >= 0)
1221 {
1222 int total_count = 0;
1223 if (work_stack.size() == 0)
1224 log_cmd_error("No selection to check.\n");
1225 RTLIL::Selection *sel = &work_stack.back();
1226 sel->optimize(design);
1227 for (auto mod_it : design->modules_)
1228 if (sel->selected_module(mod_it.first)) {
1229 for (auto &it : mod_it.second->wires_)
1230 if (sel->selected_member(mod_it.first, it.first))
1231 total_count++;
1232 for (auto &it : mod_it.second->memories)
1233 if (sel->selected_member(mod_it.first, it.first))
1234 total_count++;
1235 for (auto &it : mod_it.second->cells_)
1236 if (sel->selected_member(mod_it.first, it.first))
1237 total_count++;
1238 for (auto &it : mod_it.second->processes)
1239 if (sel->selected_member(mod_it.first, it.first))
1240 total_count++;
1241 }
1242 if (assert_count != total_count)
1243 log_error("Assertation failed: selection contains %d elements instead of the asserted %d:%s\n",
1244 total_count, assert_count, sel_str.c_str());
1245 return;
1246 }
1247
1248 if (!set_name.empty())
1249 {
1250 if (work_stack.size() == 0)
1251 design->selection_vars[set_name] = RTLIL::Selection(false);
1252 else
1253 design->selection_vars[set_name] = work_stack.back();
1254 return;
1255 }
1256
1257 if (work_stack.size() == 0) {
1258 RTLIL::Selection &sel = design->selection_stack.back();
1259 if (sel.full_selection)
1260 log("*\n");
1261 for (auto &it : sel.selected_modules)
1262 log("%s\n", id2cstr(it));
1263 for (auto &it : sel.selected_members)
1264 for (auto &it2 : it.second)
1265 log("%s/%s\n", id2cstr(it.first), id2cstr(it2));
1266 return;
1267 }
1268
1269 design->selection_stack.back() = work_stack.back();
1270 design->selection_stack.back().optimize(design);
1271 }
1272 } SelectPass;
1273
1274 struct CdPass : public Pass {
1275 CdPass() : Pass("cd", "a shortcut for 'select -module <name>'") { }
1276 virtual void help()
1277 {
1278 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
1279 log("\n");
1280 log(" cd <modname>\n");
1281 log("\n");
1282 log("This is just a shortcut for 'select -module <modname>'.\n");
1283 log("\n");
1284 log("\n");
1285 log(" cd <cellname>\n");
1286 log("\n");
1287 log("When no module with the specified name is found, but there is a cell\n");
1288 log("with the specified name in the current module, then this is equivialent\n");
1289 log("to 'cd <celltype>'.\n");
1290 log("\n");
1291 log(" cd ..\n");
1292 log("\n");
1293 log("This is just a shortcut for 'select -clear'.\n");
1294 log("\n");
1295 }
1296 virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
1297 {
1298 if (args.size() != 2)
1299 log_cmd_error("Invalid number of arguments.\n");
1300
1301 if (args[1] == "..") {
1302 design->selection_stack.back() = RTLIL::Selection(true);
1303 design->selected_active_module = std::string();
1304 return;
1305 }
1306
1307 std::string modname = RTLIL::escape_id(args[1]);
1308
1309 if (design->modules_.count(modname) == 0 && !design->selected_active_module.empty()) {
1310 RTLIL::Module *module = NULL;
1311 if (design->modules_.count(design->selected_active_module) > 0)
1312 module = design->modules_.at(design->selected_active_module);
1313 if (module != NULL && module->cells_.count(modname) > 0)
1314 modname = module->cells_.at(modname)->type.str();
1315 }
1316
1317 if (design->modules_.count(modname) > 0) {
1318 design->selected_active_module = modname;
1319 design->selection_stack.back() = RTLIL::Selection();
1320 select_filter_active_mod(design, design->selection_stack.back());
1321 design->selection_stack.back().optimize(design);
1322 return;
1323 }
1324
1325 log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname).c_str());
1326 }
1327 } CdPass;
1328
1329 template<typename T>
1330 static int log_matches(const char *title, std::string pattern, T list)
1331 {
1332 std::vector<RTLIL::IdString> matches;
1333
1334 for (auto &it : list)
1335 if (pattern.empty() || match_ids(it.first, pattern))
1336 matches.push_back(it.first);
1337
1338 if (matches.empty())
1339 return 0;
1340
1341 log("\n%d %s:\n", int(matches.size()), title);
1342 for (auto &id : matches)
1343 log(" %s\n", RTLIL::id2cstr(id));
1344 return matches.size();
1345 }
1346
1347 struct LsPass : public Pass {
1348 LsPass() : Pass("ls", "list modules or objects in modules") { }
1349 virtual void help()
1350 {
1351 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
1352 log("\n");
1353 log(" ls [pattern]\n");
1354 log("\n");
1355 log("When no active module is selected, this prints a list of all modules.\n");
1356 log("\n");
1357 log("When an active module is selected, this prints a list of objects in the module.\n");
1358 log("\n");
1359 log("If a pattern is given, the objects matching the pattern are printed\n");
1360 log("\n");
1361 log("Note that this command does not use the selection mechanism and always operates\n");
1362 log("on the whole design or whole active module. Use 'select -list' to show a list\n");
1363 log("of currently selected objects.\n");
1364 log("\n");
1365 }
1366 virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
1367 {
1368 std::string pattern;
1369 int counter = 0;
1370
1371 if (args.size() != 1 && args.size() != 2)
1372 log_cmd_error("Invalid number of arguments.\n");
1373 if (args.size() == 2)
1374 pattern = args.at(1);
1375
1376 if (design->selected_active_module.empty())
1377 {
1378 counter += log_matches("modules", pattern, design->modules_);
1379 }
1380 else
1381 if (design->modules_.count(design->selected_active_module) > 0)
1382 {
1383 RTLIL::Module *module = design->modules_.at(design->selected_active_module);
1384 counter += log_matches("wires", pattern, module->wires_);
1385 counter += log_matches("memories", pattern, module->memories);
1386 counter += log_matches("cells", pattern, module->cells_);
1387 counter += log_matches("processes", pattern, module->processes);
1388 }
1389
1390 // log("\nfound %d item%s.\n", counter, counter == 1 ? "" : "s");
1391 }
1392 } LsPass;
1393
1394 PRIVATE_NAMESPACE_END