2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2021 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/ffmerge.h"
24 bool FfMergeHelper::is_output_unused(RTLIL::SigSpec sig
) {
25 for (auto bit
: (*sigmap
)(sig
))
26 if (sigbit_users_count
[bit
] != 0)
31 bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig
, FfData
&ff
, pool
<std::pair
<Cell
*, int>> &bits
) {
32 ff
= FfData(module
, initvals
, NEW_ID
);
39 if (bit
.wire
== NULL
|| sigbit_users_count
[bit
] == 0) {
43 ff
.sig_clr
.append(State::Sx
);
44 ff
.sig_set
.append(State::Sx
);
45 ff
.val_init
.bits
.push_back(State::Sx
);
46 ff
.val_srst
.bits
.push_back(State::Sx
);
47 ff
.val_arst
.bits
.push_back(State::Sx
);
51 if (sigbit_users_count
[bit
] != 1)
54 auto &sinks
= dff_sink
[bit
];
55 if (sinks
.size() != 1)
60 std::tie(cell
, idx
) = *sinks
.begin();
61 bits
.insert(std::make_pair(cell
, idx
));
63 FfData
cur_ff(initvals
, cell
);
65 // Reject latches and $ff.
69 log_assert((*sigmap
)(cur_ff
.sig_d
[idx
]) == bit
);
72 ff
.sig_clk
= cur_ff
.sig_clk
;
73 ff
.sig_ce
= cur_ff
.sig_ce
;
74 ff
.sig_aload
= cur_ff
.sig_aload
;
75 ff
.sig_srst
= cur_ff
.sig_srst
;
76 ff
.sig_arst
= cur_ff
.sig_arst
;
77 ff
.has_clk
= cur_ff
.has_clk
;
78 ff
.has_ce
= cur_ff
.has_ce
;
79 ff
.has_aload
= cur_ff
.has_aload
;
80 ff
.has_srst
= cur_ff
.has_srst
;
81 ff
.has_arst
= cur_ff
.has_arst
;
82 ff
.has_sr
= cur_ff
.has_sr
;
83 ff
.ce_over_srst
= cur_ff
.ce_over_srst
;
84 ff
.pol_clk
= cur_ff
.pol_clk
;
85 ff
.pol_ce
= cur_ff
.pol_ce
;
86 ff
.pol_aload
= cur_ff
.pol_aload
;
87 ff
.pol_arst
= cur_ff
.pol_arst
;
88 ff
.pol_srst
= cur_ff
.pol_srst
;
89 ff
.pol_clr
= cur_ff
.pol_clr
;
90 ff
.pol_set
= cur_ff
.pol_set
;
92 if (ff
.has_clk
!= cur_ff
.has_clk
)
94 if (ff
.has_ce
!= cur_ff
.has_ce
)
96 if (ff
.has_aload
!= cur_ff
.has_aload
)
98 if (ff
.has_srst
!= cur_ff
.has_srst
)
100 if (ff
.has_arst
!= cur_ff
.has_arst
)
102 if (ff
.has_sr
!= cur_ff
.has_sr
)
105 if (ff
.sig_clk
!= cur_ff
.sig_clk
)
107 if (ff
.pol_clk
!= cur_ff
.pol_clk
)
111 if (ff
.sig_ce
!= cur_ff
.sig_ce
)
113 if (ff
.pol_ce
!= cur_ff
.pol_ce
)
117 if (ff
.sig_aload
!= cur_ff
.sig_aload
)
119 if (ff
.pol_aload
!= cur_ff
.pol_aload
)
123 if (ff
.sig_srst
!= cur_ff
.sig_srst
)
125 if (ff
.pol_srst
!= cur_ff
.pol_srst
)
127 if (ff
.has_ce
&& ff
.ce_over_srst
!= cur_ff
.ce_over_srst
)
131 if (ff
.sig_arst
!= cur_ff
.sig_arst
)
133 if (ff
.pol_arst
!= cur_ff
.pol_arst
)
137 if (ff
.pol_clr
!= cur_ff
.pol_clr
)
139 if (ff
.pol_set
!= cur_ff
.pol_set
)
145 ff
.sig_d
.append(cur_ff
.sig_d
[idx
]);
146 ff
.sig_ad
.append(ff
.has_aload
? cur_ff
.sig_ad
[idx
] : State::Sx
);
147 ff
.sig_q
.append(cur_ff
.sig_q
[idx
]);
148 ff
.sig_clr
.append(ff
.has_sr
? cur_ff
.sig_clr
[idx
] : State::S0
);
149 ff
.sig_set
.append(ff
.has_sr
? cur_ff
.sig_set
[idx
] : State::S0
);
150 ff
.val_arst
.bits
.push_back(ff
.has_arst
? cur_ff
.val_arst
[idx
] : State::Sx
);
151 ff
.val_srst
.bits
.push_back(ff
.has_srst
? cur_ff
.val_srst
[idx
] : State::Sx
);
152 ff
.val_init
.bits
.push_back(cur_ff
.val_init
[idx
]);
159 bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig
, FfData
&ff
, pool
<std::pair
<Cell
*, int>> &bits
) {
160 ff
= FfData(module
, initvals
, NEW_ID
);
165 pool
<int> const_bits
;
169 if (bit
.wire
== NULL
) {
170 const_bits
.insert(ff
.width
);
172 ff
.sig_q
.append(bit
);
173 ff
.sig_d
.append(bit
);
174 // These two will be fixed up later.
175 ff
.sig_clr
.append(State::Sx
);
176 ff
.sig_set
.append(State::Sx
);
177 ff
.val_init
.bits
.push_back(bit
.data
);
178 ff
.val_srst
.bits
.push_back(bit
.data
);
179 ff
.val_arst
.bits
.push_back(bit
.data
);
183 if (!dff_driver
.count(bit
))
188 std::tie(cell
, idx
) = dff_driver
[bit
];
189 bits
.insert(std::make_pair(cell
, idx
));
191 FfData
cur_ff(initvals
, cell
);
193 log_assert((*sigmap
)(cur_ff
.sig_q
[idx
]) == bit
);
196 ff
.sig_clk
= cur_ff
.sig_clk
;
197 ff
.sig_ce
= cur_ff
.sig_ce
;
198 ff
.sig_aload
= cur_ff
.sig_aload
;
199 ff
.sig_srst
= cur_ff
.sig_srst
;
200 ff
.sig_arst
= cur_ff
.sig_arst
;
201 ff
.has_clk
= cur_ff
.has_clk
;
202 ff
.has_gclk
= cur_ff
.has_gclk
;
203 ff
.has_ce
= cur_ff
.has_ce
;
204 ff
.has_aload
= cur_ff
.has_aload
;
205 ff
.has_srst
= cur_ff
.has_srst
;
206 ff
.has_arst
= cur_ff
.has_arst
;
207 ff
.has_sr
= cur_ff
.has_sr
;
208 ff
.ce_over_srst
= cur_ff
.ce_over_srst
;
209 ff
.pol_clk
= cur_ff
.pol_clk
;
210 ff
.pol_ce
= cur_ff
.pol_ce
;
211 ff
.pol_aload
= cur_ff
.pol_aload
;
212 ff
.pol_arst
= cur_ff
.pol_arst
;
213 ff
.pol_srst
= cur_ff
.pol_srst
;
214 ff
.pol_clr
= cur_ff
.pol_clr
;
215 ff
.pol_set
= cur_ff
.pol_set
;
217 if (ff
.has_gclk
!= cur_ff
.has_gclk
)
219 if (ff
.has_clk
!= cur_ff
.has_clk
)
221 if (ff
.has_ce
!= cur_ff
.has_ce
)
223 if (ff
.has_aload
!= cur_ff
.has_aload
)
225 if (ff
.has_srst
!= cur_ff
.has_srst
)
227 if (ff
.has_arst
!= cur_ff
.has_arst
)
229 if (ff
.has_sr
!= cur_ff
.has_sr
)
232 if (ff
.sig_clk
!= cur_ff
.sig_clk
)
234 if (ff
.pol_clk
!= cur_ff
.pol_clk
)
238 if (ff
.sig_ce
!= cur_ff
.sig_ce
)
240 if (ff
.pol_ce
!= cur_ff
.pol_ce
)
244 if (ff
.sig_aload
!= cur_ff
.sig_aload
)
246 if (ff
.pol_aload
!= cur_ff
.pol_aload
)
250 if (ff
.sig_srst
!= cur_ff
.sig_srst
)
252 if (ff
.pol_srst
!= cur_ff
.pol_srst
)
254 if (ff
.has_ce
&& ff
.ce_over_srst
!= cur_ff
.ce_over_srst
)
258 if (ff
.sig_arst
!= cur_ff
.sig_arst
)
260 if (ff
.pol_arst
!= cur_ff
.pol_arst
)
264 if (ff
.pol_clr
!= cur_ff
.pol_clr
)
266 if (ff
.pol_set
!= cur_ff
.pol_set
)
272 ff
.sig_d
.append((ff
.has_clk
|| ff
.has_gclk
) ? cur_ff
.sig_d
[idx
] : State::Sx
);
273 ff
.sig_ad
.append(ff
.has_aload
? cur_ff
.sig_ad
[idx
] : State::Sx
);
274 ff
.sig_q
.append(cur_ff
.sig_q
[idx
]);
275 ff
.sig_clr
.append(ff
.has_sr
? cur_ff
.sig_clr
[idx
] : State::S0
);
276 ff
.sig_set
.append(ff
.has_sr
? cur_ff
.sig_set
[idx
] : State::S0
);
277 ff
.val_arst
.bits
.push_back(ff
.has_arst
? cur_ff
.val_arst
[idx
] : State::Sx
);
278 ff
.val_srst
.bits
.push_back(ff
.has_srst
? cur_ff
.val_srst
[idx
] : State::Sx
);
279 ff
.val_init
.bits
.push_back(cur_ff
.val_init
[idx
]);
283 if (found
&& ff
.has_sr
) {
284 for (auto i
: const_bits
) {
285 if (ff
.sig_d
[i
] == State::S0
) {
286 ff
.sig_set
[i
] = ff
.pol_set
? State::S0
: State::S1
;
287 } else if (ff
.sig_d
[i
] == State::S1
) {
288 ff
.sig_clr
[i
] = ff
.pol_clr
? State::S0
: State::S1
;
297 void FfMergeHelper::remove_output_ff(const pool
<std::pair
<Cell
*, int>> &bits
) {
298 for (auto &it
: bits
) {
299 Cell
*cell
= it
.first
;
301 SigSpec q
= cell
->getPort(ID::Q
);
302 initvals
->remove_init(q
[idx
]);
303 dff_driver
.erase((*sigmap
)(q
[idx
]));
304 q
[idx
] = module
->addWire(stringf("$ffmerge_disconnected$%d", autoidx
++));
305 cell
->setPort(ID::Q
, q
);
309 void FfMergeHelper::mark_input_ff(const pool
<std::pair
<Cell
*, int>> &bits
) {
310 for (auto &it
: bits
) {
311 Cell
*cell
= it
.first
;
313 if (cell
->hasPort(ID::D
)) {
314 SigSpec d
= cell
->getPort(ID::D
);
315 // The user count was already at least 1
316 // (for the D port). Bump it as it is now connected
317 // to the merged-to cell as well. This suffices for
318 // it to not be considered for output merging.
319 sigbit_users_count
[d
[idx
]]++;
324 void FfMergeHelper::set(FfInitVals
*initvals_
, RTLIL::Module
*module_
)
327 initvals
= initvals_
;
328 sigmap
= initvals
->sigmap
;
331 for (auto wire
: module
->wires()) {
332 if (wire
->port_output
)
333 for (auto bit
: (*sigmap
)(wire
))
334 sigbit_users_count
[bit
]++;
337 for (auto cell
: module
->cells()) {
338 if (RTLIL::builtin_ff_cell_types().count(cell
->type
)) {
339 if (cell
->hasPort(ID::D
)) {
340 SigSpec d
= (*sigmap
)(cell
->getPort(ID::D
));
341 for (int i
= 0; i
< GetSize(d
); i
++)
342 dff_sink
[d
[i
]].insert(std::make_pair(cell
, i
));
344 SigSpec q
= (*sigmap
)(cell
->getPort(ID::Q
));
345 for (int i
= 0; i
< GetSize(q
); i
++)
346 dff_driver
[q
[i
]] = std::make_pair(cell
, i
);
348 for (auto &conn
: cell
->connections())
349 if (!cell
->known() || cell
->input(conn
.first
))
350 for (auto bit
: (*sigmap
)(conn
.second
))
351 sigbit_users_count
[bit
]++;
355 void FfMergeHelper::clear() {
358 sigbit_users_count
.clear();