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/yosys.h"
21 #include "kernel/celltypes.h"
22 #include "kernel/sigtools.h"
23 #include "kernel/utils.h"
26 PRIVATE_NAMESPACE_BEGIN
28 struct TorderPass
: public Pass
{
29 TorderPass() : Pass("torder", "print cells in topological order") { }
30 void help() YS_OVERRIDE
32 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
34 log(" torder [options] [selection]\n");
36 log("This command prints the selected cells in topological order.\n");
38 log(" -stop <cell_type> <cell_port>\n");
39 log(" do not use the specified cell port in topological sorting\n");
41 log(" -noautostop\n");
42 log(" by default Q outputs of internal FF cells and memory read port outputs\n");
43 log(" are not used in topological sorting. this option deactivates that.\n");
46 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
48 bool noautostop
= false;
49 dict
<IdString
, pool
<IdString
>> stop_db
;
51 log_header(design
, "Executing TORDER pass (print cells in topological order).\n");
54 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
55 if (args
[argidx
] == "-stop" && argidx
+2 < args
.size()) {
56 IdString cell_type
= RTLIL::escape_id(args
[++argidx
]);
57 IdString cell_port
= RTLIL::escape_id(args
[++argidx
]);
58 stop_db
[cell_type
].insert(cell_port
);
61 if (args
[argidx
] == "-noautostop") {
67 extra_args(args
, argidx
, design
);
69 for (auto module
: design
->selected_modules())
71 log("module %s\n", log_id(module
));
73 SigMap
sigmap(module
);
74 dict
<SigBit
, pool
<IdString
>> bit_drivers
, bit_users
;
75 TopoSort
<IdString
, RTLIL::sort_by_id_str
> toposort
;
77 for (auto cell
: module
->selected_cells())
78 for (auto conn
: cell
->connections())
80 if (stop_db
.count(cell
->type
) && stop_db
.at(cell
->type
).count(conn
.first
))
83 if (!noautostop
&& yosys_celltypes
.cell_known(cell
->type
)) {
84 if (conn
.first
.in(ID::Q
, ID::CTRL_OUT
, ID::RD_DATA
))
86 if (cell
->type
== ID($memrd
) && conn
.first
== ID::DATA
)
90 if (cell
->input(conn
.first
))
91 for (auto bit
: sigmap(conn
.second
))
92 bit_users
[bit
].insert(cell
->name
);
94 if (cell
->output(conn
.first
))
95 for (auto bit
: sigmap(conn
.second
))
96 bit_drivers
[bit
].insert(cell
->name
);
98 toposort
.node(cell
->name
);
101 for (auto &it
: bit_users
)
102 if (bit_drivers
.count(it
.first
))
103 for (auto driver_cell
: bit_drivers
.at(it
.first
))
104 for (auto user_cell
: it
.second
)
105 toposort
.edge(driver_cell
, user_cell
);
107 toposort
.analyze_loops
= true;
110 for (auto &it
: toposort
.loops
) {
113 log(" %s", log_id(cell
));
117 for (auto cell
: toposort
.sorted
)
118 log(" cell %s\n", log_id(cell
));
123 PRIVATE_NAMESPACE_END