c43482bd242e2c127114f68627a9f9292901600a
2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2020 Marcelina KoĆcielnicka <mwk@0x04.net>
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/ff.h"
24 FfData::FfData(FfInitVals
*initvals
, Cell
*cell_
) : FfData(cell_
->module
, initvals
, cell_
->name
)
27 sig_q
= cell
->getPort(ID::Q
);
28 width
= GetSize(sig_q
);
29 attributes
= cell
->attributes
;
32 val_init
= (*initvals
)(sig_q
);
34 std::string type_str
= cell
->type
.str();
36 if (cell
->type
.in(ID($ff
), ID($dff
), ID($dffe
), ID($dffsr
), ID($dffsre
), ID($adff
), ID($adffe
), ID($aldff
), ID($aldffe
), ID($sdff
), ID($sdffe
), ID($sdffce
), ID($dlatch
), ID($adlatch
), ID($dlatchsr
), ID($sr
))) {
37 if (cell
->type
== ID($ff
)) {
39 sig_d
= cell
->getPort(ID::D
);
40 } else if (cell
->type
== ID($sr
)) {
41 // No data input at all.
42 } else if (cell
->type
.in(ID($dlatch
), ID($adlatch
), ID($dlatchsr
))) {
44 sig_aload
= cell
->getPort(ID::EN
);
45 pol_aload
= cell
->getParam(ID::EN_POLARITY
).as_bool();
46 sig_ad
= cell
->getPort(ID::D
);
49 sig_clk
= cell
->getPort(ID::CLK
);
50 pol_clk
= cell
->getParam(ID::CLK_POLARITY
).as_bool();
51 sig_d
= cell
->getPort(ID::D
);
53 if (cell
->type
.in(ID($dffe
), ID($dffsre
), ID($adffe
), ID($aldffe
), ID($sdffe
), ID($sdffce
))) {
55 sig_ce
= cell
->getPort(ID::EN
);
56 pol_ce
= cell
->getParam(ID::EN_POLARITY
).as_bool();
58 if (cell
->type
.in(ID($dffsr
), ID($dffsre
), ID($dlatchsr
), ID($sr
))) {
60 sig_clr
= cell
->getPort(ID::CLR
);
61 sig_set
= cell
->getPort(ID::SET
);
62 pol_clr
= cell
->getParam(ID::CLR_POLARITY
).as_bool();
63 pol_set
= cell
->getParam(ID::SET_POLARITY
).as_bool();
65 if (cell
->type
.in(ID($aldff
), ID($aldffe
))) {
67 sig_aload
= cell
->getPort(ID::ALOAD
);
68 pol_aload
= cell
->getParam(ID::ALOAD_POLARITY
).as_bool();
69 sig_ad
= cell
->getPort(ID::AD
);
71 if (cell
->type
.in(ID($adff
), ID($adffe
), ID($adlatch
))) {
73 sig_arst
= cell
->getPort(ID::ARST
);
74 pol_arst
= cell
->getParam(ID::ARST_POLARITY
).as_bool();
75 val_arst
= cell
->getParam(ID::ARST_VALUE
);
77 if (cell
->type
.in(ID($sdff
), ID($sdffe
), ID($sdffce
))) {
79 sig_srst
= cell
->getPort(ID::SRST
);
80 pol_srst
= cell
->getParam(ID::SRST_POLARITY
).as_bool();
81 val_srst
= cell
->getParam(ID::SRST_VALUE
);
82 ce_over_srst
= cell
->type
== ID($sdffce
);
84 } else if (cell
->type
== ID($_FF_
)) {
87 sig_d
= cell
->getPort(ID::D
);
88 } else if (type_str
.substr(0, 5) == "$_SR_") {
91 pol_set
= type_str
[5] == 'P';
92 pol_clr
= type_str
[6] == 'P';
93 sig_set
= cell
->getPort(ID::S
);
94 sig_clr
= cell
->getPort(ID::R
);
95 } else if (type_str
.substr(0, 6) == "$_DFF_" && type_str
.size() == 8) {
97 sig_d
= cell
->getPort(ID::D
);
99 pol_clk
= type_str
[6] == 'P';
100 sig_clk
= cell
->getPort(ID::C
);
101 } else if (type_str
.substr(0, 7) == "$_DFFE_" && type_str
.size() == 10) {
103 sig_d
= cell
->getPort(ID::D
);
105 pol_clk
= type_str
[7] == 'P';
106 sig_clk
= cell
->getPort(ID::C
);
108 pol_ce
= type_str
[8] == 'P';
109 sig_ce
= cell
->getPort(ID::E
);
110 } else if (type_str
.substr(0, 6) == "$_DFF_" && type_str
.size() == 10) {
112 sig_d
= cell
->getPort(ID::D
);
114 pol_clk
= type_str
[6] == 'P';
115 sig_clk
= cell
->getPort(ID::C
);
117 pol_arst
= type_str
[7] == 'P';
118 sig_arst
= cell
->getPort(ID::R
);
119 val_arst
= type_str
[8] == '1' ? State::S1
: State::S0
;
120 } else if (type_str
.substr(0, 7) == "$_DFFE_" && type_str
.size() == 12) {
122 sig_d
= cell
->getPort(ID::D
);
124 pol_clk
= type_str
[7] == 'P';
125 sig_clk
= cell
->getPort(ID::C
);
127 pol_arst
= type_str
[8] == 'P';
128 sig_arst
= cell
->getPort(ID::R
);
129 val_arst
= type_str
[9] == '1' ? State::S1
: State::S0
;
131 pol_ce
= type_str
[10] == 'P';
132 sig_ce
= cell
->getPort(ID::E
);
133 } else if (type_str
.substr(0, 8) == "$_ALDFF_" && type_str
.size() == 11) {
135 sig_d
= cell
->getPort(ID::D
);
137 pol_clk
= type_str
[8] == 'P';
138 sig_clk
= cell
->getPort(ID::C
);
140 pol_aload
= type_str
[9] == 'P';
141 sig_aload
= cell
->getPort(ID::L
);
142 sig_ad
= cell
->getPort(ID::AD
);
143 } else if (type_str
.substr(0, 9) == "$_ALDFFE_" && type_str
.size() == 13) {
145 sig_d
= cell
->getPort(ID::D
);
147 pol_clk
= type_str
[9] == 'P';
148 sig_clk
= cell
->getPort(ID::C
);
150 pol_aload
= type_str
[10] == 'P';
151 sig_aload
= cell
->getPort(ID::L
);
152 sig_ad
= cell
->getPort(ID::AD
);
154 pol_ce
= type_str
[11] == 'P';
155 sig_ce
= cell
->getPort(ID::E
);
156 } else if (type_str
.substr(0, 8) == "$_DFFSR_" && type_str
.size() == 12) {
158 sig_d
= cell
->getPort(ID::D
);
160 pol_clk
= type_str
[8] == 'P';
161 sig_clk
= cell
->getPort(ID::C
);
163 pol_set
= type_str
[9] == 'P';
164 pol_clr
= type_str
[10] == 'P';
165 sig_set
= cell
->getPort(ID::S
);
166 sig_clr
= cell
->getPort(ID::R
);
167 } else if (type_str
.substr(0, 9) == "$_DFFSRE_" && type_str
.size() == 14) {
169 sig_d
= cell
->getPort(ID::D
);
171 pol_clk
= type_str
[9] == 'P';
172 sig_clk
= cell
->getPort(ID::C
);
174 pol_set
= type_str
[10] == 'P';
175 pol_clr
= type_str
[11] == 'P';
176 sig_set
= cell
->getPort(ID::S
);
177 sig_clr
= cell
->getPort(ID::R
);
179 pol_ce
= type_str
[12] == 'P';
180 sig_ce
= cell
->getPort(ID::E
);
181 } else if (type_str
.substr(0, 7) == "$_SDFF_" && type_str
.size() == 11) {
183 sig_d
= cell
->getPort(ID::D
);
185 pol_clk
= type_str
[7] == 'P';
186 sig_clk
= cell
->getPort(ID::C
);
188 pol_srst
= type_str
[8] == 'P';
189 sig_srst
= cell
->getPort(ID::R
);
190 val_srst
= type_str
[9] == '1' ? State::S1
: State::S0
;
191 } else if (type_str
.substr(0, 8) == "$_SDFFE_" && type_str
.size() == 13) {
193 sig_d
= cell
->getPort(ID::D
);
195 pol_clk
= type_str
[8] == 'P';
196 sig_clk
= cell
->getPort(ID::C
);
198 pol_srst
= type_str
[9] == 'P';
199 sig_srst
= cell
->getPort(ID::R
);
200 val_srst
= type_str
[10] == '1' ? State::S1
: State::S0
;
202 pol_ce
= type_str
[11] == 'P';
203 sig_ce
= cell
->getPort(ID::E
);
204 } else if (type_str
.substr(0, 9) == "$_SDFFCE_" && type_str
.size() == 14) {
206 sig_d
= cell
->getPort(ID::D
);
208 pol_clk
= type_str
[9] == 'P';
209 sig_clk
= cell
->getPort(ID::C
);
211 pol_srst
= type_str
[10] == 'P';
212 sig_srst
= cell
->getPort(ID::R
);
213 val_srst
= type_str
[11] == '1' ? State::S1
: State::S0
;
215 pol_ce
= type_str
[12] == 'P';
216 sig_ce
= cell
->getPort(ID::E
);
218 } else if (type_str
.substr(0, 9) == "$_DLATCH_" && type_str
.size() == 11) {
221 sig_ad
= cell
->getPort(ID::D
);
223 pol_aload
= type_str
[9] == 'P';
224 sig_aload
= cell
->getPort(ID::E
);
225 } else if (type_str
.substr(0, 9) == "$_DLATCH_" && type_str
.size() == 13) {
228 sig_ad
= cell
->getPort(ID::D
);
230 pol_aload
= type_str
[9] == 'P';
231 sig_aload
= cell
->getPort(ID::E
);
233 pol_arst
= type_str
[10] == 'P';
234 sig_arst
= cell
->getPort(ID::R
);
235 val_arst
= type_str
[11] == '1' ? State::S1
: State::S0
;
236 } else if (type_str
.substr(0, 11) == "$_DLATCHSR_" && type_str
.size() == 15) {
239 sig_ad
= cell
->getPort(ID::D
);
241 pol_aload
= type_str
[11] == 'P';
242 sig_aload
= cell
->getPort(ID::E
);
244 pol_set
= type_str
[12] == 'P';
245 pol_clr
= type_str
[13] == 'P';
246 sig_set
= cell
->getPort(ID::S
);
247 sig_clr
= cell
->getPort(ID::R
);
251 if (has_aload
&& !has_clk
&& !has_sr
&& !has_arst
&& sig_ad
.is_fully_const()) {
252 // Plain D latches with const D treated specially.
255 sig_arst
= sig_aload
;
256 pol_arst
= pol_aload
;
257 val_arst
= sig_ad
.as_const();
261 FfData
FfData::slice(const std::vector
<int> &bits
) {
262 FfData
res(module
, initvals
, NEW_ID
);
263 res
.sig_clk
= sig_clk
;
265 res
.sig_aload
= sig_aload
;
266 res
.sig_arst
= sig_arst
;
267 res
.sig_srst
= sig_srst
;
268 res
.has_clk
= has_clk
;
269 res
.has_gclk
= has_gclk
;
271 res
.has_aload
= has_aload
;
272 res
.has_arst
= has_arst
;
273 res
.has_srst
= has_srst
;
275 res
.ce_over_srst
= ce_over_srst
;
276 res
.is_fine
= is_fine
;
277 res
.pol_clk
= pol_clk
;
279 res
.pol_aload
= pol_aload
;
280 res
.pol_arst
= pol_arst
;
281 res
.pol_srst
= pol_srst
;
282 res
.pol_clr
= pol_clr
;
283 res
.pol_set
= pol_set
;
284 res
.attributes
= attributes
;
286 res
.sig_q
.append(sig_q
[i
]);
287 if (has_clk
|| has_gclk
)
288 res
.sig_d
.append(sig_d
[i
]);
290 res
.sig_ad
.append(sig_ad
[i
]);
292 res
.sig_clr
.append(sig_clr
[i
]);
293 res
.sig_set
.append(sig_set
[i
]);
296 res
.val_arst
.bits
.push_back(val_arst
[i
]);
298 res
.val_srst
.bits
.push_back(val_srst
[i
]);
300 res
.val_init
.bits
.push_back(val_init
[i
]);
302 res
.width
= GetSize(res
.sig_q
);
306 void FfData::add_dummy_ce() {
312 ce_over_srst
= false;
315 void FfData::add_dummy_srst() {
320 sig_srst
= State::S0
;
321 val_srst
= Const(State::Sx
, width
);
322 ce_over_srst
= false;
325 void FfData::add_dummy_arst() {
330 sig_arst
= State::S0
;
331 val_arst
= Const(State::Sx
, width
);
334 void FfData::add_dummy_aload() {
339 sig_aload
= State::S0
;
340 sig_ad
= Const(State::Sx
, width
);
343 void FfData::add_dummy_sr() {
349 sig_clr
= Const(State::S0
, width
);
350 sig_set
= Const(State::S0
, width
);
353 void FfData::add_dummy_clk() {
359 sig_d
= Const(State::Sx
, width
);
362 void FfData::arst_to_aload() {
363 log_assert(has_arst
);
364 log_assert(!has_aload
);
365 pol_aload
= pol_arst
;
366 sig_aload
= sig_arst
;
372 void FfData::arst_to_sr() {
373 log_assert(has_arst
);
377 sig_clr
= Const(pol_arst
? State::S0
: State::S1
, width
);
378 sig_set
= Const(pol_arst
? State::S0
: State::S1
, width
);
381 for (int i
= 0; i
< width
; i
++) {
382 if (val_arst
[i
] == State::S1
)
383 sig_set
[i
] = sig_arst
;
385 sig_clr
[i
] = sig_arst
;
389 void FfData::aload_to_sr() {
390 log_assert(has_aload
);
398 sig_clr
= module
->Mux(NEW_ID
, Const(State::S1
, width
), sig_ad
, sig_aload
);
399 sig_set
= module
->Mux(NEW_ID
, Const(State::S0
, width
), sig_ad
, sig_aload
);
401 sig_clr
= module
->Mux(NEW_ID
, sig_ad
, Const(State::S1
, width
), sig_aload
);
402 sig_set
= module
->Mux(NEW_ID
, sig_ad
, Const(State::S0
, width
), sig_aload
);
408 sig_clr
= module
->AndnotGate(NEW_ID
, sig_aload
, sig_ad
);
409 sig_set
= module
->AndGate(NEW_ID
, sig_aload
, sig_ad
);
411 sig_clr
= module
->OrGate(NEW_ID
, sig_aload
, sig_ad
);
412 sig_set
= module
->OrnotGate(NEW_ID
, sig_aload
, sig_ad
);
417 void FfData::convert_ce_over_srst(bool val
) {
418 if (!has_ce
|| !has_srst
|| ce_over_srst
== val
)
425 sig_ce
= module
->Or(NEW_ID
, sig_ce
, sig_srst
);
427 SigSpec tmp
= module
->Not(NEW_ID
, sig_srst
);
428 sig_ce
= module
->Or(NEW_ID
, sig_ce
, tmp
);
432 SigSpec tmp
= module
->Not(NEW_ID
, sig_srst
);
433 sig_ce
= module
->And(NEW_ID
, sig_ce
, tmp
);
435 sig_ce
= module
->And(NEW_ID
, sig_ce
, sig_srst
);
441 sig_ce
= module
->OrGate(NEW_ID
, sig_ce
, sig_srst
);
443 sig_ce
= module
->OrnotGate(NEW_ID
, sig_ce
, sig_srst
);
447 sig_ce
= module
->AndnotGate(NEW_ID
, sig_ce
, sig_srst
);
449 sig_ce
= module
->AndGate(NEW_ID
, sig_ce
, sig_srst
);
458 sig_srst
= cell
->module
->And(NEW_ID
, sig_srst
, sig_ce
);
460 SigSpec tmp
= module
->Not(NEW_ID
, sig_ce
);
461 sig_srst
= cell
->module
->And(NEW_ID
, sig_srst
, tmp
);
465 SigSpec tmp
= module
->Not(NEW_ID
, sig_ce
);
466 sig_srst
= cell
->module
->Or(NEW_ID
, sig_srst
, tmp
);
468 sig_srst
= cell
->module
->Or(NEW_ID
, sig_srst
, sig_ce
);
474 sig_srst
= cell
->module
->AndGate(NEW_ID
, sig_srst
, sig_ce
);
476 sig_srst
= cell
->module
->AndnotGate(NEW_ID
, sig_srst
, sig_ce
);
480 sig_srst
= cell
->module
->OrnotGate(NEW_ID
, sig_srst
, sig_ce
);
482 sig_srst
= cell
->module
->OrGate(NEW_ID
, sig_srst
, sig_ce
);
490 void FfData::unmap_ce() {
494 if (has_srst
&& ce_over_srst
)
499 sig_d
= module
->Mux(NEW_ID
, sig_q
, sig_d
, sig_ce
);
501 sig_d
= module
->Mux(NEW_ID
, sig_d
, sig_q
, sig_ce
);
504 sig_d
= module
->MuxGate(NEW_ID
, sig_q
, sig_d
, sig_ce
);
506 sig_d
= module
->MuxGate(NEW_ID
, sig_d
, sig_q
, sig_ce
);
511 void FfData::unmap_srst() {
514 if (has_ce
&& !ce_over_srst
)
519 sig_d
= module
->Mux(NEW_ID
, sig_d
, val_srst
, sig_srst
);
521 sig_d
= module
->Mux(NEW_ID
, val_srst
, sig_d
, sig_srst
);
524 sig_d
= module
->MuxGate(NEW_ID
, sig_d
, val_srst
[0], sig_srst
);
526 sig_d
= module
->MuxGate(NEW_ID
, val_srst
[0], sig_d
, sig_srst
);
531 Cell
*FfData::emit() {
535 if (!has_aload
&& !has_clk
&& !has_gclk
&& !has_sr
) {
537 // Convert this case to a D latch.
540 // No control inputs left. Turn into a const driver.
541 module
->connect(sig_q
, val_init
);
546 initvals
->set_init(sig_q
, val_init
);
549 log_assert(!has_clk
);
551 log_assert(!has_aload
);
552 log_assert(!has_arst
);
553 log_assert(!has_srst
);
555 cell
= module
->addFf(name
, sig_d
, sig_q
);
556 } else if (!has_aload
&& !has_clk
) {
558 cell
= module
->addSr(name
, sig_set
, sig_clr
, sig_q
, pol_set
, pol_clr
);
559 } else if (!has_clk
) {
560 log_assert(!has_srst
);
562 cell
= module
->addDlatchsr(name
, sig_aload
, sig_set
, sig_clr
, sig_ad
, sig_q
, pol_aload
, pol_set
, pol_clr
);
564 cell
= module
->addAdlatch(name
, sig_aload
, sig_arst
, sig_ad
, sig_q
, val_arst
, pol_aload
, pol_arst
);
566 cell
= module
->addDlatch(name
, sig_aload
, sig_ad
, sig_q
, pol_aload
);
570 cell
= module
->addDffsre(name
, sig_clk
, sig_ce
, sig_set
, sig_clr
, sig_d
, sig_q
, pol_clk
, pol_ce
, pol_set
, pol_clr
);
572 cell
= module
->addDffsr(name
, sig_clk
, sig_set
, sig_clr
, sig_d
, sig_q
, pol_clk
, pol_set
, pol_clr
);
573 } else if (has_arst
) {
575 cell
= module
->addAdffe(name
, sig_clk
, sig_ce
, sig_arst
, sig_d
, sig_q
, val_arst
, pol_clk
, pol_ce
, pol_arst
);
577 cell
= module
->addAdff(name
, sig_clk
, sig_arst
, sig_d
, sig_q
, val_arst
, pol_clk
, pol_arst
);
578 } else if (has_aload
) {
580 cell
= module
->addAldffe(name
, sig_clk
, sig_ce
, sig_aload
, sig_d
, sig_q
, sig_ad
, pol_clk
, pol_ce
, pol_aload
);
582 cell
= module
->addAldff(name
, sig_clk
, sig_aload
, sig_d
, sig_q
, sig_ad
, pol_clk
, pol_aload
);
583 } else if (has_srst
) {
586 cell
= module
->addSdffce(name
, sig_clk
, sig_ce
, sig_srst
, sig_d
, sig_q
, val_srst
, pol_clk
, pol_ce
, pol_srst
);
588 cell
= module
->addSdffe(name
, sig_clk
, sig_ce
, sig_srst
, sig_d
, sig_q
, val_srst
, pol_clk
, pol_ce
, pol_srst
);
590 cell
= module
->addSdff(name
, sig_clk
, sig_srst
, sig_d
, sig_q
, val_srst
, pol_clk
, pol_srst
);
593 cell
= module
->addDffe(name
, sig_clk
, sig_ce
, sig_d
, sig_q
, pol_clk
, pol_ce
);
595 cell
= module
->addDff(name
, sig_clk
, sig_d
, sig_q
, pol_clk
);
600 log_assert(!has_clk
);
602 log_assert(!has_aload
);
603 log_assert(!has_arst
);
604 log_assert(!has_srst
);
606 cell
= module
->addFfGate(name
, sig_d
, sig_q
);
607 } else if (!has_aload
&& !has_clk
) {
609 cell
= module
->addSrGate(name
, sig_set
, sig_clr
, sig_q
, pol_set
, pol_clr
);
610 } else if (!has_clk
) {
611 log_assert(!has_srst
);
613 cell
= module
->addDlatchsrGate(name
, sig_aload
, sig_set
, sig_clr
, sig_ad
, sig_q
, pol_aload
, pol_set
, pol_clr
);
615 cell
= module
->addAdlatchGate(name
, sig_aload
, sig_arst
, sig_ad
, sig_q
, val_arst
.as_bool(), pol_aload
, pol_arst
);
617 cell
= module
->addDlatchGate(name
, sig_aload
, sig_ad
, sig_q
, pol_aload
);
621 cell
= module
->addDffsreGate(name
, sig_clk
, sig_ce
, sig_set
, sig_clr
, sig_d
, sig_q
, pol_clk
, pol_ce
, pol_set
, pol_clr
);
623 cell
= module
->addDffsrGate(name
, sig_clk
, sig_set
, sig_clr
, sig_d
, sig_q
, pol_clk
, pol_set
, pol_clr
);
624 } else if (has_arst
) {
626 cell
= module
->addAdffeGate(name
, sig_clk
, sig_ce
, sig_arst
, sig_d
, sig_q
, val_arst
.as_bool(), pol_clk
, pol_ce
, pol_arst
);
628 cell
= module
->addAdffGate(name
, sig_clk
, sig_arst
, sig_d
, sig_q
, val_arst
.as_bool(), pol_clk
, pol_arst
);
629 } else if (has_aload
) {
631 cell
= module
->addAldffeGate(name
, sig_clk
, sig_ce
, sig_aload
, sig_d
, sig_q
, sig_ad
, pol_clk
, pol_ce
, pol_aload
);
633 cell
= module
->addAldffGate(name
, sig_clk
, sig_aload
, sig_d
, sig_q
, sig_ad
, pol_clk
, pol_aload
);
634 } else if (has_srst
) {
637 cell
= module
->addSdffceGate(name
, sig_clk
, sig_ce
, sig_srst
, sig_d
, sig_q
, val_srst
.as_bool(), pol_clk
, pol_ce
, pol_srst
);
639 cell
= module
->addSdffeGate(name
, sig_clk
, sig_ce
, sig_srst
, sig_d
, sig_q
, val_srst
.as_bool(), pol_clk
, pol_ce
, pol_srst
);
641 cell
= module
->addSdffGate(name
, sig_clk
, sig_srst
, sig_d
, sig_q
, val_srst
.as_bool(), pol_clk
, pol_srst
);
644 cell
= module
->addDffeGate(name
, sig_clk
, sig_ce
, sig_d
, sig_q
, pol_clk
, pol_ce
);
646 cell
= module
->addDffGate(name
, sig_clk
, sig_d
, sig_q
, pol_clk
);
650 cell
->attributes
= attributes
;
654 void FfData::remove() {
657 module
->remove(cell
);
663 State
invert(State s
) {
665 case State::S0
: return State::S1
;
666 case State::S1
: return State::S0
;
672 void FfData::flip_bits(const pool
<int> &bits
) {
678 Wire
*new_q
= module
->addWire(NEW_ID
, width
);
680 for (auto bit
: bits
) {
682 val_arst
[bit
] = invert(val_arst
[bit
]);
684 val_srst
[bit
] = invert(val_srst
[bit
]);
685 val_init
[bit
] = invert(val_init
[bit
]);
688 if (has_sr
&& cell
) {
689 log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", log_id(module
->name
), log_id(cell
->name
), log_id(cell
->type
));
694 bool new_pol_clr
= pol_set
;
698 new_sig_clr
= module
->AndnotGate(NEW_ID
, sig_set
, sig_clr
);
700 new_sig_clr
= module
->AndGate(NEW_ID
, sig_set
, sig_clr
);
704 new_sig_clr
= module
->OrGate(NEW_ID
, sig_set
, sig_clr
);
706 new_sig_clr
= module
->OrnotGate(NEW_ID
, sig_set
, sig_clr
);
711 pol_clr
= new_pol_clr
;
712 sig_clr
= new_sig_clr
;
714 if (has_clk
|| has_gclk
)
715 sig_d
= module
->NotGate(NEW_ID
, sig_d
);
717 sig_ad
= module
->NotGate(NEW_ID
, sig_ad
);
718 module
->addNotGate(NEW_ID
, new_q
, sig_q
);
726 sig_clr
= module
->Not(NEW_ID
, sig_clr
);
729 not_clr
= module
->Not(NEW_ID
, sig_clr
);
732 sig_set
= module
->Not(NEW_ID
, sig_set
);
736 SigSpec masked_set
= module
->And(NEW_ID
, sig_set
, not_clr
);
737 for (auto bit
: bits
) {
738 sig_set
[bit
] = sig_clr
[bit
];
739 sig_clr
[bit
] = masked_set
[bit
];
743 Const mask
= Const(State::S0
, width
);
745 mask
.bits
[bit
] = State::S1
;
747 if (has_clk
|| has_gclk
)
748 sig_d
= module
->Xor(NEW_ID
, sig_d
, mask
);
750 sig_ad
= module
->Xor(NEW_ID
, sig_ad
, mask
);
751 module
->addXor(NEW_ID
, new_q
, mask
, sig_q
);