Added RTLIL::Monitor
[yosys.git] / kernel / rtlil.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 "frontends/verilog/verilog_frontend.h"
22 #include "backends/ilang/ilang_backend.h"
23
24 #include <string.h>
25 #include <algorithm>
26
27 YOSYS_NAMESPACE_BEGIN
28
29 RTLIL::Const::Const()
30 {
31 flags = RTLIL::CONST_FLAG_NONE;
32 }
33
34 RTLIL::Const::Const(std::string str)
35 {
36 flags = RTLIL::CONST_FLAG_STRING;
37 for (int i = str.size()-1; i >= 0; i--) {
38 unsigned char ch = str[i];
39 for (int j = 0; j < 8; j++) {
40 bits.push_back((ch & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
41 ch = ch >> 1;
42 }
43 }
44 }
45
46 RTLIL::Const::Const(int val, int width)
47 {
48 flags = RTLIL::CONST_FLAG_NONE;
49 for (int i = 0; i < width; i++) {
50 bits.push_back((val & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
51 val = val >> 1;
52 }
53 }
54
55 RTLIL::Const::Const(RTLIL::State bit, int width)
56 {
57 flags = RTLIL::CONST_FLAG_NONE;
58 for (int i = 0; i < width; i++)
59 bits.push_back(bit);
60 }
61
62 bool RTLIL::Const::operator <(const RTLIL::Const &other) const
63 {
64 if (bits.size() != other.bits.size())
65 return bits.size() < other.bits.size();
66 for (size_t i = 0; i < bits.size(); i++)
67 if (bits[i] != other.bits[i])
68 return bits[i] < other.bits[i];
69 return false;
70 }
71
72 bool RTLIL::Const::operator ==(const RTLIL::Const &other) const
73 {
74 return bits == other.bits;
75 }
76
77 bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
78 {
79 return bits != other.bits;
80 }
81
82 bool RTLIL::Const::as_bool() const
83 {
84 for (size_t i = 0; i < bits.size(); i++)
85 if (bits[i] == RTLIL::S1)
86 return true;
87 return false;
88 }
89
90 int RTLIL::Const::as_int() const
91 {
92 int ret = 0;
93 for (size_t i = 0; i < bits.size() && i < 32; i++)
94 if (bits[i] == RTLIL::S1)
95 ret |= 1 << i;
96 return ret;
97 }
98
99 std::string RTLIL::Const::as_string() const
100 {
101 std::string ret;
102 for (size_t i = bits.size(); i > 0; i--)
103 switch (bits[i-1]) {
104 case S0: ret += "0"; break;
105 case S1: ret += "1"; break;
106 case Sx: ret += "x"; break;
107 case Sz: ret += "z"; break;
108 case Sa: ret += "-"; break;
109 case Sm: ret += "m"; break;
110 }
111 return ret;
112 }
113
114 std::string RTLIL::Const::decode_string() const
115 {
116 std::string string;
117 std::vector <char> string_chars;
118 for (int i = 0; i < int (bits.size()); i += 8) {
119 char ch = 0;
120 for (int j = 0; j < 8 && i + j < int (bits.size()); j++)
121 if (bits[i + j] == RTLIL::State::S1)
122 ch |= 1 << j;
123 if (ch != 0)
124 string_chars.push_back(ch);
125 }
126 for (int i = int (string_chars.size()) - 1; i >= 0; i--)
127 string += string_chars[i];
128 return string;
129 }
130
131 bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const
132 {
133 if (full_selection)
134 return true;
135 if (selected_modules.count(mod_name) > 0)
136 return true;
137 if (selected_members.count(mod_name) > 0)
138 return true;
139 return false;
140 }
141
142 bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name) const
143 {
144 if (full_selection)
145 return true;
146 if (selected_modules.count(mod_name) > 0)
147 return true;
148 return false;
149 }
150
151 bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
152 {
153 if (full_selection)
154 return true;
155 if (selected_modules.count(mod_name) > 0)
156 return true;
157 if (selected_members.count(mod_name) > 0)
158 if (selected_members.at(mod_name).count(memb_name) > 0)
159 return true;
160 return false;
161 }
162
163 void RTLIL::Selection::optimize(RTLIL::Design *design)
164 {
165 if (full_selection) {
166 selected_modules.clear();
167 selected_members.clear();
168 return;
169 }
170
171 std::vector<RTLIL::IdString> del_list, add_list;
172
173 del_list.clear();
174 for (auto mod_name : selected_modules) {
175 if (design->modules_.count(mod_name) == 0)
176 del_list.push_back(mod_name);
177 selected_members.erase(mod_name);
178 }
179 for (auto mod_name : del_list)
180 selected_modules.erase(mod_name);
181
182 del_list.clear();
183 for (auto &it : selected_members)
184 if (design->modules_.count(it.first) == 0)
185 del_list.push_back(it.first);
186 for (auto mod_name : del_list)
187 selected_members.erase(mod_name);
188
189 for (auto &it : selected_members) {
190 del_list.clear();
191 for (auto memb_name : it.second)
192 if (design->modules_[it.first]->count_id(memb_name) == 0)
193 del_list.push_back(memb_name);
194 for (auto memb_name : del_list)
195 it.second.erase(memb_name);
196 }
197
198 del_list.clear();
199 add_list.clear();
200 for (auto &it : selected_members)
201 if (it.second.size() == 0)
202 del_list.push_back(it.first);
203 else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() +
204 design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size())
205 add_list.push_back(it.first);
206 for (auto mod_name : del_list)
207 selected_members.erase(mod_name);
208 for (auto mod_name : add_list) {
209 selected_members.erase(mod_name);
210 selected_modules.insert(mod_name);
211 }
212
213 if (selected_modules.size() == design->modules_.size()) {
214 full_selection = true;
215 selected_modules.clear();
216 selected_members.clear();
217 }
218 }
219
220 RTLIL::Design::Design()
221 {
222 refcount_modules_ = 0;
223 }
224
225 RTLIL::Design::~Design()
226 {
227 for (auto it = modules_.begin(); it != modules_.end(); it++)
228 delete it->second;
229 }
230
231 RTLIL::ObjRange<RTLIL::Module*> RTLIL::Design::modules()
232 {
233 return RTLIL::ObjRange<RTLIL::Module*>(&modules_, &refcount_modules_);
234 }
235
236 RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name)
237 {
238 return modules_.count(name) ? modules_.at(name) : NULL;
239 }
240
241 void RTLIL::Design::add(RTLIL::Module *module)
242 {
243 log_assert(modules_.count(module->name) == 0);
244 log_assert(refcount_modules_ == 0);
245 modules_[module->name] = module;
246 module->design = this;
247
248 for (auto mon : monitors)
249 mon->notify_module_add(module);
250 }
251
252 RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
253 {
254 log_assert(modules_.count(name) == 0);
255 log_assert(refcount_modules_ == 0);
256
257 RTLIL::Module *module = new RTLIL::Module;
258 modules_[name] = module;
259 module->design = this;
260 module->name = name;
261
262 for (auto mon : monitors)
263 mon->notify_module_add(module);
264
265 return module;
266 }
267
268 void RTLIL::Design::remove(RTLIL::Module *module)
269 {
270 for (auto mon : monitors)
271 mon->notify_module_del(module);
272
273 log_assert(modules_.at(module->name) == module);
274 modules_.erase(module->name);
275 delete module;
276 }
277
278 void RTLIL::Design::check()
279 {
280 #ifndef NDEBUG
281 for (auto &it : modules_) {
282 log_assert(this == it.second->design);
283 log_assert(it.first == it.second->name);
284 log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
285 it.second->check();
286 }
287 #endif
288 }
289
290 void RTLIL::Design::optimize()
291 {
292 for (auto &it : modules_)
293 it.second->optimize();
294 for (auto &it : selection_stack)
295 it.optimize(this);
296 for (auto &it : selection_vars)
297 it.second.optimize(this);
298 }
299
300 bool RTLIL::Design::selected_module(RTLIL::IdString mod_name) const
301 {
302 if (!selected_active_module.empty() && mod_name != selected_active_module)
303 return false;
304 if (selection_stack.size() == 0)
305 return true;
306 return selection_stack.back().selected_module(mod_name);
307 }
308
309 bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name) const
310 {
311 if (!selected_active_module.empty() && mod_name != selected_active_module)
312 return false;
313 if (selection_stack.size() == 0)
314 return true;
315 return selection_stack.back().selected_whole_module(mod_name);
316 }
317
318 bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
319 {
320 if (!selected_active_module.empty() && mod_name != selected_active_module)
321 return false;
322 if (selection_stack.size() == 0)
323 return true;
324 return selection_stack.back().selected_member(mod_name, memb_name);
325 }
326
327 bool RTLIL::Design::selected_module(RTLIL::Module *mod) const
328 {
329 return selected_module(mod->name);
330 }
331
332 bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const
333 {
334 return selected_whole_module(mod->name);
335 }
336
337 std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const
338 {
339 std::vector<RTLIL::Module*> result;
340 result.reserve(modules_.size());
341 for (auto &it : modules_)
342 if (selected_module(it.first))
343 result.push_back(it.second);
344 return result;
345 }
346
347 std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const
348 {
349 std::vector<RTLIL::Module*> result;
350 result.reserve(modules_.size());
351 for (auto &it : modules_)
352 if (selected_whole_module(it.first))
353 result.push_back(it.second);
354 return result;
355 }
356
357 std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn() const
358 {
359 std::vector<RTLIL::Module*> result;
360 result.reserve(modules_.size());
361 for (auto &it : modules_)
362 if (selected_whole_module(it.first))
363 result.push_back(it.second);
364 else if (selected_module(it.first))
365 log("Warning: Ignoring partially selected module %s.\n", log_id(it.first));
366 return result;
367 }
368
369 RTLIL::Module::Module()
370 {
371 design = nullptr;
372 refcount_wires_ = 0;
373 refcount_cells_ = 0;
374 }
375
376 RTLIL::Module::~Module()
377 {
378 for (auto it = wires_.begin(); it != wires_.end(); it++)
379 delete it->second;
380 for (auto it = memories.begin(); it != memories.end(); it++)
381 delete it->second;
382 for (auto it = cells_.begin(); it != cells_.end(); it++)
383 delete it->second;
384 for (auto it = processes.begin(); it != processes.end(); it++)
385 delete it->second;
386 }
387
388 RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map<RTLIL::IdString, RTLIL::Const>)
389 {
390 log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
391 }
392
393 size_t RTLIL::Module::count_id(RTLIL::IdString id)
394 {
395 return wires_.count(id) + memories.count(id) + cells_.count(id) + processes.count(id);
396 }
397
398 #ifndef NDEBUG
399 namespace {
400 struct InternalCellChecker
401 {
402 RTLIL::Module *module;
403 RTLIL::Cell *cell;
404 std::set<RTLIL::IdString> expected_params, expected_ports;
405
406 InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { }
407
408 void error(int linenr)
409 {
410 char *ptr;
411 size_t size;
412
413 FILE *f = open_memstream(&ptr, &size);
414 ILANG_BACKEND::dump_cell(f, " ", cell);
415 fputc(0, f);
416 fclose(f);
417
418 log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s",
419 module ? module->name.c_str() : "", module ? "." : "",
420 cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, ptr);
421 }
422
423 int param(const char *name)
424 {
425 if (cell->parameters.count(name) == 0)
426 error(__LINE__);
427 expected_params.insert(name);
428 return cell->parameters.at(name).as_int();
429 }
430
431 int param_bool(const char *name)
432 {
433 int v = param(name);
434 if (cell->parameters.at(name).bits.size() > 32)
435 error(__LINE__);
436 if (v != 0 && v != 1)
437 error(__LINE__);
438 return v;
439 }
440
441 void param_bits(const char *name, int width)
442 {
443 param(name);
444 if (int(cell->parameters.at(name).bits.size()) != width)
445 error(__LINE__);
446 }
447
448 void port(const char *name, int width)
449 {
450 if (!cell->has(name))
451 error(__LINE__);
452 if (cell->get(name).size() != width)
453 error(__LINE__);
454 expected_ports.insert(name);
455 }
456
457 void check_expected(bool check_matched_sign = true)
458 {
459 for (auto &para : cell->parameters)
460 if (expected_params.count(para.first) == 0)
461 error(__LINE__);
462 for (auto &conn : cell->connections())
463 if (expected_ports.count(conn.first) == 0)
464 error(__LINE__);
465
466 if (expected_params.count("\\A_SIGNED") != 0 && expected_params.count("\\B_SIGNED") && check_matched_sign) {
467 bool a_is_signed = param("\\A_SIGNED") != 0;
468 bool b_is_signed = param("\\B_SIGNED") != 0;
469 if (a_is_signed != b_is_signed)
470 error(__LINE__);
471 }
472 }
473
474 void check_gate(const char *ports)
475 {
476 if (cell->parameters.size() != 0)
477 error(__LINE__);
478
479 for (const char *p = ports; *p; p++) {
480 char portname[3] = { '\\', *p, 0 };
481 if (!cell->has(portname))
482 error(__LINE__);
483 if (cell->get(portname).size() != 1)
484 error(__LINE__);
485 }
486
487 for (auto &conn : cell->connections()) {
488 if (conn.first.size() != 2 || conn.first.at(0) != '\\')
489 error(__LINE__);
490 if (strchr(ports, conn.first.at(1)) == NULL)
491 error(__LINE__);
492 }
493 }
494
495 void check()
496 {
497 if (cell->type[0] != '$' || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" ||
498 cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:")
499 return;
500
501 if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") {
502 param_bool("\\A_SIGNED");
503 port("\\A", param("\\A_WIDTH"));
504 port("\\Y", param("\\Y_WIDTH"));
505 check_expected();
506 return;
507 }
508
509 if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") {
510 param_bool("\\A_SIGNED");
511 param_bool("\\B_SIGNED");
512 port("\\A", param("\\A_WIDTH"));
513 port("\\B", param("\\B_WIDTH"));
514 port("\\Y", param("\\Y_WIDTH"));
515 check_expected();
516 return;
517 }
518
519 if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" ||
520 cell->type == "$reduce_xnor" || cell->type == "$reduce_bool") {
521 param_bool("\\A_SIGNED");
522 port("\\A", param("\\A_WIDTH"));
523 port("\\Y", param("\\Y_WIDTH"));
524 check_expected();
525 return;
526 }
527
528 if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" ||
529 cell->type == "$shift" || cell->type == "$shiftx") {
530 param_bool("\\A_SIGNED");
531 param_bool("\\B_SIGNED");
532 port("\\A", param("\\A_WIDTH"));
533 port("\\B", param("\\B_WIDTH"));
534 port("\\Y", param("\\Y_WIDTH"));
535 check_expected(false);
536 return;
537 }
538
539 if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" ||
540 cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") {
541 param_bool("\\A_SIGNED");
542 param_bool("\\B_SIGNED");
543 port("\\A", param("\\A_WIDTH"));
544 port("\\B", param("\\B_WIDTH"));
545 port("\\Y", param("\\Y_WIDTH"));
546 check_expected();
547 return;
548 }
549
550 if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" ||
551 cell->type == "$mod" || cell->type == "$pow") {
552 param_bool("\\A_SIGNED");
553 param_bool("\\B_SIGNED");
554 port("\\A", param("\\A_WIDTH"));
555 port("\\B", param("\\B_WIDTH"));
556 port("\\Y", param("\\Y_WIDTH"));
557 check_expected(cell->type != "$pow");
558 return;
559 }
560
561 if (cell->type == "$logic_not") {
562 param_bool("\\A_SIGNED");
563 port("\\A", param("\\A_WIDTH"));
564 port("\\Y", param("\\Y_WIDTH"));
565 check_expected();
566 return;
567 }
568
569 if (cell->type == "$logic_and" || cell->type == "$logic_or") {
570 param_bool("\\A_SIGNED");
571 param_bool("\\B_SIGNED");
572 port("\\A", param("\\A_WIDTH"));
573 port("\\B", param("\\B_WIDTH"));
574 port("\\Y", param("\\Y_WIDTH"));
575 check_expected(false);
576 return;
577 }
578
579 if (cell->type == "$slice") {
580 param("\\OFFSET");
581 port("\\A", param("\\A_WIDTH"));
582 port("\\Y", param("\\Y_WIDTH"));
583 if (param("\\OFFSET") + param("\\Y_WIDTH") > param("\\A_WIDTH"))
584 error(__LINE__);
585 check_expected();
586 return;
587 }
588
589 if (cell->type == "$concat") {
590 port("\\A", param("\\A_WIDTH"));
591 port("\\B", param("\\B_WIDTH"));
592 port("\\Y", param("\\A_WIDTH") + param("\\B_WIDTH"));
593 check_expected();
594 return;
595 }
596
597 if (cell->type == "$mux") {
598 port("\\A", param("\\WIDTH"));
599 port("\\B", param("\\WIDTH"));
600 port("\\S", 1);
601 port("\\Y", param("\\WIDTH"));
602 check_expected();
603 return;
604 }
605
606 if (cell->type == "$pmux" || cell->type == "$safe_pmux") {
607 port("\\A", param("\\WIDTH"));
608 port("\\B", param("\\WIDTH") * param("\\S_WIDTH"));
609 port("\\S", param("\\S_WIDTH"));
610 port("\\Y", param("\\WIDTH"));
611 check_expected();
612 return;
613 }
614
615 if (cell->type == "$lut") {
616 param("\\LUT");
617 port("\\I", param("\\WIDTH"));
618 port("\\O", 1);
619 check_expected();
620 return;
621 }
622
623 if (cell->type == "$sr") {
624 param_bool("\\SET_POLARITY");
625 param_bool("\\CLR_POLARITY");
626 port("\\SET", param("\\WIDTH"));
627 port("\\CLR", param("\\WIDTH"));
628 port("\\Q", param("\\WIDTH"));
629 check_expected();
630 return;
631 }
632
633 if (cell->type == "$dff") {
634 param_bool("\\CLK_POLARITY");
635 port("\\CLK", 1);
636 port("\\D", param("\\WIDTH"));
637 port("\\Q", param("\\WIDTH"));
638 check_expected();
639 return;
640 }
641
642 if (cell->type == "$dffsr") {
643 param_bool("\\CLK_POLARITY");
644 param_bool("\\SET_POLARITY");
645 param_bool("\\CLR_POLARITY");
646 port("\\CLK", 1);
647 port("\\SET", param("\\WIDTH"));
648 port("\\CLR", param("\\WIDTH"));
649 port("\\D", param("\\WIDTH"));
650 port("\\Q", param("\\WIDTH"));
651 check_expected();
652 return;
653 }
654
655 if (cell->type == "$adff") {
656 param_bool("\\CLK_POLARITY");
657 param_bool("\\ARST_POLARITY");
658 param_bits("\\ARST_VALUE", param("\\WIDTH"));
659 port("\\CLK", 1);
660 port("\\ARST", 1);
661 port("\\D", param("\\WIDTH"));
662 port("\\Q", param("\\WIDTH"));
663 check_expected();
664 return;
665 }
666
667 if (cell->type == "$dlatch") {
668 param_bool("\\EN_POLARITY");
669 port("\\EN", 1);
670 port("\\D", param("\\WIDTH"));
671 port("\\Q", param("\\WIDTH"));
672 check_expected();
673 return;
674 }
675
676 if (cell->type == "$dlatchsr") {
677 param_bool("\\EN_POLARITY");
678 param_bool("\\SET_POLARITY");
679 param_bool("\\CLR_POLARITY");
680 port("\\EN", 1);
681 port("\\SET", param("\\WIDTH"));
682 port("\\CLR", param("\\WIDTH"));
683 port("\\D", param("\\WIDTH"));
684 port("\\Q", param("\\WIDTH"));
685 check_expected();
686 return;
687 }
688
689 if (cell->type == "$fsm") {
690 param("\\NAME");
691 param_bool("\\CLK_POLARITY");
692 param_bool("\\ARST_POLARITY");
693 param("\\STATE_BITS");
694 param("\\STATE_NUM");
695 param("\\STATE_NUM_LOG2");
696 param("\\STATE_RST");
697 param_bits("\\STATE_TABLE", param("\\STATE_BITS") * param("\\STATE_NUM"));
698 param("\\TRANS_NUM");
699 param_bits("\\TRANS_TABLE", param("\\TRANS_NUM") * (2*param("\\STATE_NUM_LOG2") + param("\\CTRL_IN_WIDTH") + param("\\CTRL_OUT_WIDTH")));
700 port("\\CLK", 1);
701 port("\\ARST", 1);
702 port("\\CTRL_IN", param("\\CTRL_IN_WIDTH"));
703 port("\\CTRL_OUT", param("\\CTRL_OUT_WIDTH"));
704 check_expected();
705 return;
706 }
707
708 if (cell->type == "$memrd") {
709 param("\\MEMID");
710 param_bool("\\CLK_ENABLE");
711 param_bool("\\CLK_POLARITY");
712 param_bool("\\TRANSPARENT");
713 port("\\CLK", 1);
714 port("\\ADDR", param("\\ABITS"));
715 port("\\DATA", param("\\WIDTH"));
716 check_expected();
717 return;
718 }
719
720 if (cell->type == "$memwr") {
721 param("\\MEMID");
722 param_bool("\\CLK_ENABLE");
723 param_bool("\\CLK_POLARITY");
724 param("\\PRIORITY");
725 port("\\CLK", 1);
726 port("\\EN", param("\\WIDTH"));
727 port("\\ADDR", param("\\ABITS"));
728 port("\\DATA", param("\\WIDTH"));
729 check_expected();
730 return;
731 }
732
733 if (cell->type == "$mem") {
734 param("\\MEMID");
735 param("\\SIZE");
736 param("\\OFFSET");
737 param_bits("\\RD_CLK_ENABLE", param("\\RD_PORTS"));
738 param_bits("\\RD_CLK_POLARITY", param("\\RD_PORTS"));
739 param_bits("\\RD_TRANSPARENT", param("\\RD_PORTS"));
740 param_bits("\\WR_CLK_ENABLE", param("\\WR_PORTS"));
741 param_bits("\\WR_CLK_POLARITY", param("\\WR_PORTS"));
742 port("\\RD_CLK", param("\\RD_PORTS"));
743 port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS"));
744 port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH"));
745 port("\\WR_CLK", param("\\WR_PORTS"));
746 port("\\WR_EN", param("\\WR_PORTS") * param("\\WIDTH"));
747 port("\\WR_ADDR", param("\\WR_PORTS") * param("\\ABITS"));
748 port("\\WR_DATA", param("\\WR_PORTS") * param("\\WIDTH"));
749 check_expected();
750 return;
751 }
752
753 if (cell->type == "$assert") {
754 port("\\A", 1);
755 port("\\EN", 1);
756 check_expected();
757 return;
758 }
759
760 if (cell->type == "$_INV_") { check_gate("AY"); return; }
761 if (cell->type == "$_AND_") { check_gate("ABY"); return; }
762 if (cell->type == "$_OR_") { check_gate("ABY"); return; }
763 if (cell->type == "$_XOR_") { check_gate("ABY"); return; }
764 if (cell->type == "$_MUX_") { check_gate("ABSY"); return; }
765
766 if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; }
767 if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; }
768 if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; }
769 if (cell->type == "$_SR_PP_") { check_gate("SRQ"); return; }
770
771 if (cell->type == "$_DFF_N_") { check_gate("DQC"); return; }
772 if (cell->type == "$_DFF_P_") { check_gate("DQC"); return; }
773
774 if (cell->type == "$_DFF_NN0_") { check_gate("DQCR"); return; }
775 if (cell->type == "$_DFF_NN1_") { check_gate("DQCR"); return; }
776 if (cell->type == "$_DFF_NP0_") { check_gate("DQCR"); return; }
777 if (cell->type == "$_DFF_NP1_") { check_gate("DQCR"); return; }
778 if (cell->type == "$_DFF_PN0_") { check_gate("DQCR"); return; }
779 if (cell->type == "$_DFF_PN1_") { check_gate("DQCR"); return; }
780 if (cell->type == "$_DFF_PP0_") { check_gate("DQCR"); return; }
781 if (cell->type == "$_DFF_PP1_") { check_gate("DQCR"); return; }
782
783 if (cell->type == "$_DFFSR_NNN_") { check_gate("CSRDQ"); return; }
784 if (cell->type == "$_DFFSR_NNP_") { check_gate("CSRDQ"); return; }
785 if (cell->type == "$_DFFSR_NPN_") { check_gate("CSRDQ"); return; }
786 if (cell->type == "$_DFFSR_NPP_") { check_gate("CSRDQ"); return; }
787 if (cell->type == "$_DFFSR_PNN_") { check_gate("CSRDQ"); return; }
788 if (cell->type == "$_DFFSR_PNP_") { check_gate("CSRDQ"); return; }
789 if (cell->type == "$_DFFSR_PPN_") { check_gate("CSRDQ"); return; }
790 if (cell->type == "$_DFFSR_PPP_") { check_gate("CSRDQ"); return; }
791
792 if (cell->type == "$_DLATCH_N_") { check_gate("EDQ"); return; }
793 if (cell->type == "$_DLATCH_P_") { check_gate("EDQ"); return; }
794
795 if (cell->type == "$_DLATCHSR_NNN_") { check_gate("ESRDQ"); return; }
796 if (cell->type == "$_DLATCHSR_NNP_") { check_gate("ESRDQ"); return; }
797 if (cell->type == "$_DLATCHSR_NPN_") { check_gate("ESRDQ"); return; }
798 if (cell->type == "$_DLATCHSR_NPP_") { check_gate("ESRDQ"); return; }
799 if (cell->type == "$_DLATCHSR_PNN_") { check_gate("ESRDQ"); return; }
800 if (cell->type == "$_DLATCHSR_PNP_") { check_gate("ESRDQ"); return; }
801 if (cell->type == "$_DLATCHSR_PPN_") { check_gate("ESRDQ"); return; }
802 if (cell->type == "$_DLATCHSR_PPP_") { check_gate("ESRDQ"); return; }
803
804 error(__LINE__);
805 }
806 };
807 }
808 #endif
809
810 void RTLIL::Module::check()
811 {
812 #ifndef NDEBUG
813 for (auto &it : wires_) {
814 log_assert(this == it.second->module);
815 log_assert(it.first == it.second->name);
816 log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
817 log_assert(it.second->width >= 0);
818 log_assert(it.second->port_id >= 0);
819 for (auto &it2 : it.second->attributes) {
820 log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
821 }
822 }
823
824 for (auto &it : memories) {
825 log_assert(it.first == it.second->name);
826 log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
827 log_assert(it.second->width >= 0);
828 log_assert(it.second->size >= 0);
829 for (auto &it2 : it.second->attributes) {
830 log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
831 }
832 }
833
834 for (auto &it : cells_) {
835 log_assert(this == it.second->module);
836 log_assert(it.first == it.second->name);
837 log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
838 log_assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$'));
839 for (auto &it2 : it.second->connections()) {
840 log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
841 it2.second.check();
842 }
843 for (auto &it2 : it.second->attributes) {
844 log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
845 }
846 for (auto &it2 : it.second->parameters) {
847 log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
848 }
849 InternalCellChecker checker(this, it.second);
850 checker.check();
851 }
852
853 for (auto &it : processes) {
854 log_assert(it.first == it.second->name);
855 log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
856 // FIXME: More checks here..
857 }
858
859 for (auto &it : connections_) {
860 log_assert(it.first.size() == it.second.size());
861 it.first.check();
862 it.second.check();
863 }
864
865 for (auto &it : attributes) {
866 log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
867 }
868 #endif
869 }
870
871 void RTLIL::Module::optimize()
872 {
873 }
874
875 void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const
876 {
877 log_assert(new_mod->refcount_wires_ == 0);
878 log_assert(new_mod->refcount_cells_ == 0);
879
880 new_mod->connections_ = connections_;
881 new_mod->attributes = attributes;
882
883 for (auto &it : wires_)
884 new_mod->addWire(it.first, it.second);
885
886 for (auto &it : memories)
887 new_mod->memories[it.first] = new RTLIL::Memory(*it.second);
888
889 for (auto &it : cells_)
890 new_mod->addCell(it.first, it.second);
891
892 for (auto &it : processes)
893 new_mod->processes[it.first] = it.second->clone();
894
895 struct RewriteSigSpecWorker
896 {
897 RTLIL::Module *mod;
898 void operator()(RTLIL::SigSpec &sig)
899 {
900 std::vector<RTLIL::SigChunk> chunks = sig.chunks();
901 for (auto &c : chunks)
902 if (c.wire != NULL)
903 c.wire = mod->wires_.at(c.wire->name);
904 sig = chunks;
905 }
906 };
907
908 RewriteSigSpecWorker rewriteSigSpecWorker;
909 rewriteSigSpecWorker.mod = new_mod;
910 new_mod->rewrite_sigspecs(rewriteSigSpecWorker);
911 }
912
913 RTLIL::Module *RTLIL::Module::clone() const
914 {
915 RTLIL::Module *new_mod = new RTLIL::Module;
916 new_mod->name = name;
917 cloneInto(new_mod);
918 return new_mod;
919 }
920
921 bool RTLIL::Module::has_memories() const
922 {
923 return !memories.empty();
924 }
925
926 bool RTLIL::Module::has_processes() const
927 {
928 return !processes.empty();
929 }
930
931 bool RTLIL::Module::has_memories_warn() const
932 {
933 if (!memories.empty())
934 log("Warning: Ignoring module %s because it contains memories (run 'memory' command first).\n", log_id(this));
935 return !memories.empty();
936 }
937
938 bool RTLIL::Module::has_processes_warn() const
939 {
940 if (!processes.empty())
941 log("Warning: Ignoring module %s because it contains processes (run 'proc' command first).\n", log_id(this));
942 return !processes.empty();
943 }
944
945 std::vector<RTLIL::Wire*> RTLIL::Module::selected_wires() const
946 {
947 std::vector<RTLIL::Wire*> result;
948 result.reserve(wires_.size());
949 for (auto &it : wires_)
950 if (design->selected(this, it.second))
951 result.push_back(it.second);
952 return result;
953 }
954
955 std::vector<RTLIL::Cell*> RTLIL::Module::selected_cells() const
956 {
957 std::vector<RTLIL::Cell*> result;
958 result.reserve(wires_.size());
959 for (auto &it : cells_)
960 if (design->selected(this, it.second))
961 result.push_back(it.second);
962 return result;
963 }
964
965 void RTLIL::Module::add(RTLIL::Wire *wire)
966 {
967 log_assert(!wire->name.empty());
968 log_assert(count_id(wire->name) == 0);
969 log_assert(refcount_wires_ == 0);
970 wires_[wire->name] = wire;
971 wire->module = this;
972 }
973
974 void RTLIL::Module::add(RTLIL::Cell *cell)
975 {
976 log_assert(!cell->name.empty());
977 log_assert(count_id(cell->name) == 0);
978 log_assert(refcount_cells_ == 0);
979 cells_[cell->name] = cell;
980 cell->module = this;
981 }
982
983 namespace {
984 struct DeleteWireWorker
985 {
986 RTLIL::Module *module;
987 const std::set<RTLIL::Wire*> *wires_p;
988
989 void operator()(RTLIL::SigSpec &sig) {
990 std::vector<RTLIL::SigChunk> chunks = sig;
991 for (auto &c : chunks)
992 if (c.wire != NULL && wires_p->count(c.wire)) {
993 c.wire = module->addWire(NEW_ID, c.width);
994 c.offset = 0;
995 }
996 sig = chunks;
997 }
998 };
999 }
1000
1001 #if 0
1002 void RTLIL::Module::remove(RTLIL::Wire *wire)
1003 {
1004 std::set<RTLIL::Wire*> wires_;
1005 wires_.insert(wire);
1006 remove(wires_);
1007 }
1008 #endif
1009
1010 void RTLIL::Module::remove(const std::set<RTLIL::Wire*> &wires)
1011 {
1012 log_assert(refcount_wires_ == 0);
1013
1014 DeleteWireWorker delete_wire_worker;
1015 delete_wire_worker.module = this;
1016 delete_wire_worker.wires_p = &wires;
1017 rewrite_sigspecs(delete_wire_worker);
1018
1019 for (auto &it : wires) {
1020 log_assert(wires_.count(it->name) != 0);
1021 wires_.erase(it->name);
1022 delete it;
1023 }
1024 }
1025
1026 void RTLIL::Module::remove(RTLIL::Cell *cell)
1027 {
1028 log_assert(cells_.count(cell->name) != 0);
1029 log_assert(refcount_cells_ == 0);
1030 cells_.erase(cell->name);
1031 delete cell;
1032 }
1033
1034 void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name)
1035 {
1036 log_assert(wires_[wire->name] == wire);
1037 log_assert(refcount_wires_ == 0);
1038 wires_.erase(wire->name);
1039 wire->name = new_name;
1040 add(wire);
1041 }
1042
1043 void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name)
1044 {
1045 log_assert(cells_[cell->name] == cell);
1046 log_assert(refcount_wires_ == 0);
1047 cells_.erase(cell->name);
1048 cell->name = new_name;
1049 add(cell);
1050 }
1051
1052 void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name)
1053 {
1054 log_assert(count_id(old_name) != 0);
1055 if (wires_.count(old_name))
1056 rename(wires_.at(old_name), new_name);
1057 else if (cells_.count(old_name))
1058 rename(cells_.at(old_name), new_name);
1059 else
1060 log_abort();
1061 }
1062
1063 static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
1064 {
1065 if (a->port_id && !b->port_id)
1066 return true;
1067 if (!a->port_id && b->port_id)
1068 return false;
1069
1070 if (a->port_id == b->port_id)
1071 return a->name < b->name;
1072 return a->port_id < b->port_id;
1073 }
1074
1075 void RTLIL::Module::connect(const RTLIL::SigSig &conn)
1076 {
1077 for (auto mon : monitors)
1078 mon->notify_connect(this, conn);
1079
1080 if (design)
1081 for (auto mon : design->monitors)
1082 mon->notify_connect(this, conn);
1083
1084 connections_.push_back(conn);
1085 }
1086
1087 void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs)
1088 {
1089 connect(RTLIL::SigSig(lhs, rhs));
1090 }
1091
1092 void RTLIL::Module::new_connections(const std::vector<RTLIL::SigSig> &new_conn)
1093 {
1094 for (auto mon : monitors)
1095 mon->notify_new_connections(this, new_conn);
1096
1097 if (design)
1098 for (auto mon : design->monitors)
1099 mon->notify_new_connections(this, new_conn);
1100
1101 connections_ = new_conn;
1102 }
1103
1104 const std::vector<RTLIL::SigSig> &RTLIL::Module::connections() const
1105 {
1106 return connections_;
1107 }
1108
1109 void RTLIL::Module::fixup_ports()
1110 {
1111 std::vector<RTLIL::Wire*> all_ports;
1112
1113 for (auto &w : wires_)
1114 if (w.second->port_input || w.second->port_output)
1115 all_ports.push_back(w.second);
1116 else
1117 w.second->port_id = 0;
1118
1119 std::sort(all_ports.begin(), all_ports.end(), fixup_ports_compare);
1120 for (size_t i = 0; i < all_ports.size(); i++)
1121 all_ports[i]->port_id = i+1;
1122 }
1123
1124 RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width)
1125 {
1126 RTLIL::Wire *wire = new RTLIL::Wire;
1127 wire->name = name;
1128 wire->width = width;
1129 add(wire);
1130 return wire;
1131 }
1132
1133 RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *other)
1134 {
1135 RTLIL::Wire *wire = addWire(name);
1136 wire->width = other->width;
1137 wire->start_offset = other->start_offset;
1138 wire->port_id = other->port_id;
1139 wire->port_input = other->port_input;
1140 wire->port_output = other->port_output;
1141 wire->upto = other->upto;
1142 wire->attributes = other->attributes;
1143 return wire;
1144 }
1145
1146 RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type)
1147 {
1148 RTLIL::Cell *cell = new RTLIL::Cell;
1149 cell->name = name;
1150 cell->type = type;
1151 add(cell);
1152 return cell;
1153 }
1154
1155 RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *other)
1156 {
1157 RTLIL::Cell *cell = addCell(name, other->type);
1158 cell->connections_ = other->connections_;
1159 cell->parameters = other->parameters;
1160 cell->attributes = other->attributes;
1161 return cell;
1162 }
1163
1164 #define DEF_METHOD(_func, _y_size, _type) \
1165 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \
1166 RTLIL::Cell *cell = addCell(name, _type); \
1167 cell->parameters["\\A_SIGNED"] = is_signed; \
1168 cell->parameters["\\A_WIDTH"] = sig_a.size(); \
1169 cell->parameters["\\Y_WIDTH"] = sig_y.size(); \
1170 cell->set("\\A", sig_a); \
1171 cell->set("\\Y", sig_y); \
1172 return cell; \
1173 } \
1174 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed) { \
1175 RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
1176 add ## _func(name, sig_a, sig_y, is_signed); \
1177 return sig_y; \
1178 }
1179 DEF_METHOD(Not, sig_a.size(), "$not")
1180 DEF_METHOD(Pos, sig_a.size(), "$pos")
1181 DEF_METHOD(Bu0, sig_a.size(), "$bu0")
1182 DEF_METHOD(Neg, sig_a.size(), "$neg")
1183 DEF_METHOD(ReduceAnd, 1, "$reduce_and")
1184 DEF_METHOD(ReduceOr, 1, "$reduce_or")
1185 DEF_METHOD(ReduceXor, 1, "$reduce_xor")
1186 DEF_METHOD(ReduceXnor, 1, "$reduce_xnor")
1187 DEF_METHOD(ReduceBool, 1, "$reduce_bool")
1188 DEF_METHOD(LogicNot, 1, "$logic_not")
1189 #undef DEF_METHOD
1190
1191 #define DEF_METHOD(_func, _y_size, _type) \
1192 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed) { \
1193 RTLIL::Cell *cell = addCell(name, _type); \
1194 cell->parameters["\\A_SIGNED"] = is_signed; \
1195 cell->parameters["\\B_SIGNED"] = is_signed; \
1196 cell->parameters["\\A_WIDTH"] = sig_a.size(); \
1197 cell->parameters["\\B_WIDTH"] = sig_b.size(); \
1198 cell->parameters["\\Y_WIDTH"] = sig_y.size(); \
1199 cell->set("\\A", sig_a); \
1200 cell->set("\\B", sig_b); \
1201 cell->set("\\Y", sig_y); \
1202 return cell; \
1203 } \
1204 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed) { \
1205 RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
1206 add ## _func(name, sig_a, sig_b, sig_y, is_signed); \
1207 return sig_y; \
1208 }
1209 DEF_METHOD(And, std::max(sig_a.size(), sig_b.size()), "$and")
1210 DEF_METHOD(Or, std::max(sig_a.size(), sig_b.size()), "$or")
1211 DEF_METHOD(Xor, std::max(sig_a.size(), sig_b.size()), "$xor")
1212 DEF_METHOD(Xnor, std::max(sig_a.size(), sig_b.size()), "$xnor")
1213 DEF_METHOD(Shl, sig_a.size(), "$shl")
1214 DEF_METHOD(Shr, sig_a.size(), "$shr")
1215 DEF_METHOD(Sshl, sig_a.size(), "$sshl")
1216 DEF_METHOD(Sshr, sig_a.size(), "$sshr")
1217 DEF_METHOD(Shift, sig_a.size(), "$shift")
1218 DEF_METHOD(Shiftx, sig_a.size(), "$shiftx")
1219 DEF_METHOD(Lt, 1, "$lt")
1220 DEF_METHOD(Le, 1, "$le")
1221 DEF_METHOD(Eq, 1, "$eq")
1222 DEF_METHOD(Ne, 1, "$ne")
1223 DEF_METHOD(Eqx, 1, "$eqx")
1224 DEF_METHOD(Nex, 1, "$nex")
1225 DEF_METHOD(Ge, 1, "$ge")
1226 DEF_METHOD(Gt, 1, "$gt")
1227 DEF_METHOD(Add, std::max(sig_a.size(), sig_b.size()), "$add")
1228 DEF_METHOD(Sub, std::max(sig_a.size(), sig_b.size()), "$sub")
1229 DEF_METHOD(Mul, std::max(sig_a.size(), sig_b.size()), "$mul")
1230 DEF_METHOD(Div, std::max(sig_a.size(), sig_b.size()), "$div")
1231 DEF_METHOD(Mod, std::max(sig_a.size(), sig_b.size()), "$mod")
1232 DEF_METHOD(LogicAnd, 1, "$logic_and")
1233 DEF_METHOD(LogicOr, 1, "$logic_or")
1234 #undef DEF_METHOD
1235
1236 #define DEF_METHOD(_func, _type, _pmux) \
1237 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y) { \
1238 RTLIL::Cell *cell = addCell(name, _type); \
1239 cell->parameters["\\WIDTH"] = sig_a.size(); \
1240 cell->parameters["\\WIDTH"] = sig_b.size(); \
1241 if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \
1242 cell->set("\\A", sig_a); \
1243 cell->set("\\B", sig_b); \
1244 cell->set("\\S", sig_s); \
1245 cell->set("\\Y", sig_y); \
1246 return cell; \
1247 } \
1248 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \
1249 RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \
1250 add ## _func(name, sig_a, sig_b, sig_s, sig_y); \
1251 return sig_y; \
1252 }
1253 DEF_METHOD(Mux, "$mux", 0)
1254 DEF_METHOD(Pmux, "$pmux", 1)
1255 DEF_METHOD(SafePmux, "$safe_pmux", 1)
1256 #undef DEF_METHOD
1257
1258 #define DEF_METHOD_2(_func, _type, _P1, _P2) \
1259 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \
1260 RTLIL::Cell *cell = addCell(name, _type); \
1261 cell->set("\\" #_P1, sig1); \
1262 cell->set("\\" #_P2, sig2); \
1263 return cell; \
1264 } \
1265 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1) { \
1266 RTLIL::SigSpec sig2 = addWire(NEW_ID); \
1267 add ## _func(name, sig1, sig2); \
1268 return sig2; \
1269 }
1270 #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \
1271 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \
1272 RTLIL::Cell *cell = addCell(name, _type); \
1273 cell->set("\\" #_P1, sig1); \
1274 cell->set("\\" #_P2, sig2); \
1275 cell->set("\\" #_P3, sig3); \
1276 return cell; \
1277 } \
1278 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \
1279 RTLIL::SigSpec sig3 = addWire(NEW_ID); \
1280 add ## _func(name, sig1, sig2, sig3); \
1281 return sig3; \
1282 }
1283 #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \
1284 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3, RTLIL::SigSpec sig4) { \
1285 RTLIL::Cell *cell = addCell(name, _type); \
1286 cell->set("\\" #_P1, sig1); \
1287 cell->set("\\" #_P2, sig2); \
1288 cell->set("\\" #_P3, sig3); \
1289 cell->set("\\" #_P4, sig4); \
1290 return cell; \
1291 } \
1292 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \
1293 RTLIL::SigSpec sig4 = addWire(NEW_ID); \
1294 add ## _func(name, sig1, sig2, sig3, sig4); \
1295 return sig4; \
1296 }
1297 DEF_METHOD_2(InvGate, "$_INV_", A, Y)
1298 DEF_METHOD_3(AndGate, "$_AND_", A, B, Y)
1299 DEF_METHOD_3(OrGate, "$_OR_", A, B, Y)
1300 DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y)
1301 DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y)
1302 #undef DEF_METHOD_2
1303 #undef DEF_METHOD_3
1304 #undef DEF_METHOD_4
1305
1306 RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed)
1307 {
1308 RTLIL::Cell *cell = addCell(name, "$pow");
1309 cell->parameters["\\A_SIGNED"] = a_signed;
1310 cell->parameters["\\B_SIGNED"] = b_signed;
1311 cell->parameters["\\A_WIDTH"] = sig_a.size();
1312 cell->parameters["\\B_WIDTH"] = sig_b.size();
1313 cell->parameters["\\Y_WIDTH"] = sig_y.size();
1314 cell->set("\\A", sig_a);
1315 cell->set("\\B", sig_b);
1316 cell->set("\\Y", sig_y);
1317 return cell;
1318 }
1319
1320 RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset)
1321 {
1322 RTLIL::Cell *cell = addCell(name, "$slice");
1323 cell->parameters["\\A_WIDTH"] = sig_a.size();
1324 cell->parameters["\\Y_WIDTH"] = sig_y.size();
1325 cell->parameters["\\OFFSET"] = offset;
1326 cell->set("\\A", sig_a);
1327 cell->set("\\Y", sig_y);
1328 return cell;
1329 }
1330
1331 RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y)
1332 {
1333 RTLIL::Cell *cell = addCell(name, "$concat");
1334 cell->parameters["\\A_WIDTH"] = sig_a.size();
1335 cell->parameters["\\B_WIDTH"] = sig_b.size();
1336 cell->set("\\A", sig_a);
1337 cell->set("\\B", sig_b);
1338 cell->set("\\Y", sig_y);
1339 return cell;
1340 }
1341
1342 RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, RTLIL::SigSpec sig_o, RTLIL::Const lut)
1343 {
1344 RTLIL::Cell *cell = addCell(name, "$lut");
1345 cell->parameters["\\LUT"] = lut;
1346 cell->parameters["\\WIDTH"] = sig_i.size();
1347 cell->set("\\I", sig_i);
1348 cell->set("\\O", sig_o);
1349 return cell;
1350 }
1351
1352 RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en)
1353 {
1354 RTLIL::Cell *cell = addCell(name, "$assert");
1355 cell->set("\\A", sig_a);
1356 cell->set("\\EN", sig_en);
1357 return cell;
1358 }
1359
1360 RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity)
1361 {
1362 RTLIL::Cell *cell = addCell(name, "$sr");
1363 cell->parameters["\\SET_POLARITY"] = set_polarity;
1364 cell->parameters["\\CLR_POLARITY"] = clr_polarity;
1365 cell->parameters["\\WIDTH"] = sig_q.size();
1366 cell->set("\\SET", sig_set);
1367 cell->set("\\CLR", sig_clr);
1368 cell->set("\\Q", sig_q);
1369 return cell;
1370 }
1371
1372 RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity)
1373 {
1374 RTLIL::Cell *cell = addCell(name, "$dff");
1375 cell->parameters["\\CLK_POLARITY"] = clk_polarity;
1376 cell->parameters["\\WIDTH"] = sig_q.size();
1377 cell->set("\\CLK", sig_clk);
1378 cell->set("\\D", sig_d);
1379 cell->set("\\Q", sig_q);
1380 return cell;
1381 }
1382
1383 RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
1384 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity)
1385 {
1386 RTLIL::Cell *cell = addCell(name, "$dffsr");
1387 cell->parameters["\\CLK_POLARITY"] = clk_polarity;
1388 cell->parameters["\\SET_POLARITY"] = set_polarity;
1389 cell->parameters["\\CLR_POLARITY"] = clr_polarity;
1390 cell->parameters["\\WIDTH"] = sig_q.size();
1391 cell->set("\\CLK", sig_clk);
1392 cell->set("\\SET", sig_set);
1393 cell->set("\\CLR", sig_clr);
1394 cell->set("\\D", sig_d);
1395 cell->set("\\Q", sig_q);
1396 return cell;
1397 }
1398
1399 RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
1400 RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity)
1401 {
1402 RTLIL::Cell *cell = addCell(name, "$adff");
1403 cell->parameters["\\CLK_POLARITY"] = clk_polarity;
1404 cell->parameters["\\ARST_POLARITY"] = arst_polarity;
1405 cell->parameters["\\ARST_VALUE"] = arst_value;
1406 cell->parameters["\\WIDTH"] = sig_q.size();
1407 cell->set("\\CLK", sig_clk);
1408 cell->set("\\ARST", sig_arst);
1409 cell->set("\\D", sig_d);
1410 cell->set("\\Q", sig_q);
1411 return cell;
1412 }
1413
1414 RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity)
1415 {
1416 RTLIL::Cell *cell = addCell(name, "$dlatch");
1417 cell->parameters["\\EN_POLARITY"] = en_polarity;
1418 cell->parameters["\\WIDTH"] = sig_q.size();
1419 cell->set("\\EN", sig_en);
1420 cell->set("\\D", sig_d);
1421 cell->set("\\Q", sig_q);
1422 return cell;
1423 }
1424
1425 RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
1426 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity)
1427 {
1428 RTLIL::Cell *cell = addCell(name, "$dlatchsr");
1429 cell->parameters["\\EN_POLARITY"] = en_polarity;
1430 cell->parameters["\\SET_POLARITY"] = set_polarity;
1431 cell->parameters["\\CLR_POLARITY"] = clr_polarity;
1432 cell->parameters["\\WIDTH"] = sig_q.size();
1433 cell->set("\\EN", sig_en);
1434 cell->set("\\SET", sig_set);
1435 cell->set("\\CLR", sig_clr);
1436 cell->set("\\D", sig_d);
1437 cell->set("\\Q", sig_q);
1438 return cell;
1439 }
1440
1441 RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity)
1442 {
1443 RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'));
1444 cell->set("\\C", sig_clk);
1445 cell->set("\\D", sig_d);
1446 cell->set("\\Q", sig_q);
1447 return cell;
1448 }
1449
1450 RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
1451 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity)
1452 {
1453 RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
1454 cell->set("\\C", sig_clk);
1455 cell->set("\\S", sig_set);
1456 cell->set("\\R", sig_clr);
1457 cell->set("\\D", sig_d);
1458 cell->set("\\Q", sig_q);
1459 return cell;
1460 }
1461
1462 RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
1463 bool arst_value, bool clk_polarity, bool arst_polarity)
1464 {
1465 RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'));
1466 cell->set("\\C", sig_clk);
1467 cell->set("\\R", sig_arst);
1468 cell->set("\\D", sig_d);
1469 cell->set("\\Q", sig_q);
1470 return cell;
1471 }
1472
1473 RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity)
1474 {
1475 RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'));
1476 cell->set("\\E", sig_en);
1477 cell->set("\\D", sig_d);
1478 cell->set("\\Q", sig_q);
1479 return cell;
1480 }
1481
1482 RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
1483 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity)
1484 {
1485 RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
1486 cell->set("\\E", sig_en);
1487 cell->set("\\S", sig_set);
1488 cell->set("\\R", sig_clr);
1489 cell->set("\\D", sig_d);
1490 cell->set("\\Q", sig_q);
1491 return cell;
1492 }
1493
1494
1495 RTLIL::Wire::Wire()
1496 {
1497 module = nullptr;
1498 width = 1;
1499 start_offset = 0;
1500 port_id = 0;
1501 port_input = false;
1502 port_output = false;
1503 upto = false;
1504 }
1505
1506 RTLIL::Memory::Memory()
1507 {
1508 width = 1;
1509 size = 0;
1510 }
1511
1512 bool RTLIL::Cell::has(RTLIL::IdString portname) const
1513 {
1514 return connections_.count(portname) != 0;
1515 }
1516
1517 void RTLIL::Cell::unset(RTLIL::IdString portname)
1518 {
1519 std::pair<RTLIL::IdString, RTLIL::SigSpec> new_conn(portname, RTLIL::SigSpec());
1520
1521 for (auto mon : module->monitors)
1522 mon->notify_cell_connect(this, new_conn);
1523
1524 if (module->design)
1525 for (auto mon : module->design->monitors)
1526 mon->notify_cell_connect(this, new_conn);
1527
1528 connections_.erase(portname);
1529 }
1530
1531 void RTLIL::Cell::set(RTLIL::IdString portname, RTLIL::SigSpec signal)
1532 {
1533 std::pair<RTLIL::IdString, RTLIL::SigSpec> new_conn(portname, signal);
1534
1535 for (auto mon : module->monitors)
1536 mon->notify_cell_connect(this, new_conn);
1537
1538 if (module->design)
1539 for (auto mon : module->design->monitors)
1540 mon->notify_cell_connect(this, new_conn);
1541
1542 connections_[portname] = signal;
1543 }
1544
1545 const RTLIL::SigSpec &RTLIL::Cell::get(RTLIL::IdString portname) const
1546 {
1547 return connections_.at(portname);
1548 }
1549
1550 const std::map<RTLIL::IdString, RTLIL::SigSpec> &RTLIL::Cell::connections() const
1551 {
1552 return connections_;
1553 }
1554
1555 void RTLIL::Cell::check()
1556 {
1557 #ifndef NDEBUG
1558 InternalCellChecker checker(NULL, this);
1559 checker.check();
1560 #endif
1561 }
1562
1563 void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
1564 {
1565 if (type[0] != '$' || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" ||
1566 type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:")
1567 return;
1568
1569 if (type == "$mux" || type == "$pmux" || type == "$safe_pmux")
1570 {
1571 parameters["\\WIDTH"] = SIZE(connections_["\\Y"]);
1572 if (type == "$pmux" || type == "$safe_pmux")
1573 parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]);
1574 check();
1575 return;
1576 }
1577
1578 bool signedness_ab = type != "$slice" && type != "$concat";
1579
1580 if (connections_.count("\\A")) {
1581 if (signedness_ab) {
1582 if (set_a_signed)
1583 parameters["\\A_SIGNED"] = true;
1584 else if (parameters.count("\\A_SIGNED") == 0)
1585 parameters["\\A_SIGNED"] = false;
1586 }
1587 parameters["\\A_WIDTH"] = SIZE(connections_["\\A"]);
1588 }
1589
1590 if (connections_.count("\\B")) {
1591 if (signedness_ab) {
1592 if (set_b_signed)
1593 parameters["\\B_SIGNED"] = true;
1594 else if (parameters.count("\\B_SIGNED") == 0)
1595 parameters["\\B_SIGNED"] = false;
1596 }
1597 parameters["\\B_WIDTH"] = SIZE(connections_["\\B"]);
1598 }
1599
1600 if (connections_.count("\\Y"))
1601 parameters["\\Y_WIDTH"] = SIZE(connections_["\\Y"]);
1602
1603 check();
1604 }
1605
1606 RTLIL::SigChunk::SigChunk()
1607 {
1608 wire = NULL;
1609 width = 0;
1610 offset = 0;
1611 }
1612
1613 RTLIL::SigChunk::SigChunk(const RTLIL::Const &value)
1614 {
1615 wire = NULL;
1616 data = value;
1617 width = data.bits.size();
1618 offset = 0;
1619 }
1620
1621 RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire)
1622 {
1623 log_assert(wire != nullptr);
1624 this->wire = wire;
1625 this->width = wire->width;
1626 this->offset = 0;
1627 }
1628
1629 RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int offset, int width)
1630 {
1631 log_assert(wire != nullptr);
1632 this->wire = wire;
1633 this->width = width;
1634 this->offset = offset;
1635 }
1636
1637 RTLIL::SigChunk::SigChunk(const std::string &str)
1638 {
1639 wire = NULL;
1640 data = RTLIL::Const(str);
1641 width = data.bits.size();
1642 offset = 0;
1643 }
1644
1645 RTLIL::SigChunk::SigChunk(int val, int width)
1646 {
1647 wire = NULL;
1648 data = RTLIL::Const(val, width);
1649 this->width = data.bits.size();
1650 offset = 0;
1651 }
1652
1653 RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width)
1654 {
1655 wire = NULL;
1656 data = RTLIL::Const(bit, width);
1657 this->width = data.bits.size();
1658 offset = 0;
1659 }
1660
1661 RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
1662 {
1663 wire = bit.wire;
1664 if (wire == NULL)
1665 data = RTLIL::Const(bit.data);
1666 offset = bit.offset;
1667 width = 1;
1668 }
1669
1670 RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
1671 {
1672 RTLIL::SigChunk ret;
1673 if (wire) {
1674 ret.wire = wire;
1675 ret.offset = this->offset + offset;
1676 ret.width = length;
1677 } else {
1678 for (int i = 0; i < length; i++)
1679 ret.data.bits.push_back(data.bits[offset+i]);
1680 ret.width = length;
1681 }
1682 return ret;
1683 }
1684
1685 bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk &other) const
1686 {
1687 if (wire && other.wire)
1688 if (wire->name != other.wire->name)
1689 return wire->name < other.wire->name;
1690
1691 if (wire != other.wire)
1692 return wire < other.wire;
1693
1694 if (offset != other.offset)
1695 return offset < other.offset;
1696
1697 if (width != other.width)
1698 return width < other.width;
1699
1700 return data.bits < other.data.bits;
1701 }
1702
1703 bool RTLIL::SigChunk::operator ==(const RTLIL::SigChunk &other) const
1704 {
1705 if (wire != other.wire || width != other.width || offset != other.offset)
1706 return false;
1707 if (data.bits != other.data.bits)
1708 return false;
1709 return true;
1710 }
1711
1712 bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const
1713 {
1714 if (*this == other)
1715 return false;
1716 return true;
1717 }
1718
1719 RTLIL::SigSpec::SigSpec()
1720 {
1721 width_ = 0;
1722 hash_ = 0;
1723 }
1724
1725 RTLIL::SigSpec::SigSpec(const RTLIL::SigSpec &other)
1726 {
1727 *this = other;
1728 }
1729
1730 RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
1731 {
1732 cover("kernel.rtlil.sigspec.init.list");
1733
1734 width_ = 0;
1735 hash_ = 0;
1736
1737 std::vector<RTLIL::SigSpec> parts_vec(parts.begin(), parts.end());
1738 for (auto it = parts_vec.rbegin(); it != parts_vec.rend(); it++)
1739 append(*it);
1740 }
1741
1742 const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other)
1743 {
1744 cover("kernel.rtlil.sigspec.assign");
1745
1746 width_ = other.width_;
1747 hash_ = other.hash_;
1748 chunks_ = other.chunks_;
1749 bits_.clear();
1750
1751 if (!other.bits_.empty())
1752 {
1753 RTLIL::SigChunk *last = NULL;
1754 int last_end_offset = 0;
1755
1756 for (auto &bit : other.bits_) {
1757 if (last && bit.wire == last->wire) {
1758 if (bit.wire == NULL) {
1759 last->data.bits.push_back(bit.data);
1760 last->width++;
1761 continue;
1762 } else if (last_end_offset == bit.offset) {
1763 last_end_offset++;
1764 last->width++;
1765 continue;
1766 }
1767 }
1768 chunks_.push_back(bit);
1769 last = &chunks_.back();
1770 last_end_offset = bit.offset + 1;
1771 }
1772
1773 check();
1774 }
1775
1776 return *this;
1777 }
1778
1779 RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
1780 {
1781 cover("kernel.rtlil.sigspec.init.const");
1782
1783 chunks_.push_back(RTLIL::SigChunk(value));
1784 width_ = chunks_.back().width;
1785 hash_ = 0;
1786 check();
1787 }
1788
1789 RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
1790 {
1791 cover("kernel.rtlil.sigspec.init.chunk");
1792
1793 chunks_.push_back(chunk);
1794 width_ = chunks_.back().width;
1795 hash_ = 0;
1796 check();
1797 }
1798
1799 RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
1800 {
1801 cover("kernel.rtlil.sigspec.init.wire");
1802
1803 chunks_.push_back(RTLIL::SigChunk(wire));
1804 width_ = chunks_.back().width;
1805 hash_ = 0;
1806 check();
1807 }
1808
1809 RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
1810 {
1811 cover("kernel.rtlil.sigspec.init.wire_part");
1812
1813 chunks_.push_back(RTLIL::SigChunk(wire, offset, width));
1814 width_ = chunks_.back().width;
1815 hash_ = 0;
1816 check();
1817 }
1818
1819 RTLIL::SigSpec::SigSpec(const std::string &str)
1820 {
1821 cover("kernel.rtlil.sigspec.init.str");
1822
1823 chunks_.push_back(RTLIL::SigChunk(str));
1824 width_ = chunks_.back().width;
1825 hash_ = 0;
1826 check();
1827 }
1828
1829 RTLIL::SigSpec::SigSpec(int val, int width)
1830 {
1831 cover("kernel.rtlil.sigspec.init.int");
1832
1833 chunks_.push_back(RTLIL::SigChunk(val, width));
1834 width_ = width;
1835 hash_ = 0;
1836 check();
1837 }
1838
1839 RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
1840 {
1841 cover("kernel.rtlil.sigspec.init.state");
1842
1843 chunks_.push_back(RTLIL::SigChunk(bit, width));
1844 width_ = width;
1845 hash_ = 0;
1846 check();
1847 }
1848
1849 RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
1850 {
1851 cover("kernel.rtlil.sigspec.init.bit");
1852
1853 if (bit.wire == NULL)
1854 chunks_.push_back(RTLIL::SigChunk(bit.data, width));
1855 else
1856 for (int i = 0; i < width; i++)
1857 chunks_.push_back(bit);
1858 width_ = width;
1859 hash_ = 0;
1860 check();
1861 }
1862
1863 RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks)
1864 {
1865 cover("kernel.rtlil.sigspec.init.stdvec_chunks");
1866
1867 width_ = 0;
1868 hash_ = 0;
1869 for (auto &c : chunks)
1870 append(c);
1871 check();
1872 }
1873
1874 RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
1875 {
1876 cover("kernel.rtlil.sigspec.init.stdvec_bits");
1877
1878 width_ = 0;
1879 hash_ = 0;
1880 for (auto &bit : bits)
1881 append_bit(bit);
1882 check();
1883 }
1884
1885 RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
1886 {
1887 cover("kernel.rtlil.sigspec.init.stdset_bits");
1888
1889 width_ = 0;
1890 hash_ = 0;
1891 for (auto &bit : bits)
1892 append_bit(bit);
1893 check();
1894 }
1895
1896 void RTLIL::SigSpec::pack() const
1897 {
1898 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
1899
1900 if (that->bits_.empty())
1901 return;
1902
1903 cover("kernel.rtlil.sigspec.convert.pack");
1904 log_assert(that->chunks_.empty());
1905
1906 std::vector<RTLIL::SigBit> old_bits;
1907 old_bits.swap(that->bits_);
1908
1909 RTLIL::SigChunk *last = NULL;
1910 int last_end_offset = 0;
1911
1912 for (auto &bit : old_bits) {
1913 if (last && bit.wire == last->wire) {
1914 if (bit.wire == NULL) {
1915 last->data.bits.push_back(bit.data);
1916 last->width++;
1917 continue;
1918 } else if (last_end_offset == bit.offset) {
1919 last_end_offset++;
1920 last->width++;
1921 continue;
1922 }
1923 }
1924 that->chunks_.push_back(bit);
1925 last = &that->chunks_.back();
1926 last_end_offset = bit.offset + 1;
1927 }
1928
1929 check();
1930 }
1931
1932 void RTLIL::SigSpec::unpack() const
1933 {
1934 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
1935
1936 if (that->chunks_.empty())
1937 return;
1938
1939 cover("kernel.rtlil.sigspec.convert.unpack");
1940 log_assert(that->bits_.empty());
1941
1942 that->bits_.reserve(that->width_);
1943 for (auto &c : that->chunks_)
1944 for (int i = 0; i < c.width; i++)
1945 that->bits_.push_back(RTLIL::SigBit(c, i));
1946
1947 that->chunks_.clear();
1948 that->hash_ = 0;
1949 }
1950
1951 #define DJB2(_hash, _value) do { (_hash) = (((_hash) << 5) + (_hash)) + (_value); } while (0)
1952
1953 void RTLIL::SigSpec::hash() const
1954 {
1955 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
1956
1957 if (that->hash_ != 0)
1958 return;
1959
1960 cover("kernel.rtlil.sigspec.hash");
1961 that->pack();
1962
1963 that->hash_ = 5381;
1964 for (auto &c : that->chunks_)
1965 if (c.wire == NULL) {
1966 for (auto &v : c.data.bits)
1967 DJB2(that->hash_, v);
1968 } else {
1969 for (auto &v : c.wire->name)
1970 DJB2(that->hash_, v);
1971 DJB2(that->hash_, c.offset);
1972 DJB2(that->hash_, c.width);
1973 }
1974
1975 if (that->hash_ == 0)
1976 that->hash_ = 1;
1977 }
1978
1979 void RTLIL::SigSpec::sort()
1980 {
1981 unpack();
1982 cover("kernel.rtlil.sigspec.sort");
1983 std::sort(bits_.begin(), bits_.end());
1984 }
1985
1986 void RTLIL::SigSpec::sort_and_unify()
1987 {
1988 cover("kernel.rtlil.sigspec.sort_and_unify");
1989 *this = this->to_sigbit_set();
1990 }
1991
1992 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
1993 {
1994 replace(pattern, with, this);
1995 }
1996
1997 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const
1998 {
1999 cover("kernel.rtlil.sigspec.replace");
2000
2001 unpack();
2002 pattern.unpack();
2003 with.unpack();
2004
2005 log_assert(other != NULL);
2006 log_assert(width_ == other->width_);
2007 other->unpack();
2008
2009 log_assert(pattern.width_ == with.width_);
2010
2011 std::map<RTLIL::SigBit, RTLIL::SigBit> pattern_map;
2012 for (int i = 0; i < SIZE(pattern.bits_); i++)
2013 if (pattern.bits_[i].wire != NULL)
2014 pattern_map[pattern.bits_[i]] = with.bits_[i];
2015
2016 for (int i = 0; i < SIZE(bits_); i++)
2017 if (pattern_map.count(bits_[i]))
2018 other->bits_[i] = pattern_map.at(bits_[i]);
2019
2020 other->check();
2021 }
2022
2023 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern)
2024 {
2025 remove2(pattern, NULL);
2026 }
2027
2028 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const
2029 {
2030 RTLIL::SigSpec tmp = *this;
2031 tmp.remove2(pattern, other);
2032 }
2033
2034 void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
2035 {
2036 if (other)
2037 cover("kernel.rtlil.sigspec.remove_other");
2038 else
2039 cover("kernel.rtlil.sigspec.remove");
2040
2041 unpack();
2042
2043 if (other != NULL) {
2044 log_assert(width_ == other->width_);
2045 other->unpack();
2046 }
2047
2048 std::set<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_set();
2049 std::vector<RTLIL::SigBit> new_bits, new_other_bits;
2050
2051 for (int i = 0; i < SIZE(bits_); i++) {
2052 if (bits_[i].wire != NULL && pattern_bits.count(bits_[i]))
2053 continue;
2054 if (other != NULL)
2055 new_other_bits.push_back(other->bits_[i]);
2056 new_bits.push_back(bits_[i]);
2057 }
2058
2059 bits_.swap(new_bits);
2060 width_ = SIZE(bits_);
2061
2062 if (other != NULL) {
2063 other->bits_.swap(new_other_bits);
2064 other->width_ = SIZE(other->bits_);
2065 }
2066
2067 check();
2068 }
2069
2070 RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other) const
2071 {
2072 if (other)
2073 cover("kernel.rtlil.sigspec.extract_other");
2074 else
2075 cover("kernel.rtlil.sigspec.extract");
2076
2077 pack();
2078 pattern.pack();
2079
2080 if (other != NULL)
2081 other->pack();
2082
2083 log_assert(other == NULL || width_ == other->width_);
2084
2085 std::set<RTLIL::SigBit> pat = pattern.to_sigbit_set();
2086 std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
2087 RTLIL::SigSpec ret;
2088
2089 if (other) {
2090 std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector();
2091 for (int i = 0; i < width_; i++)
2092 if (bits_match[i].wire && pat.count(bits_match[i]))
2093 ret.append_bit(bits_other[i]);
2094 } else {
2095 for (int i = 0; i < width_; i++)
2096 if (bits_match[i].wire && pat.count(bits_match[i]))
2097 ret.append_bit(bits_match[i]);
2098 }
2099
2100 ret.check();
2101 return ret;
2102 }
2103
2104 void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
2105 {
2106 cover("kernel.rtlil.sigspec.replace_pos");
2107
2108 unpack();
2109 with.unpack();
2110
2111 log_assert(offset >= 0);
2112 log_assert(with.width_ >= 0);
2113 log_assert(offset+with.width_ <= width_);
2114
2115 for (int i = 0; i < with.width_; i++)
2116 bits_.at(offset + i) = with.bits_.at(i);
2117
2118 check();
2119 }
2120
2121 void RTLIL::SigSpec::remove_const()
2122 {
2123 if (packed())
2124 {
2125 cover("kernel.rtlil.sigspec.remove_const.packed");
2126
2127 std::vector<RTLIL::SigChunk> new_chunks;
2128 new_chunks.reserve(SIZE(chunks_));
2129
2130 width_ = 0;
2131 for (auto &chunk : chunks_)
2132 if (chunk.wire != NULL) {
2133 new_chunks.push_back(chunk);
2134 width_ += chunk.width;
2135 }
2136
2137 chunks_.swap(new_chunks);
2138 }
2139 else
2140 {
2141 cover("kernel.rtlil.sigspec.remove_const.unpacked");
2142
2143 std::vector<RTLIL::SigBit> new_bits;
2144 new_bits.reserve(width_);
2145
2146 for (auto &bit : bits_)
2147 if (bit.wire != NULL)
2148 new_bits.push_back(bit);
2149
2150 bits_.swap(new_bits);
2151 width_ = bits_.size();
2152 }
2153
2154 check();
2155 }
2156
2157 void RTLIL::SigSpec::remove(int offset, int length)
2158 {
2159 cover("kernel.rtlil.sigspec.remove_pos");
2160
2161 unpack();
2162
2163 log_assert(offset >= 0);
2164 log_assert(length >= 0);
2165 log_assert(offset + length <= width_);
2166
2167 bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length);
2168 width_ = bits_.size();
2169
2170 check();
2171 }
2172
2173 RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
2174 {
2175 unpack();
2176 cover("kernel.rtlil.sigspec.extract_pos");
2177 return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
2178 }
2179
2180 void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
2181 {
2182 if (signal.width_ == 0)
2183 return;
2184
2185 if (width_ == 0) {
2186 *this = signal;
2187 return;
2188 }
2189
2190 cover("kernel.rtlil.sigspec.append");
2191
2192 if (packed() != signal.packed()) {
2193 pack();
2194 signal.pack();
2195 }
2196
2197 if (packed())
2198 for (auto &other_c : signal.chunks_)
2199 {
2200 auto &my_last_c = chunks_.back();
2201 if (my_last_c.wire == NULL && other_c.wire == NULL) {
2202 auto &this_data = my_last_c.data.bits;
2203 auto &other_data = other_c.data.bits;
2204 this_data.insert(this_data.end(), other_data.begin(), other_data.end());
2205 my_last_c.width += other_c.width;
2206 } else
2207 if (my_last_c.wire == other_c.wire && my_last_c.offset + my_last_c.width == other_c.offset) {
2208 my_last_c.width += other_c.width;
2209 } else
2210 chunks_.push_back(other_c);
2211 }
2212 else
2213 bits_.insert(bits_.end(), signal.bits_.begin(), signal.bits_.end());
2214
2215 width_ += signal.width_;
2216 check();
2217 }
2218
2219 void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
2220 {
2221 if (packed())
2222 {
2223 cover("kernel.rtlil.sigspec.append_bit.packed");
2224
2225 if (chunks_.size() == 0)
2226 chunks_.push_back(bit);
2227 else
2228 if (bit.wire == NULL)
2229 if (chunks_.back().wire == NULL) {
2230 chunks_.back().data.bits.push_back(bit.data);
2231 chunks_.back().width++;
2232 } else
2233 chunks_.push_back(bit);
2234 else
2235 if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset)
2236 chunks_.back().width++;
2237 else
2238 chunks_.push_back(bit);
2239 }
2240 else
2241 {
2242 cover("kernel.rtlil.sigspec.append_bit.unpacked");
2243 bits_.push_back(bit);
2244 }
2245
2246 width_++;
2247 check();
2248 }
2249
2250 void RTLIL::SigSpec::extend(int width, bool is_signed)
2251 {
2252 cover("kernel.rtlil.sigspec.extend");
2253
2254 pack();
2255
2256 if (width_ > width)
2257 remove(width, width_ - width);
2258
2259 if (width_ < width) {
2260 RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
2261 if (!is_signed && padding != RTLIL::SigSpec(RTLIL::State::Sx) && padding != RTLIL::SigSpec(RTLIL::State::Sz) &&
2262 padding != RTLIL::SigSpec(RTLIL::State::Sa) && padding != RTLIL::SigSpec(RTLIL::State::Sm))
2263 padding = RTLIL::SigSpec(RTLIL::State::S0);
2264 while (width_ < width)
2265 append(padding);
2266 }
2267 }
2268
2269 void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
2270 {
2271 cover("kernel.rtlil.sigspec.extend_u0");
2272
2273 pack();
2274
2275 if (width_ > width)
2276 remove(width, width_ - width);
2277
2278 if (width_ < width) {
2279 RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
2280 if (!is_signed)
2281 padding = RTLIL::SigSpec(RTLIL::State::S0);
2282 while (width_ < width)
2283 append(padding);
2284 }
2285
2286 }
2287
2288 RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const
2289 {
2290 cover("kernel.rtlil.sigspec.repeat");
2291
2292 RTLIL::SigSpec sig;
2293 for (int i = 0; i < num; i++)
2294 sig.append(*this);
2295 return sig;
2296 }
2297
2298 #ifndef NDEBUG
2299 void RTLIL::SigSpec::check() const
2300 {
2301 if (width_ > 64)
2302 {
2303 cover("kernel.rtlil.sigspec.check.skip");
2304 }
2305 else if (packed())
2306 {
2307 cover("kernel.rtlil.sigspec.check.packed");
2308
2309 int w = 0;
2310 for (size_t i = 0; i < chunks_.size(); i++) {
2311 const RTLIL::SigChunk chunk = chunks_[i];
2312 if (chunk.wire == NULL) {
2313 if (i > 0)
2314 log_assert(chunks_[i-1].wire != NULL);
2315 log_assert(chunk.offset == 0);
2316 log_assert(chunk.data.bits.size() == (size_t)chunk.width);
2317 } else {
2318 if (i > 0 && chunks_[i-1].wire == chunk.wire)
2319 log_assert(chunk.offset != chunks_[i-1].offset + chunks_[i-1].width);
2320 log_assert(chunk.offset >= 0);
2321 log_assert(chunk.width >= 0);
2322 log_assert(chunk.offset + chunk.width <= chunk.wire->width);
2323 log_assert(chunk.data.bits.size() == 0);
2324 }
2325 w += chunk.width;
2326 }
2327 log_assert(w == width_);
2328 log_assert(bits_.empty());
2329 }
2330 else
2331 {
2332 cover("kernel.rtlil.sigspec.check.unpacked");
2333
2334 log_assert(width_ == SIZE(bits_));
2335 log_assert(chunks_.empty());
2336 }
2337 }
2338 #endif
2339
2340 bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
2341 {
2342 cover("kernel.rtlil.sigspec.comp_lt");
2343
2344 if (this == &other)
2345 return false;
2346
2347 if (width_ != other.width_)
2348 return width_ < other.width_;
2349
2350 pack();
2351 other.pack();
2352
2353 if (chunks_.size() != other.chunks_.size())
2354 return chunks_.size() < other.chunks_.size();
2355
2356 hash();
2357 other.hash();
2358
2359 if (hash_ != other.hash_)
2360 return hash_ < other.hash_;
2361
2362 for (size_t i = 0; i < chunks_.size(); i++)
2363 if (chunks_[i] != other.chunks_[i]) {
2364 cover("kernel.rtlil.sigspec.comp_lt.hash_collision");
2365 return chunks_[i] < other.chunks_[i];
2366 }
2367
2368 cover("kernel.rtlil.sigspec.comp_lt.equal");
2369 return false;
2370 }
2371
2372 bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
2373 {
2374 cover("kernel.rtlil.sigspec.comp_eq");
2375
2376 if (this == &other)
2377 return true;
2378
2379 if (width_ != other.width_)
2380 return false;
2381
2382 pack();
2383 other.pack();
2384
2385 if (chunks_.size() != chunks_.size())
2386 return false;
2387
2388 hash();
2389 other.hash();
2390
2391 if (hash_ != other.hash_)
2392 return false;
2393
2394 for (size_t i = 0; i < chunks_.size(); i++)
2395 if (chunks_[i] != other.chunks_[i]) {
2396 cover("kernel.rtlil.sigspec.comp_eq.hash_collision");
2397 return false;
2398 }
2399
2400 cover("kernel.rtlil.sigspec.comp_eq.equal");
2401 return true;
2402 }
2403
2404 bool RTLIL::SigSpec::is_wire() const
2405 {
2406 cover("kernel.rtlil.sigspec.is_wire");
2407
2408 pack();
2409 return SIZE(chunks_) == 1 && chunks_[0].wire && chunks_[0].wire->width == width_;
2410 }
2411
2412 bool RTLIL::SigSpec::is_chunk() const
2413 {
2414 cover("kernel.rtlil.sigspec.is_chunk");
2415
2416 pack();
2417 return SIZE(chunks_) == 1;
2418 }
2419
2420 bool RTLIL::SigSpec::is_fully_const() const
2421 {
2422 cover("kernel.rtlil.sigspec.is_fully_const");
2423
2424 pack();
2425 for (auto it = chunks_.begin(); it != chunks_.end(); it++)
2426 if (it->width > 0 && it->wire != NULL)
2427 return false;
2428 return true;
2429 }
2430
2431 bool RTLIL::SigSpec::is_fully_def() const
2432 {
2433 cover("kernel.rtlil.sigspec.is_fully_def");
2434
2435 pack();
2436 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
2437 if (it->width > 0 && it->wire != NULL)
2438 return false;
2439 for (size_t i = 0; i < it->data.bits.size(); i++)
2440 if (it->data.bits[i] != RTLIL::State::S0 && it->data.bits[i] != RTLIL::State::S1)
2441 return false;
2442 }
2443 return true;
2444 }
2445
2446 bool RTLIL::SigSpec::is_fully_undef() const
2447 {
2448 cover("kernel.rtlil.sigspec.is_fully_undef");
2449
2450 pack();
2451 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
2452 if (it->width > 0 && it->wire != NULL)
2453 return false;
2454 for (size_t i = 0; i < it->data.bits.size(); i++)
2455 if (it->data.bits[i] != RTLIL::State::Sx && it->data.bits[i] != RTLIL::State::Sz)
2456 return false;
2457 }
2458 return true;
2459 }
2460
2461 bool RTLIL::SigSpec::has_marked_bits() const
2462 {
2463 cover("kernel.rtlil.sigspec.has_marked_bits");
2464
2465 pack();
2466 for (auto it = chunks_.begin(); it != chunks_.end(); it++)
2467 if (it->width > 0 && it->wire == NULL) {
2468 for (size_t i = 0; i < it->data.bits.size(); i++)
2469 if (it->data.bits[i] == RTLIL::State::Sm)
2470 return true;
2471 }
2472 return false;
2473 }
2474
2475 bool RTLIL::SigSpec::as_bool() const
2476 {
2477 cover("kernel.rtlil.sigspec.as_bool");
2478
2479 pack();
2480 log_assert(is_fully_const() && SIZE(chunks_) <= 1);
2481 if (width_)
2482 return chunks_[0].data.as_bool();
2483 return false;
2484 }
2485
2486 int RTLIL::SigSpec::as_int() const
2487 {
2488 cover("kernel.rtlil.sigspec.as_int");
2489
2490 pack();
2491 log_assert(is_fully_const() && SIZE(chunks_) <= 1);
2492 if (width_)
2493 return chunks_[0].data.as_int();
2494 return 0;
2495 }
2496
2497 std::string RTLIL::SigSpec::as_string() const
2498 {
2499 cover("kernel.rtlil.sigspec.as_string");
2500
2501 pack();
2502 std::string str;
2503 for (size_t i = chunks_.size(); i > 0; i--) {
2504 const RTLIL::SigChunk &chunk = chunks_[i-1];
2505 if (chunk.wire != NULL)
2506 for (int j = 0; j < chunk.width; j++)
2507 str += "?";
2508 else
2509 str += chunk.data.as_string();
2510 }
2511 return str;
2512 }
2513
2514 RTLIL::Const RTLIL::SigSpec::as_const() const
2515 {
2516 cover("kernel.rtlil.sigspec.as_const");
2517
2518 pack();
2519 log_assert(is_fully_const() && SIZE(chunks_) <= 1);
2520 if (width_)
2521 return chunks_[0].data;
2522 return RTLIL::Const();
2523 }
2524
2525 RTLIL::Wire *RTLIL::SigSpec::as_wire() const
2526 {
2527 cover("kernel.rtlil.sigspec.as_wire");
2528
2529 pack();
2530 log_assert(is_wire());
2531 return chunks_[0].wire;
2532 }
2533
2534 RTLIL::SigChunk RTLIL::SigSpec::as_chunk() const
2535 {
2536 cover("kernel.rtlil.sigspec.as_chunk");
2537
2538 pack();
2539 log_assert(is_chunk());
2540 return chunks_[0];
2541 }
2542
2543 bool RTLIL::SigSpec::match(std::string pattern) const
2544 {
2545 cover("kernel.rtlil.sigspec.match");
2546
2547 pack();
2548 std::string str = as_string();
2549 log_assert(pattern.size() == str.size());
2550
2551 for (size_t i = 0; i < pattern.size(); i++) {
2552 if (pattern[i] == ' ')
2553 continue;
2554 if (pattern[i] == '*') {
2555 if (str[i] != 'z' && str[i] != 'x')
2556 return false;
2557 continue;
2558 }
2559 if (pattern[i] != str[i])
2560 return false;
2561 }
2562
2563 return true;
2564 }
2565
2566 std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const
2567 {
2568 cover("kernel.rtlil.sigspec.to_sigbit_set");
2569
2570 pack();
2571 std::set<RTLIL::SigBit> sigbits;
2572 for (auto &c : chunks_)
2573 for (int i = 0; i < c.width; i++)
2574 sigbits.insert(RTLIL::SigBit(c, i));
2575 return sigbits;
2576 }
2577
2578 std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
2579 {
2580 cover("kernel.rtlil.sigspec.to_sigbit_vector");
2581
2582 unpack();
2583 return bits_;
2584 }
2585
2586 RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const
2587 {
2588 cover("kernel.rtlil.sigspec.to_single_sigbit");
2589
2590 pack();
2591 log_assert(width_ == 1);
2592 for (auto &c : chunks_)
2593 if (c.width)
2594 return RTLIL::SigBit(c);
2595 log_abort();
2596 }
2597
2598 static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep)
2599 {
2600 size_t start = 0, end = 0;
2601 while ((end = text.find(sep, start)) != std::string::npos) {
2602 tokens.push_back(text.substr(start, end - start));
2603 start = end + 1;
2604 }
2605 tokens.push_back(text.substr(start));
2606 }
2607
2608 static int sigspec_parse_get_dummy_line_num()
2609 {
2610 return 0;
2611 }
2612
2613 bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
2614 {
2615 cover("kernel.rtlil.sigspec.parse");
2616
2617 std::vector<std::string> tokens;
2618 sigspec_parse_split(tokens, str, ',');
2619
2620 sig = RTLIL::SigSpec();
2621 for (int tokidx = int(tokens.size())-1; tokidx >= 0; tokidx--)
2622 {
2623 std::string netname = tokens[tokidx];
2624 std::string indices;
2625
2626 if (netname.size() == 0)
2627 continue;
2628
2629 if ('0' <= netname[0] && netname[0] <= '9') {
2630 cover("kernel.rtlil.sigspec.parse.const");
2631 AST::get_line_num = sigspec_parse_get_dummy_line_num;
2632 AST::AstNode *ast = VERILOG_FRONTEND::const2ast(netname);
2633 if (ast == NULL)
2634 return false;
2635 sig.append(RTLIL::Const(ast->bits));
2636 delete ast;
2637 continue;
2638 }
2639
2640 if (module == NULL)
2641 return false;
2642
2643 cover("kernel.rtlil.sigspec.parse.net");
2644
2645 if (netname[0] != '$' && netname[0] != '\\')
2646 netname = "\\" + netname;
2647
2648 if (module->wires_.count(netname) == 0) {
2649 size_t indices_pos = netname.size()-1;
2650 if (indices_pos > 2 && netname[indices_pos] == ']')
2651 {
2652 indices_pos--;
2653 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
2654 if (indices_pos > 0 && netname[indices_pos] == ':') {
2655 indices_pos--;
2656 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
2657 }
2658 if (indices_pos > 0 && netname[indices_pos] == '[') {
2659 indices = netname.substr(indices_pos);
2660 netname = netname.substr(0, indices_pos);
2661 }
2662 }
2663 }
2664
2665 if (module->wires_.count(netname) == 0)
2666 return false;
2667
2668 RTLIL::Wire *wire = module->wires_.at(netname);
2669 if (!indices.empty()) {
2670 std::vector<std::string> index_tokens;
2671 sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':');
2672 if (index_tokens.size() == 1) {
2673 cover("kernel.rtlil.sigspec.parse.bit_sel");
2674 sig.append(RTLIL::SigSpec(wire, atoi(index_tokens.at(0).c_str())));
2675 } else {
2676 cover("kernel.rtlil.sigspec.parse.part_sel");
2677 int a = atoi(index_tokens.at(0).c_str());
2678 int b = atoi(index_tokens.at(1).c_str());
2679 if (a > b) {
2680 int tmp = a;
2681 a = b, b = tmp;
2682 }
2683 sig.append(RTLIL::SigSpec(wire, a, b-a+1));
2684 }
2685 } else
2686 sig.append(wire);
2687 }
2688
2689 return true;
2690 }
2691
2692 bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str)
2693 {
2694 if (str.empty() || str[0] != '@')
2695 return parse(sig, module, str);
2696
2697 cover("kernel.rtlil.sigspec.parse.sel");
2698
2699 str = RTLIL::escape_id(str.substr(1));
2700 if (design->selection_vars.count(str) == 0)
2701 return false;
2702
2703 sig = RTLIL::SigSpec();
2704 RTLIL::Selection &sel = design->selection_vars.at(str);
2705 for (auto &it : module->wires_)
2706 if (sel.selected_member(module->name, it.first))
2707 sig.append(it.second);
2708
2709 return true;
2710 }
2711
2712 bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
2713 {
2714 if (str == "0") {
2715 cover("kernel.rtlil.sigspec.parse.rhs_zeros");
2716 sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.width_);
2717 return true;
2718 }
2719
2720 if (str == "~0") {
2721 cover("kernel.rtlil.sigspec.parse.rhs_ones");
2722 sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.width_);
2723 return true;
2724 }
2725
2726 if (lhs.chunks_.size() == 1) {
2727 char *p = (char*)str.c_str(), *endptr;
2728 long long int val = strtoll(p, &endptr, 10);
2729 if (endptr && endptr != p && *endptr == 0) {
2730 sig = RTLIL::SigSpec(val, lhs.width_);
2731 cover("kernel.rtlil.sigspec.parse.rhs_dec");
2732 return true;
2733 }
2734 }
2735
2736 return parse(sig, module, str);
2737 }
2738
2739 RTLIL::CaseRule::~CaseRule()
2740 {
2741 for (auto it = switches.begin(); it != switches.end(); it++)
2742 delete *it;
2743 }
2744
2745 RTLIL::CaseRule *RTLIL::CaseRule::clone() const
2746 {
2747 RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
2748 new_caserule->compare = compare;
2749 new_caserule->actions = actions;
2750 for (auto &it : switches)
2751 new_caserule->switches.push_back(it->clone());
2752 return new_caserule;
2753 }
2754
2755 RTLIL::SwitchRule::~SwitchRule()
2756 {
2757 for (auto it = cases.begin(); it != cases.end(); it++)
2758 delete *it;
2759 }
2760
2761 RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
2762 {
2763 RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
2764 new_switchrule->signal = signal;
2765 new_switchrule->attributes = attributes;
2766 for (auto &it : cases)
2767 new_switchrule->cases.push_back(it->clone());
2768 return new_switchrule;
2769
2770 }
2771
2772 RTLIL::SyncRule *RTLIL::SyncRule::clone() const
2773 {
2774 RTLIL::SyncRule *new_syncrule = new RTLIL::SyncRule;
2775 new_syncrule->type = type;
2776 new_syncrule->signal = signal;
2777 new_syncrule->actions = actions;
2778 return new_syncrule;
2779 }
2780
2781 RTLIL::Process::~Process()
2782 {
2783 for (auto it = syncs.begin(); it != syncs.end(); it++)
2784 delete *it;
2785 }
2786
2787 RTLIL::Process *RTLIL::Process::clone() const
2788 {
2789 RTLIL::Process *new_proc = new RTLIL::Process;
2790
2791 new_proc->name = name;
2792 new_proc->attributes = attributes;
2793
2794 RTLIL::CaseRule *rc_ptr = root_case.clone();
2795 new_proc->root_case = *rc_ptr;
2796 rc_ptr->switches.clear();
2797 delete rc_ptr;
2798
2799 for (auto &it : syncs)
2800 new_proc->syncs.push_back(it->clone());
2801
2802 return new_proc;
2803 }
2804
2805 YOSYS_NAMESPACE_END
2806