ice40: Adapt the relut process passes to the new $lut <=> SB_LUT4 port map
[yosys.git] / passes / cmds / torder.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
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.
9 *
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.
17 *
18 */
19
20 #include "kernel/yosys.h"
21 #include "kernel/celltypes.h"
22 #include "kernel/sigtools.h"
23 #include "kernel/utils.h"
24
25 USING_YOSYS_NAMESPACE
26 PRIVATE_NAMESPACE_BEGIN
27
28 struct TorderPass : public Pass {
29 TorderPass() : Pass("torder", "print cells in topological order") { }
30 void help() YS_OVERRIDE
31 {
32 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
33 log("\n");
34 log(" torder [options] [selection]\n");
35 log("\n");
36 log("This command prints the selected cells in topological order.\n");
37 log("\n");
38 log(" -stop <cell_type> <cell_port>\n");
39 log(" do not use the specified cell port in topological sorting\n");
40 log("\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");
44 log("\n");
45 }
46 void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
47 {
48 bool noautostop = false;
49 dict<IdString, pool<IdString>> stop_db;
50
51 log_header(design, "Executing TORDER pass (print cells in topological order).\n");
52
53 size_t argidx;
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);
59 continue;
60 }
61 if (args[argidx] == "-noautostop") {
62 noautostop = true;
63 continue;
64 }
65 break;
66 }
67 extra_args(args, argidx, design);
68
69 for (auto module : design->selected_modules())
70 {
71 log("module %s\n", log_id(module));
72
73 SigMap sigmap(module);
74 dict<SigBit, pool<IdString>> bit_drivers, bit_users;
75 TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
76
77 for (auto cell : module->selected_cells())
78 for (auto conn : cell->connections())
79 {
80 if (stop_db.count(cell->type) && stop_db.at(cell->type).count(conn.first))
81 continue;
82
83 if (!noautostop && yosys_celltypes.cell_known(cell->type)) {
84 if (conn.first.in("\\Q", "\\CTRL_OUT", "\\RD_DATA"))
85 continue;
86 if (cell->type == "$memrd" && conn.first == "\\DATA")
87 continue;
88 }
89
90 if (cell->input(conn.first))
91 for (auto bit : sigmap(conn.second))
92 bit_users[bit].insert(cell->name);
93
94 if (cell->output(conn.first))
95 for (auto bit : sigmap(conn.second))
96 bit_drivers[bit].insert(cell->name);
97
98 toposort.node(cell->name);
99 }
100
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);
106
107 toposort.analyze_loops = true;
108 toposort.sort();
109
110 for (auto &it : toposort.loops) {
111 log(" loop");
112 for (auto cell : it)
113 log(" %s", log_id(cell));
114 log("\n");
115 }
116
117 for (auto cell : toposort.sorted)
118 log(" cell %s\n", log_id(cell));
119 }
120 }
121 } TorderPass;
122
123 PRIVATE_NAMESPACE_END