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