Merge pull request #1519 from YosysHQ/eddie/submod_po
[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 "kernel/macc.h"
22 #include "kernel/celltypes.h"
23 #include "frontends/verilog/verilog_frontend.h"
24 #include "backends/ilang/ilang_backend.h"
25
26 #include <string.h>
27 #include <algorithm>
28
29 YOSYS_NAMESPACE_BEGIN
30
31 RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard;
32 std::vector<char*> RTLIL::IdString::global_id_storage_;
33 dict<char*, int, hash_cstr_ops> RTLIL::IdString::global_id_index_;
34 #ifndef YOSYS_NO_IDS_REFCNT
35 std::vector<int> RTLIL::IdString::global_refcount_storage_;
36 std::vector<int> RTLIL::IdString::global_free_idx_list_;
37 #endif
38 #ifdef YOSYS_USE_STICKY_IDS
39 int RTLIL::IdString::last_created_idx_[8];
40 int RTLIL::IdString::last_created_idx_ptr_;
41 #endif
42
43 IdString RTLIL::ID::A;
44 IdString RTLIL::ID::B;
45 IdString RTLIL::ID::Y;
46 IdString RTLIL::ID::keep;
47 IdString RTLIL::ID::whitebox;
48 IdString RTLIL::ID::blackbox;
49 dict<std::string, std::string> RTLIL::constpad;
50
51 RTLIL::Const::Const()
52 {
53 flags = RTLIL::CONST_FLAG_NONE;
54 }
55
56 RTLIL::Const::Const(std::string str)
57 {
58 flags = RTLIL::CONST_FLAG_STRING;
59 for (int i = str.size()-1; i >= 0; i--) {
60 unsigned char ch = str[i];
61 for (int j = 0; j < 8; j++) {
62 bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);
63 ch = ch >> 1;
64 }
65 }
66 }
67
68 RTLIL::Const::Const(int val, int width)
69 {
70 flags = RTLIL::CONST_FLAG_NONE;
71 for (int i = 0; i < width; i++) {
72 bits.push_back((val & 1) != 0 ? State::S1 : State::S0);
73 val = val >> 1;
74 }
75 }
76
77 RTLIL::Const::Const(RTLIL::State bit, int width)
78 {
79 flags = RTLIL::CONST_FLAG_NONE;
80 for (int i = 0; i < width; i++)
81 bits.push_back(bit);
82 }
83
84 RTLIL::Const::Const(const std::vector<bool> &bits)
85 {
86 flags = RTLIL::CONST_FLAG_NONE;
87 for (auto b : bits)
88 this->bits.push_back(b ? State::S1 : State::S0);
89 }
90
91 RTLIL::Const::Const(const RTLIL::Const &c)
92 {
93 flags = c.flags;
94 for (auto b : c.bits)
95 this->bits.push_back(b);
96 }
97
98 bool RTLIL::Const::operator <(const RTLIL::Const &other) const
99 {
100 if (bits.size() != other.bits.size())
101 return bits.size() < other.bits.size();
102 for (size_t i = 0; i < bits.size(); i++)
103 if (bits[i] != other.bits[i])
104 return bits[i] < other.bits[i];
105 return false;
106 }
107
108 bool RTLIL::Const::operator ==(const RTLIL::Const &other) const
109 {
110 return bits == other.bits;
111 }
112
113 bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
114 {
115 return bits != other.bits;
116 }
117
118 bool RTLIL::Const::as_bool() const
119 {
120 for (size_t i = 0; i < bits.size(); i++)
121 if (bits[i] == State::S1)
122 return true;
123 return false;
124 }
125
126 int RTLIL::Const::as_int(bool is_signed) const
127 {
128 int32_t ret = 0;
129 for (size_t i = 0; i < bits.size() && i < 32; i++)
130 if (bits[i] == State::S1)
131 ret |= 1 << i;
132 if (is_signed && bits.back() == State::S1)
133 for (size_t i = bits.size(); i < 32; i++)
134 ret |= 1 << i;
135 return ret;
136 }
137
138 std::string RTLIL::Const::as_string() const
139 {
140 std::string ret;
141 for (size_t i = bits.size(); i > 0; i--)
142 switch (bits[i-1]) {
143 case S0: ret += "0"; break;
144 case S1: ret += "1"; break;
145 case Sx: ret += "x"; break;
146 case Sz: ret += "z"; break;
147 case Sa: ret += "-"; break;
148 case Sm: ret += "m"; break;
149 }
150 return ret;
151 }
152
153 RTLIL::Const RTLIL::Const::from_string(std::string str)
154 {
155 Const c;
156 for (auto it = str.rbegin(); it != str.rend(); it++)
157 switch (*it) {
158 case '0': c.bits.push_back(State::S0); break;
159 case '1': c.bits.push_back(State::S1); break;
160 case 'x': c.bits.push_back(State::Sx); break;
161 case 'z': c.bits.push_back(State::Sz); break;
162 case 'm': c.bits.push_back(State::Sm); break;
163 default: c.bits.push_back(State::Sa);
164 }
165 return c;
166 }
167
168 std::string RTLIL::Const::decode_string() const
169 {
170 std::string string;
171 std::vector<char> string_chars;
172 for (int i = 0; i < int (bits.size()); i += 8) {
173 char ch = 0;
174 for (int j = 0; j < 8 && i + j < int (bits.size()); j++)
175 if (bits[i + j] == RTLIL::State::S1)
176 ch |= 1 << j;
177 if (ch != 0)
178 string_chars.push_back(ch);
179 }
180 for (int i = int (string_chars.size()) - 1; i >= 0; i--)
181 string += string_chars[i];
182 return string;
183 }
184
185 bool RTLIL::Const::is_fully_zero() const
186 {
187 cover("kernel.rtlil.const.is_fully_zero");
188
189 for (auto bit : bits)
190 if (bit != RTLIL::State::S0)
191 return false;
192
193 return true;
194 }
195
196 bool RTLIL::Const::is_fully_ones() const
197 {
198 cover("kernel.rtlil.const.is_fully_ones");
199
200 for (auto bit : bits)
201 if (bit != RTLIL::State::S1)
202 return false;
203
204 return true;
205 }
206
207 bool RTLIL::Const::is_fully_def() const
208 {
209 cover("kernel.rtlil.const.is_fully_def");
210
211 for (auto bit : bits)
212 if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
213 return false;
214
215 return true;
216 }
217
218 bool RTLIL::Const::is_fully_undef() const
219 {
220 cover("kernel.rtlil.const.is_fully_undef");
221
222 for (auto bit : bits)
223 if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
224 return false;
225
226 return true;
227 }
228
229 void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value)
230 {
231 if (value)
232 attributes[id] = RTLIL::Const(1);
233 else {
234 const auto it = attributes.find(id);
235 if (it != attributes.end())
236 attributes.erase(it);
237 }
238 }
239
240 bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const
241 {
242 const auto it = attributes.find(id);
243 if (it == attributes.end())
244 return false;
245 return it->second.as_bool();
246 }
247
248 void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<string> &data)
249 {
250 string attrval;
251 for (auto &s : data) {
252 if (!attrval.empty())
253 attrval += "|";
254 attrval += s;
255 }
256 attributes[id] = RTLIL::Const(attrval);
257 }
258
259 void RTLIL::AttrObject::add_strpool_attribute(RTLIL::IdString id, const pool<string> &data)
260 {
261 pool<string> union_data = get_strpool_attribute(id);
262 union_data.insert(data.begin(), data.end());
263 if (!union_data.empty())
264 set_strpool_attribute(id, union_data);
265 }
266
267 pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const
268 {
269 pool<string> data;
270 if (attributes.count(id) != 0)
271 for (auto s : split_tokens(attributes.at(id).decode_string(), "|"))
272 data.insert(s);
273 return data;
274 }
275
276 void RTLIL::AttrObject::set_src_attribute(const std::string &src)
277 {
278 if (src.empty())
279 attributes.erase(ID(src));
280 else
281 attributes[ID(src)] = src;
282 }
283
284 std::string RTLIL::AttrObject::get_src_attribute() const
285 {
286 std::string src;
287 if (attributes.count(ID(src)))
288 src = attributes.at(ID(src)).decode_string();
289 return src;
290 }
291
292 bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const
293 {
294 if (full_selection)
295 return true;
296 if (selected_modules.count(mod_name) > 0)
297 return true;
298 if (selected_members.count(mod_name) > 0)
299 return true;
300 return false;
301 }
302
303 bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name) const
304 {
305 if (full_selection)
306 return true;
307 if (selected_modules.count(mod_name) > 0)
308 return true;
309 return false;
310 }
311
312 bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
313 {
314 if (full_selection)
315 return true;
316 if (selected_modules.count(mod_name) > 0)
317 return true;
318 if (selected_members.count(mod_name) > 0)
319 if (selected_members.at(mod_name).count(memb_name) > 0)
320 return true;
321 return false;
322 }
323
324 void RTLIL::Selection::optimize(RTLIL::Design *design)
325 {
326 if (full_selection) {
327 selected_modules.clear();
328 selected_members.clear();
329 return;
330 }
331
332 std::vector<RTLIL::IdString> del_list, add_list;
333
334 del_list.clear();
335 for (auto mod_name : selected_modules) {
336 if (design->modules_.count(mod_name) == 0)
337 del_list.push_back(mod_name);
338 selected_members.erase(mod_name);
339 }
340 for (auto mod_name : del_list)
341 selected_modules.erase(mod_name);
342
343 del_list.clear();
344 for (auto &it : selected_members)
345 if (design->modules_.count(it.first) == 0)
346 del_list.push_back(it.first);
347 for (auto mod_name : del_list)
348 selected_members.erase(mod_name);
349
350 for (auto &it : selected_members) {
351 del_list.clear();
352 for (auto memb_name : it.second)
353 if (design->modules_[it.first]->count_id(memb_name) == 0)
354 del_list.push_back(memb_name);
355 for (auto memb_name : del_list)
356 it.second.erase(memb_name);
357 }
358
359 del_list.clear();
360 add_list.clear();
361 for (auto &it : selected_members)
362 if (it.second.size() == 0)
363 del_list.push_back(it.first);
364 else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() +
365 design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size())
366 add_list.push_back(it.first);
367 for (auto mod_name : del_list)
368 selected_members.erase(mod_name);
369 for (auto mod_name : add_list) {
370 selected_members.erase(mod_name);
371 selected_modules.insert(mod_name);
372 }
373
374 if (selected_modules.size() == design->modules_.size()) {
375 full_selection = true;
376 selected_modules.clear();
377 selected_members.clear();
378 }
379 }
380
381 RTLIL::Design::Design()
382 {
383 static unsigned int hashidx_count = 123456789;
384 hashidx_count = mkhash_xorshift(hashidx_count);
385 hashidx_ = hashidx_count;
386
387 refcount_modules_ = 0;
388 selection_stack.push_back(RTLIL::Selection());
389
390 #ifdef WITH_PYTHON
391 RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this));
392 #endif
393 }
394
395 RTLIL::Design::~Design()
396 {
397 for (auto it = modules_.begin(); it != modules_.end(); ++it)
398 delete it->second;
399 for (auto n : verilog_packages)
400 delete n;
401 for (auto n : verilog_globals)
402 delete n;
403 #ifdef WITH_PYTHON
404 RTLIL::Design::get_all_designs()->erase(hashidx_);
405 #endif
406 }
407
408 #ifdef WITH_PYTHON
409 static std::map<unsigned int, RTLIL::Design*> all_designs;
410 std::map<unsigned int, RTLIL::Design*> *RTLIL::Design::get_all_designs(void)
411 {
412 return &all_designs;
413 }
414 #endif
415
416 RTLIL::ObjRange<RTLIL::Module*> RTLIL::Design::modules()
417 {
418 return RTLIL::ObjRange<RTLIL::Module*>(&modules_, &refcount_modules_);
419 }
420
421 RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name)
422 {
423 return modules_.count(name) ? modules_.at(name) : NULL;
424 }
425
426 RTLIL::Module *RTLIL::Design::top_module()
427 {
428 RTLIL::Module *module = nullptr;
429 int module_count = 0;
430
431 for (auto mod : selected_modules()) {
432 if (mod->get_bool_attribute(ID(top)))
433 return mod;
434 module_count++;
435 module = mod;
436 }
437
438 return module_count == 1 ? module : nullptr;
439 }
440
441 void RTLIL::Design::add(RTLIL::Module *module)
442 {
443 log_assert(modules_.count(module->name) == 0);
444 log_assert(refcount_modules_ == 0);
445 modules_[module->name] = module;
446 module->design = this;
447
448 for (auto mon : monitors)
449 mon->notify_module_add(module);
450
451 if (yosys_xtrace) {
452 log("#X# New Module: %s\n", log_id(module));
453 log_backtrace("-X- ", yosys_xtrace-1);
454 }
455 }
456
457 RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
458 {
459 log_assert(modules_.count(name) == 0);
460 log_assert(refcount_modules_ == 0);
461
462 RTLIL::Module *module = new RTLIL::Module;
463 modules_[name] = module;
464 module->design = this;
465 module->name = name;
466
467 for (auto mon : monitors)
468 mon->notify_module_add(module);
469
470 if (yosys_xtrace) {
471 log("#X# New Module: %s\n", log_id(module));
472 log_backtrace("-X- ", yosys_xtrace-1);
473 }
474
475 return module;
476 }
477
478 void RTLIL::Design::scratchpad_unset(std::string varname)
479 {
480 scratchpad.erase(varname);
481 }
482
483 void RTLIL::Design::scratchpad_set_int(std::string varname, int value)
484 {
485 scratchpad[varname] = stringf("%d", value);
486 }
487
488 void RTLIL::Design::scratchpad_set_bool(std::string varname, bool value)
489 {
490 scratchpad[varname] = value ? "true" : "false";
491 }
492
493 void RTLIL::Design::scratchpad_set_string(std::string varname, std::string value)
494 {
495 scratchpad[varname] = value;
496 }
497
498 int RTLIL::Design::scratchpad_get_int(std::string varname, int default_value) const
499 {
500 if (scratchpad.count(varname) == 0)
501 return default_value;
502
503 std::string str = scratchpad.at(varname);
504
505 if (str == "0" || str == "false")
506 return 0;
507
508 if (str == "1" || str == "true")
509 return 1;
510
511 char *endptr = nullptr;
512 long int parsed_value = strtol(str.c_str(), &endptr, 10);
513 return *endptr ? default_value : parsed_value;
514 }
515
516 bool RTLIL::Design::scratchpad_get_bool(std::string varname, bool default_value) const
517 {
518 if (scratchpad.count(varname) == 0)
519 return default_value;
520
521 std::string str = scratchpad.at(varname);
522
523 if (str == "0" || str == "false")
524 return false;
525
526 if (str == "1" || str == "true")
527 return true;
528
529 return default_value;
530 }
531
532 std::string RTLIL::Design::scratchpad_get_string(std::string varname, std::string default_value) const
533 {
534 if (scratchpad.count(varname) == 0)
535 return default_value;
536 return scratchpad.at(varname);
537 }
538
539 void RTLIL::Design::remove(RTLIL::Module *module)
540 {
541 for (auto mon : monitors)
542 mon->notify_module_del(module);
543
544 if (yosys_xtrace) {
545 log("#X# Remove Module: %s\n", log_id(module));
546 log_backtrace("-X- ", yosys_xtrace-1);
547 }
548
549 log_assert(modules_.at(module->name) == module);
550 modules_.erase(module->name);
551 delete module;
552 }
553
554 void RTLIL::Design::rename(RTLIL::Module *module, RTLIL::IdString new_name)
555 {
556 modules_.erase(module->name);
557 module->name = new_name;
558 add(module);
559 }
560
561 void RTLIL::Design::sort()
562 {
563 scratchpad.sort();
564 modules_.sort(sort_by_id_str());
565 for (auto &it : modules_)
566 it.second->sort();
567 }
568
569 void RTLIL::Design::check()
570 {
571 #ifndef NDEBUG
572 for (auto &it : modules_) {
573 log_assert(this == it.second->design);
574 log_assert(it.first == it.second->name);
575 log_assert(!it.first.empty());
576 it.second->check();
577 }
578 #endif
579 }
580
581 void RTLIL::Design::optimize()
582 {
583 for (auto &it : modules_)
584 it.second->optimize();
585 for (auto &it : selection_stack)
586 it.optimize(this);
587 for (auto &it : selection_vars)
588 it.second.optimize(this);
589 }
590
591 bool RTLIL::Design::selected_module(RTLIL::IdString mod_name) const
592 {
593 if (!selected_active_module.empty() && mod_name != selected_active_module)
594 return false;
595 if (selection_stack.size() == 0)
596 return true;
597 return selection_stack.back().selected_module(mod_name);
598 }
599
600 bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name) const
601 {
602 if (!selected_active_module.empty() && mod_name != selected_active_module)
603 return false;
604 if (selection_stack.size() == 0)
605 return true;
606 return selection_stack.back().selected_whole_module(mod_name);
607 }
608
609 bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
610 {
611 if (!selected_active_module.empty() && mod_name != selected_active_module)
612 return false;
613 if (selection_stack.size() == 0)
614 return true;
615 return selection_stack.back().selected_member(mod_name, memb_name);
616 }
617
618 bool RTLIL::Design::selected_module(RTLIL::Module *mod) const
619 {
620 return selected_module(mod->name);
621 }
622
623 bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const
624 {
625 return selected_whole_module(mod->name);
626 }
627
628 std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const
629 {
630 std::vector<RTLIL::Module*> result;
631 result.reserve(modules_.size());
632 for (auto &it : modules_)
633 if (selected_module(it.first) && !it.second->get_blackbox_attribute())
634 result.push_back(it.second);
635 return result;
636 }
637
638 std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const
639 {
640 std::vector<RTLIL::Module*> result;
641 result.reserve(modules_.size());
642 for (auto &it : modules_)
643 if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute())
644 result.push_back(it.second);
645 return result;
646 }
647
648 std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn() const
649 {
650 std::vector<RTLIL::Module*> result;
651 result.reserve(modules_.size());
652 for (auto &it : modules_)
653 if (it.second->get_blackbox_attribute())
654 continue;
655 else if (selected_whole_module(it.first))
656 result.push_back(it.second);
657 else if (selected_module(it.first))
658 log_warning("Ignoring partially selected module %s.\n", log_id(it.first));
659 return result;
660 }
661
662 RTLIL::Module::Module()
663 {
664 static unsigned int hashidx_count = 123456789;
665 hashidx_count = mkhash_xorshift(hashidx_count);
666 hashidx_ = hashidx_count;
667
668 design = nullptr;
669 refcount_wires_ = 0;
670 refcount_cells_ = 0;
671
672 #ifdef WITH_PYTHON
673 RTLIL::Module::get_all_modules()->insert(std::pair<unsigned int, RTLIL::Module*>(hashidx_, this));
674 #endif
675 }
676
677 RTLIL::Module::~Module()
678 {
679 for (auto it = wires_.begin(); it != wires_.end(); ++it)
680 delete it->second;
681 for (auto it = memories.begin(); it != memories.end(); ++it)
682 delete it->second;
683 for (auto it = cells_.begin(); it != cells_.end(); ++it)
684 delete it->second;
685 for (auto it = processes.begin(); it != processes.end(); ++it)
686 delete it->second;
687 #ifdef WITH_PYTHON
688 RTLIL::Module::get_all_modules()->erase(hashidx_);
689 #endif
690 }
691
692 #ifdef WITH_PYTHON
693 static std::map<unsigned int, RTLIL::Module*> all_modules;
694 std::map<unsigned int, RTLIL::Module*> *RTLIL::Module::get_all_modules(void)
695 {
696 return &all_modules;
697 }
698 #endif
699
700 void RTLIL::Module::makeblackbox()
701 {
702 pool<RTLIL::Wire*> delwires;
703
704 for (auto it = wires_.begin(); it != wires_.end(); ++it)
705 if (!it->second->port_input && !it->second->port_output)
706 delwires.insert(it->second);
707
708 for (auto it = memories.begin(); it != memories.end(); ++it)
709 delete it->second;
710 memories.clear();
711
712 for (auto it = cells_.begin(); it != cells_.end(); ++it)
713 delete it->second;
714 cells_.clear();
715
716 for (auto it = processes.begin(); it != processes.end(); ++it)
717 delete it->second;
718 processes.clear();
719
720 remove(delwires);
721 set_bool_attribute(ID::blackbox);
722 }
723
724 void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>)
725 {
726 log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name));
727 }
728
729 RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, bool mayfail)
730 {
731 if (mayfail)
732 return RTLIL::IdString();
733 log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
734 }
735
736
737 RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, dict<RTLIL::IdString, RTLIL::Module*>, dict<RTLIL::IdString, RTLIL::IdString>, bool mayfail)
738 {
739 if (mayfail)
740 return RTLIL::IdString();
741 log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
742 }
743
744 size_t RTLIL::Module::count_id(RTLIL::IdString id)
745 {
746 return wires_.count(id) + memories.count(id) + cells_.count(id) + processes.count(id);
747 }
748
749 #ifndef NDEBUG
750 namespace {
751 struct InternalCellChecker
752 {
753 RTLIL::Module *module;
754 RTLIL::Cell *cell;
755 pool<RTLIL::IdString> expected_params, expected_ports;
756
757 InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { }
758
759 void error(int linenr)
760 {
761 std::stringstream buf;
762 ILANG_BACKEND::dump_cell(buf, " ", cell);
763
764 log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s",
765 module ? module->name.c_str() : "", module ? "." : "",
766 cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());
767 }
768
769 int param(RTLIL::IdString name)
770 {
771 if (cell->parameters.count(name) == 0)
772 error(__LINE__);
773 expected_params.insert(name);
774 return cell->parameters.at(name).as_int();
775 }
776
777 int param_bool(RTLIL::IdString name)
778 {
779 int v = param(name);
780 if (cell->parameters.at(name).bits.size() > 32)
781 error(__LINE__);
782 if (v != 0 && v != 1)
783 error(__LINE__);
784 return v;
785 }
786
787 int param_bool(RTLIL::IdString name, bool expected)
788 {
789 int v = param_bool(name);
790 if (v != expected)
791 error(__LINE__);
792 return v;
793 }
794
795 void param_bits(RTLIL::IdString name, int width)
796 {
797 param(name);
798 if (int(cell->parameters.at(name).bits.size()) != width)
799 error(__LINE__);
800 }
801
802 void port(RTLIL::IdString name, int width)
803 {
804 if (!cell->hasPort(name))
805 error(__LINE__);
806 if (cell->getPort(name).size() != width)
807 error(__LINE__);
808 expected_ports.insert(name);
809 }
810
811 void check_expected(bool check_matched_sign = true)
812 {
813 for (auto &para : cell->parameters)
814 if (expected_params.count(para.first) == 0)
815 error(__LINE__);
816 for (auto &conn : cell->connections())
817 if (expected_ports.count(conn.first) == 0)
818 error(__LINE__);
819
820 if (expected_params.count(ID(A_SIGNED)) != 0 && expected_params.count(ID(B_SIGNED)) && check_matched_sign) {
821 bool a_is_signed = param(ID(A_SIGNED)) != 0;
822 bool b_is_signed = param(ID(B_SIGNED)) != 0;
823 if (a_is_signed != b_is_signed)
824 error(__LINE__);
825 }
826 }
827
828 void check_gate(const char *ports)
829 {
830 if (cell->parameters.size() != 0)
831 error(__LINE__);
832
833 for (const char *p = ports; *p; p++) {
834 char portname[3] = { '\\', *p, 0 };
835 if (!cell->hasPort(portname))
836 error(__LINE__);
837 if (cell->getPort(portname).size() != 1)
838 error(__LINE__);
839 }
840
841 for (auto &conn : cell->connections()) {
842 if (conn.first.size() != 2 || conn.first[0] != '\\')
843 error(__LINE__);
844 if (strchr(ports, conn.first[1]) == NULL)
845 error(__LINE__);
846 }
847 }
848
849 void check()
850 {
851 if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") ||
852 cell->type.begins_with("$verific$") || cell->type.begins_with("$array:") || cell->type.begins_with("$extern:"))
853 return;
854
855 if (cell->type.in(ID($not), ID($pos), ID($neg))) {
856 param_bool(ID(A_SIGNED));
857 port(ID::A, param(ID(A_WIDTH)));
858 port(ID::Y, param(ID(Y_WIDTH)));
859 check_expected();
860 return;
861 }
862
863 if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {
864 param_bool(ID(A_SIGNED));
865 param_bool(ID(B_SIGNED));
866 port(ID::A, param(ID(A_WIDTH)));
867 port(ID::B, param(ID(B_WIDTH)));
868 port(ID::Y, param(ID(Y_WIDTH)));
869 check_expected();
870 return;
871 }
872
873 if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) {
874 param_bool(ID(A_SIGNED));
875 port(ID::A, param(ID(A_WIDTH)));
876 port(ID::Y, param(ID(Y_WIDTH)));
877 check_expected();
878 return;
879 }
880
881 if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
882 param_bool(ID(A_SIGNED));
883 param_bool(ID(B_SIGNED), /*expected=*/false);
884 port(ID::A, param(ID(A_WIDTH)));
885 port(ID::B, param(ID(B_WIDTH)));
886 port(ID::Y, param(ID(Y_WIDTH)));
887 check_expected(/*check_matched_sign=*/false);
888 return;
889 }
890
891 if (cell->type.in(ID($shift), ID($shiftx))) {
892 param_bool(ID(A_SIGNED));
893 param_bool(ID(B_SIGNED));
894 port(ID::A, param(ID(A_WIDTH)));
895 port(ID::B, param(ID(B_WIDTH)));
896 port(ID::Y, param(ID(Y_WIDTH)));
897 check_expected(/*check_matched_sign=*/false);
898 return;
899 }
900
901 if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {
902 param_bool(ID(A_SIGNED));
903 param_bool(ID(B_SIGNED));
904 port(ID::A, param(ID(A_WIDTH)));
905 port(ID::B, param(ID(B_WIDTH)));
906 port(ID::Y, param(ID(Y_WIDTH)));
907 check_expected();
908 return;
909 }
910
911 if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) {
912 param_bool(ID(A_SIGNED));
913 param_bool(ID(B_SIGNED));
914 port(ID::A, param(ID(A_WIDTH)));
915 port(ID::B, param(ID(B_WIDTH)));
916 port(ID::Y, param(ID(Y_WIDTH)));
917 check_expected(cell->type != ID($pow));
918 return;
919 }
920
921 if (cell->type == ID($fa)) {
922 port(ID::A, param(ID(WIDTH)));
923 port(ID::B, param(ID(WIDTH)));
924 port(ID(C), param(ID(WIDTH)));
925 port(ID(X), param(ID(WIDTH)));
926 port(ID::Y, param(ID(WIDTH)));
927 check_expected();
928 return;
929 }
930
931 if (cell->type == ID($lcu)) {
932 port(ID(P), param(ID(WIDTH)));
933 port(ID(G), param(ID(WIDTH)));
934 port(ID(CI), 1);
935 port(ID(CO), param(ID(WIDTH)));
936 check_expected();
937 return;
938 }
939
940 if (cell->type == ID($alu)) {
941 param_bool(ID(A_SIGNED));
942 param_bool(ID(B_SIGNED));
943 port(ID::A, param(ID(A_WIDTH)));
944 port(ID::B, param(ID(B_WIDTH)));
945 port(ID(CI), 1);
946 port(ID(BI), 1);
947 port(ID(X), param(ID(Y_WIDTH)));
948 port(ID::Y, param(ID(Y_WIDTH)));
949 port(ID(CO), param(ID(Y_WIDTH)));
950 check_expected();
951 return;
952 }
953
954 if (cell->type == ID($macc)) {
955 param(ID(CONFIG));
956 param(ID(CONFIG_WIDTH));
957 port(ID::A, param(ID(A_WIDTH)));
958 port(ID::B, param(ID(B_WIDTH)));
959 port(ID::Y, param(ID(Y_WIDTH)));
960 check_expected();
961 Macc().from_cell(cell);
962 return;
963 }
964
965 if (cell->type == ID($logic_not)) {
966 param_bool(ID(A_SIGNED));
967 port(ID::A, param(ID(A_WIDTH)));
968 port(ID::Y, param(ID(Y_WIDTH)));
969 check_expected();
970 return;
971 }
972
973 if (cell->type.in(ID($logic_and), ID($logic_or))) {
974 param_bool(ID(A_SIGNED));
975 param_bool(ID(B_SIGNED));
976 port(ID::A, param(ID(A_WIDTH)));
977 port(ID::B, param(ID(B_WIDTH)));
978 port(ID::Y, param(ID(Y_WIDTH)));
979 check_expected(/*check_matched_sign=*/false);
980 return;
981 }
982
983 if (cell->type == ID($slice)) {
984 param(ID(OFFSET));
985 port(ID::A, param(ID(A_WIDTH)));
986 port(ID::Y, param(ID(Y_WIDTH)));
987 if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH)))
988 error(__LINE__);
989 check_expected();
990 return;
991 }
992
993 if (cell->type == ID($concat)) {
994 port(ID::A, param(ID(A_WIDTH)));
995 port(ID::B, param(ID(B_WIDTH)));
996 port(ID::Y, param(ID(A_WIDTH)) + param(ID(B_WIDTH)));
997 check_expected();
998 return;
999 }
1000
1001 if (cell->type == ID($mux)) {
1002 port(ID::A, param(ID(WIDTH)));
1003 port(ID::B, param(ID(WIDTH)));
1004 port(ID(S), 1);
1005 port(ID::Y, param(ID(WIDTH)));
1006 check_expected();
1007 return;
1008 }
1009
1010 if (cell->type == ID($pmux)) {
1011 port(ID::A, param(ID(WIDTH)));
1012 port(ID::B, param(ID(WIDTH)) * param(ID(S_WIDTH)));
1013 port(ID(S), param(ID(S_WIDTH)));
1014 port(ID::Y, param(ID(WIDTH)));
1015 check_expected();
1016 return;
1017 }
1018
1019 if (cell->type == ID($lut)) {
1020 param(ID(LUT));
1021 port(ID::A, param(ID(WIDTH)));
1022 port(ID::Y, 1);
1023 check_expected();
1024 return;
1025 }
1026
1027 if (cell->type == ID($sop)) {
1028 param(ID(DEPTH));
1029 param(ID(TABLE));
1030 port(ID::A, param(ID(WIDTH)));
1031 port(ID::Y, 1);
1032 check_expected();
1033 return;
1034 }
1035
1036 if (cell->type == ID($sr)) {
1037 param_bool(ID(SET_POLARITY));
1038 param_bool(ID(CLR_POLARITY));
1039 port(ID(SET), param(ID(WIDTH)));
1040 port(ID(CLR), param(ID(WIDTH)));
1041 port(ID(Q), param(ID(WIDTH)));
1042 check_expected();
1043 return;
1044 }
1045
1046 if (cell->type == ID($ff)) {
1047 port(ID(D), param(ID(WIDTH)));
1048 port(ID(Q), param(ID(WIDTH)));
1049 check_expected();
1050 return;
1051 }
1052
1053 if (cell->type == ID($dff)) {
1054 param_bool(ID(CLK_POLARITY));
1055 port(ID(CLK), 1);
1056 port(ID(D), param(ID(WIDTH)));
1057 port(ID(Q), param(ID(WIDTH)));
1058 check_expected();
1059 return;
1060 }
1061
1062 if (cell->type == ID($dffe)) {
1063 param_bool(ID(CLK_POLARITY));
1064 param_bool(ID(EN_POLARITY));
1065 port(ID(CLK), 1);
1066 port(ID(EN), 1);
1067 port(ID(D), param(ID(WIDTH)));
1068 port(ID(Q), param(ID(WIDTH)));
1069 check_expected();
1070 return;
1071 }
1072
1073 if (cell->type == ID($dffsr)) {
1074 param_bool(ID(CLK_POLARITY));
1075 param_bool(ID(SET_POLARITY));
1076 param_bool(ID(CLR_POLARITY));
1077 port(ID(CLK), 1);
1078 port(ID(SET), param(ID(WIDTH)));
1079 port(ID(CLR), param(ID(WIDTH)));
1080 port(ID(D), param(ID(WIDTH)));
1081 port(ID(Q), param(ID(WIDTH)));
1082 check_expected();
1083 return;
1084 }
1085
1086 if (cell->type == ID($adff)) {
1087 param_bool(ID(CLK_POLARITY));
1088 param_bool(ID(ARST_POLARITY));
1089 param_bits(ID(ARST_VALUE), param(ID(WIDTH)));
1090 port(ID(CLK), 1);
1091 port(ID(ARST), 1);
1092 port(ID(D), param(ID(WIDTH)));
1093 port(ID(Q), param(ID(WIDTH)));
1094 check_expected();
1095 return;
1096 }
1097
1098 if (cell->type == ID($dlatch)) {
1099 param_bool(ID(EN_POLARITY));
1100 port(ID(EN), 1);
1101 port(ID(D), param(ID(WIDTH)));
1102 port(ID(Q), param(ID(WIDTH)));
1103 check_expected();
1104 return;
1105 }
1106
1107 if (cell->type == ID($dlatchsr)) {
1108 param_bool(ID(EN_POLARITY));
1109 param_bool(ID(SET_POLARITY));
1110 param_bool(ID(CLR_POLARITY));
1111 port(ID(EN), 1);
1112 port(ID(SET), param(ID(WIDTH)));
1113 port(ID(CLR), param(ID(WIDTH)));
1114 port(ID(D), param(ID(WIDTH)));
1115 port(ID(Q), param(ID(WIDTH)));
1116 check_expected();
1117 return;
1118 }
1119
1120 if (cell->type == ID($fsm)) {
1121 param(ID(NAME));
1122 param_bool(ID(CLK_POLARITY));
1123 param_bool(ID(ARST_POLARITY));
1124 param(ID(STATE_BITS));
1125 param(ID(STATE_NUM));
1126 param(ID(STATE_NUM_LOG2));
1127 param(ID(STATE_RST));
1128 param_bits(ID(STATE_TABLE), param(ID(STATE_BITS)) * param(ID(STATE_NUM)));
1129 param(ID(TRANS_NUM));
1130 param_bits(ID(TRANS_TABLE), param(ID(TRANS_NUM)) * (2*param(ID(STATE_NUM_LOG2)) + param(ID(CTRL_IN_WIDTH)) + param(ID(CTRL_OUT_WIDTH))));
1131 port(ID(CLK), 1);
1132 port(ID(ARST), 1);
1133 port(ID(CTRL_IN), param(ID(CTRL_IN_WIDTH)));
1134 port(ID(CTRL_OUT), param(ID(CTRL_OUT_WIDTH)));
1135 check_expected();
1136 return;
1137 }
1138
1139 if (cell->type == ID($memrd)) {
1140 param(ID(MEMID));
1141 param_bool(ID(CLK_ENABLE));
1142 param_bool(ID(CLK_POLARITY));
1143 param_bool(ID(TRANSPARENT));
1144 port(ID(CLK), 1);
1145 port(ID(EN), 1);
1146 port(ID(ADDR), param(ID(ABITS)));
1147 port(ID(DATA), param(ID(WIDTH)));
1148 check_expected();
1149 return;
1150 }
1151
1152 if (cell->type == ID($memwr)) {
1153 param(ID(MEMID));
1154 param_bool(ID(CLK_ENABLE));
1155 param_bool(ID(CLK_POLARITY));
1156 param(ID(PRIORITY));
1157 port(ID(CLK), 1);
1158 port(ID(EN), param(ID(WIDTH)));
1159 port(ID(ADDR), param(ID(ABITS)));
1160 port(ID(DATA), param(ID(WIDTH)));
1161 check_expected();
1162 return;
1163 }
1164
1165 if (cell->type == ID($meminit)) {
1166 param(ID(MEMID));
1167 param(ID(PRIORITY));
1168 port(ID(ADDR), param(ID(ABITS)));
1169 port(ID(DATA), param(ID(WIDTH)) * param(ID(WORDS)));
1170 check_expected();
1171 return;
1172 }
1173
1174 if (cell->type == ID($mem)) {
1175 param(ID(MEMID));
1176 param(ID(SIZE));
1177 param(ID(OFFSET));
1178 param(ID(INIT));
1179 param_bits(ID(RD_CLK_ENABLE), max(1, param(ID(RD_PORTS))));
1180 param_bits(ID(RD_CLK_POLARITY), max(1, param(ID(RD_PORTS))));
1181 param_bits(ID(RD_TRANSPARENT), max(1, param(ID(RD_PORTS))));
1182 param_bits(ID(WR_CLK_ENABLE), max(1, param(ID(WR_PORTS))));
1183 param_bits(ID(WR_CLK_POLARITY), max(1, param(ID(WR_PORTS))));
1184 port(ID(RD_CLK), param(ID(RD_PORTS)));
1185 port(ID(RD_EN), param(ID(RD_PORTS)));
1186 port(ID(RD_ADDR), param(ID(RD_PORTS)) * param(ID(ABITS)));
1187 port(ID(RD_DATA), param(ID(RD_PORTS)) * param(ID(WIDTH)));
1188 port(ID(WR_CLK), param(ID(WR_PORTS)));
1189 port(ID(WR_EN), param(ID(WR_PORTS)) * param(ID(WIDTH)));
1190 port(ID(WR_ADDR), param(ID(WR_PORTS)) * param(ID(ABITS)));
1191 port(ID(WR_DATA), param(ID(WR_PORTS)) * param(ID(WIDTH)));
1192 check_expected();
1193 return;
1194 }
1195
1196 if (cell->type == ID($tribuf)) {
1197 port(ID::A, param(ID(WIDTH)));
1198 port(ID::Y, param(ID(WIDTH)));
1199 port(ID(EN), 1);
1200 check_expected();
1201 return;
1202 }
1203
1204 if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
1205 port(ID::A, 1);
1206 port(ID(EN), 1);
1207 check_expected();
1208 return;
1209 }
1210
1211 if (cell->type == ID($initstate)) {
1212 port(ID::Y, 1);
1213 check_expected();
1214 return;
1215 }
1216
1217 if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) {
1218 port(ID::Y, param(ID(WIDTH)));
1219 check_expected();
1220 return;
1221 }
1222
1223 if (cell->type == ID($equiv)) {
1224 port(ID::A, 1);
1225 port(ID::B, 1);
1226 port(ID::Y, 1);
1227 check_expected();
1228 return;
1229 }
1230
1231 if (cell->type.in(ID($specify2), ID($specify3))) {
1232 param_bool(ID(FULL));
1233 param_bool(ID(SRC_DST_PEN));
1234 param_bool(ID(SRC_DST_POL));
1235 param(ID(T_RISE_MIN));
1236 param(ID(T_RISE_TYP));
1237 param(ID(T_RISE_MAX));
1238 param(ID(T_FALL_MIN));
1239 param(ID(T_FALL_TYP));
1240 param(ID(T_FALL_MAX));
1241 port(ID(EN), 1);
1242 port(ID(SRC), param(ID(SRC_WIDTH)));
1243 port(ID(DST), param(ID(DST_WIDTH)));
1244 if (cell->type == ID($specify3)) {
1245 param_bool(ID(EDGE_EN));
1246 param_bool(ID(EDGE_POL));
1247 param_bool(ID(DAT_DST_PEN));
1248 param_bool(ID(DAT_DST_POL));
1249 port(ID(DAT), param(ID(DST_WIDTH)));
1250 }
1251 check_expected();
1252 return;
1253 }
1254
1255 if (cell->type == ID($specrule)) {
1256 param(ID(TYPE));
1257 param_bool(ID(SRC_PEN));
1258 param_bool(ID(SRC_POL));
1259 param_bool(ID(DST_PEN));
1260 param_bool(ID(DST_POL));
1261 param(ID(T_LIMIT_MIN));
1262 param(ID(T_LIMIT_TYP));
1263 param(ID(T_LIMIT_MAX));
1264 param(ID(T_LIMIT2_MIN));
1265 param(ID(T_LIMIT2_TYP));
1266 param(ID(T_LIMIT2_MAX));
1267 port(ID(SRC_EN), 1);
1268 port(ID(DST_EN), 1);
1269 port(ID(SRC), param(ID(SRC_WIDTH)));
1270 port(ID(DST), param(ID(DST_WIDTH)));
1271 check_expected();
1272 return;
1273 }
1274
1275 if (cell->type == ID($_BUF_)) { check_gate("AY"); return; }
1276 if (cell->type == ID($_NOT_)) { check_gate("AY"); return; }
1277 if (cell->type == ID($_AND_)) { check_gate("ABY"); return; }
1278 if (cell->type == ID($_NAND_)) { check_gate("ABY"); return; }
1279 if (cell->type == ID($_OR_)) { check_gate("ABY"); return; }
1280 if (cell->type == ID($_NOR_)) { check_gate("ABY"); return; }
1281 if (cell->type == ID($_XOR_)) { check_gate("ABY"); return; }
1282 if (cell->type == ID($_XNOR_)) { check_gate("ABY"); return; }
1283 if (cell->type == ID($_ANDNOT_)) { check_gate("ABY"); return; }
1284 if (cell->type == ID($_ORNOT_)) { check_gate("ABY"); return; }
1285 if (cell->type == ID($_MUX_)) { check_gate("ABSY"); return; }
1286 if (cell->type == ID($_NMUX_)) { check_gate("ABSY"); return; }
1287 if (cell->type == ID($_AOI3_)) { check_gate("ABCY"); return; }
1288 if (cell->type == ID($_OAI3_)) { check_gate("ABCY"); return; }
1289 if (cell->type == ID($_AOI4_)) { check_gate("ABCDY"); return; }
1290 if (cell->type == ID($_OAI4_)) { check_gate("ABCDY"); return; }
1291
1292 if (cell->type == ID($_TBUF_)) { check_gate("AYE"); return; }
1293
1294 if (cell->type == ID($_MUX4_)) { check_gate("ABCDSTY"); return; }
1295 if (cell->type == ID($_MUX8_)) { check_gate("ABCDEFGHSTUY"); return; }
1296 if (cell->type == ID($_MUX16_)) { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; }
1297
1298 if (cell->type == ID($_SR_NN_)) { check_gate("SRQ"); return; }
1299 if (cell->type == ID($_SR_NP_)) { check_gate("SRQ"); return; }
1300 if (cell->type == ID($_SR_PN_)) { check_gate("SRQ"); return; }
1301 if (cell->type == ID($_SR_PP_)) { check_gate("SRQ"); return; }
1302
1303 if (cell->type == ID($_FF_)) { check_gate("DQ"); return; }
1304 if (cell->type == ID($_DFF_N_)) { check_gate("DQC"); return; }
1305 if (cell->type == ID($_DFF_P_)) { check_gate("DQC"); return; }
1306
1307 if (cell->type == ID($_DFFE_NN_)) { check_gate("DQCE"); return; }
1308 if (cell->type == ID($_DFFE_NP_)) { check_gate("DQCE"); return; }
1309 if (cell->type == ID($_DFFE_PN_)) { check_gate("DQCE"); return; }
1310 if (cell->type == ID($_DFFE_PP_)) { check_gate("DQCE"); return; }
1311
1312 if (cell->type == ID($_DFF_NN0_)) { check_gate("DQCR"); return; }
1313 if (cell->type == ID($_DFF_NN1_)) { check_gate("DQCR"); return; }
1314 if (cell->type == ID($_DFF_NP0_)) { check_gate("DQCR"); return; }
1315 if (cell->type == ID($_DFF_NP1_)) { check_gate("DQCR"); return; }
1316 if (cell->type == ID($_DFF_PN0_)) { check_gate("DQCR"); return; }
1317 if (cell->type == ID($_DFF_PN1_)) { check_gate("DQCR"); return; }
1318 if (cell->type == ID($_DFF_PP0_)) { check_gate("DQCR"); return; }
1319 if (cell->type == ID($_DFF_PP1_)) { check_gate("DQCR"); return; }
1320
1321 if (cell->type == ID($_DFFSR_NNN_)) { check_gate("CSRDQ"); return; }
1322 if (cell->type == ID($_DFFSR_NNP_)) { check_gate("CSRDQ"); return; }
1323 if (cell->type == ID($_DFFSR_NPN_)) { check_gate("CSRDQ"); return; }
1324 if (cell->type == ID($_DFFSR_NPP_)) { check_gate("CSRDQ"); return; }
1325 if (cell->type == ID($_DFFSR_PNN_)) { check_gate("CSRDQ"); return; }
1326 if (cell->type == ID($_DFFSR_PNP_)) { check_gate("CSRDQ"); return; }
1327 if (cell->type == ID($_DFFSR_PPN_)) { check_gate("CSRDQ"); return; }
1328 if (cell->type == ID($_DFFSR_PPP_)) { check_gate("CSRDQ"); return; }
1329
1330 if (cell->type == ID($_DLATCH_N_)) { check_gate("EDQ"); return; }
1331 if (cell->type == ID($_DLATCH_P_)) { check_gate("EDQ"); return; }
1332
1333 if (cell->type == ID($_DLATCHSR_NNN_)) { check_gate("ESRDQ"); return; }
1334 if (cell->type == ID($_DLATCHSR_NNP_)) { check_gate("ESRDQ"); return; }
1335 if (cell->type == ID($_DLATCHSR_NPN_)) { check_gate("ESRDQ"); return; }
1336 if (cell->type == ID($_DLATCHSR_NPP_)) { check_gate("ESRDQ"); return; }
1337 if (cell->type == ID($_DLATCHSR_PNN_)) { check_gate("ESRDQ"); return; }
1338 if (cell->type == ID($_DLATCHSR_PNP_)) { check_gate("ESRDQ"); return; }
1339 if (cell->type == ID($_DLATCHSR_PPN_)) { check_gate("ESRDQ"); return; }
1340 if (cell->type == ID($_DLATCHSR_PPP_)) { check_gate("ESRDQ"); return; }
1341
1342 error(__LINE__);
1343 }
1344 };
1345 }
1346 #endif
1347
1348 void RTLIL::Module::sort()
1349 {
1350 wires_.sort(sort_by_id_str());
1351 cells_.sort(sort_by_id_str());
1352 avail_parameters.sort(sort_by_id_str());
1353 memories.sort(sort_by_id_str());
1354 processes.sort(sort_by_id_str());
1355 for (auto &it : cells_)
1356 it.second->sort();
1357 for (auto &it : wires_)
1358 it.second->attributes.sort(sort_by_id_str());
1359 for (auto &it : memories)
1360 it.second->attributes.sort(sort_by_id_str());
1361 }
1362
1363 void RTLIL::Module::check()
1364 {
1365 #ifndef NDEBUG
1366 std::vector<bool> ports_declared;
1367 for (auto &it : wires_) {
1368 log_assert(this == it.second->module);
1369 log_assert(it.first == it.second->name);
1370 log_assert(!it.first.empty());
1371 log_assert(it.second->width >= 0);
1372 log_assert(it.second->port_id >= 0);
1373 for (auto &it2 : it.second->attributes)
1374 log_assert(!it2.first.empty());
1375 if (it.second->port_id) {
1376 log_assert(GetSize(ports) >= it.second->port_id);
1377 log_assert(ports.at(it.second->port_id-1) == it.first);
1378 log_assert(it.second->port_input || it.second->port_output);
1379 if (GetSize(ports_declared) < it.second->port_id)
1380 ports_declared.resize(it.second->port_id);
1381 log_assert(ports_declared[it.second->port_id-1] == false);
1382 ports_declared[it.second->port_id-1] = true;
1383 } else
1384 log_assert(!it.second->port_input && !it.second->port_output);
1385 }
1386 for (auto port_declared : ports_declared)
1387 log_assert(port_declared == true);
1388 log_assert(GetSize(ports) == GetSize(ports_declared));
1389
1390 for (auto &it : memories) {
1391 log_assert(it.first == it.second->name);
1392 log_assert(!it.first.empty());
1393 log_assert(it.second->width >= 0);
1394 log_assert(it.second->size >= 0);
1395 for (auto &it2 : it.second->attributes)
1396 log_assert(!it2.first.empty());
1397 }
1398
1399 for (auto &it : cells_) {
1400 log_assert(this == it.second->module);
1401 log_assert(it.first == it.second->name);
1402 log_assert(!it.first.empty());
1403 log_assert(!it.second->type.empty());
1404 for (auto &it2 : it.second->connections()) {
1405 log_assert(!it2.first.empty());
1406 it2.second.check();
1407 }
1408 for (auto &it2 : it.second->attributes)
1409 log_assert(!it2.first.empty());
1410 for (auto &it2 : it.second->parameters)
1411 log_assert(!it2.first.empty());
1412 InternalCellChecker checker(this, it.second);
1413 checker.check();
1414 }
1415
1416 for (auto &it : processes) {
1417 log_assert(it.first == it.second->name);
1418 log_assert(!it.first.empty());
1419 log_assert(it.second->root_case.compare.empty());
1420 std::vector<CaseRule*> all_cases = {&it.second->root_case};
1421 for (size_t i = 0; i < all_cases.size(); i++) {
1422 for (auto &switch_it : all_cases[i]->switches) {
1423 for (auto &case_it : switch_it->cases) {
1424 for (auto &compare_it : case_it->compare) {
1425 log_assert(switch_it->signal.size() == compare_it.size());
1426 }
1427 all_cases.push_back(case_it);
1428 }
1429 }
1430 }
1431 for (auto &sync_it : it.second->syncs) {
1432 switch (sync_it->type) {
1433 case SyncType::ST0:
1434 case SyncType::ST1:
1435 case SyncType::STp:
1436 case SyncType::STn:
1437 case SyncType::STe:
1438 log_assert(!sync_it->signal.empty());
1439 break;
1440 case SyncType::STa:
1441 case SyncType::STg:
1442 case SyncType::STi:
1443 log_assert(sync_it->signal.empty());
1444 break;
1445 }
1446 }
1447 }
1448
1449 for (auto &it : connections_) {
1450 log_assert(it.first.size() == it.second.size());
1451 log_assert(!it.first.has_const());
1452 it.first.check();
1453 it.second.check();
1454 }
1455
1456 for (auto &it : attributes)
1457 log_assert(!it.first.empty());
1458 #endif
1459 }
1460
1461 void RTLIL::Module::optimize()
1462 {
1463 }
1464
1465 void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const
1466 {
1467 log_assert(new_mod->refcount_wires_ == 0);
1468 log_assert(new_mod->refcount_cells_ == 0);
1469
1470 new_mod->avail_parameters = avail_parameters;
1471
1472 for (auto &conn : connections_)
1473 new_mod->connect(conn);
1474
1475 for (auto &attr : attributes)
1476 new_mod->attributes[attr.first] = attr.second;
1477
1478 for (auto &it : wires_)
1479 new_mod->addWire(it.first, it.second);
1480
1481 for (auto &it : memories)
1482 new_mod->memories[it.first] = new RTLIL::Memory(*it.second);
1483
1484 for (auto &it : cells_)
1485 new_mod->addCell(it.first, it.second);
1486
1487 for (auto &it : processes)
1488 new_mod->processes[it.first] = it.second->clone();
1489
1490 struct RewriteSigSpecWorker
1491 {
1492 RTLIL::Module *mod;
1493 void operator()(RTLIL::SigSpec &sig)
1494 {
1495 std::vector<RTLIL::SigChunk> chunks = sig.chunks();
1496 for (auto &c : chunks)
1497 if (c.wire != NULL)
1498 c.wire = mod->wires_.at(c.wire->name);
1499 sig = chunks;
1500 }
1501 };
1502
1503 RewriteSigSpecWorker rewriteSigSpecWorker;
1504 rewriteSigSpecWorker.mod = new_mod;
1505 new_mod->rewrite_sigspecs(rewriteSigSpecWorker);
1506 new_mod->fixup_ports();
1507 }
1508
1509 RTLIL::Module *RTLIL::Module::clone() const
1510 {
1511 RTLIL::Module *new_mod = new RTLIL::Module;
1512 new_mod->name = name;
1513 cloneInto(new_mod);
1514 return new_mod;
1515 }
1516
1517 bool RTLIL::Module::has_memories() const
1518 {
1519 return !memories.empty();
1520 }
1521
1522 bool RTLIL::Module::has_processes() const
1523 {
1524 return !processes.empty();
1525 }
1526
1527 bool RTLIL::Module::has_memories_warn() const
1528 {
1529 if (!memories.empty())
1530 log_warning("Ignoring module %s because it contains memories (run 'memory' command first).\n", log_id(this));
1531 return !memories.empty();
1532 }
1533
1534 bool RTLIL::Module::has_processes_warn() const
1535 {
1536 if (!processes.empty())
1537 log_warning("Ignoring module %s because it contains processes (run 'proc' command first).\n", log_id(this));
1538 return !processes.empty();
1539 }
1540
1541 std::vector<RTLIL::Wire*> RTLIL::Module::selected_wires() const
1542 {
1543 std::vector<RTLIL::Wire*> result;
1544 result.reserve(wires_.size());
1545 for (auto &it : wires_)
1546 if (design->selected(this, it.second))
1547 result.push_back(it.second);
1548 return result;
1549 }
1550
1551 std::vector<RTLIL::Cell*> RTLIL::Module::selected_cells() const
1552 {
1553 std::vector<RTLIL::Cell*> result;
1554 result.reserve(cells_.size());
1555 for (auto &it : cells_)
1556 if (design->selected(this, it.second))
1557 result.push_back(it.second);
1558 return result;
1559 }
1560
1561 void RTLIL::Module::add(RTLIL::Wire *wire)
1562 {
1563 log_assert(!wire->name.empty());
1564 log_assert(count_id(wire->name) == 0);
1565 log_assert(refcount_wires_ == 0);
1566 wires_[wire->name] = wire;
1567 wire->module = this;
1568 }
1569
1570 void RTLIL::Module::add(RTLIL::Cell *cell)
1571 {
1572 log_assert(!cell->name.empty());
1573 log_assert(count_id(cell->name) == 0);
1574 log_assert(refcount_cells_ == 0);
1575 cells_[cell->name] = cell;
1576 cell->module = this;
1577 }
1578
1579 void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
1580 {
1581 log_assert(refcount_wires_ == 0);
1582
1583 struct DeleteWireWorker
1584 {
1585 RTLIL::Module *module;
1586 const pool<RTLIL::Wire*> *wires_p;
1587
1588 void operator()(RTLIL::SigSpec &sig) {
1589 std::vector<RTLIL::SigChunk> chunks = sig;
1590 for (auto &c : chunks)
1591 if (c.wire != NULL && wires_p->count(c.wire)) {
1592 c.wire = module->addWire(NEW_ID, c.width);
1593 c.offset = 0;
1594 }
1595 sig = chunks;
1596 }
1597
1598 void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) {
1599 log_assert(GetSize(lhs) == GetSize(rhs));
1600 RTLIL::SigSpec new_lhs, new_rhs;
1601 for (int i = 0; i < GetSize(lhs); i++) {
1602 RTLIL::SigBit lhs_bit = lhs[i];
1603 if (lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire))
1604 continue;
1605 RTLIL::SigBit rhs_bit = rhs[i];
1606 if (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))
1607 continue;
1608 new_lhs.append(lhs_bit);
1609 new_rhs.append(rhs_bit);
1610 }
1611 lhs = new_lhs;
1612 rhs = new_rhs;
1613 }
1614 };
1615
1616 DeleteWireWorker delete_wire_worker;
1617 delete_wire_worker.module = this;
1618 delete_wire_worker.wires_p = &wires;
1619 rewrite_sigspecs2(delete_wire_worker);
1620
1621 for (auto &it : wires) {
1622 log_assert(wires_.count(it->name) != 0);
1623 wires_.erase(it->name);
1624 delete it;
1625 }
1626 }
1627
1628 void RTLIL::Module::remove(RTLIL::Cell *cell)
1629 {
1630 while (!cell->connections_.empty())
1631 cell->unsetPort(cell->connections_.begin()->first);
1632
1633 log_assert(cells_.count(cell->name) != 0);
1634 log_assert(refcount_cells_ == 0);
1635 cells_.erase(cell->name);
1636 delete cell;
1637 }
1638
1639 void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name)
1640 {
1641 log_assert(wires_[wire->name] == wire);
1642 log_assert(refcount_wires_ == 0);
1643 wires_.erase(wire->name);
1644 wire->name = new_name;
1645 add(wire);
1646 }
1647
1648 void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name)
1649 {
1650 log_assert(cells_[cell->name] == cell);
1651 log_assert(refcount_wires_ == 0);
1652 cells_.erase(cell->name);
1653 cell->name = new_name;
1654 add(cell);
1655 }
1656
1657 void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name)
1658 {
1659 log_assert(count_id(old_name) != 0);
1660 if (wires_.count(old_name))
1661 rename(wires_.at(old_name), new_name);
1662 else if (cells_.count(old_name))
1663 rename(cells_.at(old_name), new_name);
1664 else
1665 log_abort();
1666 }
1667
1668 void RTLIL::Module::swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2)
1669 {
1670 log_assert(wires_[w1->name] == w1);
1671 log_assert(wires_[w2->name] == w2);
1672 log_assert(refcount_wires_ == 0);
1673
1674 wires_.erase(w1->name);
1675 wires_.erase(w2->name);
1676
1677 std::swap(w1->name, w2->name);
1678
1679 wires_[w1->name] = w1;
1680 wires_[w2->name] = w2;
1681 }
1682
1683 void RTLIL::Module::swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2)
1684 {
1685 log_assert(cells_[c1->name] == c1);
1686 log_assert(cells_[c2->name] == c2);
1687 log_assert(refcount_cells_ == 0);
1688
1689 cells_.erase(c1->name);
1690 cells_.erase(c2->name);
1691
1692 std::swap(c1->name, c2->name);
1693
1694 cells_[c1->name] = c1;
1695 cells_[c2->name] = c2;
1696 }
1697
1698 RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name)
1699 {
1700 int index = 0;
1701 return uniquify(name, index);
1702 }
1703
1704 RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name, int &index)
1705 {
1706 if (index == 0) {
1707 if (count_id(name) == 0)
1708 return name;
1709 index++;
1710 }
1711
1712 while (1) {
1713 RTLIL::IdString new_name = stringf("%s_%d", name.c_str(), index);
1714 if (count_id(new_name) == 0)
1715 return new_name;
1716 index++;
1717 }
1718 }
1719
1720 static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
1721 {
1722 if (a->port_id && !b->port_id)
1723 return true;
1724 if (!a->port_id && b->port_id)
1725 return false;
1726
1727 if (a->port_id == b->port_id)
1728 return a->name < b->name;
1729 return a->port_id < b->port_id;
1730 }
1731
1732 void RTLIL::Module::connect(const RTLIL::SigSig &conn)
1733 {
1734 for (auto mon : monitors)
1735 mon->notify_connect(this, conn);
1736
1737 if (design)
1738 for (auto mon : design->monitors)
1739 mon->notify_connect(this, conn);
1740
1741 // ignore all attempts to assign constants to other constants
1742 if (conn.first.has_const()) {
1743 RTLIL::SigSig new_conn;
1744 for (int i = 0; i < GetSize(conn.first); i++)
1745 if (conn.first[i].wire) {
1746 new_conn.first.append(conn.first[i]);
1747 new_conn.second.append(conn.second[i]);
1748 }
1749 if (GetSize(new_conn.first))
1750 connect(new_conn);
1751 return;
1752 }
1753
1754 if (yosys_xtrace) {
1755 log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
1756 log_backtrace("-X- ", yosys_xtrace-1);
1757 }
1758
1759 log_assert(GetSize(conn.first) == GetSize(conn.second));
1760 connections_.push_back(conn);
1761 }
1762
1763 void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs)
1764 {
1765 connect(RTLIL::SigSig(lhs, rhs));
1766 }
1767
1768 void RTLIL::Module::new_connections(const std::vector<RTLIL::SigSig> &new_conn)
1769 {
1770 for (auto mon : monitors)
1771 mon->notify_connect(this, new_conn);
1772
1773 if (design)
1774 for (auto mon : design->monitors)
1775 mon->notify_connect(this, new_conn);
1776
1777 if (yosys_xtrace) {
1778 log("#X# New connections vector in %s:\n", log_id(this));
1779 for (auto &conn: new_conn)
1780 log("#X# %s = %s (%d bits)\n", log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
1781 log_backtrace("-X- ", yosys_xtrace-1);
1782 }
1783
1784 connections_ = new_conn;
1785 }
1786
1787 const std::vector<RTLIL::SigSig> &RTLIL::Module::connections() const
1788 {
1789 return connections_;
1790 }
1791
1792 void RTLIL::Module::fixup_ports()
1793 {
1794 std::vector<RTLIL::Wire*> all_ports;
1795
1796 for (auto &w : wires_)
1797 if (w.second->port_input || w.second->port_output)
1798 all_ports.push_back(w.second);
1799 else
1800 w.second->port_id = 0;
1801
1802 std::sort(all_ports.begin(), all_ports.end(), fixup_ports_compare);
1803
1804 ports.clear();
1805 for (size_t i = 0; i < all_ports.size(); i++) {
1806 ports.push_back(all_ports[i]->name);
1807 all_ports[i]->port_id = i+1;
1808 }
1809 }
1810
1811 RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width)
1812 {
1813 RTLIL::Wire *wire = new RTLIL::Wire;
1814 wire->name = name;
1815 wire->width = width;
1816 add(wire);
1817 return wire;
1818 }
1819
1820 RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *other)
1821 {
1822 RTLIL::Wire *wire = addWire(name);
1823 wire->width = other->width;
1824 wire->start_offset = other->start_offset;
1825 wire->port_id = other->port_id;
1826 wire->port_input = other->port_input;
1827 wire->port_output = other->port_output;
1828 wire->upto = other->upto;
1829 wire->attributes = other->attributes;
1830 return wire;
1831 }
1832
1833 RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type)
1834 {
1835 RTLIL::Cell *cell = new RTLIL::Cell;
1836 cell->name = name;
1837 cell->type = type;
1838 add(cell);
1839 return cell;
1840 }
1841
1842 RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *other)
1843 {
1844 RTLIL::Cell *cell = addCell(name, other->type);
1845 cell->connections_ = other->connections_;
1846 cell->parameters = other->parameters;
1847 cell->attributes = other->attributes;
1848 return cell;
1849 }
1850
1851 #define DEF_METHOD(_func, _y_size, _type) \
1852 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
1853 RTLIL::Cell *cell = addCell(name, _type); \
1854 cell->parameters[ID(A_SIGNED)] = is_signed; \
1855 cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
1856 cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
1857 cell->setPort(ID::A, sig_a); \
1858 cell->setPort(ID::Y, sig_y); \
1859 cell->set_src_attribute(src); \
1860 return cell; \
1861 } \
1862 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed, const std::string &src) { \
1863 RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
1864 add ## _func(name, sig_a, sig_y, is_signed, src); \
1865 return sig_y; \
1866 }
1867 DEF_METHOD(Not, sig_a.size(), ID($not))
1868 DEF_METHOD(Pos, sig_a.size(), ID($pos))
1869 DEF_METHOD(Neg, sig_a.size(), ID($neg))
1870 DEF_METHOD(ReduceAnd, 1, ID($reduce_and))
1871 DEF_METHOD(ReduceOr, 1, ID($reduce_or))
1872 DEF_METHOD(ReduceXor, 1, ID($reduce_xor))
1873 DEF_METHOD(ReduceXnor, 1, ID($reduce_xnor))
1874 DEF_METHOD(ReduceBool, 1, ID($reduce_bool))
1875 DEF_METHOD(LogicNot, 1, ID($logic_not))
1876 #undef DEF_METHOD
1877
1878 #define DEF_METHOD(_func, _y_size, _type) \
1879 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
1880 RTLIL::Cell *cell = addCell(name, _type); \
1881 cell->parameters[ID(A_SIGNED)] = is_signed; \
1882 cell->parameters[ID(B_SIGNED)] = is_signed; \
1883 cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
1884 cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
1885 cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
1886 cell->setPort(ID::A, sig_a); \
1887 cell->setPort(ID::B, sig_b); \
1888 cell->setPort(ID::Y, sig_y); \
1889 cell->set_src_attribute(src); \
1890 return cell; \
1891 } \
1892 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \
1893 RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
1894 add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \
1895 return sig_y; \
1896 }
1897 DEF_METHOD(And, max(sig_a.size(), sig_b.size()), ID($and))
1898 DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), ID($or))
1899 DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), ID($xor))
1900 DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), ID($xnor))
1901 DEF_METHOD(Shift, sig_a.size(), ID($shift))
1902 DEF_METHOD(Shiftx, sig_a.size(), ID($shiftx))
1903 DEF_METHOD(Lt, 1, ID($lt))
1904 DEF_METHOD(Le, 1, ID($le))
1905 DEF_METHOD(Eq, 1, ID($eq))
1906 DEF_METHOD(Ne, 1, ID($ne))
1907 DEF_METHOD(Eqx, 1, ID($eqx))
1908 DEF_METHOD(Nex, 1, ID($nex))
1909 DEF_METHOD(Ge, 1, ID($ge))
1910 DEF_METHOD(Gt, 1, ID($gt))
1911 DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), ID($add))
1912 DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), ID($sub))
1913 DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), ID($mul))
1914 DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), ID($div))
1915 DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), ID($mod))
1916 DEF_METHOD(LogicAnd, 1, ID($logic_and))
1917 DEF_METHOD(LogicOr, 1, ID($logic_or))
1918 #undef DEF_METHOD
1919
1920 #define DEF_METHOD(_func, _y_size, _type) \
1921 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
1922 RTLIL::Cell *cell = addCell(name, _type); \
1923 cell->parameters[ID(A_SIGNED)] = is_signed; \
1924 cell->parameters[ID(B_SIGNED)] = false; \
1925 cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
1926 cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
1927 cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
1928 cell->setPort(ID::A, sig_a); \
1929 cell->setPort(ID::B, sig_b); \
1930 cell->setPort(ID::Y, sig_y); \
1931 cell->set_src_attribute(src); \
1932 return cell; \
1933 } \
1934 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \
1935 RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
1936 add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \
1937 return sig_y; \
1938 }
1939 DEF_METHOD(Shl, sig_a.size(), ID($shl))
1940 DEF_METHOD(Shr, sig_a.size(), ID($shr))
1941 DEF_METHOD(Sshl, sig_a.size(), ID($sshl))
1942 DEF_METHOD(Sshr, sig_a.size(), ID($sshr))
1943 #undef DEF_METHOD
1944
1945 #define DEF_METHOD(_func, _type, _pmux) \
1946 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, const std::string &src) { \
1947 RTLIL::Cell *cell = addCell(name, _type); \
1948 cell->parameters[ID(WIDTH)] = sig_a.size(); \
1949 if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \
1950 cell->setPort(ID::A, sig_a); \
1951 cell->setPort(ID::B, sig_b); \
1952 cell->setPort(ID(S), sig_s); \
1953 cell->setPort(ID::Y, sig_y); \
1954 cell->set_src_attribute(src); \
1955 return cell; \
1956 } \
1957 RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src) { \
1958 RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \
1959 add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \
1960 return sig_y; \
1961 }
1962 DEF_METHOD(Mux, ID($mux), 0)
1963 DEF_METHOD(Pmux, ID($pmux), 1)
1964 #undef DEF_METHOD
1965
1966 #define DEF_METHOD_2(_func, _type, _P1, _P2) \
1967 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, const std::string &src) { \
1968 RTLIL::Cell *cell = addCell(name, _type); \
1969 cell->setPort("\\" #_P1, sig1); \
1970 cell->setPort("\\" #_P2, sig2); \
1971 cell->set_src_attribute(src); \
1972 return cell; \
1973 } \
1974 RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, const std::string &src) { \
1975 RTLIL::SigBit sig2 = addWire(NEW_ID); \
1976 add ## _func(name, sig1, sig2, src); \
1977 return sig2; \
1978 }
1979 #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \
1980 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, const std::string &src) { \
1981 RTLIL::Cell *cell = addCell(name, _type); \
1982 cell->setPort("\\" #_P1, sig1); \
1983 cell->setPort("\\" #_P2, sig2); \
1984 cell->setPort("\\" #_P3, sig3); \
1985 cell->set_src_attribute(src); \
1986 return cell; \
1987 } \
1988 RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, const std::string &src) { \
1989 RTLIL::SigBit sig3 = addWire(NEW_ID); \
1990 add ## _func(name, sig1, sig2, sig3, src); \
1991 return sig3; \
1992 }
1993 #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \
1994 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, const std::string &src) { \
1995 RTLIL::Cell *cell = addCell(name, _type); \
1996 cell->setPort("\\" #_P1, sig1); \
1997 cell->setPort("\\" #_P2, sig2); \
1998 cell->setPort("\\" #_P3, sig3); \
1999 cell->setPort("\\" #_P4, sig4); \
2000 cell->set_src_attribute(src); \
2001 return cell; \
2002 } \
2003 RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, const std::string &src) { \
2004 RTLIL::SigBit sig4 = addWire(NEW_ID); \
2005 add ## _func(name, sig1, sig2, sig3, sig4, src); \
2006 return sig4; \
2007 }
2008 #define DEF_METHOD_5(_func, _type, _P1, _P2, _P3, _P4, _P5) \
2009 RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, RTLIL::SigBit sig5, const std::string &src) { \
2010 RTLIL::Cell *cell = addCell(name, _type); \
2011 cell->setPort("\\" #_P1, sig1); \
2012 cell->setPort("\\" #_P2, sig2); \
2013 cell->setPort("\\" #_P3, sig3); \
2014 cell->setPort("\\" #_P4, sig4); \
2015 cell->setPort("\\" #_P5, sig5); \
2016 cell->set_src_attribute(src); \
2017 return cell; \
2018 } \
2019 RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, const std::string &src) { \
2020 RTLIL::SigBit sig5 = addWire(NEW_ID); \
2021 add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \
2022 return sig5; \
2023 }
2024 DEF_METHOD_2(BufGate, ID($_BUF_), A, Y)
2025 DEF_METHOD_2(NotGate, ID($_NOT_), A, Y)
2026 DEF_METHOD_3(AndGate, ID($_AND_), A, B, Y)
2027 DEF_METHOD_3(NandGate, ID($_NAND_), A, B, Y)
2028 DEF_METHOD_3(OrGate, ID($_OR_), A, B, Y)
2029 DEF_METHOD_3(NorGate, ID($_NOR_), A, B, Y)
2030 DEF_METHOD_3(XorGate, ID($_XOR_), A, B, Y)
2031 DEF_METHOD_3(XnorGate, ID($_XNOR_), A, B, Y)
2032 DEF_METHOD_3(AndnotGate, ID($_ANDNOT_), A, B, Y)
2033 DEF_METHOD_3(OrnotGate, ID($_ORNOT_), A, B, Y)
2034 DEF_METHOD_4(MuxGate, ID($_MUX_), A, B, S, Y)
2035 DEF_METHOD_4(NmuxGate, ID($_NMUX_), A, B, S, Y)
2036 DEF_METHOD_4(Aoi3Gate, ID($_AOI3_), A, B, C, Y)
2037 DEF_METHOD_4(Oai3Gate, ID($_OAI3_), A, B, C, Y)
2038 DEF_METHOD_5(Aoi4Gate, ID($_AOI4_), A, B, C, D, Y)
2039 DEF_METHOD_5(Oai4Gate, ID($_OAI4_), A, B, C, D, Y)
2040 #undef DEF_METHOD_2
2041 #undef DEF_METHOD_3
2042 #undef DEF_METHOD_4
2043 #undef DEF_METHOD_5
2044
2045 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, const std::string &src)
2046 {
2047 RTLIL::Cell *cell = addCell(name, ID($pow));
2048 cell->parameters[ID(A_SIGNED)] = a_signed;
2049 cell->parameters[ID(B_SIGNED)] = b_signed;
2050 cell->parameters[ID(A_WIDTH)] = sig_a.size();
2051 cell->parameters[ID(B_WIDTH)] = sig_b.size();
2052 cell->parameters[ID(Y_WIDTH)] = sig_y.size();
2053 cell->setPort(ID::A, sig_a);
2054 cell->setPort(ID::B, sig_b);
2055 cell->setPort(ID::Y, sig_y);
2056 cell->set_src_attribute(src);
2057 return cell;
2058 }
2059
2060 RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src)
2061 {
2062 RTLIL::Cell *cell = addCell(name, ID($slice));
2063 cell->parameters[ID(A_WIDTH)] = sig_a.size();
2064 cell->parameters[ID(Y_WIDTH)] = sig_y.size();
2065 cell->parameters[ID(OFFSET)] = offset;
2066 cell->setPort(ID::A, sig_a);
2067 cell->setPort(ID::Y, sig_y);
2068 cell->set_src_attribute(src);
2069 return cell;
2070 }
2071
2072 RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)
2073 {
2074 RTLIL::Cell *cell = addCell(name, ID($concat));
2075 cell->parameters[ID(A_WIDTH)] = sig_a.size();
2076 cell->parameters[ID(B_WIDTH)] = sig_b.size();
2077 cell->setPort(ID::A, sig_a);
2078 cell->setPort(ID::B, sig_b);
2079 cell->setPort(ID::Y, sig_y);
2080 cell->set_src_attribute(src);
2081 return cell;
2082 }
2083
2084 RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src)
2085 {
2086 RTLIL::Cell *cell = addCell(name, ID($lut));
2087 cell->parameters[ID(LUT)] = lut;
2088 cell->parameters[ID(WIDTH)] = sig_a.size();
2089 cell->setPort(ID::A, sig_a);
2090 cell->setPort(ID::Y, sig_y);
2091 cell->set_src_attribute(src);
2092 return cell;
2093 }
2094
2095 RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src)
2096 {
2097 RTLIL::Cell *cell = addCell(name, ID($tribuf));
2098 cell->parameters[ID(WIDTH)] = sig_a.size();
2099 cell->setPort(ID::A, sig_a);
2100 cell->setPort(ID(EN), sig_en);
2101 cell->setPort(ID::Y, sig_y);
2102 cell->set_src_attribute(src);
2103 return cell;
2104 }
2105
2106 RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
2107 {
2108 RTLIL::Cell *cell = addCell(name, ID($assert));
2109 cell->setPort(ID::A, sig_a);
2110 cell->setPort(ID(EN), sig_en);
2111 cell->set_src_attribute(src);
2112 return cell;
2113 }
2114
2115 RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
2116 {
2117 RTLIL::Cell *cell = addCell(name, ID($assume));
2118 cell->setPort(ID::A, sig_a);
2119 cell->setPort(ID(EN), sig_en);
2120 cell->set_src_attribute(src);
2121 return cell;
2122 }
2123
2124 RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
2125 {
2126 RTLIL::Cell *cell = addCell(name, ID($live));
2127 cell->setPort(ID::A, sig_a);
2128 cell->setPort(ID(EN), sig_en);
2129 cell->set_src_attribute(src);
2130 return cell;
2131 }
2132
2133 RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
2134 {
2135 RTLIL::Cell *cell = addCell(name, ID($fair));
2136 cell->setPort(ID::A, sig_a);
2137 cell->setPort(ID(EN), sig_en);
2138 cell->set_src_attribute(src);
2139 return cell;
2140 }
2141
2142 RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
2143 {
2144 RTLIL::Cell *cell = addCell(name, ID($cover));
2145 cell->setPort(ID::A, sig_a);
2146 cell->setPort(ID(EN), sig_en);
2147 cell->set_src_attribute(src);
2148 return cell;
2149 }
2150
2151 RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)
2152 {
2153 RTLIL::Cell *cell = addCell(name, ID($equiv));
2154 cell->setPort(ID::A, sig_a);
2155 cell->setPort(ID::B, sig_b);
2156 cell->setPort(ID::Y, sig_y);
2157 cell->set_src_attribute(src);
2158 return cell;
2159 }
2160
2161 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, const std::string &src)
2162 {
2163 RTLIL::Cell *cell = addCell(name, ID($sr));
2164 cell->parameters[ID(SET_POLARITY)] = set_polarity;
2165 cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
2166 cell->parameters[ID(WIDTH)] = sig_q.size();
2167 cell->setPort(ID(SET), sig_set);
2168 cell->setPort(ID(CLR), sig_clr);
2169 cell->setPort(ID(Q), sig_q);
2170 cell->set_src_attribute(src);
2171 return cell;
2172 }
2173
2174 RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)
2175 {
2176 RTLIL::Cell *cell = addCell(name, ID($ff));
2177 cell->parameters[ID(WIDTH)] = sig_q.size();
2178 cell->setPort(ID(D), sig_d);
2179 cell->setPort(ID(Q), sig_q);
2180 cell->set_src_attribute(src);
2181 return cell;
2182 }
2183
2184 RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)
2185 {
2186 RTLIL::Cell *cell = addCell(name, ID($dff));
2187 cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
2188 cell->parameters[ID(WIDTH)] = sig_q.size();
2189 cell->setPort(ID(CLK), sig_clk);
2190 cell->setPort(ID(D), sig_d);
2191 cell->setPort(ID(Q), sig_q);
2192 cell->set_src_attribute(src);
2193 return cell;
2194 }
2195
2196 RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
2197 {
2198 RTLIL::Cell *cell = addCell(name, ID($dffe));
2199 cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
2200 cell->parameters[ID(EN_POLARITY)] = en_polarity;
2201 cell->parameters[ID(WIDTH)] = sig_q.size();
2202 cell->setPort(ID(CLK), sig_clk);
2203 cell->setPort(ID(EN), sig_en);
2204 cell->setPort(ID(D), sig_d);
2205 cell->setPort(ID(Q), sig_q);
2206 cell->set_src_attribute(src);
2207 return cell;
2208 }
2209
2210 RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
2211 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
2212 {
2213 RTLIL::Cell *cell = addCell(name, ID($dffsr));
2214 cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
2215 cell->parameters[ID(SET_POLARITY)] = set_polarity;
2216 cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
2217 cell->parameters[ID(WIDTH)] = sig_q.size();
2218 cell->setPort(ID(CLK), sig_clk);
2219 cell->setPort(ID(SET), sig_set);
2220 cell->setPort(ID(CLR), sig_clr);
2221 cell->setPort(ID(D), sig_d);
2222 cell->setPort(ID(Q), sig_q);
2223 cell->set_src_attribute(src);
2224 return cell;
2225 }
2226
2227 RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
2228 RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)
2229 {
2230 RTLIL::Cell *cell = addCell(name, ID($adff));
2231 cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
2232 cell->parameters[ID(ARST_POLARITY)] = arst_polarity;
2233 cell->parameters[ID(ARST_VALUE)] = arst_value;
2234 cell->parameters[ID(WIDTH)] = sig_q.size();
2235 cell->setPort(ID(CLK), sig_clk);
2236 cell->setPort(ID(ARST), sig_arst);
2237 cell->setPort(ID(D), sig_d);
2238 cell->setPort(ID(Q), sig_q);
2239 cell->set_src_attribute(src);
2240 return cell;
2241 }
2242
2243 RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)
2244 {
2245 RTLIL::Cell *cell = addCell(name, ID($dlatch));
2246 cell->parameters[ID(EN_POLARITY)] = en_polarity;
2247 cell->parameters[ID(WIDTH)] = sig_q.size();
2248 cell->setPort(ID(EN), sig_en);
2249 cell->setPort(ID(D), sig_d);
2250 cell->setPort(ID(Q), sig_q);
2251 cell->set_src_attribute(src);
2252 return cell;
2253 }
2254
2255 RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
2256 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
2257 {
2258 RTLIL::Cell *cell = addCell(name, ID($dlatchsr));
2259 cell->parameters[ID(EN_POLARITY)] = en_polarity;
2260 cell->parameters[ID(SET_POLARITY)] = set_polarity;
2261 cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
2262 cell->parameters[ID(WIDTH)] = sig_q.size();
2263 cell->setPort(ID(EN), sig_en);
2264 cell->setPort(ID(SET), sig_set);
2265 cell->setPort(ID(CLR), sig_clr);
2266 cell->setPort(ID(D), sig_d);
2267 cell->setPort(ID(Q), sig_q);
2268 cell->set_src_attribute(src);
2269 return cell;
2270 }
2271
2272 RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)
2273 {
2274 RTLIL::Cell *cell = addCell(name, ID($_FF_));
2275 cell->setPort(ID(D), sig_d);
2276 cell->setPort(ID(Q), sig_q);
2277 cell->set_src_attribute(src);
2278 return cell;
2279 }
2280
2281 RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)
2282 {
2283 RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'));
2284 cell->setPort(ID(C), sig_clk);
2285 cell->setPort(ID(D), sig_d);
2286 cell->setPort(ID(Q), sig_q);
2287 cell->set_src_attribute(src);
2288 return cell;
2289 }
2290
2291 RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
2292 {
2293 RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
2294 cell->setPort(ID(C), sig_clk);
2295 cell->setPort(ID(E), sig_en);
2296 cell->setPort(ID(D), sig_d);
2297 cell->setPort(ID(Q), sig_q);
2298 cell->set_src_attribute(src);
2299 return cell;
2300 }
2301
2302 RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
2303 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
2304 {
2305 RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
2306 cell->setPort(ID(C), sig_clk);
2307 cell->setPort(ID(S), sig_set);
2308 cell->setPort(ID(R), sig_clr);
2309 cell->setPort(ID(D), sig_d);
2310 cell->setPort(ID(Q), sig_q);
2311 cell->set_src_attribute(src);
2312 return cell;
2313 }
2314
2315 RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
2316 bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)
2317 {
2318 RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'));
2319 cell->setPort(ID(C), sig_clk);
2320 cell->setPort(ID(R), sig_arst);
2321 cell->setPort(ID(D), sig_d);
2322 cell->setPort(ID(Q), sig_q);
2323 cell->set_src_attribute(src);
2324 return cell;
2325 }
2326
2327 RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)
2328 {
2329 RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'));
2330 cell->setPort(ID(E), sig_en);
2331 cell->setPort(ID(D), sig_d);
2332 cell->setPort(ID(Q), sig_q);
2333 cell->set_src_attribute(src);
2334 return cell;
2335 }
2336
2337 RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
2338 RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
2339 {
2340 RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
2341 cell->setPort(ID(E), sig_en);
2342 cell->setPort(ID(S), sig_set);
2343 cell->setPort(ID(R), sig_clr);
2344 cell->setPort(ID(D), sig_d);
2345 cell->setPort(ID(Q), sig_q);
2346 cell->set_src_attribute(src);
2347 return cell;
2348 }
2349
2350 RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const std::string &src)
2351 {
2352 RTLIL::SigSpec sig = addWire(NEW_ID, width);
2353 Cell *cell = addCell(name, ID($anyconst));
2354 cell->setParam(ID(WIDTH), width);
2355 cell->setPort(ID::Y, sig);
2356 cell->set_src_attribute(src);
2357 return sig;
2358 }
2359
2360 RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std::string &src)
2361 {
2362 RTLIL::SigSpec sig = addWire(NEW_ID, width);
2363 Cell *cell = addCell(name, ID($anyseq));
2364 cell->setParam(ID(WIDTH), width);
2365 cell->setPort(ID::Y, sig);
2366 cell->set_src_attribute(src);
2367 return sig;
2368 }
2369
2370 RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const std::string &src)
2371 {
2372 RTLIL::SigSpec sig = addWire(NEW_ID, width);
2373 Cell *cell = addCell(name, ID($allconst));
2374 cell->setParam(ID(WIDTH), width);
2375 cell->setPort(ID::Y, sig);
2376 cell->set_src_attribute(src);
2377 return sig;
2378 }
2379
2380 RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std::string &src)
2381 {
2382 RTLIL::SigSpec sig = addWire(NEW_ID, width);
2383 Cell *cell = addCell(name, ID($allseq));
2384 cell->setParam(ID(WIDTH), width);
2385 cell->setPort(ID::Y, sig);
2386 cell->set_src_attribute(src);
2387 return sig;
2388 }
2389
2390 RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string &src)
2391 {
2392 RTLIL::SigSpec sig = addWire(NEW_ID);
2393 Cell *cell = addCell(name, ID($initstate));
2394 cell->setPort(ID::Y, sig);
2395 cell->set_src_attribute(src);
2396 return sig;
2397 }
2398
2399 RTLIL::Wire::Wire()
2400 {
2401 static unsigned int hashidx_count = 123456789;
2402 hashidx_count = mkhash_xorshift(hashidx_count);
2403 hashidx_ = hashidx_count;
2404
2405 module = nullptr;
2406 width = 1;
2407 start_offset = 0;
2408 port_id = 0;
2409 port_input = false;
2410 port_output = false;
2411 upto = false;
2412
2413 #ifdef WITH_PYTHON
2414 RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this));
2415 #endif
2416 }
2417
2418 RTLIL::Wire::~Wire()
2419 {
2420 #ifdef WITH_PYTHON
2421 RTLIL::Wire::get_all_wires()->erase(hashidx_);
2422 #endif
2423 }
2424
2425 #ifdef WITH_PYTHON
2426 static std::map<unsigned int, RTLIL::Wire*> all_wires;
2427 std::map<unsigned int, RTLIL::Wire*> *RTLIL::Wire::get_all_wires(void)
2428 {
2429 return &all_wires;
2430 }
2431 #endif
2432
2433 RTLIL::Memory::Memory()
2434 {
2435 static unsigned int hashidx_count = 123456789;
2436 hashidx_count = mkhash_xorshift(hashidx_count);
2437 hashidx_ = hashidx_count;
2438
2439 width = 1;
2440 start_offset = 0;
2441 size = 0;
2442 #ifdef WITH_PYTHON
2443 RTLIL::Memory::get_all_memorys()->insert(std::pair<unsigned int, RTLIL::Memory*>(hashidx_, this));
2444 #endif
2445 }
2446
2447 RTLIL::Cell::Cell() : module(nullptr)
2448 {
2449 static unsigned int hashidx_count = 123456789;
2450 hashidx_count = mkhash_xorshift(hashidx_count);
2451 hashidx_ = hashidx_count;
2452
2453 // log("#memtrace# %p\n", this);
2454 memhasher();
2455
2456 #ifdef WITH_PYTHON
2457 RTLIL::Cell::get_all_cells()->insert(std::pair<unsigned int, RTLIL::Cell*>(hashidx_, this));
2458 #endif
2459 }
2460
2461 RTLIL::Cell::~Cell()
2462 {
2463 #ifdef WITH_PYTHON
2464 RTLIL::Cell::get_all_cells()->erase(hashidx_);
2465 #endif
2466 }
2467
2468 #ifdef WITH_PYTHON
2469 static std::map<unsigned int, RTLIL::Cell*> all_cells;
2470 std::map<unsigned int, RTLIL::Cell*> *RTLIL::Cell::get_all_cells(void)
2471 {
2472 return &all_cells;
2473 }
2474 #endif
2475
2476 bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const
2477 {
2478 return connections_.count(portname) != 0;
2479 }
2480
2481 void RTLIL::Cell::unsetPort(RTLIL::IdString portname)
2482 {
2483 RTLIL::SigSpec signal;
2484 auto conn_it = connections_.find(portname);
2485
2486 if (conn_it != connections_.end())
2487 {
2488 for (auto mon : module->monitors)
2489 mon->notify_connect(this, conn_it->first, conn_it->second, signal);
2490
2491 if (module->design)
2492 for (auto mon : module->design->monitors)
2493 mon->notify_connect(this, conn_it->first, conn_it->second, signal);
2494
2495 if (yosys_xtrace) {
2496 log("#X# Unconnect %s.%s.%s\n", log_id(this->module), log_id(this), log_id(portname));
2497 log_backtrace("-X- ", yosys_xtrace-1);
2498 }
2499
2500 connections_.erase(conn_it);
2501 }
2502 }
2503
2504 void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
2505 {
2506 auto conn_it = connections_.find(portname);
2507
2508 if (conn_it == connections_.end()) {
2509 connections_[portname] = RTLIL::SigSpec();
2510 conn_it = connections_.find(portname);
2511 log_assert(conn_it != connections_.end());
2512 } else
2513 if (conn_it->second == signal)
2514 return;
2515
2516 for (auto mon : module->monitors)
2517 mon->notify_connect(this, conn_it->first, conn_it->second, signal);
2518
2519 if (module->design)
2520 for (auto mon : module->design->monitors)
2521 mon->notify_connect(this, conn_it->first, conn_it->second, signal);
2522
2523 if (yosys_xtrace) {
2524 log("#X# Connect %s.%s.%s = %s (%d)\n", log_id(this->module), log_id(this), log_id(portname), log_signal(signal), GetSize(signal));
2525 log_backtrace("-X- ", yosys_xtrace-1);
2526 }
2527
2528 conn_it->second = signal;
2529 }
2530
2531 const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const
2532 {
2533 return connections_.at(portname);
2534 }
2535
2536 const dict<RTLIL::IdString, RTLIL::SigSpec> &RTLIL::Cell::connections() const
2537 {
2538 return connections_;
2539 }
2540
2541 bool RTLIL::Cell::known() const
2542 {
2543 if (yosys_celltypes.cell_known(type))
2544 return true;
2545 if (module && module->design && module->design->module(type))
2546 return true;
2547 return false;
2548 }
2549
2550 bool RTLIL::Cell::input(RTLIL::IdString portname) const
2551 {
2552 if (yosys_celltypes.cell_known(type))
2553 return yosys_celltypes.cell_input(type, portname);
2554 if (module && module->design) {
2555 RTLIL::Module *m = module->design->module(type);
2556 RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
2557 return w && w->port_input;
2558 }
2559 return false;
2560 }
2561
2562 bool RTLIL::Cell::output(RTLIL::IdString portname) const
2563 {
2564 if (yosys_celltypes.cell_known(type))
2565 return yosys_celltypes.cell_output(type, portname);
2566 if (module && module->design) {
2567 RTLIL::Module *m = module->design->module(type);
2568 RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
2569 return w && w->port_output;
2570 }
2571 return false;
2572 }
2573
2574 bool RTLIL::Cell::hasParam(RTLIL::IdString paramname) const
2575 {
2576 return parameters.count(paramname) != 0;
2577 }
2578
2579 void RTLIL::Cell::unsetParam(RTLIL::IdString paramname)
2580 {
2581 parameters.erase(paramname);
2582 }
2583
2584 void RTLIL::Cell::setParam(RTLIL::IdString paramname, RTLIL::Const value)
2585 {
2586 parameters[paramname] = value;
2587 }
2588
2589 const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const
2590 {
2591 return parameters.at(paramname);
2592 }
2593
2594 void RTLIL::Cell::sort()
2595 {
2596 connections_.sort(sort_by_id_str());
2597 parameters.sort(sort_by_id_str());
2598 attributes.sort(sort_by_id_str());
2599 }
2600
2601 void RTLIL::Cell::check()
2602 {
2603 #ifndef NDEBUG
2604 InternalCellChecker checker(NULL, this);
2605 checker.check();
2606 #endif
2607 }
2608
2609 void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
2610 {
2611 if (!type.begins_with("$") || type.begins_with("$_") || type.begins_with("$paramod") || type.begins_with("$fmcombine") ||
2612 type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:"))
2613 return;
2614
2615 if (type == ID($mux) || type == ID($pmux)) {
2616 parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
2617 if (type == ID($pmux))
2618 parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]);
2619 check();
2620 return;
2621 }
2622
2623 if (type == ID($lut) || type == ID($sop)) {
2624 parameters[ID(WIDTH)] = GetSize(connections_[ID::A]);
2625 return;
2626 }
2627
2628 if (type == ID($fa)) {
2629 parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
2630 return;
2631 }
2632
2633 if (type == ID($lcu)) {
2634 parameters[ID(WIDTH)] = GetSize(connections_[ID(CO)]);
2635 return;
2636 }
2637
2638 bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc));
2639
2640 if (connections_.count(ID::A)) {
2641 if (signedness_ab) {
2642 if (set_a_signed)
2643 parameters[ID(A_SIGNED)] = true;
2644 else if (parameters.count(ID(A_SIGNED)) == 0)
2645 parameters[ID(A_SIGNED)] = false;
2646 }
2647 parameters[ID(A_WIDTH)] = GetSize(connections_[ID::A]);
2648 }
2649
2650 if (connections_.count(ID::B)) {
2651 if (signedness_ab) {
2652 if (set_b_signed)
2653 parameters[ID(B_SIGNED)] = true;
2654 else if (parameters.count(ID(B_SIGNED)) == 0)
2655 parameters[ID(B_SIGNED)] = false;
2656 }
2657 parameters[ID(B_WIDTH)] = GetSize(connections_[ID::B]);
2658 }
2659
2660 if (connections_.count(ID::Y))
2661 parameters[ID(Y_WIDTH)] = GetSize(connections_[ID::Y]);
2662
2663 if (connections_.count(ID(Q)))
2664 parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]);
2665
2666 check();
2667 }
2668
2669 RTLIL::SigChunk::SigChunk()
2670 {
2671 wire = NULL;
2672 width = 0;
2673 offset = 0;
2674 }
2675
2676 RTLIL::SigChunk::SigChunk(const RTLIL::Const &value)
2677 {
2678 wire = NULL;
2679 data = value.bits;
2680 width = GetSize(data);
2681 offset = 0;
2682 }
2683
2684 RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire)
2685 {
2686 log_assert(wire != nullptr);
2687 this->wire = wire;
2688 this->width = wire->width;
2689 this->offset = 0;
2690 }
2691
2692 RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int offset, int width)
2693 {
2694 log_assert(wire != nullptr);
2695 this->wire = wire;
2696 this->width = width;
2697 this->offset = offset;
2698 }
2699
2700 RTLIL::SigChunk::SigChunk(const std::string &str)
2701 {
2702 wire = NULL;
2703 data = RTLIL::Const(str).bits;
2704 width = GetSize(data);
2705 offset = 0;
2706 }
2707
2708 RTLIL::SigChunk::SigChunk(int val, int width)
2709 {
2710 wire = NULL;
2711 data = RTLIL::Const(val, width).bits;
2712 this->width = GetSize(data);
2713 offset = 0;
2714 }
2715
2716 RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width)
2717 {
2718 wire = NULL;
2719 data = RTLIL::Const(bit, width).bits;
2720 this->width = GetSize(data);
2721 offset = 0;
2722 }
2723
2724 RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
2725 {
2726 wire = bit.wire;
2727 offset = 0;
2728 if (wire == NULL)
2729 data = RTLIL::Const(bit.data).bits;
2730 else
2731 offset = bit.offset;
2732 width = 1;
2733 }
2734
2735 RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) : data(sigchunk.data)
2736 {
2737 wire = sigchunk.wire;
2738 data = sigchunk.data;
2739 width = sigchunk.width;
2740 offset = sigchunk.offset;
2741 }
2742
2743 RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
2744 {
2745 RTLIL::SigChunk ret;
2746 if (wire) {
2747 ret.wire = wire;
2748 ret.offset = this->offset + offset;
2749 ret.width = length;
2750 } else {
2751 for (int i = 0; i < length; i++)
2752 ret.data.push_back(data[offset+i]);
2753 ret.width = length;
2754 }
2755 return ret;
2756 }
2757
2758 bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk &other) const
2759 {
2760 if (wire && other.wire)
2761 if (wire->name != other.wire->name)
2762 return wire->name < other.wire->name;
2763
2764 if (wire != other.wire)
2765 return wire < other.wire;
2766
2767 if (offset != other.offset)
2768 return offset < other.offset;
2769
2770 if (width != other.width)
2771 return width < other.width;
2772
2773 return data < other.data;
2774 }
2775
2776 bool RTLIL::SigChunk::operator ==(const RTLIL::SigChunk &other) const
2777 {
2778 return wire == other.wire && width == other.width && offset == other.offset && data == other.data;
2779 }
2780
2781 bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const
2782 {
2783 if (*this == other)
2784 return false;
2785 return true;
2786 }
2787
2788 RTLIL::SigSpec::SigSpec()
2789 {
2790 width_ = 0;
2791 hash_ = 0;
2792 }
2793
2794 RTLIL::SigSpec::SigSpec(const RTLIL::SigSpec &other)
2795 {
2796 *this = other;
2797 }
2798
2799 RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
2800 {
2801 cover("kernel.rtlil.sigspec.init.list");
2802
2803 width_ = 0;
2804 hash_ = 0;
2805
2806 std::vector<RTLIL::SigSpec> parts_vec(parts.begin(), parts.end());
2807 for (auto it = parts_vec.rbegin(); it != parts_vec.rend(); it++)
2808 append(*it);
2809 }
2810
2811 const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other)
2812 {
2813 cover("kernel.rtlil.sigspec.assign");
2814
2815 width_ = other.width_;
2816 hash_ = other.hash_;
2817 chunks_ = other.chunks_;
2818 bits_.clear();
2819
2820 if (!other.bits_.empty())
2821 {
2822 RTLIL::SigChunk *last = NULL;
2823 int last_end_offset = 0;
2824
2825 for (auto &bit : other.bits_) {
2826 if (last && bit.wire == last->wire) {
2827 if (bit.wire == NULL) {
2828 last->data.push_back(bit.data);
2829 last->width++;
2830 continue;
2831 } else if (last_end_offset == bit.offset) {
2832 last_end_offset++;
2833 last->width++;
2834 continue;
2835 }
2836 }
2837 chunks_.push_back(bit);
2838 last = &chunks_.back();
2839 last_end_offset = bit.offset + 1;
2840 }
2841
2842 check();
2843 }
2844
2845 return *this;
2846 }
2847
2848 RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
2849 {
2850 cover("kernel.rtlil.sigspec.init.const");
2851
2852 chunks_.push_back(RTLIL::SigChunk(value));
2853 width_ = chunks_.back().width;
2854 hash_ = 0;
2855 check();
2856 }
2857
2858 RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
2859 {
2860 cover("kernel.rtlil.sigspec.init.chunk");
2861
2862 chunks_.push_back(chunk);
2863 width_ = chunks_.back().width;
2864 hash_ = 0;
2865 check();
2866 }
2867
2868 RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
2869 {
2870 cover("kernel.rtlil.sigspec.init.wire");
2871
2872 chunks_.push_back(RTLIL::SigChunk(wire));
2873 width_ = chunks_.back().width;
2874 hash_ = 0;
2875 check();
2876 }
2877
2878 RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
2879 {
2880 cover("kernel.rtlil.sigspec.init.wire_part");
2881
2882 chunks_.push_back(RTLIL::SigChunk(wire, offset, width));
2883 width_ = chunks_.back().width;
2884 hash_ = 0;
2885 check();
2886 }
2887
2888 RTLIL::SigSpec::SigSpec(const std::string &str)
2889 {
2890 cover("kernel.rtlil.sigspec.init.str");
2891
2892 chunks_.push_back(RTLIL::SigChunk(str));
2893 width_ = chunks_.back().width;
2894 hash_ = 0;
2895 check();
2896 }
2897
2898 RTLIL::SigSpec::SigSpec(int val, int width)
2899 {
2900 cover("kernel.rtlil.sigspec.init.int");
2901
2902 chunks_.push_back(RTLIL::SigChunk(val, width));
2903 width_ = width;
2904 hash_ = 0;
2905 check();
2906 }
2907
2908 RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
2909 {
2910 cover("kernel.rtlil.sigspec.init.state");
2911
2912 chunks_.push_back(RTLIL::SigChunk(bit, width));
2913 width_ = width;
2914 hash_ = 0;
2915 check();
2916 }
2917
2918 RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
2919 {
2920 cover("kernel.rtlil.sigspec.init.bit");
2921
2922 if (bit.wire == NULL)
2923 chunks_.push_back(RTLIL::SigChunk(bit.data, width));
2924 else
2925 for (int i = 0; i < width; i++)
2926 chunks_.push_back(bit);
2927 width_ = width;
2928 hash_ = 0;
2929 check();
2930 }
2931
2932 RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks)
2933 {
2934 cover("kernel.rtlil.sigspec.init.stdvec_chunks");
2935
2936 width_ = 0;
2937 hash_ = 0;
2938 for (auto &c : chunks)
2939 append(c);
2940 check();
2941 }
2942
2943 RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
2944 {
2945 cover("kernel.rtlil.sigspec.init.stdvec_bits");
2946
2947 width_ = 0;
2948 hash_ = 0;
2949 for (auto &bit : bits)
2950 append_bit(bit);
2951 check();
2952 }
2953
2954 RTLIL::SigSpec::SigSpec(pool<RTLIL::SigBit> bits)
2955 {
2956 cover("kernel.rtlil.sigspec.init.pool_bits");
2957
2958 width_ = 0;
2959 hash_ = 0;
2960 for (auto &bit : bits)
2961 append_bit(bit);
2962 check();
2963 }
2964
2965 RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
2966 {
2967 cover("kernel.rtlil.sigspec.init.stdset_bits");
2968
2969 width_ = 0;
2970 hash_ = 0;
2971 for (auto &bit : bits)
2972 append_bit(bit);
2973 check();
2974 }
2975
2976 RTLIL::SigSpec::SigSpec(bool bit)
2977 {
2978 cover("kernel.rtlil.sigspec.init.bool");
2979
2980 width_ = 0;
2981 hash_ = 0;
2982 append_bit(bit);
2983 check();
2984 }
2985
2986 void RTLIL::SigSpec::pack() const
2987 {
2988 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
2989
2990 if (that->bits_.empty())
2991 return;
2992
2993 cover("kernel.rtlil.sigspec.convert.pack");
2994 log_assert(that->chunks_.empty());
2995
2996 std::vector<RTLIL::SigBit> old_bits;
2997 old_bits.swap(that->bits_);
2998
2999 RTLIL::SigChunk *last = NULL;
3000 int last_end_offset = 0;
3001
3002 for (auto &bit : old_bits) {
3003 if (last && bit.wire == last->wire) {
3004 if (bit.wire == NULL) {
3005 last->data.push_back(bit.data);
3006 last->width++;
3007 continue;
3008 } else if (last_end_offset == bit.offset) {
3009 last_end_offset++;
3010 last->width++;
3011 continue;
3012 }
3013 }
3014 that->chunks_.push_back(bit);
3015 last = &that->chunks_.back();
3016 last_end_offset = bit.offset + 1;
3017 }
3018
3019 check();
3020 }
3021
3022 void RTLIL::SigSpec::unpack() const
3023 {
3024 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
3025
3026 if (that->chunks_.empty())
3027 return;
3028
3029 cover("kernel.rtlil.sigspec.convert.unpack");
3030 log_assert(that->bits_.empty());
3031
3032 that->bits_.reserve(that->width_);
3033 for (auto &c : that->chunks_)
3034 for (int i = 0; i < c.width; i++)
3035 that->bits_.push_back(RTLIL::SigBit(c, i));
3036
3037 that->chunks_.clear();
3038 that->hash_ = 0;
3039 }
3040
3041 void RTLIL::SigSpec::updhash() const
3042 {
3043 RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
3044
3045 if (that->hash_ != 0)
3046 return;
3047
3048 cover("kernel.rtlil.sigspec.hash");
3049 that->pack();
3050
3051 that->hash_ = mkhash_init;
3052 for (auto &c : that->chunks_)
3053 if (c.wire == NULL) {
3054 for (auto &v : c.data)
3055 that->hash_ = mkhash(that->hash_, v);
3056 } else {
3057 that->hash_ = mkhash(that->hash_, c.wire->name.index_);
3058 that->hash_ = mkhash(that->hash_, c.offset);
3059 that->hash_ = mkhash(that->hash_, c.width);
3060 }
3061
3062 if (that->hash_ == 0)
3063 that->hash_ = 1;
3064 }
3065
3066 void RTLIL::SigSpec::sort()
3067 {
3068 unpack();
3069 cover("kernel.rtlil.sigspec.sort");
3070 std::sort(bits_.begin(), bits_.end());
3071 }
3072
3073 void RTLIL::SigSpec::sort_and_unify()
3074 {
3075 unpack();
3076 cover("kernel.rtlil.sigspec.sort_and_unify");
3077
3078 // A copy of the bits vector is used to prevent duplicating the logic from
3079 // SigSpec::SigSpec(std::vector<SigBit>). This incurrs an extra copy but
3080 // that isn't showing up as significant in profiles.
3081 std::vector<SigBit> unique_bits = bits_;
3082 std::sort(unique_bits.begin(), unique_bits.end());
3083 auto last = std::unique(unique_bits.begin(), unique_bits.end());
3084 unique_bits.erase(last, unique_bits.end());
3085
3086 *this = unique_bits;
3087 }
3088
3089 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
3090 {
3091 replace(pattern, with, this);
3092 }
3093
3094 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const
3095 {
3096 log_assert(other != NULL);
3097 log_assert(width_ == other->width_);
3098 log_assert(pattern.width_ == with.width_);
3099
3100 pattern.unpack();
3101 with.unpack();
3102 unpack();
3103 other->unpack();
3104
3105 for (int i = 0; i < GetSize(pattern.bits_); i++) {
3106 if (pattern.bits_[i].wire != NULL) {
3107 for (int j = 0; j < GetSize(bits_); j++) {
3108 if (bits_[j] == pattern.bits_[i]) {
3109 other->bits_[j] = with.bits_[i];
3110 }
3111 }
3112 }
3113 }
3114
3115 other->check();
3116 }
3117
3118 void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules)
3119 {
3120 replace(rules, this);
3121 }
3122
3123 void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const
3124 {
3125 cover("kernel.rtlil.sigspec.replace_dict");
3126
3127 log_assert(other != NULL);
3128 log_assert(width_ == other->width_);
3129
3130 if (rules.empty()) return;
3131 unpack();
3132 other->unpack();
3133
3134 for (int i = 0; i < GetSize(bits_); i++) {
3135 auto it = rules.find(bits_[i]);
3136 if (it != rules.end())
3137 other->bits_[i] = it->second;
3138 }
3139
3140 other->check();
3141 }
3142
3143 void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules)
3144 {
3145 replace(rules, this);
3146 }
3147
3148 void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const
3149 {
3150 cover("kernel.rtlil.sigspec.replace_map");
3151
3152 log_assert(other != NULL);
3153 log_assert(width_ == other->width_);
3154
3155 if (rules.empty()) return;
3156 unpack();
3157 other->unpack();
3158
3159 for (int i = 0; i < GetSize(bits_); i++) {
3160 auto it = rules.find(bits_[i]);
3161 if (it != rules.end())
3162 other->bits_[i] = it->second;
3163 }
3164
3165 other->check();
3166 }
3167
3168 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern)
3169 {
3170 remove2(pattern, NULL);
3171 }
3172
3173 void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const
3174 {
3175 RTLIL::SigSpec tmp = *this;
3176 tmp.remove2(pattern, other);
3177 }
3178
3179 void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
3180 {
3181 if (other)
3182 cover("kernel.rtlil.sigspec.remove_other");
3183 else
3184 cover("kernel.rtlil.sigspec.remove");
3185
3186 unpack();
3187 if (other != NULL) {
3188 log_assert(width_ == other->width_);
3189 other->unpack();
3190 }
3191
3192 for (int i = GetSize(bits_) - 1; i >= 0; i--)
3193 {
3194 if (bits_[i].wire == NULL) continue;
3195
3196 for (auto &pattern_chunk : pattern.chunks())
3197 if (bits_[i].wire == pattern_chunk.wire &&
3198 bits_[i].offset >= pattern_chunk.offset &&
3199 bits_[i].offset < pattern_chunk.offset + pattern_chunk.width) {
3200 bits_.erase(bits_.begin() + i);
3201 width_--;
3202 if (other != NULL) {
3203 other->bits_.erase(other->bits_.begin() + i);
3204 other->width_--;
3205 }
3206 break;
3207 }
3208 }
3209
3210 check();
3211 }
3212
3213 void RTLIL::SigSpec::remove(const pool<RTLIL::SigBit> &pattern)
3214 {
3215 remove2(pattern, NULL);
3216 }
3217
3218 void RTLIL::SigSpec::remove(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const
3219 {
3220 RTLIL::SigSpec tmp = *this;
3221 tmp.remove2(pattern, other);
3222 }
3223
3224 void RTLIL::SigSpec::remove2(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other)
3225 {
3226 if (other)
3227 cover("kernel.rtlil.sigspec.remove_other");
3228 else
3229 cover("kernel.rtlil.sigspec.remove");
3230
3231 unpack();
3232
3233 if (other != NULL) {
3234 log_assert(width_ == other->width_);
3235 other->unpack();
3236 }
3237
3238 for (int i = GetSize(bits_) - 1; i >= 0; i--) {
3239 if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
3240 bits_.erase(bits_.begin() + i);
3241 width_--;
3242 if (other != NULL) {
3243 other->bits_.erase(other->bits_.begin() + i);
3244 other->width_--;
3245 }
3246 }
3247 }
3248
3249 check();
3250 }
3251
3252 void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other)
3253 {
3254 if (other)
3255 cover("kernel.rtlil.sigspec.remove_other");
3256 else
3257 cover("kernel.rtlil.sigspec.remove");
3258
3259 unpack();
3260
3261 if (other != NULL) {
3262 log_assert(width_ == other->width_);
3263 other->unpack();
3264 }
3265
3266 for (int i = GetSize(bits_) - 1; i >= 0; i--) {
3267 if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
3268 bits_.erase(bits_.begin() + i);
3269 width_--;
3270 if (other != NULL) {
3271 other->bits_.erase(other->bits_.begin() + i);
3272 other->width_--;
3273 }
3274 }
3275 }
3276
3277 check();
3278 }
3279
3280 RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const
3281 {
3282 if (other)
3283 cover("kernel.rtlil.sigspec.extract_other");
3284 else
3285 cover("kernel.rtlil.sigspec.extract");
3286
3287 log_assert(other == NULL || width_ == other->width_);
3288
3289 RTLIL::SigSpec ret;
3290 std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
3291
3292 for (auto& pattern_chunk : pattern.chunks()) {
3293 if (other) {
3294 std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector();
3295 for (int i = 0; i < width_; i++)
3296 if (bits_match[i].wire &&
3297 bits_match[i].wire == pattern_chunk.wire &&
3298 bits_match[i].offset >= pattern_chunk.offset &&
3299 bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width)
3300 ret.append_bit(bits_other[i]);
3301 } else {
3302 for (int i = 0; i < width_; i++)
3303 if (bits_match[i].wire &&
3304 bits_match[i].wire == pattern_chunk.wire &&
3305 bits_match[i].offset >= pattern_chunk.offset &&
3306 bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width)
3307 ret.append_bit(bits_match[i]);
3308 }
3309 }
3310
3311 ret.check();
3312 return ret;
3313 }
3314
3315 RTLIL::SigSpec RTLIL::SigSpec::extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other) const
3316 {
3317 if (other)
3318 cover("kernel.rtlil.sigspec.extract_other");
3319 else
3320 cover("kernel.rtlil.sigspec.extract");
3321
3322 log_assert(other == NULL || width_ == other->width_);
3323
3324 std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
3325 RTLIL::SigSpec ret;
3326
3327 if (other) {
3328 std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector();
3329 for (int i = 0; i < width_; i++)
3330 if (bits_match[i].wire && pattern.count(bits_match[i]))
3331 ret.append_bit(bits_other[i]);
3332 } else {
3333 for (int i = 0; i < width_; i++)
3334 if (bits_match[i].wire && pattern.count(bits_match[i]))
3335 ret.append_bit(bits_match[i]);
3336 }
3337
3338 ret.check();
3339 return ret;
3340 }
3341
3342 void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
3343 {
3344 cover("kernel.rtlil.sigspec.replace_pos");
3345
3346 unpack();
3347 with.unpack();
3348
3349 log_assert(offset >= 0);
3350 log_assert(with.width_ >= 0);
3351 log_assert(offset+with.width_ <= width_);
3352
3353 for (int i = 0; i < with.width_; i++)
3354 bits_.at(offset + i) = with.bits_.at(i);
3355
3356 check();
3357 }
3358
3359 void RTLIL::SigSpec::remove_const()
3360 {
3361 if (packed())
3362 {
3363 cover("kernel.rtlil.sigspec.remove_const.packed");
3364
3365 std::vector<RTLIL::SigChunk> new_chunks;
3366 new_chunks.reserve(GetSize(chunks_));
3367
3368 width_ = 0;
3369 for (auto &chunk : chunks_)
3370 if (chunk.wire != NULL) {
3371 new_chunks.push_back(chunk);
3372 width_ += chunk.width;
3373 }
3374
3375 chunks_.swap(new_chunks);
3376 }
3377 else
3378 {
3379 cover("kernel.rtlil.sigspec.remove_const.unpacked");
3380
3381 std::vector<RTLIL::SigBit> new_bits;
3382 new_bits.reserve(width_);
3383
3384 for (auto &bit : bits_)
3385 if (bit.wire != NULL)
3386 new_bits.push_back(bit);
3387
3388 bits_.swap(new_bits);
3389 width_ = bits_.size();
3390 }
3391
3392 check();
3393 }
3394
3395 void RTLIL::SigSpec::remove(int offset, int length)
3396 {
3397 cover("kernel.rtlil.sigspec.remove_pos");
3398
3399 unpack();
3400
3401 log_assert(offset >= 0);
3402 log_assert(length >= 0);
3403 log_assert(offset + length <= width_);
3404
3405 bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length);
3406 width_ = bits_.size();
3407
3408 check();
3409 }
3410
3411 RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
3412 {
3413 unpack();
3414 cover("kernel.rtlil.sigspec.extract_pos");
3415 return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
3416 }
3417
3418 void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
3419 {
3420 if (signal.width_ == 0)
3421 return;
3422
3423 if (width_ == 0) {
3424 *this = signal;
3425 return;
3426 }
3427
3428 cover("kernel.rtlil.sigspec.append");
3429
3430 if (packed() != signal.packed()) {
3431 pack();
3432 signal.pack();
3433 }
3434
3435 if (packed())
3436 for (auto &other_c : signal.chunks_)
3437 {
3438 auto &my_last_c = chunks_.back();
3439 if (my_last_c.wire == NULL && other_c.wire == NULL) {
3440 auto &this_data = my_last_c.data;
3441 auto &other_data = other_c.data;
3442 this_data.insert(this_data.end(), other_data.begin(), other_data.end());
3443 my_last_c.width += other_c.width;
3444 } else
3445 if (my_last_c.wire == other_c.wire && my_last_c.offset + my_last_c.width == other_c.offset) {
3446 my_last_c.width += other_c.width;
3447 } else
3448 chunks_.push_back(other_c);
3449 }
3450 else
3451 bits_.insert(bits_.end(), signal.bits_.begin(), signal.bits_.end());
3452
3453 width_ += signal.width_;
3454 check();
3455 }
3456
3457 void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
3458 {
3459 if (packed())
3460 {
3461 cover("kernel.rtlil.sigspec.append_bit.packed");
3462
3463 if (chunks_.size() == 0)
3464 chunks_.push_back(bit);
3465 else
3466 if (bit.wire == NULL)
3467 if (chunks_.back().wire == NULL) {
3468 chunks_.back().data.push_back(bit.data);
3469 chunks_.back().width++;
3470 } else
3471 chunks_.push_back(bit);
3472 else
3473 if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset)
3474 chunks_.back().width++;
3475 else
3476 chunks_.push_back(bit);
3477 }
3478 else
3479 {
3480 cover("kernel.rtlil.sigspec.append_bit.unpacked");
3481 bits_.push_back(bit);
3482 }
3483
3484 width_++;
3485 check();
3486 }
3487
3488 void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
3489 {
3490 cover("kernel.rtlil.sigspec.extend_u0");
3491
3492 pack();
3493
3494 if (width_ > width)
3495 remove(width, width_ - width);
3496
3497 if (width_ < width) {
3498 RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::Sx;
3499 if (!is_signed)
3500 padding = RTLIL::State::S0;
3501 while (width_ < width)
3502 append(padding);
3503 }
3504
3505 }
3506
3507 RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const
3508 {
3509 cover("kernel.rtlil.sigspec.repeat");
3510
3511 RTLIL::SigSpec sig;
3512 for (int i = 0; i < num; i++)
3513 sig.append(*this);
3514 return sig;
3515 }
3516
3517 #ifndef NDEBUG
3518 void RTLIL::SigSpec::check() const
3519 {
3520 if (width_ > 64)
3521 {
3522 cover("kernel.rtlil.sigspec.check.skip");
3523 }
3524 else if (packed())
3525 {
3526 cover("kernel.rtlil.sigspec.check.packed");
3527
3528 int w = 0;
3529 for (size_t i = 0; i < chunks_.size(); i++) {
3530 const RTLIL::SigChunk chunk = chunks_[i];
3531 if (chunk.wire == NULL) {
3532 if (i > 0)
3533 log_assert(chunks_[i-1].wire != NULL);
3534 log_assert(chunk.offset == 0);
3535 log_assert(chunk.data.size() == (size_t)chunk.width);
3536 } else {
3537 if (i > 0 && chunks_[i-1].wire == chunk.wire)
3538 log_assert(chunk.offset != chunks_[i-1].offset + chunks_[i-1].width);
3539 log_assert(chunk.offset >= 0);
3540 log_assert(chunk.width >= 0);
3541 log_assert(chunk.offset + chunk.width <= chunk.wire->width);
3542 log_assert(chunk.data.size() == 0);
3543 }
3544 w += chunk.width;
3545 }
3546 log_assert(w == width_);
3547 log_assert(bits_.empty());
3548 }
3549 else
3550 {
3551 cover("kernel.rtlil.sigspec.check.unpacked");
3552
3553 log_assert(width_ == GetSize(bits_));
3554 log_assert(chunks_.empty());
3555 }
3556 }
3557 #endif
3558
3559 bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
3560 {
3561 cover("kernel.rtlil.sigspec.comp_lt");
3562
3563 if (this == &other)
3564 return false;
3565
3566 if (width_ != other.width_)
3567 return width_ < other.width_;
3568
3569 pack();
3570 other.pack();
3571
3572 if (chunks_.size() != other.chunks_.size())
3573 return chunks_.size() < other.chunks_.size();
3574
3575 updhash();
3576 other.updhash();
3577
3578 if (hash_ != other.hash_)
3579 return hash_ < other.hash_;
3580
3581 for (size_t i = 0; i < chunks_.size(); i++)
3582 if (chunks_[i] != other.chunks_[i]) {
3583 cover("kernel.rtlil.sigspec.comp_lt.hash_collision");
3584 return chunks_[i] < other.chunks_[i];
3585 }
3586
3587 cover("kernel.rtlil.sigspec.comp_lt.equal");
3588 return false;
3589 }
3590
3591 bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
3592 {
3593 cover("kernel.rtlil.sigspec.comp_eq");
3594
3595 if (this == &other)
3596 return true;
3597
3598 if (width_ != other.width_)
3599 return false;
3600
3601 // Without this, SigSpec() == SigSpec(State::S0, 0) will fail
3602 // since the RHS will contain one SigChunk of width 0 causing
3603 // the size check below to fail
3604 if (width_ == 0)
3605 return true;
3606
3607 pack();
3608 other.pack();
3609
3610 if (chunks_.size() != other.chunks_.size())
3611 return false;
3612
3613 updhash();
3614 other.updhash();
3615
3616 if (hash_ != other.hash_)
3617 return false;
3618
3619 for (size_t i = 0; i < chunks_.size(); i++)
3620 if (chunks_[i] != other.chunks_[i]) {
3621 cover("kernel.rtlil.sigspec.comp_eq.hash_collision");
3622 return false;
3623 }
3624
3625 cover("kernel.rtlil.sigspec.comp_eq.equal");
3626 return true;
3627 }
3628
3629 bool RTLIL::SigSpec::is_wire() const
3630 {
3631 cover("kernel.rtlil.sigspec.is_wire");
3632
3633 pack();
3634 return GetSize(chunks_) == 1 && chunks_[0].wire && chunks_[0].wire->width == width_;
3635 }
3636
3637 bool RTLIL::SigSpec::is_chunk() const
3638 {
3639 cover("kernel.rtlil.sigspec.is_chunk");
3640
3641 pack();
3642 return GetSize(chunks_) == 1;
3643 }
3644
3645 bool RTLIL::SigSpec::is_fully_const() const
3646 {
3647 cover("kernel.rtlil.sigspec.is_fully_const");
3648
3649 pack();
3650 for (auto it = chunks_.begin(); it != chunks_.end(); it++)
3651 if (it->width > 0 && it->wire != NULL)
3652 return false;
3653 return true;
3654 }
3655
3656 bool RTLIL::SigSpec::is_fully_zero() const
3657 {
3658 cover("kernel.rtlil.sigspec.is_fully_zero");
3659
3660 pack();
3661 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
3662 if (it->width > 0 && it->wire != NULL)
3663 return false;
3664 for (size_t i = 0; i < it->data.size(); i++)
3665 if (it->data[i] != RTLIL::State::S0)
3666 return false;
3667 }
3668 return true;
3669 }
3670
3671 bool RTLIL::SigSpec::is_fully_ones() const
3672 {
3673 cover("kernel.rtlil.sigspec.is_fully_ones");
3674
3675 pack();
3676 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
3677 if (it->width > 0 && it->wire != NULL)
3678 return false;
3679 for (size_t i = 0; i < it->data.size(); i++)
3680 if (it->data[i] != RTLIL::State::S1)
3681 return false;
3682 }
3683 return true;
3684 }
3685
3686 bool RTLIL::SigSpec::is_fully_def() const
3687 {
3688 cover("kernel.rtlil.sigspec.is_fully_def");
3689
3690 pack();
3691 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
3692 if (it->width > 0 && it->wire != NULL)
3693 return false;
3694 for (size_t i = 0; i < it->data.size(); i++)
3695 if (it->data[i] != RTLIL::State::S0 && it->data[i] != RTLIL::State::S1)
3696 return false;
3697 }
3698 return true;
3699 }
3700
3701 bool RTLIL::SigSpec::is_fully_undef() const
3702 {
3703 cover("kernel.rtlil.sigspec.is_fully_undef");
3704
3705 pack();
3706 for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
3707 if (it->width > 0 && it->wire != NULL)
3708 return false;
3709 for (size_t i = 0; i < it->data.size(); i++)
3710 if (it->data[i] != RTLIL::State::Sx && it->data[i] != RTLIL::State::Sz)
3711 return false;
3712 }
3713 return true;
3714 }
3715
3716 bool RTLIL::SigSpec::has_const() const
3717 {
3718 cover("kernel.rtlil.sigspec.has_const");
3719
3720 pack();
3721 for (auto it = chunks_.begin(); it != chunks_.end(); it++)
3722 if (it->width > 0 && it->wire == NULL)
3723 return true;
3724 return false;
3725 }
3726
3727 bool RTLIL::SigSpec::has_marked_bits() const
3728 {
3729 cover("kernel.rtlil.sigspec.has_marked_bits");
3730
3731 pack();
3732 for (auto it = chunks_.begin(); it != chunks_.end(); it++)
3733 if (it->width > 0 && it->wire == NULL) {
3734 for (size_t i = 0; i < it->data.size(); i++)
3735 if (it->data[i] == RTLIL::State::Sm)
3736 return true;
3737 }
3738 return false;
3739 }
3740
3741 bool RTLIL::SigSpec::as_bool() const
3742 {
3743 cover("kernel.rtlil.sigspec.as_bool");
3744
3745 pack();
3746 log_assert(is_fully_const() && GetSize(chunks_) <= 1);
3747 if (width_)
3748 return RTLIL::Const(chunks_[0].data).as_bool();
3749 return false;
3750 }
3751
3752 int RTLIL::SigSpec::as_int(bool is_signed) const
3753 {
3754 cover("kernel.rtlil.sigspec.as_int");
3755
3756 pack();
3757 log_assert(is_fully_const() && GetSize(chunks_) <= 1);
3758 if (width_)
3759 return RTLIL::Const(chunks_[0].data).as_int(is_signed);
3760 return 0;
3761 }
3762
3763 std::string RTLIL::SigSpec::as_string() const
3764 {
3765 cover("kernel.rtlil.sigspec.as_string");
3766
3767 pack();
3768 std::string str;
3769 for (size_t i = chunks_.size(); i > 0; i--) {
3770 const RTLIL::SigChunk &chunk = chunks_[i-1];
3771 if (chunk.wire != NULL)
3772 for (int j = 0; j < chunk.width; j++)
3773 str += "?";
3774 else
3775 str += RTLIL::Const(chunk.data).as_string();
3776 }
3777 return str;
3778 }
3779
3780 RTLIL::Const RTLIL::SigSpec::as_const() const
3781 {
3782 cover("kernel.rtlil.sigspec.as_const");
3783
3784 pack();
3785 log_assert(is_fully_const() && GetSize(chunks_) <= 1);
3786 if (width_)
3787 return chunks_[0].data;
3788 return RTLIL::Const();
3789 }
3790
3791 RTLIL::Wire *RTLIL::SigSpec::as_wire() const
3792 {
3793 cover("kernel.rtlil.sigspec.as_wire");
3794
3795 pack();
3796 log_assert(is_wire());
3797 return chunks_[0].wire;
3798 }
3799
3800 RTLIL::SigChunk RTLIL::SigSpec::as_chunk() const
3801 {
3802 cover("kernel.rtlil.sigspec.as_chunk");
3803
3804 pack();
3805 log_assert(is_chunk());
3806 return chunks_[0];
3807 }
3808
3809 RTLIL::SigBit RTLIL::SigSpec::as_bit() const
3810 {
3811 cover("kernel.rtlil.sigspec.as_bit");
3812
3813 log_assert(width_ == 1);
3814 if (packed())
3815 return RTLIL::SigBit(*chunks_.begin());
3816 else
3817 return bits_[0];
3818 }
3819
3820 bool RTLIL::SigSpec::match(std::string pattern) const
3821 {
3822 cover("kernel.rtlil.sigspec.match");
3823
3824 pack();
3825 std::string str = as_string();
3826 log_assert(pattern.size() == str.size());
3827
3828 for (size_t i = 0; i < pattern.size(); i++) {
3829 if (pattern[i] == ' ')
3830 continue;
3831 if (pattern[i] == '*') {
3832 if (str[i] != 'z' && str[i] != 'x')
3833 return false;
3834 continue;
3835 }
3836 if (pattern[i] != str[i])
3837 return false;
3838 }
3839
3840 return true;
3841 }
3842
3843 std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const
3844 {
3845 cover("kernel.rtlil.sigspec.to_sigbit_set");
3846
3847 pack();
3848 std::set<RTLIL::SigBit> sigbits;
3849 for (auto &c : chunks_)
3850 for (int i = 0; i < c.width; i++)
3851 sigbits.insert(RTLIL::SigBit(c, i));
3852 return sigbits;
3853 }
3854
3855 pool<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_pool() const
3856 {
3857 cover("kernel.rtlil.sigspec.to_sigbit_pool");
3858
3859 pack();
3860 pool<RTLIL::SigBit> sigbits;
3861 for (auto &c : chunks_)
3862 for (int i = 0; i < c.width; i++)
3863 sigbits.insert(RTLIL::SigBit(c, i));
3864 return sigbits;
3865 }
3866
3867 std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
3868 {
3869 cover("kernel.rtlil.sigspec.to_sigbit_vector");
3870
3871 unpack();
3872 return bits_;
3873 }
3874
3875 std::map<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_map(const RTLIL::SigSpec &other) const
3876 {
3877 cover("kernel.rtlil.sigspec.to_sigbit_map");
3878
3879 unpack();
3880 other.unpack();
3881
3882 log_assert(width_ == other.width_);
3883
3884 std::map<RTLIL::SigBit, RTLIL::SigBit> new_map;
3885 for (int i = 0; i < width_; i++)
3886 new_map[bits_[i]] = other.bits_[i];
3887
3888 return new_map;
3889 }
3890
3891 dict<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_dict(const RTLIL::SigSpec &other) const
3892 {
3893 cover("kernel.rtlil.sigspec.to_sigbit_dict");
3894
3895 unpack();
3896 other.unpack();
3897
3898 log_assert(width_ == other.width_);
3899
3900 dict<RTLIL::SigBit, RTLIL::SigBit> new_map;
3901 for (int i = 0; i < width_; i++)
3902 new_map[bits_[i]] = other.bits_[i];
3903
3904 return new_map;
3905 }
3906
3907 static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep)
3908 {
3909 size_t start = 0, end = 0;
3910 while ((end = text.find(sep, start)) != std::string::npos) {
3911 tokens.push_back(text.substr(start, end - start));
3912 start = end + 1;
3913 }
3914 tokens.push_back(text.substr(start));
3915 }
3916
3917 static int sigspec_parse_get_dummy_line_num()
3918 {
3919 return 0;
3920 }
3921
3922 bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
3923 {
3924 cover("kernel.rtlil.sigspec.parse");
3925
3926 AST::current_filename = "input";
3927 AST::use_internal_line_num();
3928 AST::set_line_num(0);
3929
3930 std::vector<std::string> tokens;
3931 sigspec_parse_split(tokens, str, ',');
3932
3933 sig = RTLIL::SigSpec();
3934 for (int tokidx = int(tokens.size())-1; tokidx >= 0; tokidx--)
3935 {
3936 std::string netname = tokens[tokidx];
3937 std::string indices;
3938
3939 if (netname.size() == 0)
3940 continue;
3941
3942 if (('0' <= netname[0] && netname[0] <= '9') || netname[0] == '\'') {
3943 cover("kernel.rtlil.sigspec.parse.const");
3944 AST::get_line_num = sigspec_parse_get_dummy_line_num;
3945 AST::AstNode *ast = VERILOG_FRONTEND::const2ast(netname);
3946 if (ast == NULL)
3947 return false;
3948 sig.append(RTLIL::Const(ast->bits));
3949 delete ast;
3950 continue;
3951 }
3952
3953 if (module == NULL)
3954 return false;
3955
3956 cover("kernel.rtlil.sigspec.parse.net");
3957
3958 if (netname[0] != '$' && netname[0] != '\\')
3959 netname = "\\" + netname;
3960
3961 if (module->wires_.count(netname) == 0) {
3962 size_t indices_pos = netname.size()-1;
3963 if (indices_pos > 2 && netname[indices_pos] == ']')
3964 {
3965 indices_pos--;
3966 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
3967 if (indices_pos > 0 && netname[indices_pos] == ':') {
3968 indices_pos--;
3969 while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--;
3970 }
3971 if (indices_pos > 0 && netname[indices_pos] == '[') {
3972 indices = netname.substr(indices_pos);
3973 netname = netname.substr(0, indices_pos);
3974 }
3975 }
3976 }
3977
3978 if (module->wires_.count(netname) == 0)
3979 return false;
3980
3981 RTLIL::Wire *wire = module->wires_.at(netname);
3982 if (!indices.empty()) {
3983 std::vector<std::string> index_tokens;
3984 sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':');
3985 if (index_tokens.size() == 1) {
3986 cover("kernel.rtlil.sigspec.parse.bit_sel");
3987 int a = atoi(index_tokens.at(0).c_str());
3988 if (a < 0 || a >= wire->width)
3989 return false;
3990 sig.append(RTLIL::SigSpec(wire, a));
3991 } else {
3992 cover("kernel.rtlil.sigspec.parse.part_sel");
3993 int a = atoi(index_tokens.at(0).c_str());
3994 int b = atoi(index_tokens.at(1).c_str());
3995 if (a > b) {
3996 int tmp = a;
3997 a = b, b = tmp;
3998 }
3999 if (a < 0 || a >= wire->width)
4000 return false;
4001 if (b < 0 || b >= wire->width)
4002 return false;
4003 sig.append(RTLIL::SigSpec(wire, a, b-a+1));
4004 }
4005 } else
4006 sig.append(wire);
4007 }
4008
4009 return true;
4010 }
4011
4012 bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str)
4013 {
4014 if (str.empty() || str[0] != '@')
4015 return parse(sig, module, str);
4016
4017 cover("kernel.rtlil.sigspec.parse.sel");
4018
4019 str = RTLIL::escape_id(str.substr(1));
4020 if (design->selection_vars.count(str) == 0)
4021 return false;
4022
4023 sig = RTLIL::SigSpec();
4024 RTLIL::Selection &sel = design->selection_vars.at(str);
4025 for (auto &it : module->wires_)
4026 if (sel.selected_member(module->name, it.first))
4027 sig.append(it.second);
4028
4029 return true;
4030 }
4031
4032 bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
4033 {
4034 if (str == "0") {
4035 cover("kernel.rtlil.sigspec.parse.rhs_zeros");
4036 sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.width_);
4037 return true;
4038 }
4039
4040 if (str == "~0") {
4041 cover("kernel.rtlil.sigspec.parse.rhs_ones");
4042 sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.width_);
4043 return true;
4044 }
4045
4046 if (lhs.chunks_.size() == 1) {
4047 char *p = (char*)str.c_str(), *endptr;
4048 long int val = strtol(p, &endptr, 10);
4049 if (endptr && endptr != p && *endptr == 0) {
4050 sig = RTLIL::SigSpec(val, lhs.width_);
4051 cover("kernel.rtlil.sigspec.parse.rhs_dec");
4052 return true;
4053 }
4054 }
4055
4056 return parse(sig, module, str);
4057 }
4058
4059 RTLIL::CaseRule::~CaseRule()
4060 {
4061 for (auto it = switches.begin(); it != switches.end(); it++)
4062 delete *it;
4063 }
4064
4065 bool RTLIL::CaseRule::empty() const
4066 {
4067 return actions.empty() && switches.empty();
4068 }
4069
4070 RTLIL::CaseRule *RTLIL::CaseRule::clone() const
4071 {
4072 RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
4073 new_caserule->compare = compare;
4074 new_caserule->actions = actions;
4075 for (auto &it : switches)
4076 new_caserule->switches.push_back(it->clone());
4077 return new_caserule;
4078 }
4079
4080 RTLIL::SwitchRule::~SwitchRule()
4081 {
4082 for (auto it = cases.begin(); it != cases.end(); it++)
4083 delete *it;
4084 }
4085
4086 bool RTLIL::SwitchRule::empty() const
4087 {
4088 return cases.empty();
4089 }
4090
4091 RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
4092 {
4093 RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
4094 new_switchrule->signal = signal;
4095 new_switchrule->attributes = attributes;
4096 for (auto &it : cases)
4097 new_switchrule->cases.push_back(it->clone());
4098 return new_switchrule;
4099
4100 }
4101
4102 RTLIL::SyncRule *RTLIL::SyncRule::clone() const
4103 {
4104 RTLIL::SyncRule *new_syncrule = new RTLIL::SyncRule;
4105 new_syncrule->type = type;
4106 new_syncrule->signal = signal;
4107 new_syncrule->actions = actions;
4108 return new_syncrule;
4109 }
4110
4111 RTLIL::Process::~Process()
4112 {
4113 for (auto it = syncs.begin(); it != syncs.end(); it++)
4114 delete *it;
4115 }
4116
4117 RTLIL::Process *RTLIL::Process::clone() const
4118 {
4119 RTLIL::Process *new_proc = new RTLIL::Process;
4120
4121 new_proc->name = name;
4122 new_proc->attributes = attributes;
4123
4124 RTLIL::CaseRule *rc_ptr = root_case.clone();
4125 new_proc->root_case = *rc_ptr;
4126 rc_ptr->switches.clear();
4127 delete rc_ptr;
4128
4129 for (auto &it : syncs)
4130 new_proc->syncs.push_back(it->clone());
4131
4132 return new_proc;
4133 }
4134
4135 #ifdef WITH_PYTHON
4136 RTLIL::Memory::~Memory()
4137 {
4138 RTLIL::Memory::get_all_memorys()->erase(hashidx_);
4139 }
4140 static std::map<unsigned int, RTLIL::Memory*> all_memorys;
4141 std::map<unsigned int, RTLIL::Memory*> *RTLIL::Memory::get_all_memorys(void)
4142 {
4143 return &all_memorys;
4144 }
4145 #endif
4146 YOSYS_NAMESPACE_END