2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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.
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.
20 #include "kernel/rtlil.h"
21 #include "kernel/log.h"
22 #include "frontends/verilog/verilog_frontend.h"
23 #include "backends/ilang/ilang_backend.h"
29 int RTLIL::autoidx
= 1;
33 flags
= RTLIL::CONST_FLAG_NONE
;
36 RTLIL::Const::Const(std::string str
)
38 flags
= RTLIL::CONST_FLAG_STRING
;
39 for (int i
= str
.size()-1; i
>= 0; i
--) {
40 unsigned char ch
= str
[i
];
41 for (int j
= 0; j
< 8; j
++) {
42 bits
.push_back((ch
& 1) != 0 ? RTLIL::S1
: RTLIL::S0
);
48 RTLIL::Const::Const(int val
, int width
)
50 flags
= RTLIL::CONST_FLAG_NONE
;
51 for (int i
= 0; i
< width
; i
++) {
52 bits
.push_back((val
& 1) != 0 ? RTLIL::S1
: RTLIL::S0
);
57 RTLIL::Const::Const(RTLIL::State bit
, int width
)
59 flags
= RTLIL::CONST_FLAG_NONE
;
60 for (int i
= 0; i
< width
; i
++)
64 bool RTLIL::Const::operator <(const RTLIL::Const
&other
) const
66 if (bits
.size() != other
.bits
.size())
67 return bits
.size() < other
.bits
.size();
68 for (size_t i
= 0; i
< bits
.size(); i
++)
69 if (bits
[i
] != other
.bits
[i
])
70 return bits
[i
] < other
.bits
[i
];
74 bool RTLIL::Const::operator ==(const RTLIL::Const
&other
) const
76 return bits
== other
.bits
;
79 bool RTLIL::Const::operator !=(const RTLIL::Const
&other
) const
81 return bits
!= other
.bits
;
84 bool RTLIL::Const::as_bool() const
86 for (size_t i
= 0; i
< bits
.size(); i
++)
87 if (bits
[i
] == RTLIL::S1
)
92 int RTLIL::Const::as_int() const
95 for (size_t i
= 0; i
< bits
.size() && i
< 32; i
++)
96 if (bits
[i
] == RTLIL::S1
)
101 std::string
RTLIL::Const::as_string() const
104 for (size_t i
= bits
.size(); i
> 0; i
--)
106 case S0
: ret
+= "0"; break;
107 case S1
: ret
+= "1"; break;
108 case Sx
: ret
+= "x"; break;
109 case Sz
: ret
+= "z"; break;
110 case Sa
: ret
+= "-"; break;
111 case Sm
: ret
+= "m"; break;
116 std::string
RTLIL::Const::decode_string() const
119 std::vector
<char> string_chars
;
120 for (int i
= 0; i
< int (bits
.size()); i
+= 8) {
122 for (int j
= 0; j
< 8 && i
+ j
< int (bits
.size()); j
++)
123 if (bits
[i
+ j
] == RTLIL::State::S1
)
126 string_chars
.push_back(ch
);
128 for (int i
= int (string_chars
.size()) - 1; i
>= 0; i
--)
129 string
+= string_chars
[i
];
133 bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name
) const
137 if (selected_modules
.count(mod_name
) > 0)
139 if (selected_members
.count(mod_name
) > 0)
144 bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name
) const
148 if (selected_modules
.count(mod_name
) > 0)
153 bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name
, RTLIL::IdString memb_name
) const
157 if (selected_modules
.count(mod_name
) > 0)
159 if (selected_members
.count(mod_name
) > 0)
160 if (selected_members
.at(mod_name
).count(memb_name
) > 0)
165 void RTLIL::Selection::optimize(RTLIL::Design
*design
)
167 if (full_selection
) {
168 selected_modules
.clear();
169 selected_members
.clear();
173 std::vector
<RTLIL::IdString
> del_list
, add_list
;
176 for (auto mod_name
: selected_modules
) {
177 if (design
->modules
.count(mod_name
) == 0)
178 del_list
.push_back(mod_name
);
179 selected_members
.erase(mod_name
);
181 for (auto mod_name
: del_list
)
182 selected_modules
.erase(mod_name
);
185 for (auto &it
: selected_members
)
186 if (design
->modules
.count(it
.first
) == 0)
187 del_list
.push_back(it
.first
);
188 for (auto mod_name
: del_list
)
189 selected_members
.erase(mod_name
);
191 for (auto &it
: selected_members
) {
193 for (auto memb_name
: it
.second
)
194 if (design
->modules
[it
.first
]->count_id(memb_name
) == 0)
195 del_list
.push_back(memb_name
);
196 for (auto memb_name
: del_list
)
197 it
.second
.erase(memb_name
);
202 for (auto &it
: selected_members
)
203 if (it
.second
.size() == 0)
204 del_list
.push_back(it
.first
);
205 else if (it
.second
.size() == design
->modules
[it
.first
]->wires
.size() + design
->modules
[it
.first
]->memories
.size() +
206 design
->modules
[it
.first
]->cells
.size() + design
->modules
[it
.first
]->processes
.size())
207 add_list
.push_back(it
.first
);
208 for (auto mod_name
: del_list
)
209 selected_members
.erase(mod_name
);
210 for (auto mod_name
: add_list
) {
211 selected_members
.erase(mod_name
);
212 selected_modules
.insert(mod_name
);
215 if (selected_modules
.size() == design
->modules
.size()) {
216 full_selection
= true;
217 selected_modules
.clear();
218 selected_members
.clear();
222 RTLIL::Design::~Design()
224 for (auto it
= modules
.begin(); it
!= modules
.end(); it
++)
228 void RTLIL::Design::check()
231 for (auto &it
: modules
) {
232 assert(it
.first
== it
.second
->name
);
233 assert(it
.first
.size() > 0 && (it
.first
[0] == '\\' || it
.first
[0] == '$'));
239 void RTLIL::Design::optimize()
241 for (auto &it
: modules
)
242 it
.second
->optimize();
243 for (auto &it
: selection_stack
)
245 for (auto &it
: selection_vars
)
246 it
.second
.optimize(this);
249 bool RTLIL::Design::selected_module(RTLIL::IdString mod_name
) const
251 if (!selected_active_module
.empty() && mod_name
!= selected_active_module
)
253 if (selection_stack
.size() == 0)
255 return selection_stack
.back().selected_module(mod_name
);
258 bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name
) const
260 if (!selected_active_module
.empty() && mod_name
!= selected_active_module
)
262 if (selection_stack
.size() == 0)
264 return selection_stack
.back().selected_whole_module(mod_name
);
267 bool RTLIL::Design::selected_member(RTLIL::IdString mod_name
, RTLIL::IdString memb_name
) const
269 if (!selected_active_module
.empty() && mod_name
!= selected_active_module
)
271 if (selection_stack
.size() == 0)
273 return selection_stack
.back().selected_member(mod_name
, memb_name
);
276 RTLIL::Module::~Module()
278 for (auto it
= wires
.begin(); it
!= wires
.end(); it
++)
280 for (auto it
= memories
.begin(); it
!= memories
.end(); it
++)
282 for (auto it
= cells
.begin(); it
!= cells
.end(); it
++)
284 for (auto it
= processes
.begin(); it
!= processes
.end(); it
++)
288 RTLIL::IdString
RTLIL::Module::derive(RTLIL::Design
*, std::map
<RTLIL::IdString
, RTLIL::Const
>)
290 log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name
));
293 size_t RTLIL::Module::count_id(RTLIL::IdString id
)
295 return wires
.count(id
) + memories
.count(id
) + cells
.count(id
) + processes
.count(id
);
300 struct InternalCellChecker
302 RTLIL::Module
*module
;
304 std::set
<RTLIL::IdString
> expected_params
, expected_ports
;
306 InternalCellChecker(RTLIL::Module
*module
, RTLIL::Cell
*cell
) : module(module
), cell(cell
) { }
308 void error(int linenr
)
313 FILE *f
= open_memstream(&ptr
, &size
);
314 ILANG_BACKEND::dump_cell(f
, " ", cell
);
318 log_error("Found error in internal cell %s.%s (%s) at %s:%d:\n%s",
319 module
->name
.c_str(), cell
->name
.c_str(), cell
->type
.c_str(),
320 __FILE__
, linenr
, ptr
);
323 int param(const char *name
)
325 if (cell
->parameters
.count(name
) == 0)
327 expected_params
.insert(name
);
328 return cell
->parameters
.at(name
).as_int();
331 void port(const char *name
, int width
)
333 if (cell
->connections
.count(name
) == 0)
335 if (cell
->connections
.at(name
).width
!= width
)
337 expected_ports
.insert(name
);
340 void check_expected(bool check_matched_sign
= true)
342 for (auto ¶
: cell
->parameters
)
343 if (expected_params
.count(para
.first
) == 0)
345 for (auto &conn
: cell
->connections
)
346 if (expected_ports
.count(conn
.first
) == 0)
349 if (expected_params
.count("\\A_SIGNED") != 0 && expected_params
.count("\\B_SIGNED") && check_matched_sign
) {
350 bool a_is_signed
= param("\\A_SIGNED") != 0;
351 bool b_is_signed
= param("\\B_SIGNED") != 0;
352 if (a_is_signed
!= b_is_signed
)
357 void check_gate(const char *ports
)
359 if (cell
->parameters
.size() != 0)
362 for (const char *p
= ports
; *p
; p
++) {
363 char portname
[3] = { '\\', *p
, 0 };
364 if (cell
->connections
.count(portname
) == 0)
366 if (cell
->connections
.at(portname
).width
!= 1)
370 for (auto &conn
: cell
->connections
) {
371 if (conn
.first
.size() != 2 || conn
.first
.at(0) != '\\')
373 if (strchr(ports
, conn
.first
.at(1)) == NULL
)
380 if (cell
->type
== "$not" || cell
->type
== "$pos" || cell
->type
== "$bu0" || cell
->type
== "$neg") {
382 port("\\A", param("\\A_WIDTH"));
383 port("\\Y", param("\\Y_WIDTH"));
388 if (cell
->type
== "$and" || cell
->type
== "$or" || cell
->type
== "$xor" || cell
->type
== "$xnor") {
391 port("\\A", param("\\A_WIDTH"));
392 port("\\B", param("\\B_WIDTH"));
393 port("\\Y", param("\\Y_WIDTH"));
398 if (cell
->type
== "$reduce_and" || cell
->type
== "$reduce_or" || cell
->type
== "$reduce_xor" ||
399 cell
->type
== "$reduce_xnor" || cell
->type
== "$reduce_bool") {
401 port("\\A", param("\\A_WIDTH"));
402 port("\\Y", param("\\Y_WIDTH"));
407 if (cell
->type
== "$shl" || cell
->type
== "$shr" || cell
->type
== "$sshl" || cell
->type
== "$sshr") {
410 port("\\A", param("\\A_WIDTH"));
411 port("\\B", param("\\B_WIDTH"));
412 port("\\Y", param("\\Y_WIDTH"));
413 check_expected(false);
417 if (cell
->type
== "$lt" || cell
->type
== "$le" || cell
->type
== "$eq" || cell
->type
== "$ne" ||
418 cell
->type
== "$eqx" || cell
->type
== "$nex" || cell
->type
== "$ge" || cell
->type
== "$gt") {
421 port("\\A", param("\\A_WIDTH"));
422 port("\\B", param("\\B_WIDTH"));
423 port("\\Y", param("\\Y_WIDTH"));
428 if (cell
->type
== "$add" || cell
->type
== "$sub" || cell
->type
== "$mul" || cell
->type
== "$div" ||
429 cell
->type
== "$mod" || cell
->type
== "$pow") {
432 port("\\A", param("\\A_WIDTH"));
433 port("\\B", param("\\B_WIDTH"));
434 port("\\Y", param("\\Y_WIDTH"));
435 check_expected(cell
->type
!= "$pow");
439 if (cell
->type
== "$logic_not") {
441 port("\\A", param("\\A_WIDTH"));
442 port("\\Y", param("\\Y_WIDTH"));
447 if (cell
->type
== "$logic_and" || cell
->type
== "$logic_or") {
450 port("\\A", param("\\A_WIDTH"));
451 port("\\B", param("\\B_WIDTH"));
452 port("\\Y", param("\\Y_WIDTH"));
453 check_expected(false);
457 if (cell
->type
== "$mux") {
458 port("\\A", param("\\WIDTH"));
459 port("\\B", param("\\WIDTH"));
461 port("\\Y", param("\\WIDTH"));
466 if (cell
->type
== "$pmux" || cell
->type
== "$safe_pmux") {
467 port("\\A", param("\\WIDTH"));
468 port("\\B", param("\\WIDTH") * param("\\S_WIDTH"));
469 port("\\S", param("\\S_WIDTH"));
470 port("\\Y", param("\\WIDTH"));
475 if (cell
->type
== "$lut") {
477 port("\\I", param("\\WIDTH"));
483 if (cell
->type
== "$sr") {
484 param("\\SET_POLARITY");
485 param("\\CLR_POLARITY");
486 port("\\SET", param("\\WIDTH"));
487 port("\\CLR", param("\\WIDTH"));
488 port("\\Q", param("\\WIDTH"));
493 if (cell
->type
== "$dff") {
494 param("\\CLK_POLARITY");
496 port("\\D", param("\\WIDTH"));
497 port("\\Q", param("\\WIDTH"));
502 if (cell
->type
== "$dffsr") {
503 param("\\CLK_POLARITY");
504 param("\\SET_POLARITY");
505 param("\\CLR_POLARITY");
507 port("\\SET", param("\\WIDTH"));
508 port("\\CLR", param("\\WIDTH"));
509 port("\\D", param("\\WIDTH"));
510 port("\\Q", param("\\WIDTH"));
515 if (cell
->type
== "$adff") {
516 param("\\CLK_POLARITY");
517 param("\\ARST_POLARITY");
518 param("\\ARST_VALUE");
521 port("\\D", param("\\WIDTH"));
522 port("\\Q", param("\\WIDTH"));
527 if (cell
->type
== "$dlatch") {
528 param("\\EN_POLARITY");
530 port("\\D", param("\\WIDTH"));
531 port("\\Q", param("\\WIDTH"));
536 if (cell
->type
== "$fsm") {
538 param("\\CLK_POLARITY");
539 param("\\ARST_POLARITY");
540 param("\\STATE_BITS");
541 param("\\STATE_NUM");
542 param("\\STATE_NUM_LOG2");
543 param("\\STATE_RST");
544 param("\\STATE_TABLE");
545 param("\\TRANS_NUM");
546 param("\\TRANS_TABLE");
549 port("\\CTRL_IN", param("\\CTRL_IN_WIDTH"));
550 port("\\CTRL_OUT", param("\\CTRL_OUT_WIDTH"));
555 if (cell
->type
== "$memrd") {
557 param("\\CLK_ENABLE");
558 param("\\CLK_POLARITY");
560 port("\\ADDR", param("\\ABITS"));
561 port("\\DATA", param("\\WIDTH"));
566 if (cell
->type
== "$memwr") {
568 param("\\CLK_ENABLE");
569 param("\\CLK_POLARITY");
573 port("\\ADDR", param("\\ABITS"));
574 port("\\DATA", param("\\WIDTH"));
579 if (cell
->type
== "$mem") {
583 param("\\RD_CLK_ENABLE");
584 param("\\RD_CLK_POLARITY");
585 param("\\WR_CLK_ENABLE");
586 param("\\WR_CLK_POLARITY");
587 port("\\RD_CLK", param("\\RD_PORTS"));
588 port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS"));
589 port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH"));
590 port("\\WR_CLK", param("\\WR_PORTS"));
591 port("\\WR_EN", param("\\WR_PORTS"));
592 port("\\WR_ADDR", param("\\WR_PORTS") * param("\\ABITS"));
593 port("\\WR_DATA", param("\\WR_PORTS") * param("\\WIDTH"));
598 if (cell
->type
== "$assert") {
605 if (cell
->type
== "$_INV_") { check_gate("AY"); return; }
606 if (cell
->type
== "$_AND_") { check_gate("ABY"); return; }
607 if (cell
->type
== "$_OR_") { check_gate("ABY"); return; }
608 if (cell
->type
== "$_XOR_") { check_gate("ABY"); return; }
609 if (cell
->type
== "$_MUX_") { check_gate("ABSY"); return; }
611 if (cell
->type
== "$_SR_NN_") { check_gate("SRQ"); return; }
612 if (cell
->type
== "$_SR_NP_") { check_gate("SRQ"); return; }
613 if (cell
->type
== "$_SR_PN_") { check_gate("SRQ"); return; }
614 if (cell
->type
== "$_SR_PP_") { check_gate("SRQ"); return; }
616 if (cell
->type
== "$_DFF_N_") { check_gate("DQC"); return; }
617 if (cell
->type
== "$_DFF_P_") { check_gate("DQC"); return; }
619 if (cell
->type
== "$_DFF_NN0_") { check_gate("DQCR"); return; }
620 if (cell
->type
== "$_DFF_NN1_") { check_gate("DQCR"); return; }
621 if (cell
->type
== "$_DFF_NP0_") { check_gate("DQCR"); return; }
622 if (cell
->type
== "$_DFF_NP1_") { check_gate("DQCR"); return; }
623 if (cell
->type
== "$_DFF_PN0_") { check_gate("DQCR"); return; }
624 if (cell
->type
== "$_DFF_PN1_") { check_gate("DQCR"); return; }
625 if (cell
->type
== "$_DFF_PP0_") { check_gate("DQCR"); return; }
626 if (cell
->type
== "$_DFF_PP1_") { check_gate("DQCR"); return; }
628 if (cell
->type
== "$_DFFSR_NNN_") { check_gate("CSRDQ"); return; }
629 if (cell
->type
== "$_DFFSR_NNP_") { check_gate("CSRDQ"); return; }
630 if (cell
->type
== "$_DFFSR_NPN_") { check_gate("CSRDQ"); return; }
631 if (cell
->type
== "$_DFFSR_NPP_") { check_gate("CSRDQ"); return; }
632 if (cell
->type
== "$_DFFSR_PNN_") { check_gate("CSRDQ"); return; }
633 if (cell
->type
== "$_DFFSR_PNP_") { check_gate("CSRDQ"); return; }
634 if (cell
->type
== "$_DFFSR_PPN_") { check_gate("CSRDQ"); return; }
635 if (cell
->type
== "$_DFFSR_PPP_") { check_gate("CSRDQ"); return; }
637 if (cell
->type
== "$_DLATCH_N_") { check_gate("EDQ"); return; }
638 if (cell
->type
== "$_DLATCH_P_") { check_gate("EDQ"); return; }
646 void RTLIL::Module::check()
649 for (auto &it
: wires
) {
650 assert(it
.first
== it
.second
->name
);
651 assert(it
.first
.size() > 0 && (it
.first
[0] == '\\' || it
.first
[0] == '$'));
652 assert(it
.second
->width
>= 0);
653 assert(it
.second
->port_id
>= 0);
654 for (auto &it2
: it
.second
->attributes
) {
655 assert(it2
.first
.size() > 0 && (it2
.first
[0] == '\\' || it2
.first
[0] == '$'));
659 for (auto &it
: memories
) {
660 assert(it
.first
== it
.second
->name
);
661 assert(it
.first
.size() > 0 && (it
.first
[0] == '\\' || it
.first
[0] == '$'));
662 assert(it
.second
->width
>= 0);
663 assert(it
.second
->size
>= 0);
664 for (auto &it2
: it
.second
->attributes
) {
665 assert(it2
.first
.size() > 0 && (it2
.first
[0] == '\\' || it2
.first
[0] == '$'));
669 for (auto &it
: cells
) {
670 assert(it
.first
== it
.second
->name
);
671 assert(it
.first
.size() > 0 && (it
.first
[0] == '\\' || it
.first
[0] == '$'));
672 assert(it
.second
->type
.size() > 0 && (it
.second
->type
[0] == '\\' || it
.second
->type
[0] == '$'));
673 for (auto &it2
: it
.second
->connections
) {
674 assert(it2
.first
.size() > 0 && (it2
.first
[0] == '\\' || it2
.first
[0] == '$'));
677 for (auto &it2
: it
.second
->attributes
) {
678 assert(it2
.first
.size() > 0 && (it2
.first
[0] == '\\' || it2
.first
[0] == '$'));
680 for (auto &it2
: it
.second
->parameters
) {
681 assert(it2
.first
.size() > 0 && (it2
.first
[0] == '\\' || it2
.first
[0] == '$'));
683 if (it
.second
->type
[0] == '$' && it
.second
->type
.substr(0, 3) != "$__" && it
.second
->type
.substr(0, 8) != "$paramod") {
684 InternalCellChecker
checker(this, it
.second
);
689 for (auto &it
: processes
) {
690 assert(it
.first
== it
.second
->name
);
691 assert(it
.first
.size() > 0 && (it
.first
[0] == '\\' || it
.first
[0] == '$'));
692 // FIXME: More checks here..
695 for (auto &it
: connections
) {
696 assert(it
.first
.width
== it
.second
.width
);
701 for (auto &it
: attributes
) {
702 assert(it
.first
.size() > 0 && (it
.first
[0] == '\\' || it
.first
[0] == '$'));
707 void RTLIL::Module::optimize()
709 for (auto &it
: cells
)
710 it
.second
->optimize();
711 for (auto &it
: processes
)
712 it
.second
->optimize();
713 for (auto &it
: connections
) {
715 it
.second
.optimize();
719 void RTLIL::Module::cloneInto(RTLIL::Module
*new_mod
) const
721 new_mod
->name
= name
;
722 new_mod
->connections
= connections
;
723 new_mod
->attributes
= attributes
;
725 for (auto &it
: wires
)
726 new_mod
->wires
[it
.first
] = new RTLIL::Wire(*it
.second
);
728 for (auto &it
: memories
)
729 new_mod
->memories
[it
.first
] = new RTLIL::Memory(*it
.second
);
731 for (auto &it
: cells
)
732 new_mod
->cells
[it
.first
] = new RTLIL::Cell(*it
.second
);
734 for (auto &it
: processes
)
735 new_mod
->processes
[it
.first
] = it
.second
->clone();
737 struct RewriteSigSpecWorker
740 void operator()(RTLIL::SigSpec
&sig
)
742 for (auto &c
: sig
.chunks
)
744 c
.wire
= mod
->wires
.at(c
.wire
->name
);
748 RewriteSigSpecWorker rewriteSigSpecWorker
;
749 rewriteSigSpecWorker
.mod
= new_mod
;
750 new_mod
->rewrite_sigspecs(rewriteSigSpecWorker
);
753 RTLIL::Module
*RTLIL::Module::clone() const
755 RTLIL::Module
*new_mod
= new RTLIL::Module
;
760 RTLIL::Wire
*RTLIL::Module::new_wire(int width
, RTLIL::IdString name
)
762 RTLIL::Wire
*wire
= new RTLIL::Wire
;
769 void RTLIL::Module::add(RTLIL::Wire
*wire
)
771 assert(!wire
->name
.empty());
772 assert(count_id(wire
->name
) == 0);
773 wires
[wire
->name
] = wire
;
776 void RTLIL::Module::add(RTLIL::Cell
*cell
)
778 assert(!cell
->name
.empty());
779 assert(count_id(cell
->name
) == 0);
780 cells
[cell
->name
] = cell
;
783 static bool fixup_ports_compare(const RTLIL::Wire
*a
, const RTLIL::Wire
*b
)
785 if (a
->port_id
&& !b
->port_id
)
787 if (!a
->port_id
&& b
->port_id
)
790 if (a
->port_id
== b
->port_id
)
791 return a
->name
< b
->name
;
792 return a
->port_id
< b
->port_id
;
795 void RTLIL::Module::fixup_ports()
797 std::vector
<RTLIL::Wire
*> all_ports
;
799 for (auto &w
: wires
)
800 if (w
.second
->port_input
|| w
.second
->port_output
)
801 all_ports
.push_back(w
.second
);
803 w
.second
->port_id
= 0;
805 std::sort(all_ports
.begin(), all_ports
.end(), fixup_ports_compare
);
806 for (size_t i
= 0; i
< all_ports
.size(); i
++)
807 all_ports
[i
]->port_id
= i
+1;
819 RTLIL::Memory::Memory()
825 void RTLIL::Cell::optimize()
827 for (auto &it
: connections
)
828 it
.second
.optimize();
831 RTLIL::SigChunk::SigChunk()
838 RTLIL::SigChunk::SigChunk(const RTLIL::Const
&data
)
842 width
= data
.bits
.size();
846 RTLIL::SigChunk::SigChunk(RTLIL::Wire
*wire
, int width
, int offset
)
849 this->width
= width
>= 0 ? width
: wire
->width
;
850 this->offset
= offset
;
853 RTLIL::SigChunk::SigChunk(const std::string
&str
)
856 data
= RTLIL::Const(str
);
857 width
= data
.bits
.size();
861 RTLIL::SigChunk::SigChunk(int val
, int width
)
864 data
= RTLIL::Const(val
, width
);
865 this->width
= data
.bits
.size();
869 RTLIL::SigChunk::SigChunk(RTLIL::State bit
, int width
)
872 data
= RTLIL::Const(bit
, width
);
873 this->width
= data
.bits
.size();
877 RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit
)
881 data
= RTLIL::Const(bit
.data
);
886 RTLIL::SigChunk
RTLIL::SigChunk::extract(int offset
, int length
) const
891 ret
.offset
= this->offset
+ offset
;
894 for (int i
= 0; i
< length
; i
++)
895 ret
.data
.bits
.push_back(data
.bits
[offset
+i
]);
901 bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk
&other
) const
903 if (wire
&& other
.wire
)
904 if (wire
->name
!= other
.wire
->name
)
905 return wire
->name
< other
.wire
->name
;
906 if (wire
!= other
.wire
)
907 return wire
< other
.wire
;
909 if (offset
!= other
.offset
)
910 return offset
< other
.offset
;
912 if (width
!= other
.width
)
913 return width
< other
.width
;
915 if (data
.bits
!= other
.data
.bits
)
916 return data
.bits
< other
.data
.bits
;
921 bool RTLIL::SigChunk::operator ==(const RTLIL::SigChunk
&other
) const
923 if (wire
!= other
.wire
|| width
!= other
.width
|| offset
!= other
.offset
)
925 if (data
.bits
!= other
.data
.bits
)
930 bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk
&other
) const
937 RTLIL::SigSpec::SigSpec()
942 RTLIL::SigSpec::SigSpec(const RTLIL::Const
&data
)
944 chunks
.push_back(RTLIL::SigChunk(data
));
945 width
= chunks
.back().width
;
949 RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk
&chunk
)
951 chunks
.push_back(chunk
);
952 width
= chunks
.back().width
;
956 RTLIL::SigSpec::SigSpec(RTLIL::Wire
*wire
, int width
, int offset
)
958 chunks
.push_back(RTLIL::SigChunk(wire
, width
, offset
));
959 this->width
= chunks
.back().width
;
963 RTLIL::SigSpec::SigSpec(const std::string
&str
)
965 chunks
.push_back(RTLIL::SigChunk(str
));
966 width
= chunks
.back().width
;
970 RTLIL::SigSpec::SigSpec(int val
, int width
)
972 chunks
.push_back(RTLIL::SigChunk(val
, width
));
977 RTLIL::SigSpec::SigSpec(RTLIL::State bit
, int width
)
979 chunks
.push_back(RTLIL::SigChunk(bit
, width
));
984 RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit
, int width
)
986 if (bit
.wire
== NULL
)
987 chunks
.push_back(RTLIL::SigChunk(bit
.data
, width
));
989 for (int i
= 0; i
< width
; i
++)
990 chunks
.push_back(bit
);
995 RTLIL::SigSpec::SigSpec(std::vector
<RTLIL::SigBit
> bits
)
997 chunks
.reserve(bits
.size());
998 for (auto &bit
: bits
)
999 chunks
.push_back(bit
);
1000 this->width
= bits
.size();
1004 void RTLIL::SigSpec::expand()
1006 std::vector
<RTLIL::SigChunk
> new_chunks
;
1007 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1008 for (int j
= 0; j
< chunks
[i
].width
; j
++)
1009 new_chunks
.push_back(chunks
[i
].extract(j
, 1));
1011 chunks
.swap(new_chunks
);
1015 void RTLIL::SigSpec::optimize()
1017 std::vector
<RTLIL::SigChunk
> new_chunks
;
1018 for (auto &c
: chunks
)
1019 if (new_chunks
.size() == 0) {
1020 new_chunks
.push_back(c
);
1022 RTLIL::SigChunk
&cc
= new_chunks
.back();
1023 if (c
.wire
== NULL
&& cc
.wire
== NULL
)
1024 cc
.data
.bits
.insert(cc
.data
.bits
.end(), c
.data
.bits
.begin(), c
.data
.bits
.end());
1025 if (c
.wire
== cc
.wire
&& (c
.wire
== NULL
|| cc
.offset
+ cc
.width
== c
.offset
))
1026 cc
.width
+= c
.width
;
1028 new_chunks
.push_back(c
);
1030 chunks
.swap(new_chunks
);
1034 RTLIL::SigSpec
RTLIL::SigSpec::optimized() const
1036 RTLIL::SigSpec ret
= *this;
1041 bool RTLIL::SigChunk::compare(const RTLIL::SigChunk
&a
, const RTLIL::SigChunk
&b
)
1043 if (a
.wire
!= b
.wire
) {
1044 if (a
.wire
== NULL
|| b
.wire
== NULL
)
1045 return a
.wire
< b
.wire
;
1046 else if (a
.wire
->name
!= b
.wire
->name
)
1047 return a
.wire
->name
< b
.wire
->name
;
1049 return a
.wire
< b
.wire
;
1051 if (a
.offset
!= b
.offset
)
1052 return a
.offset
< b
.offset
;
1053 if (a
.width
!= b
.width
)
1054 return a
.width
< b
.width
;
1055 return a
.data
.bits
< b
.data
.bits
;
1058 void RTLIL::SigSpec::sort()
1061 std::sort(chunks
.begin(), chunks
.end(), RTLIL::SigChunk::compare
);
1065 void RTLIL::SigSpec::sort_and_unify()
1068 std::sort(chunks
.begin(), chunks
.end(), RTLIL::SigChunk::compare
);
1069 for (size_t i
= 1; i
< chunks
.size(); i
++) {
1070 RTLIL::SigChunk
&ch1
= chunks
[i
-1];
1071 RTLIL::SigChunk
&ch2
= chunks
[i
];
1072 if (!RTLIL::SigChunk::compare(ch1
, ch2
) && !RTLIL::SigChunk::compare(ch2
, ch1
)) {
1073 chunks
.erase(chunks
.begin()+i
);
1074 width
-= chunks
[i
].width
;
1081 void RTLIL::SigSpec::replace(const RTLIL::SigSpec
&pattern
, const RTLIL::SigSpec
&with
)
1083 replace(pattern
, with
, this);
1086 void RTLIL::SigSpec::replace(const RTLIL::SigSpec
&pattern
, const RTLIL::SigSpec
&with
, RTLIL::SigSpec
*other
) const
1088 int pos
= 0, restart_pos
= 0;
1089 assert(other
== NULL
|| width
== other
->width
);
1090 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1092 const RTLIL::SigChunk
&ch1
= chunks
[i
];
1093 if (chunks
[i
].wire
!= NULL
&& pos
>= restart_pos
)
1094 for (size_t j
= 0, poff
= 0; j
< pattern
.chunks
.size(); j
++) {
1095 const RTLIL::SigChunk
&ch2
= pattern
.chunks
[j
];
1096 assert(ch2
.wire
!= NULL
);
1097 if (ch1
.wire
== ch2
.wire
) {
1098 int lower
= std::max(ch1
.offset
, ch2
.offset
);
1099 int upper
= std::min(ch1
.offset
+ ch1
.width
, ch2
.offset
+ ch2
.width
);
1100 if (lower
< upper
) {
1101 restart_pos
= pos
+upper
-ch1
.offset
;
1102 other
->replace(pos
+lower
-ch1
.offset
, with
.extract(poff
+lower
-ch2
.offset
, upper
-lower
));
1108 pos
+= chunks
[i
].width
;
1113 void RTLIL::SigSpec::remove(const RTLIL::SigSpec
&pattern
)
1115 remove2(pattern
, NULL
);
1118 void RTLIL::SigSpec::remove(const RTLIL::SigSpec
&pattern
, RTLIL::SigSpec
*other
) const
1120 RTLIL::SigSpec tmp
= *this;
1121 tmp
.remove2(pattern
, other
);
1124 void RTLIL::SigSpec::remove2(const RTLIL::SigSpec
&pattern
, RTLIL::SigSpec
*other
)
1127 assert(other
== NULL
|| width
== other
->width
);
1128 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1130 const RTLIL::SigChunk
&ch1
= chunks
[i
];
1131 if (chunks
[i
].wire
!= NULL
)
1132 for (size_t j
= 0; j
< pattern
.chunks
.size(); j
++) {
1133 const RTLIL::SigChunk
&ch2
= pattern
.chunks
[j
];
1134 assert(ch2
.wire
!= NULL
);
1135 if (ch1
.wire
== ch2
.wire
) {
1136 int lower
= std::max(ch1
.offset
, ch2
.offset
);
1137 int upper
= std::min(ch1
.offset
+ ch1
.width
, ch2
.offset
+ ch2
.width
);
1138 if (lower
< upper
) {
1140 other
->remove(pos
+lower
-ch1
.offset
, upper
-lower
);
1141 remove(pos
+lower
-ch1
.offset
, upper
-lower
);
1142 if (i
== chunks
.size())
1148 pos
+= chunks
[i
].width
;
1153 RTLIL::SigSpec
RTLIL::SigSpec::extract(RTLIL::SigSpec pattern
, RTLIL::SigSpec
*other
) const
1155 assert(other
== NULL
|| width
== other
->width
);
1157 std::set
<RTLIL::SigBit
> pat
= pattern
.to_sigbit_set();
1158 std::vector
<RTLIL::SigBit
> bits_match
= to_sigbit_vector();
1162 std::vector
<RTLIL::SigBit
> bits_other
= other
? other
->to_sigbit_vector() : bits_match
;
1163 for (int i
= 0; i
< width
; i
++)
1164 if (bits_match
[i
].wire
&& pat
.count(bits_match
[i
]))
1165 ret
.append_bit(bits_other
[i
]);
1167 for (int i
= 0; i
< width
; i
++)
1168 if (bits_match
[i
].wire
&& pat
.count(bits_match
[i
]))
1169 ret
.append_bit(bits_match
[i
]);
1176 void RTLIL::SigSpec::replace(int offset
, const RTLIL::SigSpec
&with
)
1179 assert(offset
>= 0);
1180 assert(with
.width
>= 0);
1181 assert(offset
+with
.width
<= width
);
1182 remove(offset
, with
.width
);
1183 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1184 if (pos
== offset
) {
1185 chunks
.insert(chunks
.begin()+i
, with
.chunks
.begin(), with
.chunks
.end());
1186 width
+= with
.width
;
1190 pos
+= chunks
[i
].width
;
1192 assert(pos
== offset
);
1193 chunks
.insert(chunks
.end(), with
.chunks
.begin(), with
.chunks
.end());
1194 width
+= with
.width
;
1198 void RTLIL::SigSpec::remove_const()
1200 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1201 if (chunks
[i
].wire
!= NULL
)
1203 width
-= chunks
[i
].width
;
1204 chunks
.erase(chunks
.begin() + (i
--));
1209 void RTLIL::SigSpec::remove(int offset
, int length
)
1212 assert(offset
>= 0);
1213 assert(length
>= 0);
1214 assert(offset
+length
<= width
);
1215 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1216 int orig_width
= chunks
[i
].width
;
1217 if (pos
+chunks
[i
].width
> offset
&& pos
< offset
+length
) {
1218 int off
= offset
- pos
;
1224 if (len
> chunks
[i
].width
-off
)
1225 len
= chunks
[i
].width
-off
;
1226 RTLIL::SigChunk lsb_chunk
= chunks
[i
].extract(0, off
);
1227 RTLIL::SigChunk msb_chunk
= chunks
[i
].extract(off
+len
, chunks
[i
].width
-off
-len
);
1228 if (lsb_chunk
.width
== 0 && msb_chunk
.width
== 0) {
1229 chunks
.erase(chunks
.begin()+i
);
1231 } else if (lsb_chunk
.width
== 0 && msb_chunk
.width
!= 0) {
1232 chunks
[i
] = msb_chunk
;
1233 } else if (lsb_chunk
.width
!= 0 && msb_chunk
.width
== 0) {
1234 chunks
[i
] = lsb_chunk
;
1235 } else if (lsb_chunk
.width
!= 0 && msb_chunk
.width
!= 0) {
1236 chunks
[i
] = lsb_chunk
;
1237 chunks
.insert(chunks
.begin()+i
+1, msb_chunk
);
1248 RTLIL::SigSpec
RTLIL::SigSpec::extract(int offset
, int length
) const
1252 assert(offset
>= 0);
1253 assert(length
>= 0);
1254 assert(offset
+length
<= width
);
1255 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1256 if (pos
+chunks
[i
].width
> offset
&& pos
< offset
+length
) {
1257 int off
= offset
- pos
;
1263 if (len
> chunks
[i
].width
-off
)
1264 len
= chunks
[i
].width
-off
;
1265 ret
.chunks
.push_back(chunks
[i
].extract(off
, len
));
1270 pos
+= chunks
[i
].width
;
1272 assert(length
== 0);
1277 void RTLIL::SigSpec::append(const RTLIL::SigSpec
&signal
)
1279 for (size_t i
= 0; i
< signal
.chunks
.size(); i
++) {
1280 chunks
.push_back(signal
.chunks
[i
]);
1281 width
+= signal
.chunks
[i
].width
;
1286 void RTLIL::SigSpec::append_bit(const RTLIL::SigBit
&bit
)
1288 if (chunks
.size() == 0)
1289 chunks
.push_back(bit
);
1291 if (bit
.wire
== NULL
)
1292 if (chunks
.back().wire
== NULL
)
1293 chunks
.back().data
.bits
.push_back(bit
.data
);
1295 chunks
.push_back(bit
);
1297 if (chunks
.back().wire
== bit
.wire
&& chunks
.back().offset
+ chunks
.back().width
== bit
.offset
)
1298 chunks
.back().width
++;
1300 chunks
.push_back(bit
);
1305 bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal
, RTLIL::State freeState
, bool override
)
1307 bool no_collisions
= true;
1309 assert(width
== signal
.width
);
1313 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1314 bool self_free
= chunks
[i
].wire
== NULL
&& chunks
[i
].data
.bits
[0] == freeState
;
1315 bool other_free
= signal
.chunks
[i
].wire
== NULL
&& signal
.chunks
[i
].data
.bits
[0] == freeState
;
1316 if (!self_free
&& !other_free
) {
1318 chunks
[i
] = signal
.chunks
[i
];
1320 chunks
[i
] = RTLIL::SigChunk(RTLIL::State::Sx
, 1);
1321 no_collisions
= false;
1323 if (self_free
&& !other_free
)
1324 chunks
[i
] = signal
.chunks
[i
];
1328 return no_collisions
;
1331 void RTLIL::SigSpec::extend(int width
, bool is_signed
)
1333 if (this->width
> width
)
1334 remove(width
, this->width
- width
);
1336 if (this->width
< width
) {
1337 RTLIL::SigSpec padding
= this->width
> 0 ? extract(this->width
- 1, 1) : RTLIL::SigSpec(RTLIL::State::S0
);
1338 if (!is_signed
&& padding
!= RTLIL::SigSpec(RTLIL::State::Sx
) && padding
!= RTLIL::SigSpec(RTLIL::State::Sz
) &&
1339 padding
!= RTLIL::SigSpec(RTLIL::State::Sa
) && padding
!= RTLIL::SigSpec(RTLIL::State::Sm
))
1340 padding
= RTLIL::SigSpec(RTLIL::State::S0
);
1341 while (this->width
< width
)
1348 void RTLIL::SigSpec::extend_u0(int width
, bool is_signed
)
1350 if (this->width
> width
)
1351 remove(width
, this->width
- width
);
1353 if (this->width
< width
) {
1354 RTLIL::SigSpec padding
= this->width
> 0 ? extract(this->width
- 1, 1) : RTLIL::SigSpec(RTLIL::State::S0
);
1356 padding
= RTLIL::SigSpec(RTLIL::State::S0
);
1357 while (this->width
< width
)
1364 void RTLIL::SigSpec::check() const
1367 for (size_t i
= 0; i
< chunks
.size(); i
++) {
1368 const RTLIL::SigChunk chunk
= chunks
[i
];
1369 if (chunk
.wire
== NULL
) {
1370 assert(chunk
.offset
== 0);
1371 assert(chunk
.data
.bits
.size() == (size_t)chunk
.width
);
1373 assert(chunk
.offset
>= 0);
1374 assert(chunk
.width
>= 0);
1375 assert(chunk
.offset
+ chunk
.width
<= chunk
.wire
->width
);
1376 assert(chunk
.data
.bits
.size() == 0);
1383 bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec
&other
) const
1385 if (width
!= other
.width
)
1386 return width
< other
.width
;
1388 RTLIL::SigSpec a
= *this, b
= other
;
1392 if (a
.chunks
.size() != b
.chunks
.size())
1393 return a
.chunks
.size() < b
.chunks
.size();
1395 for (size_t i
= 0; i
< a
.chunks
.size(); i
++)
1396 if (a
.chunks
[i
] != b
.chunks
[i
])
1397 return a
.chunks
[i
] < b
.chunks
[i
];
1402 bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec
&other
) const
1404 if (width
!= other
.width
)
1407 RTLIL::SigSpec a
= *this, b
= other
;
1411 if (a
.chunks
.size() != b
.chunks
.size())
1414 for (size_t i
= 0; i
< a
.chunks
.size(); i
++)
1415 if (a
.chunks
[i
] != b
.chunks
[i
])
1421 bool RTLIL::SigSpec::operator !=(const RTLIL::SigSpec
&other
) const
1428 bool RTLIL::SigSpec::is_fully_const() const
1430 for (auto it
= chunks
.begin(); it
!= chunks
.end(); it
++)
1431 if (it
->width
> 0 && it
->wire
!= NULL
)
1436 bool RTLIL::SigSpec::is_fully_def() const
1438 for (auto it
= chunks
.begin(); it
!= chunks
.end(); it
++) {
1439 if (it
->width
> 0 && it
->wire
!= NULL
)
1441 for (size_t i
= 0; i
< it
->data
.bits
.size(); i
++)
1442 if (it
->data
.bits
[i
] != RTLIL::State::S0
&& it
->data
.bits
[i
] != RTLIL::State::S1
)
1448 bool RTLIL::SigSpec::is_fully_undef() const
1450 for (auto it
= chunks
.begin(); it
!= chunks
.end(); it
++) {
1451 if (it
->width
> 0 && it
->wire
!= NULL
)
1453 for (size_t i
= 0; i
< it
->data
.bits
.size(); i
++)
1454 if (it
->data
.bits
[i
] != RTLIL::State::Sx
&& it
->data
.bits
[i
] != RTLIL::State::Sz
)
1460 bool RTLIL::SigSpec::has_marked_bits() const
1462 for (auto it
= chunks
.begin(); it
!= chunks
.end(); it
++)
1463 if (it
->width
> 0 && it
->wire
== NULL
) {
1464 for (size_t i
= 0; i
< it
->data
.bits
.size(); i
++)
1465 if (it
->data
.bits
[i
] == RTLIL::State::Sm
)
1471 bool RTLIL::SigSpec::as_bool() const
1473 assert(is_fully_const());
1474 SigSpec sig
= *this;
1477 return sig
.chunks
[0].data
.as_bool();
1481 int RTLIL::SigSpec::as_int() const
1483 assert(is_fully_const());
1484 SigSpec sig
= *this;
1487 return sig
.chunks
[0].data
.as_int();
1491 std::string
RTLIL::SigSpec::as_string() const
1494 for (size_t i
= chunks
.size(); i
> 0; i
--) {
1495 const RTLIL::SigChunk
&chunk
= chunks
[i
-1];
1496 if (chunk
.wire
!= NULL
)
1497 for (int j
= 0; j
< chunk
.width
; j
++)
1500 str
+= chunk
.data
.as_string();
1505 RTLIL::Const
RTLIL::SigSpec::as_const() const
1507 assert(is_fully_const());
1508 SigSpec sig
= *this;
1511 return sig
.chunks
[0].data
;
1512 return RTLIL::Const();
1515 bool RTLIL::SigSpec::match(std::string pattern
) const
1517 std::string str
= as_string();
1518 assert(pattern
.size() == str
.size());
1520 for (size_t i
= 0; i
< pattern
.size(); i
++) {
1521 if (pattern
[i
] == ' ')
1523 if (pattern
[i
] == '*') {
1524 if (str
[i
] != 'z' && str
[i
] != 'x')
1528 if (pattern
[i
] != str
[i
])
1535 std::set
<RTLIL::SigBit
> RTLIL::SigSpec::to_sigbit_set() const
1537 std::set
<RTLIL::SigBit
> sigbits
;
1538 for (auto &c
: chunks
)
1539 for (int i
= 0; i
< c
.width
; i
++)
1540 sigbits
.insert(RTLIL::SigBit(c
, i
));
1544 std::vector
<RTLIL::SigBit
> RTLIL::SigSpec::to_sigbit_vector() const
1546 std::vector
<RTLIL::SigBit
> sigbits
;
1547 sigbits
.reserve(width
);
1548 for (auto &c
: chunks
)
1549 for (int i
= 0; i
< c
.width
; i
++)
1550 sigbits
.push_back(RTLIL::SigBit(c
, i
));
1554 static void sigspec_parse_split(std::vector
<std::string
> &tokens
, const std::string
&text
, char sep
)
1556 size_t start
= 0, end
= 0;
1557 while ((end
= text
.find(sep
, start
)) != std::string::npos
) {
1558 tokens
.push_back(text
.substr(start
, end
- start
));
1561 tokens
.push_back(text
.substr(start
));
1564 static int sigspec_parse_get_dummy_line_num()
1569 bool RTLIL::SigSpec::parse(RTLIL::SigSpec
&sig
, RTLIL::Module
*module
, std::string str
)
1571 std::vector
<std::string
> tokens
;
1572 sigspec_parse_split(tokens
, str
, ',');
1574 sig
= RTLIL::SigSpec();
1575 for (int tokidx
= int(tokens
.size())-1; tokidx
>= 0; tokidx
--)
1577 std::string netname
= tokens
[tokidx
];
1578 std::string indices
;
1580 if (netname
.size() == 0)
1583 if ('0' <= netname
[0] && netname
[0] <= '9') {
1584 AST::get_line_num
= sigspec_parse_get_dummy_line_num
;
1585 AST::AstNode
*ast
= VERILOG_FRONTEND::const2ast(netname
);
1588 sig
.append(RTLIL::Const(ast
->bits
));
1596 if (netname
[0] != '$' && netname
[0] != '\\')
1597 netname
= "\\" + netname
;
1599 if (module
->wires
.count(netname
) == 0) {
1600 size_t indices_pos
= netname
.size()-1;
1601 if (indices_pos
> 2 && netname
[indices_pos
] == ']')
1604 while (indices_pos
> 0 && ('0' <= netname
[indices_pos
] && netname
[indices_pos
] <= '9')) indices_pos
--;
1605 if (indices_pos
> 0 && netname
[indices_pos
] == ':') {
1607 while (indices_pos
> 0 && ('0' <= netname
[indices_pos
] && netname
[indices_pos
] <= '9')) indices_pos
--;
1609 if (indices_pos
> 0 && netname
[indices_pos
] == '[') {
1610 indices
= netname
.substr(indices_pos
);
1611 netname
= netname
.substr(0, indices_pos
);
1616 if (module
->wires
.count(netname
) == 0)
1619 RTLIL::Wire
*wire
= module
->wires
.at(netname
);
1620 if (!indices
.empty()) {
1621 std::vector
<std::string
> index_tokens
;
1622 sigspec_parse_split(index_tokens
, indices
.substr(1, indices
.size()-2), ':');
1623 if (index_tokens
.size() == 1)
1624 sig
.append(RTLIL::SigSpec(wire
, 1, atoi(index_tokens
.at(0).c_str())));
1626 int a
= atoi(index_tokens
.at(0).c_str());
1627 int b
= atoi(index_tokens
.at(1).c_str());
1632 sig
.append(RTLIL::SigSpec(wire
, b
-a
+1, a
));
1641 bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec
&lhs
, RTLIL::SigSpec
&sig
, RTLIL::Module
*module
, std::string str
)
1644 sig
= RTLIL::SigSpec(RTLIL::State::S0
, lhs
.width
);
1649 sig
= RTLIL::SigSpec(RTLIL::State::S1
, lhs
.width
);
1653 if (lhs
.chunks
.size() == 1) {
1654 char *p
= (char*)str
.c_str(), *endptr
;
1655 long long int val
= strtoll(p
, &endptr
, 10);
1656 if (endptr
&& endptr
!= p
&& *endptr
== 0) {
1657 sig
= RTLIL::SigSpec(val
, lhs
.width
);
1662 return parse(sig
, module
, str
);
1665 RTLIL::CaseRule::~CaseRule()
1667 for (auto it
= switches
.begin(); it
!= switches
.end(); it
++)
1671 void RTLIL::CaseRule::optimize()
1673 for (auto it
: switches
)
1675 for (auto &it
: compare
)
1677 for (auto &it
: actions
) {
1678 it
.first
.optimize();
1679 it
.second
.optimize();
1683 RTLIL::CaseRule
*RTLIL::CaseRule::clone() const
1685 RTLIL::CaseRule
*new_caserule
= new RTLIL::CaseRule
;
1686 new_caserule
->compare
= compare
;
1687 new_caserule
->actions
= actions
;
1688 for (auto &it
: switches
)
1689 new_caserule
->switches
.push_back(it
->clone());
1690 return new_caserule
;
1693 RTLIL::SwitchRule::~SwitchRule()
1695 for (auto it
= cases
.begin(); it
!= cases
.end(); it
++)
1699 void RTLIL::SwitchRule::optimize()
1702 for (auto it
: cases
)
1706 RTLIL::SwitchRule
*RTLIL::SwitchRule::clone() const
1708 RTLIL::SwitchRule
*new_switchrule
= new RTLIL::SwitchRule
;
1709 new_switchrule
->signal
= signal
;
1710 new_switchrule
->attributes
= attributes
;
1711 for (auto &it
: cases
)
1712 new_switchrule
->cases
.push_back(it
->clone());
1713 return new_switchrule
;
1717 void RTLIL::SyncRule::optimize()
1720 for (auto &it
: actions
) {
1721 it
.first
.optimize();
1722 it
.second
.optimize();
1726 RTLIL::SyncRule
*RTLIL::SyncRule::clone() const
1728 RTLIL::SyncRule
*new_syncrule
= new RTLIL::SyncRule
;
1729 new_syncrule
->type
= type
;
1730 new_syncrule
->signal
= signal
;
1731 new_syncrule
->actions
= actions
;
1732 return new_syncrule
;
1735 RTLIL::Process::~Process()
1737 for (auto it
= syncs
.begin(); it
!= syncs
.end(); it
++)
1741 void RTLIL::Process::optimize()
1743 root_case
.optimize();
1744 for (auto it
: syncs
)
1748 RTLIL::Process
*RTLIL::Process::clone() const
1750 RTLIL::Process
*new_proc
= new RTLIL::Process
;
1752 new_proc
->name
= name
;
1753 new_proc
->attributes
= attributes
;
1755 RTLIL::CaseRule
*rc_ptr
= root_case
.clone();
1756 new_proc
->root_case
= *rc_ptr
;
1757 rc_ptr
->switches
.clear();
1760 for (auto &it
: syncs
)
1761 new_proc
->syncs
.push_back(it
->clone());