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