SigSpec refactoring: change RTLIL::SigSpec::chunks() to be read-only, created interim...
[yosys.git] / passes / cmds / delete.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/register.h"
21 #include "kernel/rtlil.h"
22 #include "kernel/log.h"
23
24 struct DeleteWireWorker
25 {
26 RTLIL::Module *module;
27 std::set<std::string> *delete_wires_p;
28
29 void operator()(RTLIL::SigSpec &sig) {
30 sig.optimize();
31 for (auto &c : sig.chunks_rw())
32 if (c.wire != NULL && delete_wires_p->count(c.wire->name)) {
33 c.wire = module->addWire(NEW_ID, c.width);
34 c.offset = 0;
35 }
36 }
37 };
38
39 struct DeletePass : public Pass {
40 DeletePass() : Pass("delete", "delete objects in the design") { }
41 virtual void help()
42 {
43 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
44 log("\n");
45 log(" delete [selection]\n");
46 log("\n");
47 log("Deletes the selected objects. This will also remove entire modules, if the\n");
48 log("whole module is selected.\n");
49 log("\n");
50 log("\n");
51 log(" delete {-input|-output|-port} [selection]\n");
52 log("\n");
53 log("Does not delete any object but removes the input and/or output flag on the\n");
54 log("selected wires, thus 'deleting' module ports.\n");
55 log("\n");
56 }
57 virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
58 {
59 bool flag_input = false;
60 bool flag_output = false;
61
62 size_t argidx;
63 for (argidx = 1; argidx < args.size(); argidx++)
64 {
65 if (args[argidx] == "-input") {
66 flag_input = true;
67 continue;
68 }
69 if (args[argidx] == "-output") {
70 flag_output = true;
71 continue;
72 }
73 if (args[argidx] == "-port") {
74 flag_input = true;
75 flag_output = true;
76 continue;
77 }
78 break;
79 }
80 extra_args(args, argidx, design);
81
82 std::vector<std::string> delete_mods;
83
84 for (auto &mod_it : design->modules)
85 {
86 if (design->selected_whole_module(mod_it.first) && !flag_input && !flag_output) {
87 delete_mods.push_back(mod_it.first);
88 continue;
89 }
90
91 if (!design->selected_module(mod_it.first))
92 continue;
93
94 RTLIL::Module *module = mod_it.second;
95
96 if (flag_input || flag_output) {
97 for (auto &it : module->wires)
98 if (design->selected(module, it.second)) {
99 if (flag_input)
100 it.second->port_input = false;
101 if (flag_output)
102 it.second->port_output = false;
103 }
104 module->fixup_ports();
105 continue;
106 }
107
108 std::set<std::string> delete_wires;
109 std::set<std::string> delete_cells;
110 std::set<std::string> delete_procs;
111 std::set<std::string> delete_mems;
112
113 for (auto &it : module->wires)
114 if (design->selected(module, it.second))
115 delete_wires.insert(it.first);
116
117 for (auto &it : module->memories)
118 if (design->selected(module, it.second))
119 delete_mems.insert(it.first);
120
121 for (auto &it : module->cells) {
122 if (design->selected(module, it.second))
123 delete_cells.insert(it.first);
124 if ((it.second->type == "$memrd" || it.second->type == "$memwr") &&
125 delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0)
126 delete_cells.insert(it.first);
127 }
128
129 for (auto &it : module->processes)
130 if (design->selected(module, it.second))
131 delete_procs.insert(it.first);
132
133 DeleteWireWorker delete_wire_worker;
134 delete_wire_worker.module = module;
135 delete_wire_worker.delete_wires_p = &delete_wires;
136 module->rewrite_sigspecs(delete_wire_worker);
137
138 for (auto &it : delete_wires) {
139 delete module->wires.at(it);
140 module->wires.erase(it);
141 }
142
143 for (auto &it : delete_mems) {
144 delete module->memories.at(it);
145 module->memories.erase(it);
146 }
147
148 for (auto &it : delete_cells) {
149 delete module->cells.at(it);
150 module->cells.erase(it);
151 }
152
153 for (auto &it : delete_procs) {
154 delete module->processes.at(it);
155 module->processes.erase(it);
156 }
157
158 module->fixup_ports();
159 }
160
161 for (auto &it : delete_mods) {
162 delete design->modules.at(it);
163 design->modules.erase(it);
164 }
165 }
166 } DeletePass;
167