Added $assert cell
[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/rtlil.h"
21 #include "kernel/log.h"
22 #include "frontends/verilog/verilog_frontend.h"
23 #include "backends/ilang/ilang_backend.h"
24
25 #include <assert.h>
26 #include <string.h>
27 #include <algorithm>
28
29 int RTLIL::autoidx = 1;
30
31 RTLIL::Const::Const()
32 {
33 flags = RTLIL::CONST_FLAG_NONE;
34 }
35
36 RTLIL::Const::Const(std::string str)
37 {
38 flags = RTLIL::CONST_FLAG_STRING;
39 for (int i = str.size()-1; i >= 0; i--) {
40 unsigned char ch = str[i];
41 for (int j = 0; j < 8; j++) {
42 bits.push_back((ch & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
43 ch = ch >> 1;
44 }
45 }
46 }
47
48 RTLIL::Const::Const(int val, int width)
49 {
50 flags = RTLIL::CONST_FLAG_NONE;
51 for (int i = 0; i < width; i++) {
52 bits.push_back((val & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
53 val = val >> 1;
54 }
55 }
56
57 RTLIL::Const::Const(RTLIL::State bit, int width)
58 {
59 flags = RTLIL::CONST_FLAG_NONE;
60 for (int i = 0; i < width; i++)
61 bits.push_back(bit);
62 }
63
64 bool RTLIL::Const::operator <(const RTLIL::Const &other) const
65 {
66 if (bits.size() != other.bits.size())
67 return bits.size() < other.bits.size();
68 for (size_t i = 0; i < bits.size(); i++)
69 if (bits[i] != other.bits[i])
70 return bits[i] < other.bits[i];
71 return false;
72 }
73
74 bool RTLIL::Const::operator ==(const RTLIL::Const &other) const
75 {
76 return bits == other.bits;
77 }
78
79 bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
80 {
81 return bits != other.bits;
82 }
83
84 bool RTLIL::Const::as_bool() const
85 {
86 for (size_t i = 0; i < bits.size(); i++)
87 if (bits[i] == RTLIL::S1)
88 return true;
89 return false;
90 }
91
92 int RTLIL::Const::as_int() const
93 {
94 int ret = 0;
95 for (size_t i = 0; i < bits.size() && i < 32; i++)
96 if (bits[i] == RTLIL::S1)
97 ret |= 1 << i;
98 return ret;
99 }
100
101 std::string RTLIL::Const::as_string() const
102 {
103 std::string ret;
104 for (size_t i = bits.size(); i > 0; i--)
105 switch (bits[i-1]) {
106 case S0: ret += "0"; break;
107 case S1: ret += "1"; break;
108 case Sx: ret += "x"; break;
109 case Sz: ret += "z"; break;
110 case Sa: ret += "-"; break;
111 case Sm: ret += "m"; break;
112 }
113 return ret;
114 }
115
116 std::string RTLIL::Const::decode_string() const
117 {
118 std::string string;
119 std::vector <char> string_chars;
120 for (int i = 0; i < int (bits.size()); i += 8) {
121 char ch = 0;
122 for (int j = 0; j < 8 && i + j < int (bits.size()); j++)
123 if (bits[i + j] == RTLIL::State::S1)
124 ch |= 1 << j;
125 if (ch != 0)
126 string_chars.push_back(ch);
127 }
128 for (int i = int (string_chars.size()) - 1; i >= 0; i--)
129 string += string_chars[i];
130 return string;
131 }
132
133 bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const
134 {
135 if (full_selection)
136 return true;
137 if (selected_modules.count(mod_name) > 0)
138 return true;
139 if (selected_members.count(mod_name) > 0)
140 return true;
141 return false;
142 }
143
144 bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name) const
145 {
146 if (full_selection)
147 return true;
148 if (selected_modules.count(mod_name) > 0)
149 return true;
150 return false;
151 }
152
153 bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
154 {
155 if (full_selection)
156 return true;
157 if (selected_modules.count(mod_name) > 0)
158 return true;
159 if (selected_members.count(mod_name) > 0)
160 if (selected_members.at(mod_name).count(memb_name) > 0)
161 return true;
162 return false;
163 }
164
165 void RTLIL::Selection::optimize(RTLIL::Design *design)
166 {
167 if (full_selection) {
168 selected_modules.clear();
169 selected_members.clear();
170 return;
171 }
172
173 std::vector<RTLIL::IdString> del_list, add_list;
174
175 del_list.clear();
176 for (auto mod_name : selected_modules) {
177 if (design->modules.count(mod_name) == 0)
178 del_list.push_back(mod_name);
179 selected_members.erase(mod_name);
180 }
181 for (auto mod_name : del_list)
182 selected_modules.erase(mod_name);
183
184 del_list.clear();
185 for (auto &it : selected_members)
186 if (design->modules.count(it.first) == 0)
187 del_list.push_back(it.first);
188 for (auto mod_name : del_list)
189 selected_members.erase(mod_name);
190
191 for (auto &it : selected_members) {
192 del_list.clear();
193 for (auto memb_name : it.second)
194 if (design->modules[it.first]->count_id(memb_name) == 0)
195 del_list.push_back(memb_name);
196 for (auto memb_name : del_list)
197 it.second.erase(memb_name);
198 }
199
200 del_list.clear();
201 add_list.clear();
202 for (auto &it : selected_members)
203 if (it.second.size() == 0)
204 del_list.push_back(it.first);
205 else if (it.second.size() == design->modules[it.first]->wires.size() + design->modules[it.first]->memories.size() +
206 design->modules[it.first]->cells.size() + design->modules[it.first]->processes.size())
207 add_list.push_back(it.first);
208 for (auto mod_name : del_list)
209 selected_members.erase(mod_name);
210 for (auto mod_name : add_list) {
211 selected_members.erase(mod_name);
212 selected_modules.insert(mod_name);
213 }
214
215 if (selected_modules.size() == design->modules.size()) {
216 full_selection = true;
217 selected_modules.clear();
218 selected_members.clear();
219 }
220 }
221
222 RTLIL::Design::~Design()
223 {
224 for (auto it = modules.begin(); it != modules.end(); it++)
225 delete it->second;
226 }
227
228 void RTLIL::Design::check()
229 {
230 #ifndef NDEBUG
231 for (auto &it : modules) {
232 assert(it.first == it.second->name);
233 assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
234 it.second->check();
235 }
236 #endif
237 }
238
239 void RTLIL::Design::optimize()
240 {
241 for (auto &it : modules)
242 it.second->optimize();
243 for (auto &it : selection_stack)
244 it.optimize(this);
245 for (auto &it : selection_vars)
246 it.second.optimize(this);
247 }
248
249 bool RTLIL::Design::selected_module(RTLIL::IdString mod_name) const
250 {
251 if (!selected_active_module.empty() && mod_name != selected_active_module)
252 return false;
253 if (selection_stack.size() == 0)
254 return true;
255 return selection_stack.back().selected_module(mod_name);
256 }
257
258 bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name) const
259 {
260 if (!selected_active_module.empty() && mod_name != selected_active_module)
261 return false;
262 if (selection_stack.size() == 0)
263 return true;
264 return selection_stack.back().selected_whole_module(mod_name);
265 }
266
267 bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
268 {
269 if (!selected_active_module.empty() && mod_name != selected_active_module)
270 return false;
271 if (selection_stack.size() == 0)
272 return true;
273 return selection_stack.back().selected_member(mod_name, memb_name);
274 }
275
276 RTLIL::Module::~Module()
277 {
278 for (auto it = wires.begin(); it != wires.end(); it++)
279 delete it->second;
280 for (auto it = memories.begin(); it != memories.end(); it++)
281 delete it->second;
282 for (auto it = cells.begin(); it != cells.end(); it++)
283 delete it->second;
284 for (auto it = processes.begin(); it != processes.end(); it++)
285 delete it->second;
286 }
287
288 RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map<RTLIL::IdString, RTLIL::Const>)
289 {
290 log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
291 }
292
293 size_t RTLIL::Module::count_id(RTLIL::IdString id)
294 {
295 return wires.count(id) + memories.count(id) + cells.count(id) + processes.count(id);
296 }
297
298 #ifndef NDEBUG
299 namespace {
300 struct InternalCellChecker
301 {
302 RTLIL::Module *module;
303 RTLIL::Cell *cell;
304 std::set<RTLIL::IdString> expected_params, expected_ports;
305
306 InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { }
307
308 void error(int linenr)
309 {
310 char *ptr;
311 size_t size;
312
313 FILE *f = open_memstream(&ptr, &size);
314 ILANG_BACKEND::dump_cell(f, " ", cell);
315 fputc(0, f);
316 fclose(f);
317
318 log_error("Found error in internal cell %s.%s (%s) at %s:%d:\n%s",
319 module->name.c_str(), cell->name.c_str(), cell->type.c_str(),
320 __FILE__, linenr, ptr);
321 }
322
323 int param(const char *name)
324 {
325 if (cell->parameters.count(name) == 0)
326 error(__LINE__);
327 expected_params.insert(name);
328 return cell->parameters.at(name).as_int();
329 }
330
331 void port(const char *name, int width)
332 {
333 if (cell->connections.count(name) == 0)
334 error(__LINE__);
335 if (cell->connections.at(name).width != width)
336 error(__LINE__);
337 expected_ports.insert(name);
338 }
339
340 void check_expected(bool check_matched_sign = true)
341 {
342 for (auto &para : cell->parameters)
343 if (expected_params.count(para.first) == 0)
344 error(__LINE__);
345 for (auto &conn : cell->connections)
346 if (expected_ports.count(conn.first) == 0)
347 error(__LINE__);
348
349 if (expected_params.count("\\A_SIGNED") != 0 && expected_params.count("\\B_SIGNED") && check_matched_sign) {
350 bool a_is_signed = param("\\A_SIGNED") != 0;
351 bool b_is_signed = param("\\B_SIGNED") != 0;
352 if (a_is_signed != b_is_signed)
353 error(__LINE__);
354 }
355 }
356
357 void check_gate(const char *ports)
358 {
359 if (cell->parameters.size() != 0)
360 error(__LINE__);
361
362 for (const char *p = ports; *p; p++) {
363 char portname[3] = { '\\', *p, 0 };
364 if (cell->connections.count(portname) == 0)
365 error(__LINE__);
366 if (cell->connections.at(portname).width != 1)
367 error(__LINE__);
368 }
369
370 for (auto &conn : cell->connections) {
371 if (conn.first.size() != 2 || conn.first.at(0) != '\\')
372 error(__LINE__);
373 if (strchr(ports, conn.first.at(1)) == NULL)
374 error(__LINE__);
375 }
376 }
377
378 void check()
379 {
380 if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") {
381 param("\\A_SIGNED");
382 port("\\A", param("\\A_WIDTH"));
383 port("\\Y", param("\\Y_WIDTH"));
384 check_expected();
385 return;
386 }
387
388 if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") {
389 param("\\A_SIGNED");
390 param("\\B_SIGNED");
391 port("\\A", param("\\A_WIDTH"));
392 port("\\B", param("\\B_WIDTH"));
393 port("\\Y", param("\\Y_WIDTH"));
394 check_expected();
395 return;
396 }
397
398 if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" ||
399 cell->type == "$reduce_xnor" || cell->type == "$reduce_bool") {
400 param("\\A_SIGNED");
401 port("\\A", param("\\A_WIDTH"));
402 port("\\Y", param("\\Y_WIDTH"));
403 check_expected();
404 return;
405 }
406
407 if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") {
408 param("\\A_SIGNED");
409 param("\\B_SIGNED");
410 port("\\A", param("\\A_WIDTH"));
411 port("\\B", param("\\B_WIDTH"));
412 port("\\Y", param("\\Y_WIDTH"));
413 check_expected(false);
414 return;
415 }
416
417 if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" ||
418 cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") {
419 param("\\A_SIGNED");
420 param("\\B_SIGNED");
421 port("\\A", param("\\A_WIDTH"));
422 port("\\B", param("\\B_WIDTH"));
423 port("\\Y", param("\\Y_WIDTH"));
424 check_expected();
425 return;
426 }
427
428 if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" ||
429 cell->type == "$mod" || cell->type == "$pow") {
430 param("\\A_SIGNED");
431 param("\\B_SIGNED");
432 port("\\A", param("\\A_WIDTH"));
433 port("\\B", param("\\B_WIDTH"));
434 port("\\Y", param("\\Y_WIDTH"));
435 check_expected(cell->type != "$pow");
436 return;
437 }
438
439 if (cell->type == "$logic_not") {
440 param("\\A_SIGNED");
441 port("\\A", param("\\A_WIDTH"));
442 port("\\Y", param("\\Y_WIDTH"));
443 check_expected();
444 return;
445 }
446
447 if (cell->type == "$logic_and" || cell->type == "$logic_or") {
448 param("\\A_SIGNED");
449 param("\\B_SIGNED");
450 port("\\A", param("\\A_WIDTH"));
451 port("\\B", param("\\B_WIDTH"));
452 port("\\Y", param("\\Y_WIDTH"));
453 check_expected(false);
454 return;
455 }
456
457 if (cell->type == "$mux") {
458 port("\\A", param("\\WIDTH"));
459 port("\\B", param("\\WIDTH"));
460 port("\\S", 1);
461 port("\\Y", param("\\WIDTH"));
462 check_expected();
463 return;
464 }
465
466 if (cell->type == "$pmux" || cell->type == "$safe_pmux") {
467 port("\\A", param("\\WIDTH"));
468 port("\\B", param("\\WIDTH") * param("\\S_WIDTH"));
469 port("\\S", param("\\S_WIDTH"));
470 port("\\Y", param("\\WIDTH"));
471 check_expected();
472 return;
473 }
474
475 if (cell->type == "$lut") {
476 param("\\LUT");
477 port("\\I", param("\\WIDTH"));
478 port("\\O", 1);
479 check_expected();
480 return;
481 }
482
483 if (cell->type == "$sr") {
484 param("\\SET_POLARITY");
485 param("\\CLR_POLARITY");
486 port("\\SET", param("\\WIDTH"));
487 port("\\CLR", param("\\WIDTH"));
488 port("\\Q", param("\\WIDTH"));
489 check_expected();
490 return;
491 }
492
493 if (cell->type == "$dff") {
494 param("\\CLK_POLARITY");
495 port("\\CLK", 1);
496 port("\\D", param("\\WIDTH"));
497 port("\\Q", param("\\WIDTH"));
498 check_expected();
499 return;
500 }
501
502 if (cell->type == "$dffsr") {
503 param("\\CLK_POLARITY");
504 param("\\SET_POLARITY");
505 param("\\CLR_POLARITY");
506 port("\\CLK", 1);
507 port("\\SET", param("\\WIDTH"));
508 port("\\CLR", param("\\WIDTH"));
509 port("\\D", param("\\WIDTH"));
510 port("\\Q", param("\\WIDTH"));
511 check_expected();
512 return;
513 }
514
515 if (cell->type == "$adff") {
516 param("\\CLK_POLARITY");
517 param("\\ARST_POLARITY");
518 param("\\ARST_VALUE");
519 port("\\CLK", 1);
520 port("\\ARST", 1);
521 port("\\D", param("\\WIDTH"));
522 port("\\Q", param("\\WIDTH"));
523 check_expected();
524 return;
525 }
526
527 if (cell->type == "$dlatch") {
528 param("\\EN_POLARITY");
529 port("\\EN", 1);
530 port("\\D", param("\\WIDTH"));
531 port("\\Q", param("\\WIDTH"));
532 check_expected();
533 return;
534 }
535
536 if (cell->type == "$fsm") {
537 param("\\NAME");
538 param("\\CLK_POLARITY");
539 param("\\ARST_POLARITY");
540 param("\\STATE_BITS");
541 param("\\STATE_NUM");
542 param("\\STATE_NUM_LOG2");
543 param("\\STATE_RST");
544 param("\\STATE_TABLE");
545 param("\\TRANS_NUM");
546 param("\\TRANS_TABLE");
547 port("\\CLK", 1);
548 port("\\ARST", 1);
549 port("\\CTRL_IN", param("\\CTRL_IN_WIDTH"));
550 port("\\CTRL_OUT", param("\\CTRL_OUT_WIDTH"));
551 check_expected();
552 return;
553 }
554
555 if (cell->type == "$memrd") {
556 param("\\MEMID");
557 param("\\CLK_ENABLE");
558 param("\\CLK_POLARITY");
559 port("\\CLK", 1);
560 port("\\ADDR", param("\\ABITS"));
561 port("\\DATA", param("\\WIDTH"));
562 check_expected();
563 return;
564 }
565
566 if (cell->type == "$memwr") {
567 param("\\MEMID");
568 param("\\CLK_ENABLE");
569 param("\\CLK_POLARITY");
570 param("\\PRIORITY");
571 port("\\CLK", 1);
572 port("\\EN", 1);
573 port("\\ADDR", param("\\ABITS"));
574 port("\\DATA", param("\\WIDTH"));
575 check_expected();
576 return;
577 }
578
579 if (cell->type == "$mem") {
580 param("\\MEMID");
581 param("\\SIZE");
582 param("\\OFFSET");
583 param("\\RD_CLK_ENABLE");
584 param("\\RD_CLK_POLARITY");
585 param("\\WR_CLK_ENABLE");
586 param("\\WR_CLK_POLARITY");
587 port("\\RD_CLK", param("\\RD_PORTS"));
588 port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS"));
589 port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH"));
590 port("\\WR_CLK", param("\\WR_PORTS"));
591 port("\\WR_EN", param("\\WR_PORTS"));
592 port("\\WR_ADDR", param("\\WR_PORTS") * param("\\ABITS"));
593 port("\\WR_DATA", param("\\WR_PORTS") * param("\\WIDTH"));
594 check_expected();
595 return;
596 }
597
598 if (cell->type == "$assert") {
599 port("\\A", 1);
600 port("\\EN", 1);
601 check_expected();
602 return;
603 }
604
605 if (cell->type == "$_INV_") { check_gate("AY"); return; }
606 if (cell->type == "$_AND_") { check_gate("ABY"); return; }
607 if (cell->type == "$_OR_") { check_gate("ABY"); return; }
608 if (cell->type == "$_XOR_") { check_gate("ABY"); return; }
609 if (cell->type == "$_MUX_") { check_gate("ABSY"); return; }
610
611 if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; }
612 if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; }
613 if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; }
614 if (cell->type == "$_SR_PP_") { check_gate("SRQ"); return; }
615
616 if (cell->type == "$_DFF_N_") { check_gate("DQC"); return; }
617 if (cell->type == "$_DFF_P_") { check_gate("DQC"); return; }
618
619 if (cell->type == "$_DFF_NN0_") { check_gate("DQCR"); return; }
620 if (cell->type == "$_DFF_NN1_") { check_gate("DQCR"); return; }
621 if (cell->type == "$_DFF_NP0_") { check_gate("DQCR"); return; }
622 if (cell->type == "$_DFF_NP1_") { check_gate("DQCR"); return; }
623 if (cell->type == "$_DFF_PN0_") { check_gate("DQCR"); return; }
624 if (cell->type == "$_DFF_PN1_") { check_gate("DQCR"); return; }
625 if (cell->type == "$_DFF_PP0_") { check_gate("DQCR"); return; }
626 if (cell->type == "$_DFF_PP1_") { check_gate("DQCR"); return; }
627
628 if (cell->type == "$_DFFSR_NNN_") { check_gate("CSRDQ"); return; }
629 if (cell->type == "$_DFFSR_NNP_") { check_gate("CSRDQ"); return; }
630 if (cell->type == "$_DFFSR_NPN_") { check_gate("CSRDQ"); return; }
631 if (cell->type == "$_DFFSR_NPP_") { check_gate("CSRDQ"); return; }
632 if (cell->type == "$_DFFSR_PNN_") { check_gate("CSRDQ"); return; }
633 if (cell->type == "$_DFFSR_PNP_") { check_gate("CSRDQ"); return; }
634 if (cell->type == "$_DFFSR_PPN_") { check_gate("CSRDQ"); return; }
635 if (cell->type == "$_DFFSR_PPP_") { check_gate("CSRDQ"); return; }
636
637 if (cell->type == "$_DLATCH_N_") { check_gate("EDQ"); return; }
638 if (cell->type == "$_DLATCH_P_") { check_gate("EDQ"); return; }
639
640 error(__LINE__);
641 }
642 };
643 }
644 #endif
645
646 void RTLIL::Module::check()
647 {
648 #ifndef NDEBUG
649 for (auto &it : wires) {
650 assert(it.first == it.second->name);
651 assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
652 assert(it.second->width >= 0);
653 assert(it.second->port_id >= 0);
654 for (auto &it2 : it.second->attributes) {
655 assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
656 }
657 }
658
659 for (auto &it : memories) {
660 assert(it.first == it.second->name);
661 assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
662 assert(it.second->width >= 0);
663 assert(it.second->size >= 0);
664 for (auto &it2 : it.second->attributes) {
665 assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
666 }
667 }
668
669 for (auto &it : cells) {
670 assert(it.first == it.second->name);
671 assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
672 assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$'));
673 for (auto &it2 : it.second->connections) {
674 assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
675 it2.second.check();
676 }
677 for (auto &it2 : it.second->attributes) {
678 assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
679 }
680 for (auto &it2 : it.second->parameters) {
681 assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$'));
682 }
683 if (it.second->type[0] == '$' && it.second->type.substr(0, 3) != "$__" && it.second->type.substr(0, 8) != "$paramod") {
684 InternalCellChecker checker(this, it.second);
685 checker.check();
686 }
687 }
688
689 for (auto &it : processes) {
690 assert(it.first == it.second->name);
691 assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
692 // FIXME: More checks here..
693 }
694
695 for (auto &it : connections) {
696 assert(it.first.width == it.second.width);
697 it.first.check();
698 it.second.check();
699 }
700
701 for (auto &it : attributes) {
702 assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$'));
703 }
704 #endif
705 }
706
707 void RTLIL::Module::optimize()
708 {
709 for (auto &it : cells)
710 it.second->optimize();
711 for (auto &it : processes)
712 it.second->optimize();
713 for (auto &it : connections) {
714 it.first.optimize();
715 it.second.optimize();
716 }
717 }
718
719 void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const
720 {
721 new_mod->name = name;
722 new_mod->connections = connections;
723 new_mod->attributes = attributes;
724
725 for (auto &it : wires)
726 new_mod->wires[it.first] = new RTLIL::Wire(*it.second);
727
728 for (auto &it : memories)
729 new_mod->memories[it.first] = new RTLIL::Memory(*it.second);
730
731 for (auto &it : cells)
732 new_mod->cells[it.first] = new RTLIL::Cell(*it.second);
733
734 for (auto &it : processes)
735 new_mod->processes[it.first] = it.second->clone();
736
737 struct RewriteSigSpecWorker
738 {
739 RTLIL::Module *mod;
740 void operator()(RTLIL::SigSpec &sig)
741 {
742 for (auto &c : sig.chunks)
743 if (c.wire != NULL)
744 c.wire = mod->wires.at(c.wire->name);
745 }
746 };
747
748 RewriteSigSpecWorker rewriteSigSpecWorker;
749 rewriteSigSpecWorker.mod = new_mod;
750 new_mod->rewrite_sigspecs(rewriteSigSpecWorker);
751 }
752
753 RTLIL::Module *RTLIL::Module::clone() const
754 {
755 RTLIL::Module *new_mod = new RTLIL::Module;
756 cloneInto(new_mod);
757 return new_mod;
758 }
759
760 RTLIL::Wire *RTLIL::Module::new_wire(int width, RTLIL::IdString name)
761 {
762 RTLIL::Wire *wire = new RTLIL::Wire;
763 wire->width = width;
764 wire->name = name;
765 add(wire);
766 return wire;
767 }
768
769 void RTLIL::Module::add(RTLIL::Wire *wire)
770 {
771 assert(!wire->name.empty());
772 assert(count_id(wire->name) == 0);
773 wires[wire->name] = wire;
774 }
775
776 void RTLIL::Module::add(RTLIL::Cell *cell)
777 {
778 assert(!cell->name.empty());
779 assert(count_id(cell->name) == 0);
780 cells[cell->name] = cell;
781 }
782
783 static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
784 {
785 if (a->port_id && !b->port_id)
786 return true;
787 if (!a->port_id && b->port_id)
788 return false;
789
790 if (a->port_id == b->port_id)
791 return a->name < b->name;
792 return a->port_id < b->port_id;
793 }
794
795 void RTLIL::Module::fixup_ports()
796 {
797 std::vector<RTLIL::Wire*> all_ports;
798
799 for (auto &w : wires)
800 if (w.second->port_input || w.second->port_output)
801 all_ports.push_back(w.second);
802 else
803 w.second->port_id = 0;
804
805 std::sort(all_ports.begin(), all_ports.end(), fixup_ports_compare);
806 for (size_t i = 0; i < all_ports.size(); i++)
807 all_ports[i]->port_id = i+1;
808 }
809
810 RTLIL::Wire::Wire()
811 {
812 width = 1;
813 start_offset = 0;
814 port_id = 0;
815 port_input = false;
816 port_output = false;
817 }
818
819 RTLIL::Memory::Memory()
820 {
821 width = 1;
822 size = 0;
823 }
824
825 void RTLIL::Cell::optimize()
826 {
827 for (auto &it : connections)
828 it.second.optimize();
829 }
830
831 RTLIL::SigChunk::SigChunk()
832 {
833 wire = NULL;
834 width = 0;
835 offset = 0;
836 }
837
838 RTLIL::SigChunk::SigChunk(const RTLIL::Const &data)
839 {
840 wire = NULL;
841 this->data = data;
842 width = data.bits.size();
843 offset = 0;
844 }
845
846 RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int width, int offset)
847 {
848 this->wire = wire;
849 this->width = width >= 0 ? width : wire->width;
850 this->offset = offset;
851 }
852
853 RTLIL::SigChunk::SigChunk(const std::string &str)
854 {
855 wire = NULL;
856 data = RTLIL::Const(str);
857 width = data.bits.size();
858 offset = 0;
859 }
860
861 RTLIL::SigChunk::SigChunk(int val, int width)
862 {
863 wire = NULL;
864 data = RTLIL::Const(val, width);
865 this->width = data.bits.size();
866 offset = 0;
867 }
868
869 RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width)
870 {
871 wire = NULL;
872 data = RTLIL::Const(bit, width);
873 this->width = data.bits.size();
874 offset = 0;
875 }
876
877 RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
878 {
879 wire = bit.wire;
880 if (wire == NULL)
881 data = RTLIL::Const(bit.data);
882 offset = bit.offset;
883 width = 1;
884 }
885
886 RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
887 {
888 RTLIL::SigChunk ret;
889 if (wire) {
890 ret.wire = wire;
891 ret.offset = this->offset + offset;
892 ret.width = length;
893 } else {
894 for (int i = 0; i < length; i++)
895 ret.data.bits.push_back(data.bits[offset+i]);
896 ret.width = length;
897 }
898 return ret;
899 }
900
901 bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk &other) const
902 {
903 if (wire && other.wire)
904 if (wire->name != other.wire->name)
905 return wire->name < other.wire->name;
906 if (wire != other.wire)
907 return wire < other.wire;
908
909 if (offset != other.offset)
910 return offset < other.offset;
911
912 if (width != other.width)
913 return width < other.width;
914
915 if (data.bits != other.data.bits)
916 return data.bits < other.data.bits;
917
918 return false;
919 }
920
921 bool RTLIL::SigChunk::operator ==(const RTLIL::SigChunk &other) const
922 {
923 if (wire != other.wire || width != other.width || offset != other.offset)
924 return false;
925 if (data.bits != other.data.bits)
926 return false;
927 return true;
928 }
929
930 bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const
931 {
932 if (*this == other)
933 return false;
934 return true;
935 }
936
937 RTLIL::SigSpec::SigSpec()
938 {
939 width = 0;
940 }
941
942 RTLIL::SigSpec::SigSpec(const RTLIL::Const &data)
943 {
944 chunks.push_back(RTLIL::SigChunk(data));
945 width = chunks.back().width;
946 check();
947 }
948
949 RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
950 {
951 chunks.push_back(chunk);
952 width = chunks.back().width;
953 check();
954 }
955
956 RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int width, int offset)
957 {
958 chunks.push_back(RTLIL::SigChunk(wire, width, offset));
959 this->width = chunks.back().width;
960 check();
961 }
962
963 RTLIL::SigSpec::SigSpec(const std::string &str)
964 {
965 chunks.push_back(RTLIL::SigChunk(str));
966 width = chunks.back().width;
967 check();
968 }
969
970 RTLIL::SigSpec::SigSpec(int val, int width)
971 {
972 chunks.push_back(RTLIL::SigChunk(val, width));
973 this->width = width;
974 check();
975 }
976
977 RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
978 {
979 chunks.push_back(RTLIL::SigChunk(bit, width));
980 this->width = width;
981 check();
982 }
983
984 RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
985 {
986 if (bit.wire == NULL)
987 chunks.push_back(RTLIL::SigChunk(bit.data, width));
988 else
989 for (int i = 0; i < width; i++)
990 chunks.push_back(bit);
991 this->width = width;
992 check();
993 }
994
995 RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
996 {
997 chunks.reserve(bits.size());
998 for (auto &bit : bits)
999 chunks.push_back(bit);
1000 this->width = bits.size();
1001 check();
1002 }
1003
1004 void RTLIL::SigSpec::expand()
1005 {
1006 std::vector<RTLIL::SigChunk> new_chunks;
1007 for (size_t i = 0; i < chunks.size(); i++) {
1008 for (int j = 0; j < chunks[i].width; j++)
1009 new_chunks.push_back(chunks[i].extract(j, 1));
1010 }
1011 chunks.swap(new_chunks);
1012 check();
1013 }
1014
1015 void RTLIL::SigSpec::optimize()
1016 {
1017 std::vector<RTLIL::SigChunk> new_chunks;
1018 for (auto &c : chunks)
1019 if (new_chunks.size() == 0) {
1020 new_chunks.push_back(c);
1021 } else {
1022 RTLIL::SigChunk &cc = new_chunks.back();
1023 if (c.wire == NULL && cc.wire == NULL)
1024 cc.data.bits.insert(cc.data.bits.end(), c.data.bits.begin(), c.data.bits.end());
1025 if (c.wire == cc.wire && (c.wire == NULL || cc.offset + cc.width == c.offset))
1026 cc.width += c.width;
1027 else
1028 new_chunks.push_back(c);
1029 }
1030 chunks.swap(new_chunks);
1031 check();
1032 }
1033
1034 RTLIL::SigSpec RTLIL::SigSpec::optimized() const
1035 {
1036 RTLIL::SigSpec ret = *this;
1037 ret.optimize();
1038 return ret;
1039 }
1040
1041 bool RTLIL::SigChunk::compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b)
1042 {
1043 if (a.wire != b.wire) {
1044 if (a.wire == NULL || b.wire == NULL)
1045 return a.wire < b.wire;
1046 else if (a.wire->name != b.wire->name)
1047 return a.wire->name < b.wire->name;
1048 else
1049 return a.wire < b.wire;
1050 }
1051 if (a.offset != b.offset)
1052 return a.offset < b.offset;
1053 if (a.width != b.width)
1054 return a.width < b.width;
1055 return a.data.bits < b.data.bits;
1056 }
1057
1058 void RTLIL::SigSpec::sort()
1059 {
1060 expand();
1061 std::sort(chunks.begin(), chunks.end(), RTLIL::SigChunk::compare);
1062 optimize();
1063 }
1064
1065 void RTLIL::SigSpec::sort_and_unify()
1066 {
1067 expand();
1068 std::sort(chunks.begin(), chunks.end(), RTLIL::SigChunk::compare);
1069 for (size_t i = 1; i < chunks.size(); i++) {
1070 RTLIL::SigChunk &ch1 = chunks[i-1];
1071 RTLIL::SigChunk &ch2 = chunks[i];
1072 if (!RTLIL::SigChunk::compare(ch1, ch2) && !RTLIL::SigChunk::compare(ch2, ch1)) {
1073 chunks.erase(chunks.begin()+i);
1074 width -= chunks[i].width;
1075 i--;
1076 }
1077 }
1078 optimize();
1079 }
1080
1081 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
1082 {
1083 replace(pattern, with, this);
1084 }
1085
1086 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const
1087 {
1088 int pos = 0, restart_pos = 0;
1089 assert(other == NULL || width == other->width);
1090 for (size_t i = 0; i < chunks.size(); i++) {
1091 restart:
1092 const RTLIL::SigChunk &ch1 = chunks[i];
1093 if (chunks[i].wire != NULL && pos >= restart_pos)
1094 for (size_t j = 0, poff = 0; j < pattern.chunks.size(); j++) {
1095 const RTLIL::SigChunk &ch2 = pattern.chunks[j];
1096 assert(ch2.wire != NULL);
1097 if (ch1.wire == ch2.wire) {
1098 int lower = std::max(ch1.offset, ch2.offset);
1099 int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width);
1100 if (lower < upper) {
1101 restart_pos = pos+upper-ch1.offset;
1102 other->replace(pos+lower-ch1.offset, with.extract(poff+lower-ch2.offset, upper-lower));
1103 goto restart;
1104 }
1105 }
1106 poff += ch2.width;
1107 }
1108 pos += chunks[i].width;
1109 }
1110 check();
1111 }
1112
1113 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern)
1114 {
1115 remove2(pattern, NULL);
1116 }
1117
1118 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const
1119 {
1120 RTLIL::SigSpec tmp = *this;
1121 tmp.remove2(pattern, other);
1122 }
1123
1124 void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
1125 {
1126 int pos = 0;
1127 assert(other == NULL || width == other->width);
1128 for (size_t i = 0; i < chunks.size(); i++) {
1129 restart:
1130 const RTLIL::SigChunk &ch1 = chunks[i];
1131 if (chunks[i].wire != NULL)
1132 for (size_t j = 0; j < pattern.chunks.size(); j++) {
1133 const RTLIL::SigChunk &ch2 = pattern.chunks[j];
1134 assert(ch2.wire != NULL);
1135 if (ch1.wire == ch2.wire) {
1136 int lower = std::max(ch1.offset, ch2.offset);
1137 int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width);
1138 if (lower < upper) {
1139 if (other)
1140 other->remove(pos+lower-ch1.offset, upper-lower);
1141 remove(pos+lower-ch1.offset, upper-lower);
1142 if (i == chunks.size())
1143 break;
1144 goto restart;
1145 }
1146 }
1147 }
1148 pos += chunks[i].width;
1149 }
1150 check();
1151 }
1152
1153 RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const
1154 {
1155 assert(other == NULL || width == other->width);
1156
1157 std::set<RTLIL::SigBit> pat = pattern.to_sigbit_set();
1158 std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
1159 RTLIL::SigSpec ret;
1160
1161 if (other) {
1162 std::vector<RTLIL::SigBit> bits_other = other ? other->to_sigbit_vector() : bits_match;
1163 for (int i = 0; i < width; i++)
1164 if (bits_match[i].wire && pat.count(bits_match[i]))
1165 ret.append_bit(bits_other[i]);
1166 } else {
1167 for (int i = 0; i < width; i++)
1168 if (bits_match[i].wire && pat.count(bits_match[i]))
1169 ret.append_bit(bits_match[i]);
1170 }
1171
1172 ret.check();
1173 return ret;
1174 }
1175
1176 void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
1177 {
1178 int pos = 0;
1179 assert(offset >= 0);
1180 assert(with.width >= 0);
1181 assert(offset+with.width <= width);
1182 remove(offset, with.width);
1183 for (size_t i = 0; i < chunks.size(); i++) {
1184 if (pos == offset) {
1185 chunks.insert(chunks.begin()+i, with.chunks.begin(), with.chunks.end());
1186 width += with.width;
1187 check();
1188 return;
1189 }
1190 pos += chunks[i].width;
1191 }
1192 assert(pos == offset);
1193 chunks.insert(chunks.end(), with.chunks.begin(), with.chunks.end());
1194 width += with.width;
1195 check();
1196 }
1197
1198 void RTLIL::SigSpec::remove_const()
1199 {
1200 for (size_t i = 0; i < chunks.size(); i++) {
1201 if (chunks[i].wire != NULL)
1202 continue;
1203 width -= chunks[i].width;
1204 chunks.erase(chunks.begin() + (i--));
1205 }
1206 check();
1207 }
1208
1209 void RTLIL::SigSpec::remove(int offset, int length)
1210 {
1211 int pos = 0;
1212 assert(offset >= 0);
1213 assert(length >= 0);
1214 assert(offset+length <= width);
1215 for (size_t i = 0; i < chunks.size(); i++) {
1216 int orig_width = chunks[i].width;
1217 if (pos+chunks[i].width > offset && pos < offset+length) {
1218 int off = offset - pos;
1219 int len = length;
1220 if (off < 0) {
1221 len += off;
1222 off = 0;
1223 }
1224 if (len > chunks[i].width-off)
1225 len = chunks[i].width-off;
1226 RTLIL::SigChunk lsb_chunk = chunks[i].extract(0, off);
1227 RTLIL::SigChunk msb_chunk = chunks[i].extract(off+len, chunks[i].width-off-len);
1228 if (lsb_chunk.width == 0 && msb_chunk.width == 0) {
1229 chunks.erase(chunks.begin()+i);
1230 i--;
1231 } else if (lsb_chunk.width == 0 && msb_chunk.width != 0) {
1232 chunks[i] = msb_chunk;
1233 } else if (lsb_chunk.width != 0 && msb_chunk.width == 0) {
1234 chunks[i] = lsb_chunk;
1235 } else if (lsb_chunk.width != 0 && msb_chunk.width != 0) {
1236 chunks[i] = lsb_chunk;
1237 chunks.insert(chunks.begin()+i+1, msb_chunk);
1238 i++;
1239 } else
1240 assert(0);
1241 width -= len;
1242 }
1243 pos += orig_width;
1244 }
1245 check();
1246 }
1247
1248 RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
1249 {
1250 int pos = 0;
1251 RTLIL::SigSpec ret;
1252 assert(offset >= 0);
1253 assert(length >= 0);
1254 assert(offset+length <= width);
1255 for (size_t i = 0; i < chunks.size(); i++) {
1256 if (pos+chunks[i].width > offset && pos < offset+length) {
1257 int off = offset - pos;
1258 int len = length;
1259 if (off < 0) {
1260 len += off;
1261 off = 0;
1262 }
1263 if (len > chunks[i].width-off)
1264 len = chunks[i].width-off;
1265 ret.chunks.push_back(chunks[i].extract(off, len));
1266 ret.width += len;
1267 offset += len;
1268 length -= len;
1269 }
1270 pos += chunks[i].width;
1271 }
1272 assert(length == 0);
1273 ret.check();
1274 return ret;
1275 }
1276
1277 void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
1278 {
1279 for (size_t i = 0; i < signal.chunks.size(); i++) {
1280 chunks.push_back(signal.chunks[i]);
1281 width += signal.chunks[i].width;
1282 }
1283 // check();
1284 }
1285
1286 void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
1287 {
1288 if (chunks.size() == 0)
1289 chunks.push_back(bit);
1290 else
1291 if (bit.wire == NULL)
1292 if (chunks.back().wire == NULL)
1293 chunks.back().data.bits.push_back(bit.data);
1294 else
1295 chunks.push_back(bit);
1296 else
1297 if (chunks.back().wire == bit.wire && chunks.back().offset + chunks.back().width == bit.offset)
1298 chunks.back().width++;
1299 else
1300 chunks.push_back(bit);
1301 width++;
1302 // check();
1303 }
1304
1305 bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool override)
1306 {
1307 bool no_collisions = true;
1308
1309 assert(width == signal.width);
1310 expand();
1311 signal.expand();
1312
1313 for (size_t i = 0; i < chunks.size(); i++) {
1314 bool self_free = chunks[i].wire == NULL && chunks[i].data.bits[0] == freeState;
1315 bool other_free = signal.chunks[i].wire == NULL && signal.chunks[i].data.bits[0] == freeState;
1316 if (!self_free && !other_free) {
1317 if (override)
1318 chunks[i] = signal.chunks[i];
1319 else
1320 chunks[i] = RTLIL::SigChunk(RTLIL::State::Sx, 1);
1321 no_collisions = false;
1322 }
1323 if (self_free && !other_free)
1324 chunks[i] = signal.chunks[i];
1325 }
1326
1327 optimize();
1328 return no_collisions;
1329 }
1330
1331 void RTLIL::SigSpec::extend(int width, bool is_signed)
1332 {
1333 if (this->width > width)
1334 remove(width, this->width - width);
1335
1336 if (this->width < width) {
1337 RTLIL::SigSpec padding = this->width > 0 ? extract(this->width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
1338 if (!is_signed && padding != RTLIL::SigSpec(RTLIL::State::Sx) && padding != RTLIL::SigSpec(RTLIL::State::Sz) &&
1339 padding != RTLIL::SigSpec(RTLIL::State::Sa) && padding != RTLIL::SigSpec(RTLIL::State::Sm))
1340 padding = RTLIL::SigSpec(RTLIL::State::S0);
1341 while (this->width < width)
1342 append(padding);
1343 }
1344
1345 optimize();
1346 }
1347
1348 void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
1349 {
1350 if (this->width > width)
1351 remove(width, this->width - width);
1352
1353 if (this->width < width) {
1354 RTLIL::SigSpec padding = this->width > 0 ? extract(this->width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
1355 if (!is_signed)
1356 padding = RTLIL::SigSpec(RTLIL::State::S0);
1357 while (this->width < width)
1358 append(padding);
1359 }
1360
1361 optimize();
1362 }
1363
1364 void RTLIL::SigSpec::check() const
1365 {
1366 int w = 0;
1367 for (size_t i = 0; i < chunks.size(); i++) {
1368 const RTLIL::SigChunk chunk = chunks[i];
1369 if (chunk.wire == NULL) {
1370 assert(chunk.offset == 0);
1371 assert(chunk.data.bits.size() == (size_t)chunk.width);
1372 } else {
1373 assert(chunk.offset >= 0);
1374 assert(chunk.width >= 0);
1375 assert(chunk.offset + chunk.width <= chunk.wire->width);
1376 assert(chunk.data.bits.size() == 0);
1377 }
1378 w += chunk.width;
1379 }
1380 assert(w == width);
1381 }
1382
1383 bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
1384 {
1385 if (width != other.width)
1386 return width < other.width;
1387
1388 RTLIL::SigSpec a = *this, b = other;
1389 a.optimize();
1390 b.optimize();
1391
1392 if (a.chunks.size() != b.chunks.size())
1393 return a.chunks.size() < b.chunks.size();
1394
1395 for (size_t i = 0; i < a.chunks.size(); i++)
1396 if (a.chunks[i] != b.chunks[i])
1397 return a.chunks[i] < b.chunks[i];
1398
1399 return false;
1400 }
1401
1402 bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
1403 {
1404 if (width != other.width)
1405 return false;
1406
1407 RTLIL::SigSpec a = *this, b = other;
1408 a.optimize();
1409 b.optimize();
1410
1411 if (a.chunks.size() != b.chunks.size())
1412 return false;
1413
1414 for (size_t i = 0; i < a.chunks.size(); i++)
1415 if (a.chunks[i] != b.chunks[i])
1416 return false;
1417
1418 return true;
1419 }
1420
1421 bool RTLIL::SigSpec::operator !=(const RTLIL::SigSpec &other) const
1422 {
1423 if (*this == other)
1424 return false;
1425 return true;
1426 }
1427
1428 bool RTLIL::SigSpec::is_fully_const() const
1429 {
1430 for (auto it = chunks.begin(); it != chunks.end(); it++)
1431 if (it->width > 0 && it->wire != NULL)
1432 return false;
1433 return true;
1434 }
1435
1436 bool RTLIL::SigSpec::is_fully_def() const
1437 {
1438 for (auto it = chunks.begin(); it != chunks.end(); it++) {
1439 if (it->width > 0 && it->wire != NULL)
1440 return false;
1441 for (size_t i = 0; i < it->data.bits.size(); i++)
1442 if (it->data.bits[i] != RTLIL::State::S0 && it->data.bits[i] != RTLIL::State::S1)
1443 return false;
1444 }
1445 return true;
1446 }
1447
1448 bool RTLIL::SigSpec::is_fully_undef() const
1449 {
1450 for (auto it = chunks.begin(); it != chunks.end(); it++) {
1451 if (it->width > 0 && it->wire != NULL)
1452 return false;
1453 for (size_t i = 0; i < it->data.bits.size(); i++)
1454 if (it->data.bits[i] != RTLIL::State::Sx && it->data.bits[i] != RTLIL::State::Sz)
1455 return false;
1456 }
1457 return true;
1458 }
1459
1460 bool RTLIL::SigSpec::has_marked_bits() const
1461 {
1462 for (auto it = chunks.begin(); it != chunks.end(); it++)
1463 if (it->width > 0 && it->wire == NULL) {
1464 for (size_t i = 0; i < it->data.bits.size(); i++)
1465 if (it->data.bits[i] == RTLIL::State::Sm)
1466 return true;
1467 }
1468 return false;
1469 }
1470
1471 bool RTLIL::SigSpec::as_bool() const
1472 {
1473 assert(is_fully_const());
1474 SigSpec sig = *this;
1475 sig.optimize();
1476 if (sig.width)
1477 return sig.chunks[0].data.as_bool();
1478 return false;
1479 }
1480
1481 int RTLIL::SigSpec::as_int() const
1482 {
1483 assert(is_fully_const());
1484 SigSpec sig = *this;
1485 sig.optimize();
1486 if (sig.width)
1487 return sig.chunks[0].data.as_int();
1488 return 0;
1489 }
1490
1491 std::string RTLIL::SigSpec::as_string() const
1492 {
1493 std::string str;
1494 for (size_t i = chunks.size(); i > 0; i--) {
1495 const RTLIL::SigChunk &chunk = chunks[i-1];
1496 if (chunk.wire != NULL)
1497 for (int j = 0; j < chunk.width; j++)
1498 str += "?";
1499 else
1500 str += chunk.data.as_string();
1501 }
1502 return str;
1503 }
1504
1505 RTLIL::Const RTLIL::SigSpec::as_const() const
1506 {
1507 assert(is_fully_const());
1508 SigSpec sig = *this;
1509 sig.optimize();
1510 if (sig.width)
1511 return sig.chunks[0].data;
1512 return RTLIL::Const();
1513 }
1514
1515 bool RTLIL::SigSpec::match(std::string pattern) const
1516 {
1517 std::string str = as_string();
1518 assert(pattern.size() == str.size());
1519
1520 for (size_t i = 0; i < pattern.size(); i++) {
1521 if (pattern[i] == ' ')
1522 continue;
1523 if (pattern[i] == '*') {
1524 if (str[i] != 'z' && str[i] != 'x')
1525 return false;
1526 continue;
1527 }
1528 if (pattern[i] != str[i])
1529 return false;
1530 }
1531
1532 return true;
1533 }
1534
1535 std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const
1536 {
1537 std::set<RTLIL::SigBit> sigbits;
1538 for (auto &c : chunks)
1539 for (int i = 0; i < c.width; i++)
1540 sigbits.insert(RTLIL::SigBit(c, i));
1541 return sigbits;
1542 }
1543
1544 std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
1545 {
1546 std::vector<RTLIL::SigBit> sigbits;
1547 sigbits.reserve(width);
1548 for (auto &c : chunks)
1549 for (int i = 0; i < c.width; i++)
1550 sigbits.push_back(RTLIL::SigBit(c, i));
1551 return sigbits;
1552 }
1553
1554 static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep)
1555 {
1556 size_t start = 0, end = 0;
1557 while ((end = text.find(sep, start)) != std::string::npos) {
1558 tokens.push_back(text.substr(start, end - start));
1559 start = end + 1;
1560 }
1561 tokens.push_back(text.substr(start));
1562 }
1563
1564 static int sigspec_parse_get_dummy_line_num()
1565 {
1566 return 0;
1567 }
1568
1569 bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
1570 {
1571 std::vector<std::string> tokens;
1572 sigspec_parse_split(tokens, str, ',');
1573
1574 sig = RTLIL::SigSpec();
1575 for (int tokidx = int(tokens.size())-1; tokidx >= 0; tokidx--)
1576 {
1577 std::string netname = tokens[tokidx];
1578 std::string indices;
1579
1580 if (netname.size() == 0)
1581 continue;
1582
1583 if ('0' <= netname[0] && netname[0] <= '9') {
1584 AST::get_line_num = sigspec_parse_get_dummy_line_num;
1585 AST::AstNode *ast = VERILOG_FRONTEND::const2ast(netname);
1586 if (ast == NULL)
1587 return false;
1588 sig.append(RTLIL::Const(ast->bits));
1589 delete ast;
1590 continue;
1591 }
1592
1593 if (module == NULL)
1594 return false;
1595
1596 if (netname[0] != '$' && netname[0] != '\\')
1597 netname = "\\" + netname;
1598
1599 if (module->wires.count(netname) == 0) {
1600 size_t indices_pos = netname.size()-1;
1601 if (indices_pos > 2 && netname[indices_pos] == ']')
1602 {
1603 indices_pos--;
1604 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
1605 if (indices_pos > 0 && netname[indices_pos] == ':') {
1606 indices_pos--;
1607 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
1608 }
1609 if (indices_pos > 0 && netname[indices_pos] == '[') {
1610 indices = netname.substr(indices_pos);
1611 netname = netname.substr(0, indices_pos);
1612 }
1613 }
1614 }
1615
1616 if (module->wires.count(netname) == 0)
1617 return false;
1618
1619 RTLIL::Wire *wire = module->wires.at(netname);
1620 if (!indices.empty()) {
1621 std::vector<std::string> index_tokens;
1622 sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':');
1623 if (index_tokens.size() == 1)
1624 sig.append(RTLIL::SigSpec(wire, 1, atoi(index_tokens.at(0).c_str())));
1625 else {
1626 int a = atoi(index_tokens.at(0).c_str());
1627 int b = atoi(index_tokens.at(1).c_str());
1628 if (a > b) {
1629 int tmp = a;
1630 a = b, b = tmp;
1631 }
1632 sig.append(RTLIL::SigSpec(wire, b-a+1, a));
1633 }
1634 } else
1635 sig.append(wire);
1636 }
1637
1638 return true;
1639 }
1640
1641 bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
1642 {
1643 if (str == "0") {
1644 sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.width);
1645 return true;
1646 }
1647
1648 if (str == "~0") {
1649 sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.width);
1650 return true;
1651 }
1652
1653 if (lhs.chunks.size() == 1) {
1654 char *p = (char*)str.c_str(), *endptr;
1655 long long int val = strtoll(p, &endptr, 10);
1656 if (endptr && endptr != p && *endptr == 0) {
1657 sig = RTLIL::SigSpec(val, lhs.width);
1658 return true;
1659 }
1660 }
1661
1662 return parse(sig, module, str);
1663 }
1664
1665 RTLIL::CaseRule::~CaseRule()
1666 {
1667 for (auto it = switches.begin(); it != switches.end(); it++)
1668 delete *it;
1669 }
1670
1671 void RTLIL::CaseRule::optimize()
1672 {
1673 for (auto it : switches)
1674 it->optimize();
1675 for (auto &it : compare)
1676 it.optimize();
1677 for (auto &it : actions) {
1678 it.first.optimize();
1679 it.second.optimize();
1680 }
1681 }
1682
1683 RTLIL::CaseRule *RTLIL::CaseRule::clone() const
1684 {
1685 RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
1686 new_caserule->compare = compare;
1687 new_caserule->actions = actions;
1688 for (auto &it : switches)
1689 new_caserule->switches.push_back(it->clone());
1690 return new_caserule;
1691 }
1692
1693 RTLIL::SwitchRule::~SwitchRule()
1694 {
1695 for (auto it = cases.begin(); it != cases.end(); it++)
1696 delete *it;
1697 }
1698
1699 void RTLIL::SwitchRule::optimize()
1700 {
1701 signal.optimize();
1702 for (auto it : cases)
1703 it->optimize();
1704 }
1705
1706 RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
1707 {
1708 RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
1709 new_switchrule->signal = signal;
1710 new_switchrule->attributes = attributes;
1711 for (auto &it : cases)
1712 new_switchrule->cases.push_back(it->clone());
1713 return new_switchrule;
1714
1715 }
1716
1717 void RTLIL::SyncRule::optimize()
1718 {
1719 signal.optimize();
1720 for (auto &it : actions) {
1721 it.first.optimize();
1722 it.second.optimize();
1723 }
1724 }
1725
1726 RTLIL::SyncRule *RTLIL::SyncRule::clone() const
1727 {
1728 RTLIL::SyncRule *new_syncrule = new RTLIL::SyncRule;
1729 new_syncrule->type = type;
1730 new_syncrule->signal = signal;
1731 new_syncrule->actions = actions;
1732 return new_syncrule;
1733 }
1734
1735 RTLIL::Process::~Process()
1736 {
1737 for (auto it = syncs.begin(); it != syncs.end(); it++)
1738 delete *it;
1739 }
1740
1741 void RTLIL::Process::optimize()
1742 {
1743 root_case.optimize();
1744 for (auto it : syncs)
1745 it->optimize();
1746 }
1747
1748 RTLIL::Process *RTLIL::Process::clone() const
1749 {
1750 RTLIL::Process *new_proc = new RTLIL::Process;
1751
1752 new_proc->name = name;
1753 new_proc->attributes = attributes;
1754
1755 RTLIL::CaseRule *rc_ptr = root_case.clone();
1756 new_proc->root_case = *rc_ptr;
1757 rc_ptr->switches.clear();
1758 delete rc_ptr;
1759
1760 for (auto &it : syncs)
1761 new_proc->syncs.push_back(it->clone());
1762
1763 return new_proc;
1764 }
1765