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.
23 #include "kernel/celltypes.h"
24 #include "kernel/rtlil.h"
25 #include "kernel/sigtools.h"
30 CellTypes
comb_cells_filt()
41 RTLIL::Module
*module
;
44 dict
<RTLIL::SigBit
, Cell
*> sigbit_driver_map
;
45 dict
<RTLIL::Cell
*, std::set
<RTLIL::SigBit
>> cell_inputs_map
;
47 Netlist(RTLIL::Module
*module
) : module(module
), sigmap(module
), ct(module
->design
) { setup_netlist(module
, ct
); }
49 Netlist(RTLIL::Module
*module
, const CellTypes
&ct
) : module(module
), sigmap(module
), ct(ct
) { setup_netlist(module
, ct
); }
51 RTLIL::Cell
*driver_cell(RTLIL::SigBit sig
) const
54 if (!sigbit_driver_map
.count(sig
)) {
58 return sigbit_driver_map
.at(sig
);
61 RTLIL::SigBit
& driver_port(RTLIL::SigBit sig
)
63 RTLIL::Cell
*cell
= driver_cell(sig
);
65 for (auto &port
: cell
->connections_
) {
66 if (ct
.cell_output(cell
->type
, port
.first
)) {
67 RTLIL::SigSpec port_sig
= sigmap(port
.second
);
68 for (int i
= 0; i
< GetSize(port_sig
); i
++) {
69 if (port_sig
[i
] == sig
) {
70 return port
.second
[i
];
77 void setup_netlist(RTLIL::Module
*module
, const CellTypes
&ct
)
79 for (auto cell
: module
->cells()) {
80 if (ct
.cell_known(cell
->type
)) {
81 std::set
<RTLIL::SigBit
> inputs
, outputs
;
82 for (auto &port
: cell
->connections()) {
83 std::vector
<RTLIL::SigBit
> bits
= sigmap(port
.second
).to_sigbit_vector();
84 if (ct
.cell_output(cell
->type
, port
.first
))
85 outputs
.insert(bits
.begin(), bits
.end());
87 inputs
.insert(bits
.begin(), bits
.end());
89 cell_inputs_map
[cell
] = inputs
;
90 for (auto &bit
: outputs
) {
91 sigbit_driver_map
[bit
] = cell
;
100 struct NetlistConeWireIter
: public std::iterator
<std::input_iterator_tag
, RTLIL::SigBit
> {
101 using set_iter_t
= std::set
<RTLIL::SigBit
>::iterator
;
106 CellTypes
*cell_filter
;
108 std::stack
<std::pair
<set_iter_t
, set_iter_t
>> dfs_path_stack
;
109 std::set
<RTLIL::Cell
*> cells_visited
;
111 NetlistConeWireIter(const Netlist
&net
) : net(net
), sentinel(true), cell_filter(NULL
) {}
113 NetlistConeWireIter(const Netlist
&net
, RTLIL::SigBit sig
, CellTypes
*cell_filter
= NULL
)
114 : net(net
), sig(sig
), sentinel(false), cell_filter(cell_filter
)
118 const RTLIL::SigBit
&operator*() const { return sig
; };
119 bool operator!=(const NetlistConeWireIter
&other
) const
121 if (sentinel
|| other
.sentinel
) {
122 return sentinel
!= other
.sentinel
;
124 return sig
!= other
.sig
;
128 bool operator==(const NetlistConeWireIter
&other
) const
130 if (sentinel
|| other
.sentinel
) {
131 return sentinel
== other
.sentinel
;
133 return sig
== other
.sig
;
137 void next_sig_in_dag()
140 if (dfs_path_stack
.empty()) {
145 auto &cell_inputs_iter
= dfs_path_stack
.top().first
;
146 auto &cell_inputs_iter_guard
= dfs_path_stack
.top().second
;
149 if (cell_inputs_iter
!= cell_inputs_iter_guard
) {
150 sig
= *cell_inputs_iter
;
153 dfs_path_stack
.pop();
158 NetlistConeWireIter
&operator++()
160 RTLIL::Cell
*cell
= net
.driver_cell(sig
);
167 if (cells_visited
.count(cell
)) {
172 if ((cell_filter
) && (!cell_filter
->cell_known(cell
->type
))) {
177 auto &inputs
= net
.cell_inputs_map
.at(cell
);
178 dfs_path_stack
.push(std::make_pair(inputs
.begin(), inputs
.end()));
179 cells_visited
.insert(cell
);
180 sig
= (*dfs_path_stack
.top().first
);
185 struct NetlistConeWireIterable
{
188 CellTypes
*cell_filter
;
190 NetlistConeWireIterable(const Netlist
&net
, RTLIL::SigBit sig
, CellTypes
*cell_filter
= NULL
) : net(net
), sig(sig
), cell_filter(cell_filter
)
194 NetlistConeWireIter
begin() { return NetlistConeWireIter(net
, sig
, cell_filter
); }
195 NetlistConeWireIter
end() { return NetlistConeWireIter(net
); }
198 struct NetlistConeCellIter
: public std::iterator
<std::input_iterator_tag
, RTLIL::Cell
*> {
201 NetlistConeWireIter sig_iter
;
203 NetlistConeCellIter(const Netlist
&net
) : net(net
), sig_iter(net
) {}
205 NetlistConeCellIter(const Netlist
&net
, RTLIL::SigBit sig
, CellTypes
*cell_filter
= NULL
) : net(net
), sig_iter(net
, sig
, cell_filter
)
207 if ((!sig_iter
.sentinel
) && (!has_driver_cell(*sig_iter
))) {
212 bool has_driver_cell(const RTLIL::SigBit
&s
) { return net
.sigbit_driver_map
.count(s
); }
214 RTLIL::Cell
*operator*() const { return net
.sigbit_driver_map
.at(*sig_iter
); };
216 bool operator!=(const NetlistConeCellIter
&other
) const { return sig_iter
!= other
.sig_iter
; }
217 bool operator==(const NetlistConeCellIter
&other
) const { return sig_iter
== other
.sig_iter
; }
218 NetlistConeCellIter
&operator++()
222 if (sig_iter
.sentinel
) {
226 RTLIL::Cell
* cell
= net
.driver_cell(*sig_iter
);
232 if ((sig_iter
.cell_filter
) && (!sig_iter
.cell_filter
->cell_known(cell
->type
))) {
236 if (!sig_iter
.cells_visited
.count(cell
)) {
243 struct NetlistConeCellIterable
{
246 CellTypes
*cell_filter
;
248 NetlistConeCellIterable(const Netlist
&net
, RTLIL::SigBit sig
, CellTypes
*cell_filter
= NULL
) : net(net
), sig(sig
), cell_filter(cell_filter
)
252 NetlistConeCellIter
begin() { return NetlistConeCellIter(net
, sig
, cell_filter
); }
253 NetlistConeCellIter
end() { return NetlistConeCellIter(net
); }
256 // struct NetlistConeInputsIter : public std::iterator<std::input_iterator_tag, const RTLIL::Cell *> {
257 // const Netlist &net;
258 // RTLIL::SigBit sig;
260 // NetlistConeWireIter sig_iter;
262 // bool has_driver_cell(const RTLIL::SigBit &s) { return net.sigbit_driver_map.count(s); }
264 // NetlistConeInputsIter(const Netlist &net, RTLIL::SigBit sig = NULL) : net(net), sig(sig), sig_iter(net, sig)
266 // if ((sig != NULL) && (has_driver_cell(sig_iter))) {
271 // const RTLIL::SigBit &operator*() const { return sig_iter; };
272 // bool operator!=(const NetlistConeInputsIter &other) const { return sig_iter != other.sig_iter; }
273 // bool operator==(const NetlistConeInputsIter &other) const { return sig_iter == other.sig_iter; }
274 // NetlistConeInputsIter &operator++()
278 // if (sig_iter->empty()) {
281 // } while (has_driver_cell(sig_iter));
287 // struct NetlistConeInputsIterable {
288 // const Netlist &net;
289 // RTLIL::SigBit sig;
291 // NetlistConeInputsIterable(const Netlist &net, RTLIL::SigBit sig) : net(net), sig(sig) {}
293 // NetlistConeInputsIter begin() { return NetlistConeInputsIter(net, sig); }
294 // NetlistConeInputsIter end() { return NetlistConeInputsIter(net); }
296 } // namespace detail
298 detail::NetlistConeWireIterable
cone(const Netlist
&net
, RTLIL::SigBit sig
, CellTypes
*cell_filter
= NULL
)
300 return detail::NetlistConeWireIterable(net
, net
.sigmap(sig
), cell_filter
= cell_filter
);
303 // detail::NetlistConeInputsIterable cone_inputs(RTLIL::SigBit sig) { return NetlistConeInputsIterable(this, &sig); }
304 detail::NetlistConeCellIterable
cell_cone(const Netlist
&net
, RTLIL::SigBit sig
, CellTypes
*cell_filter
= NULL
)
306 return detail::NetlistConeCellIterable(net
, net
.sigmap(sig
), cell_filter
);