Renamed port access function on RTLIL::Cell, added param access functions
[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->hasPort(name))
451 error(__LINE__);
452 if (cell->getPort(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->hasPort(portname))
482 error(__LINE__);
483 if (cell->getPort(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::setPort<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->setPort("\\A", sig_a); \
1171 cell->setPort("\\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->setPort("\\A", sig_a); \
1200 cell->setPort("\\B", sig_b); \
1201 cell->setPort("\\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->setPort("\\A", sig_a); \
1243 cell->setPort("\\B", sig_b); \
1244 cell->setPort("\\S", sig_s); \
1245 cell->setPort("\\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->setPort("\\" #_P1, sig1); \
1262 cell->setPort("\\" #_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->setPort("\\" #_P1, sig1); \
1274 cell->setPort("\\" #_P2, sig2); \
1275 cell->setPort("\\" #_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->setPort("\\" #_P1, sig1); \
1287 cell->setPort("\\" #_P2, sig2); \
1288 cell->setPort("\\" #_P3, sig3); \
1289 cell->setPort("\\" #_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->setPort("\\A", sig_a);
1315 cell->setPort("\\B", sig_b);
1316 cell->setPort("\\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->setPort("\\A", sig_a);
1327 cell->setPort("\\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->setPort("\\A", sig_a);
1337 cell->setPort("\\B", sig_b);
1338 cell->setPort("\\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->setPort("\\I", sig_i);
1348 cell->setPort("\\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->setPort("\\A", sig_a);
1356 cell->setPort("\\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->setPort("\\SET", sig_set);
1367 cell->setPort("\\CLR", sig_clr);
1368 cell->setPort("\\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->setPort("\\CLK", sig_clk);
1378 cell->setPort("\\D", sig_d);
1379 cell->setPort("\\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->setPort("\\CLK", sig_clk);
1392 cell->setPort("\\SET", sig_set);
1393 cell->setPort("\\CLR", sig_clr);
1394 cell->setPort("\\D", sig_d);
1395 cell->setPort("\\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->setPort("\\CLK", sig_clk);
1408 cell->setPort("\\ARST", sig_arst);
1409 cell->setPort("\\D", sig_d);
1410 cell->setPort("\\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->setPort("\\EN", sig_en);
1420 cell->setPort("\\D", sig_d);
1421 cell->setPort("\\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->setPort("\\EN", sig_en);
1434 cell->setPort("\\SET", sig_set);
1435 cell->setPort("\\CLR", sig_clr);
1436 cell->setPort("\\D", sig_d);
1437 cell->setPort("\\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->setPort("\\C", sig_clk);
1445 cell->setPort("\\D", sig_d);
1446 cell->setPort("\\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->setPort("\\C", sig_clk);
1455 cell->setPort("\\S", sig_set);
1456 cell->setPort("\\R", sig_clr);
1457 cell->setPort("\\D", sig_d);
1458 cell->setPort("\\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->setPort("\\C", sig_clk);
1467 cell->setPort("\\R", sig_arst);
1468 cell->setPort("\\D", sig_d);
1469 cell->setPort("\\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->setPort("\\E", sig_en);
1477 cell->setPort("\\D", sig_d);
1478 cell->setPort("\\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->setPort("\\E", sig_en);
1487 cell->setPort("\\S", sig_set);
1488 cell->setPort("\\R", sig_clr);
1489 cell->setPort("\\D", sig_d);
1490 cell->setPort("\\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::hasPort(RTLIL::IdString portname) const
1513 {
1514 return connections_.count(portname) != 0;
1515 }
1516
1517 void RTLIL::Cell::unsetPort(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::setPort(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::getPort(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 bool RTLIL::Cell::hasParam(RTLIL::IdString paramname) const
1556 {
1557 return parameters.count(paramname);
1558 }
1559
1560 void RTLIL::Cell::unsetParam(RTLIL::IdString paramname)
1561 {
1562 parameters.erase(paramname);
1563 }
1564
1565 void RTLIL::Cell::setParam(RTLIL::IdString paramname, RTLIL::Const value)
1566 {
1567 parameters[paramname] = value;
1568 }
1569
1570 const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const
1571 {
1572 return parameters.at(paramname);
1573 }
1574
1575 void RTLIL::Cell::check()
1576 {
1577 #ifndef NDEBUG
1578 InternalCellChecker checker(NULL, this);
1579 checker.check();
1580 #endif
1581 }
1582
1583 void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
1584 {
1585 if (type[0] != '$' || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" ||
1586 type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:")
1587 return;
1588
1589 if (type == "$mux" || type == "$pmux" || type == "$safe_pmux")
1590 {
1591 parameters["\\WIDTH"] = SIZE(connections_["\\Y"]);
1592 if (type == "$pmux" || type == "$safe_pmux")
1593 parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]);
1594 check();
1595 return;
1596 }
1597
1598 bool signedness_ab = type != "$slice" && type != "$concat";
1599
1600 if (connections_.count("\\A")) {
1601 if (signedness_ab) {
1602 if (set_a_signed)
1603 parameters["\\A_SIGNED"] = true;
1604 else if (parameters.count("\\A_SIGNED") == 0)
1605 parameters["\\A_SIGNED"] = false;
1606 }
1607 parameters["\\A_WIDTH"] = SIZE(connections_["\\A"]);
1608 }
1609
1610 if (connections_.count("\\B")) {
1611 if (signedness_ab) {
1612 if (set_b_signed)
1613 parameters["\\B_SIGNED"] = true;
1614 else if (parameters.count("\\B_SIGNED") == 0)
1615 parameters["\\B_SIGNED"] = false;
1616 }
1617 parameters["\\B_WIDTH"] = SIZE(connections_["\\B"]);
1618 }
1619
1620 if (connections_.count("\\Y"))
1621 parameters["\\Y_WIDTH"] = SIZE(connections_["\\Y"]);
1622
1623 check();
1624 }
1625
1626 RTLIL::SigChunk::SigChunk()
1627 {
1628 wire = NULL;
1629 width = 0;
1630 offset = 0;
1631 }
1632
1633 RTLIL::SigChunk::SigChunk(const RTLIL::Const &value)
1634 {
1635 wire = NULL;
1636 data = value;
1637 width = data.bits.size();
1638 offset = 0;
1639 }
1640
1641 RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire)
1642 {
1643 log_assert(wire != nullptr);
1644 this->wire = wire;
1645 this->width = wire->width;
1646 this->offset = 0;
1647 }
1648
1649 RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int offset, int width)
1650 {
1651 log_assert(wire != nullptr);
1652 this->wire = wire;
1653 this->width = width;
1654 this->offset = offset;
1655 }
1656
1657 RTLIL::SigChunk::SigChunk(const std::string &str)
1658 {
1659 wire = NULL;
1660 data = RTLIL::Const(str);
1661 width = data.bits.size();
1662 offset = 0;
1663 }
1664
1665 RTLIL::SigChunk::SigChunk(int val, int width)
1666 {
1667 wire = NULL;
1668 data = RTLIL::Const(val, width);
1669 this->width = data.bits.size();
1670 offset = 0;
1671 }
1672
1673 RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width)
1674 {
1675 wire = NULL;
1676 data = RTLIL::Const(bit, width);
1677 this->width = data.bits.size();
1678 offset = 0;
1679 }
1680
1681 RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
1682 {
1683 wire = bit.wire;
1684 if (wire == NULL)
1685 data = RTLIL::Const(bit.data);
1686 offset = bit.offset;
1687 width = 1;
1688 }
1689
1690 RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
1691 {
1692 RTLIL::SigChunk ret;
1693 if (wire) {
1694 ret.wire = wire;
1695 ret.offset = this->offset + offset;
1696 ret.width = length;
1697 } else {
1698 for (int i = 0; i < length; i++)
1699 ret.data.bits.push_back(data.bits[offset+i]);
1700 ret.width = length;
1701 }
1702 return ret;
1703 }
1704
1705 bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk &other) const
1706 {
1707 if (wire && other.wire)
1708 if (wire->name != other.wire->name)
1709 return wire->name < other.wire->name;
1710
1711 if (wire != other.wire)
1712 return wire < other.wire;
1713
1714 if (offset != other.offset)
1715 return offset < other.offset;
1716
1717 if (width != other.width)
1718 return width < other.width;
1719
1720 return data.bits < other.data.bits;
1721 }
1722
1723 bool RTLIL::SigChunk::operator ==(const RTLIL::SigChunk &other) const
1724 {
1725 if (wire != other.wire || width != other.width || offset != other.offset)
1726 return false;
1727 if (data.bits != other.data.bits)
1728 return false;
1729 return true;
1730 }
1731
1732 bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const
1733 {
1734 if (*this == other)
1735 return false;
1736 return true;
1737 }
1738
1739 RTLIL::SigSpec::SigSpec()
1740 {
1741 width_ = 0;
1742 hash_ = 0;
1743 }
1744
1745 RTLIL::SigSpec::SigSpec(const RTLIL::SigSpec &other)
1746 {
1747 *this = other;
1748 }
1749
1750 RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
1751 {
1752 cover("kernel.rtlil.sigspec.init.list");
1753
1754 width_ = 0;
1755 hash_ = 0;
1756
1757 std::vector<RTLIL::SigSpec> parts_vec(parts.begin(), parts.end());
1758 for (auto it = parts_vec.rbegin(); it != parts_vec.rend(); it++)
1759 append(*it);
1760 }
1761
1762 const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other)
1763 {
1764 cover("kernel.rtlil.sigspec.assign");
1765
1766 width_ = other.width_;
1767 hash_ = other.hash_;
1768 chunks_ = other.chunks_;
1769 bits_.clear();
1770
1771 if (!other.bits_.empty())
1772 {
1773 RTLIL::SigChunk *last = NULL;
1774 int last_end_offset = 0;
1775
1776 for (auto &bit : other.bits_) {
1777 if (last && bit.wire == last->wire) {
1778 if (bit.wire == NULL) {
1779 last->data.bits.push_back(bit.data);
1780 last->width++;
1781 continue;
1782 } else if (last_end_offset == bit.offset) {
1783 last_end_offset++;
1784 last->width++;
1785 continue;
1786 }
1787 }
1788 chunks_.push_back(bit);
1789 last = &chunks_.back();
1790 last_end_offset = bit.offset + 1;
1791 }
1792
1793 check();
1794 }
1795
1796 return *this;
1797 }
1798
1799 RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
1800 {
1801 cover("kernel.rtlil.sigspec.init.const");
1802
1803 chunks_.push_back(RTLIL::SigChunk(value));
1804 width_ = chunks_.back().width;
1805 hash_ = 0;
1806 check();
1807 }
1808
1809 RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
1810 {
1811 cover("kernel.rtlil.sigspec.init.chunk");
1812
1813 chunks_.push_back(chunk);
1814 width_ = chunks_.back().width;
1815 hash_ = 0;
1816 check();
1817 }
1818
1819 RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
1820 {
1821 cover("kernel.rtlil.sigspec.init.wire");
1822
1823 chunks_.push_back(RTLIL::SigChunk(wire));
1824 width_ = chunks_.back().width;
1825 hash_ = 0;
1826 check();
1827 }
1828
1829 RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
1830 {
1831 cover("kernel.rtlil.sigspec.init.wire_part");
1832
1833 chunks_.push_back(RTLIL::SigChunk(wire, offset, width));
1834 width_ = chunks_.back().width;
1835 hash_ = 0;
1836 check();
1837 }
1838
1839 RTLIL::SigSpec::SigSpec(const std::string &str)
1840 {
1841 cover("kernel.rtlil.sigspec.init.str");
1842
1843 chunks_.push_back(RTLIL::SigChunk(str));
1844 width_ = chunks_.back().width;
1845 hash_ = 0;
1846 check();
1847 }
1848
1849 RTLIL::SigSpec::SigSpec(int val, int width)
1850 {
1851 cover("kernel.rtlil.sigspec.init.int");
1852
1853 chunks_.push_back(RTLIL::SigChunk(val, width));
1854 width_ = width;
1855 hash_ = 0;
1856 check();
1857 }
1858
1859 RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
1860 {
1861 cover("kernel.rtlil.sigspec.init.state");
1862
1863 chunks_.push_back(RTLIL::SigChunk(bit, width));
1864 width_ = width;
1865 hash_ = 0;
1866 check();
1867 }
1868
1869 RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
1870 {
1871 cover("kernel.rtlil.sigspec.init.bit");
1872
1873 if (bit.wire == NULL)
1874 chunks_.push_back(RTLIL::SigChunk(bit.data, width));
1875 else
1876 for (int i = 0; i < width; i++)
1877 chunks_.push_back(bit);
1878 width_ = width;
1879 hash_ = 0;
1880 check();
1881 }
1882
1883 RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks)
1884 {
1885 cover("kernel.rtlil.sigspec.init.stdvec_chunks");
1886
1887 width_ = 0;
1888 hash_ = 0;
1889 for (auto &c : chunks)
1890 append(c);
1891 check();
1892 }
1893
1894 RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
1895 {
1896 cover("kernel.rtlil.sigspec.init.stdvec_bits");
1897
1898 width_ = 0;
1899 hash_ = 0;
1900 for (auto &bit : bits)
1901 append_bit(bit);
1902 check();
1903 }
1904
1905 RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
1906 {
1907 cover("kernel.rtlil.sigspec.init.stdset_bits");
1908
1909 width_ = 0;
1910 hash_ = 0;
1911 for (auto &bit : bits)
1912 append_bit(bit);
1913 check();
1914 }
1915
1916 void RTLIL::SigSpec::pack() const
1917 {
1918 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
1919
1920 if (that->bits_.empty())
1921 return;
1922
1923 cover("kernel.rtlil.sigspec.convert.pack");
1924 log_assert(that->chunks_.empty());
1925
1926 std::vector<RTLIL::SigBit> old_bits;
1927 old_bits.swap(that->bits_);
1928
1929 RTLIL::SigChunk *last = NULL;
1930 int last_end_offset = 0;
1931
1932 for (auto &bit : old_bits) {
1933 if (last && bit.wire == last->wire) {
1934 if (bit.wire == NULL) {
1935 last->data.bits.push_back(bit.data);
1936 last->width++;
1937 continue;
1938 } else if (last_end_offset == bit.offset) {
1939 last_end_offset++;
1940 last->width++;
1941 continue;
1942 }
1943 }
1944 that->chunks_.push_back(bit);
1945 last = &that->chunks_.back();
1946 last_end_offset = bit.offset + 1;
1947 }
1948
1949 check();
1950 }
1951
1952 void RTLIL::SigSpec::unpack() const
1953 {
1954 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
1955
1956 if (that->chunks_.empty())
1957 return;
1958
1959 cover("kernel.rtlil.sigspec.convert.unpack");
1960 log_assert(that->bits_.empty());
1961
1962 that->bits_.reserve(that->width_);
1963 for (auto &c : that->chunks_)
1964 for (int i = 0; i < c.width; i++)
1965 that->bits_.push_back(RTLIL::SigBit(c, i));
1966
1967 that->chunks_.clear();
1968 that->hash_ = 0;
1969 }
1970
1971 #define DJB2(_hash, _value) do { (_hash) = (((_hash) << 5) + (_hash)) + (_value); } while (0)
1972
1973 void RTLIL::SigSpec::hash() const
1974 {
1975 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
1976
1977 if (that->hash_ != 0)
1978 return;
1979
1980 cover("kernel.rtlil.sigspec.hash");
1981 that->pack();
1982
1983 that->hash_ = 5381;
1984 for (auto &c : that->chunks_)
1985 if (c.wire == NULL) {
1986 for (auto &v : c.data.bits)
1987 DJB2(that->hash_, v);
1988 } else {
1989 for (auto &v : c.wire->name)
1990 DJB2(that->hash_, v);
1991 DJB2(that->hash_, c.offset);
1992 DJB2(that->hash_, c.width);
1993 }
1994
1995 if (that->hash_ == 0)
1996 that->hash_ = 1;
1997 }
1998
1999 void RTLIL::SigSpec::sort()
2000 {
2001 unpack();
2002 cover("kernel.rtlil.sigspec.sort");
2003 std::sort(bits_.begin(), bits_.end());
2004 }
2005
2006 void RTLIL::SigSpec::sort_and_unify()
2007 {
2008 cover("kernel.rtlil.sigspec.sort_and_unify");
2009 *this = this->to_sigbit_set();
2010 }
2011
2012 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
2013 {
2014 replace(pattern, with, this);
2015 }
2016
2017 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const
2018 {
2019 cover("kernel.rtlil.sigspec.replace");
2020
2021 unpack();
2022 pattern.unpack();
2023 with.unpack();
2024
2025 log_assert(other != NULL);
2026 log_assert(width_ == other->width_);
2027 other->unpack();
2028
2029 log_assert(pattern.width_ == with.width_);
2030
2031 std::map<RTLIL::SigBit, RTLIL::SigBit> pattern_map;
2032 for (int i = 0; i < SIZE(pattern.bits_); i++)
2033 if (pattern.bits_[i].wire != NULL)
2034 pattern_map[pattern.bits_[i]] = with.bits_[i];
2035
2036 for (int i = 0; i < SIZE(bits_); i++)
2037 if (pattern_map.count(bits_[i]))
2038 other->bits_[i] = pattern_map.at(bits_[i]);
2039
2040 other->check();
2041 }
2042
2043 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern)
2044 {
2045 remove2(pattern, NULL);
2046 }
2047
2048 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const
2049 {
2050 RTLIL::SigSpec tmp = *this;
2051 tmp.remove2(pattern, other);
2052 }
2053
2054 void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
2055 {
2056 if (other)
2057 cover("kernel.rtlil.sigspec.remove_other");
2058 else
2059 cover("kernel.rtlil.sigspec.remove");
2060
2061 unpack();
2062
2063 if (other != NULL) {
2064 log_assert(width_ == other->width_);
2065 other->unpack();
2066 }
2067
2068 std::set<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_set();
2069 std::vector<RTLIL::SigBit> new_bits, new_other_bits;
2070
2071 for (int i = 0; i < SIZE(bits_); i++) {
2072 if (bits_[i].wire != NULL && pattern_bits.count(bits_[i]))
2073 continue;
2074 if (other != NULL)
2075 new_other_bits.push_back(other->bits_[i]);
2076 new_bits.push_back(bits_[i]);
2077 }
2078
2079 bits_.swap(new_bits);
2080 width_ = SIZE(bits_);
2081
2082 if (other != NULL) {
2083 other->bits_.swap(new_other_bits);
2084 other->width_ = SIZE(other->bits_);
2085 }
2086
2087 check();
2088 }
2089
2090 RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other) const
2091 {
2092 if (other)
2093 cover("kernel.rtlil.sigspec.extract_other");
2094 else
2095 cover("kernel.rtlil.sigspec.extract");
2096
2097 pack();
2098 pattern.pack();
2099
2100 if (other != NULL)
2101 other->pack();
2102
2103 log_assert(other == NULL || width_ == other->width_);
2104
2105 std::set<RTLIL::SigBit> pat = pattern.to_sigbit_set();
2106 std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
2107 RTLIL::SigSpec ret;
2108
2109 if (other) {
2110 std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector();
2111 for (int i = 0; i < width_; i++)
2112 if (bits_match[i].wire && pat.count(bits_match[i]))
2113 ret.append_bit(bits_other[i]);
2114 } else {
2115 for (int i = 0; i < width_; i++)
2116 if (bits_match[i].wire && pat.count(bits_match[i]))
2117 ret.append_bit(bits_match[i]);
2118 }
2119
2120 ret.check();
2121 return ret;
2122 }
2123
2124 void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
2125 {
2126 cover("kernel.rtlil.sigspec.replace_pos");
2127
2128 unpack();
2129 with.unpack();
2130
2131 log_assert(offset >= 0);
2132 log_assert(with.width_ >= 0);
2133 log_assert(offset+with.width_ <= width_);
2134
2135 for (int i = 0; i < with.width_; i++)
2136 bits_.at(offset + i) = with.bits_.at(i);
2137
2138 check();
2139 }
2140
2141 void RTLIL::SigSpec::remove_const()
2142 {
2143 if (packed())
2144 {
2145 cover("kernel.rtlil.sigspec.remove_const.packed");
2146
2147 std::vector<RTLIL::SigChunk> new_chunks;
2148 new_chunks.reserve(SIZE(chunks_));
2149
2150 width_ = 0;
2151 for (auto &chunk : chunks_)
2152 if (chunk.wire != NULL) {
2153 new_chunks.push_back(chunk);
2154 width_ += chunk.width;
2155 }
2156
2157 chunks_.swap(new_chunks);
2158 }
2159 else
2160 {
2161 cover("kernel.rtlil.sigspec.remove_const.unpacked");
2162
2163 std::vector<RTLIL::SigBit> new_bits;
2164 new_bits.reserve(width_);
2165
2166 for (auto &bit : bits_)
2167 if (bit.wire != NULL)
2168 new_bits.push_back(bit);
2169
2170 bits_.swap(new_bits);
2171 width_ = bits_.size();
2172 }
2173
2174 check();
2175 }
2176
2177 void RTLIL::SigSpec::remove(int offset, int length)
2178 {
2179 cover("kernel.rtlil.sigspec.remove_pos");
2180
2181 unpack();
2182
2183 log_assert(offset >= 0);
2184 log_assert(length >= 0);
2185 log_assert(offset + length <= width_);
2186
2187 bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length);
2188 width_ = bits_.size();
2189
2190 check();
2191 }
2192
2193 RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
2194 {
2195 unpack();
2196 cover("kernel.rtlil.sigspec.extract_pos");
2197 return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
2198 }
2199
2200 void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
2201 {
2202 if (signal.width_ == 0)
2203 return;
2204
2205 if (width_ == 0) {
2206 *this = signal;
2207 return;
2208 }
2209
2210 cover("kernel.rtlil.sigspec.append");
2211
2212 if (packed() != signal.packed()) {
2213 pack();
2214 signal.pack();
2215 }
2216
2217 if (packed())
2218 for (auto &other_c : signal.chunks_)
2219 {
2220 auto &my_last_c = chunks_.back();
2221 if (my_last_c.wire == NULL && other_c.wire == NULL) {
2222 auto &this_data = my_last_c.data.bits;
2223 auto &other_data = other_c.data.bits;
2224 this_data.insert(this_data.end(), other_data.begin(), other_data.end());
2225 my_last_c.width += other_c.width;
2226 } else
2227 if (my_last_c.wire == other_c.wire && my_last_c.offset + my_last_c.width == other_c.offset) {
2228 my_last_c.width += other_c.width;
2229 } else
2230 chunks_.push_back(other_c);
2231 }
2232 else
2233 bits_.insert(bits_.end(), signal.bits_.begin(), signal.bits_.end());
2234
2235 width_ += signal.width_;
2236 check();
2237 }
2238
2239 void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
2240 {
2241 if (packed())
2242 {
2243 cover("kernel.rtlil.sigspec.append_bit.packed");
2244
2245 if (chunks_.size() == 0)
2246 chunks_.push_back(bit);
2247 else
2248 if (bit.wire == NULL)
2249 if (chunks_.back().wire == NULL) {
2250 chunks_.back().data.bits.push_back(bit.data);
2251 chunks_.back().width++;
2252 } else
2253 chunks_.push_back(bit);
2254 else
2255 if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset)
2256 chunks_.back().width++;
2257 else
2258 chunks_.push_back(bit);
2259 }
2260 else
2261 {
2262 cover("kernel.rtlil.sigspec.append_bit.unpacked");
2263 bits_.push_back(bit);
2264 }
2265
2266 width_++;
2267 check();
2268 }
2269
2270 void RTLIL::SigSpec::extend(int width, bool is_signed)
2271 {
2272 cover("kernel.rtlil.sigspec.extend");
2273
2274 pack();
2275
2276 if (width_ > width)
2277 remove(width, width_ - width);
2278
2279 if (width_ < width) {
2280 RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
2281 if (!is_signed && padding != RTLIL::SigSpec(RTLIL::State::Sx) && padding != RTLIL::SigSpec(RTLIL::State::Sz) &&
2282 padding != RTLIL::SigSpec(RTLIL::State::Sa) && padding != RTLIL::SigSpec(RTLIL::State::Sm))
2283 padding = RTLIL::SigSpec(RTLIL::State::S0);
2284 while (width_ < width)
2285 append(padding);
2286 }
2287 }
2288
2289 void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
2290 {
2291 cover("kernel.rtlil.sigspec.extend_u0");
2292
2293 pack();
2294
2295 if (width_ > width)
2296 remove(width, width_ - width);
2297
2298 if (width_ < width) {
2299 RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
2300 if (!is_signed)
2301 padding = RTLIL::SigSpec(RTLIL::State::S0);
2302 while (width_ < width)
2303 append(padding);
2304 }
2305
2306 }
2307
2308 RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const
2309 {
2310 cover("kernel.rtlil.sigspec.repeat");
2311
2312 RTLIL::SigSpec sig;
2313 for (int i = 0; i < num; i++)
2314 sig.append(*this);
2315 return sig;
2316 }
2317
2318 #ifndef NDEBUG
2319 void RTLIL::SigSpec::check() const
2320 {
2321 if (width_ > 64)
2322 {
2323 cover("kernel.rtlil.sigspec.check.skip");
2324 }
2325 else if (packed())
2326 {
2327 cover("kernel.rtlil.sigspec.check.packed");
2328
2329 int w = 0;
2330 for (size_t i = 0; i < chunks_.size(); i++) {
2331 const RTLIL::SigChunk chunk = chunks_[i];
2332 if (chunk.wire == NULL) {
2333 if (i > 0)
2334 log_assert(chunks_[i-1].wire != NULL);
2335 log_assert(chunk.offset == 0);
2336 log_assert(chunk.data.bits.size() == (size_t)chunk.width);
2337 } else {
2338 if (i > 0 && chunks_[i-1].wire == chunk.wire)
2339 log_assert(chunk.offset != chunks_[i-1].offset + chunks_[i-1].width);
2340 log_assert(chunk.offset >= 0);
2341 log_assert(chunk.width >= 0);
2342 log_assert(chunk.offset + chunk.width <= chunk.wire->width);
2343 log_assert(chunk.data.bits.size() == 0);
2344 }
2345 w += chunk.width;
2346 }
2347 log_assert(w == width_);
2348 log_assert(bits_.empty());
2349 }
2350 else
2351 {
2352 cover("kernel.rtlil.sigspec.check.unpacked");
2353
2354 log_assert(width_ == SIZE(bits_));
2355 log_assert(chunks_.empty());
2356 }
2357 }
2358 #endif
2359
2360 bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
2361 {
2362 cover("kernel.rtlil.sigspec.comp_lt");
2363
2364 if (this == &other)
2365 return false;
2366
2367 if (width_ != other.width_)
2368 return width_ < other.width_;
2369
2370 pack();
2371 other.pack();
2372
2373 if (chunks_.size() != other.chunks_.size())
2374 return chunks_.size() < other.chunks_.size();
2375
2376 hash();
2377 other.hash();
2378
2379 if (hash_ != other.hash_)
2380 return hash_ < other.hash_;
2381
2382 for (size_t i = 0; i < chunks_.size(); i++)
2383 if (chunks_[i] != other.chunks_[i]) {
2384 cover("kernel.rtlil.sigspec.comp_lt.hash_collision");
2385 return chunks_[i] < other.chunks_[i];
2386 }
2387
2388 cover("kernel.rtlil.sigspec.comp_lt.equal");
2389 return false;
2390 }
2391
2392 bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
2393 {
2394 cover("kernel.rtlil.sigspec.comp_eq");
2395
2396 if (this == &other)
2397 return true;
2398
2399 if (width_ != other.width_)
2400 return false;
2401
2402 pack();
2403 other.pack();
2404
2405 if (chunks_.size() != chunks_.size())
2406 return false;
2407
2408 hash();
2409 other.hash();
2410
2411 if (hash_ != other.hash_)
2412 return false;
2413
2414 for (size_t i = 0; i < chunks_.size(); i++)
2415 if (chunks_[i] != other.chunks_[i]) {
2416 cover("kernel.rtlil.sigspec.comp_eq.hash_collision");
2417 return false;
2418 }
2419
2420 cover("kernel.rtlil.sigspec.comp_eq.equal");
2421 return true;
2422 }
2423
2424 bool RTLIL::SigSpec::is_wire() const
2425 {
2426 cover("kernel.rtlil.sigspec.is_wire");
2427
2428 pack();
2429 return SIZE(chunks_) == 1 && chunks_[0].wire && chunks_[0].wire->width == width_;
2430 }
2431
2432 bool RTLIL::SigSpec::is_chunk() const
2433 {
2434 cover("kernel.rtlil.sigspec.is_chunk");
2435
2436 pack();
2437 return SIZE(chunks_) == 1;
2438 }
2439
2440 bool RTLIL::SigSpec::is_fully_const() const
2441 {
2442 cover("kernel.rtlil.sigspec.is_fully_const");
2443
2444 pack();
2445 for (auto it = chunks_.begin(); it != chunks_.end(); it++)
2446 if (it->width > 0 && it->wire != NULL)
2447 return false;
2448 return true;
2449 }
2450
2451 bool RTLIL::SigSpec::is_fully_def() const
2452 {
2453 cover("kernel.rtlil.sigspec.is_fully_def");
2454
2455 pack();
2456 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
2457 if (it->width > 0 && it->wire != NULL)
2458 return false;
2459 for (size_t i = 0; i < it->data.bits.size(); i++)
2460 if (it->data.bits[i] != RTLIL::State::S0 && it->data.bits[i] != RTLIL::State::S1)
2461 return false;
2462 }
2463 return true;
2464 }
2465
2466 bool RTLIL::SigSpec::is_fully_undef() const
2467 {
2468 cover("kernel.rtlil.sigspec.is_fully_undef");
2469
2470 pack();
2471 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
2472 if (it->width > 0 && it->wire != NULL)
2473 return false;
2474 for (size_t i = 0; i < it->data.bits.size(); i++)
2475 if (it->data.bits[i] != RTLIL::State::Sx && it->data.bits[i] != RTLIL::State::Sz)
2476 return false;
2477 }
2478 return true;
2479 }
2480
2481 bool RTLIL::SigSpec::has_marked_bits() const
2482 {
2483 cover("kernel.rtlil.sigspec.has_marked_bits");
2484
2485 pack();
2486 for (auto it = chunks_.begin(); it != chunks_.end(); it++)
2487 if (it->width > 0 && it->wire == NULL) {
2488 for (size_t i = 0; i < it->data.bits.size(); i++)
2489 if (it->data.bits[i] == RTLIL::State::Sm)
2490 return true;
2491 }
2492 return false;
2493 }
2494
2495 bool RTLIL::SigSpec::as_bool() const
2496 {
2497 cover("kernel.rtlil.sigspec.as_bool");
2498
2499 pack();
2500 log_assert(is_fully_const() && SIZE(chunks_) <= 1);
2501 if (width_)
2502 return chunks_[0].data.as_bool();
2503 return false;
2504 }
2505
2506 int RTLIL::SigSpec::as_int() const
2507 {
2508 cover("kernel.rtlil.sigspec.as_int");
2509
2510 pack();
2511 log_assert(is_fully_const() && SIZE(chunks_) <= 1);
2512 if (width_)
2513 return chunks_[0].data.as_int();
2514 return 0;
2515 }
2516
2517 std::string RTLIL::SigSpec::as_string() const
2518 {
2519 cover("kernel.rtlil.sigspec.as_string");
2520
2521 pack();
2522 std::string str;
2523 for (size_t i = chunks_.size(); i > 0; i--) {
2524 const RTLIL::SigChunk &chunk = chunks_[i-1];
2525 if (chunk.wire != NULL)
2526 for (int j = 0; j < chunk.width; j++)
2527 str += "?";
2528 else
2529 str += chunk.data.as_string();
2530 }
2531 return str;
2532 }
2533
2534 RTLIL::Const RTLIL::SigSpec::as_const() const
2535 {
2536 cover("kernel.rtlil.sigspec.as_const");
2537
2538 pack();
2539 log_assert(is_fully_const() && SIZE(chunks_) <= 1);
2540 if (width_)
2541 return chunks_[0].data;
2542 return RTLIL::Const();
2543 }
2544
2545 RTLIL::Wire *RTLIL::SigSpec::as_wire() const
2546 {
2547 cover("kernel.rtlil.sigspec.as_wire");
2548
2549 pack();
2550 log_assert(is_wire());
2551 return chunks_[0].wire;
2552 }
2553
2554 RTLIL::SigChunk RTLIL::SigSpec::as_chunk() const
2555 {
2556 cover("kernel.rtlil.sigspec.as_chunk");
2557
2558 pack();
2559 log_assert(is_chunk());
2560 return chunks_[0];
2561 }
2562
2563 bool RTLIL::SigSpec::match(std::string pattern) const
2564 {
2565 cover("kernel.rtlil.sigspec.match");
2566
2567 pack();
2568 std::string str = as_string();
2569 log_assert(pattern.size() == str.size());
2570
2571 for (size_t i = 0; i < pattern.size(); i++) {
2572 if (pattern[i] == ' ')
2573 continue;
2574 if (pattern[i] == '*') {
2575 if (str[i] != 'z' && str[i] != 'x')
2576 return false;
2577 continue;
2578 }
2579 if (pattern[i] != str[i])
2580 return false;
2581 }
2582
2583 return true;
2584 }
2585
2586 std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const
2587 {
2588 cover("kernel.rtlil.sigspec.to_sigbit_set");
2589
2590 pack();
2591 std::set<RTLIL::SigBit> sigbits;
2592 for (auto &c : chunks_)
2593 for (int i = 0; i < c.width; i++)
2594 sigbits.insert(RTLIL::SigBit(c, i));
2595 return sigbits;
2596 }
2597
2598 std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
2599 {
2600 cover("kernel.rtlil.sigspec.to_sigbit_vector");
2601
2602 unpack();
2603 return bits_;
2604 }
2605
2606 RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const
2607 {
2608 cover("kernel.rtlil.sigspec.to_single_sigbit");
2609
2610 pack();
2611 log_assert(width_ == 1);
2612 for (auto &c : chunks_)
2613 if (c.width)
2614 return RTLIL::SigBit(c);
2615 log_abort();
2616 }
2617
2618 static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep)
2619 {
2620 size_t start = 0, end = 0;
2621 while ((end = text.find(sep, start)) != std::string::npos) {
2622 tokens.push_back(text.substr(start, end - start));
2623 start = end + 1;
2624 }
2625 tokens.push_back(text.substr(start));
2626 }
2627
2628 static int sigspec_parse_get_dummy_line_num()
2629 {
2630 return 0;
2631 }
2632
2633 bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
2634 {
2635 cover("kernel.rtlil.sigspec.parse");
2636
2637 std::vector<std::string> tokens;
2638 sigspec_parse_split(tokens, str, ',');
2639
2640 sig = RTLIL::SigSpec();
2641 for (int tokidx = int(tokens.size())-1; tokidx >= 0; tokidx--)
2642 {
2643 std::string netname = tokens[tokidx];
2644 std::string indices;
2645
2646 if (netname.size() == 0)
2647 continue;
2648
2649 if ('0' <= netname[0] && netname[0] <= '9') {
2650 cover("kernel.rtlil.sigspec.parse.const");
2651 AST::get_line_num = sigspec_parse_get_dummy_line_num;
2652 AST::AstNode *ast = VERILOG_FRONTEND::const2ast(netname);
2653 if (ast == NULL)
2654 return false;
2655 sig.append(RTLIL::Const(ast->bits));
2656 delete ast;
2657 continue;
2658 }
2659
2660 if (module == NULL)
2661 return false;
2662
2663 cover("kernel.rtlil.sigspec.parse.net");
2664
2665 if (netname[0] != '$' && netname[0] != '\\')
2666 netname = "\\" + netname;
2667
2668 if (module->wires_.count(netname) == 0) {
2669 size_t indices_pos = netname.size()-1;
2670 if (indices_pos > 2 && netname[indices_pos] == ']')
2671 {
2672 indices_pos--;
2673 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
2674 if (indices_pos > 0 && netname[indices_pos] == ':') {
2675 indices_pos--;
2676 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
2677 }
2678 if (indices_pos > 0 && netname[indices_pos] == '[') {
2679 indices = netname.substr(indices_pos);
2680 netname = netname.substr(0, indices_pos);
2681 }
2682 }
2683 }
2684
2685 if (module->wires_.count(netname) == 0)
2686 return false;
2687
2688 RTLIL::Wire *wire = module->wires_.at(netname);
2689 if (!indices.empty()) {
2690 std::vector<std::string> index_tokens;
2691 sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':');
2692 if (index_tokens.size() == 1) {
2693 cover("kernel.rtlil.sigspec.parse.bit_sel");
2694 sig.append(RTLIL::SigSpec(wire, atoi(index_tokens.at(0).c_str())));
2695 } else {
2696 cover("kernel.rtlil.sigspec.parse.part_sel");
2697 int a = atoi(index_tokens.at(0).c_str());
2698 int b = atoi(index_tokens.at(1).c_str());
2699 if (a > b) {
2700 int tmp = a;
2701 a = b, b = tmp;
2702 }
2703 sig.append(RTLIL::SigSpec(wire, a, b-a+1));
2704 }
2705 } else
2706 sig.append(wire);
2707 }
2708
2709 return true;
2710 }
2711
2712 bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str)
2713 {
2714 if (str.empty() || str[0] != '@')
2715 return parse(sig, module, str);
2716
2717 cover("kernel.rtlil.sigspec.parse.sel");
2718
2719 str = RTLIL::escape_id(str.substr(1));
2720 if (design->selection_vars.count(str) == 0)
2721 return false;
2722
2723 sig = RTLIL::SigSpec();
2724 RTLIL::Selection &sel = design->selection_vars.at(str);
2725 for (auto &it : module->wires_)
2726 if (sel.selected_member(module->name, it.first))
2727 sig.append(it.second);
2728
2729 return true;
2730 }
2731
2732 bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
2733 {
2734 if (str == "0") {
2735 cover("kernel.rtlil.sigspec.parse.rhs_zeros");
2736 sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.width_);
2737 return true;
2738 }
2739
2740 if (str == "~0") {
2741 cover("kernel.rtlil.sigspec.parse.rhs_ones");
2742 sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.width_);
2743 return true;
2744 }
2745
2746 if (lhs.chunks_.size() == 1) {
2747 char *p = (char*)str.c_str(), *endptr;
2748 long long int val = strtoll(p, &endptr, 10);
2749 if (endptr && endptr != p && *endptr == 0) {
2750 sig = RTLIL::SigSpec(val, lhs.width_);
2751 cover("kernel.rtlil.sigspec.parse.rhs_dec");
2752 return true;
2753 }
2754 }
2755
2756 return parse(sig, module, str);
2757 }
2758
2759 RTLIL::CaseRule::~CaseRule()
2760 {
2761 for (auto it = switches.begin(); it != switches.end(); it++)
2762 delete *it;
2763 }
2764
2765 RTLIL::CaseRule *RTLIL::CaseRule::clone() const
2766 {
2767 RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
2768 new_caserule->compare = compare;
2769 new_caserule->actions = actions;
2770 for (auto &it : switches)
2771 new_caserule->switches.push_back(it->clone());
2772 return new_caserule;
2773 }
2774
2775 RTLIL::SwitchRule::~SwitchRule()
2776 {
2777 for (auto it = cases.begin(); it != cases.end(); it++)
2778 delete *it;
2779 }
2780
2781 RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
2782 {
2783 RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
2784 new_switchrule->signal = signal;
2785 new_switchrule->attributes = attributes;
2786 for (auto &it : cases)
2787 new_switchrule->cases.push_back(it->clone());
2788 return new_switchrule;
2789
2790 }
2791
2792 RTLIL::SyncRule *RTLIL::SyncRule::clone() const
2793 {
2794 RTLIL::SyncRule *new_syncrule = new RTLIL::SyncRule;
2795 new_syncrule->type = type;
2796 new_syncrule->signal = signal;
2797 new_syncrule->actions = actions;
2798 return new_syncrule;
2799 }
2800
2801 RTLIL::Process::~Process()
2802 {
2803 for (auto it = syncs.begin(); it != syncs.end(); it++)
2804 delete *it;
2805 }
2806
2807 RTLIL::Process *RTLIL::Process::clone() const
2808 {
2809 RTLIL::Process *new_proc = new RTLIL::Process;
2810
2811 new_proc->name = name;
2812 new_proc->attributes = attributes;
2813
2814 RTLIL::CaseRule *rc_ptr = root_case.clone();
2815 new_proc->root_case = *rc_ptr;
2816 rc_ptr->switches.clear();
2817 delete rc_ptr;
2818
2819 for (auto &it : syncs)
2820 new_proc->syncs.push_back(it->clone());
2821
2822 return new_proc;
2823 }
2824
2825 YOSYS_NAMESPACE_END
2826