1 /*
2  *  yosys -- Yosys Open SYnthesis Suite
3  *
4  *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com>
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 
22 USING_YOSYS_NAMESPACE
23 PRIVATE_NAMESPACE_BEGIN
24 
25 struct DeletePass : public Pass {
DeletePassDeletePass26 	DeletePass() : Pass("delete", "delete objects in the design") { }
helpDeletePass27 	void help() override
28 	{
29 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
30 		log("\n");
31 		log("    delete [selection]\n");
32 		log("\n");
33 		log("Deletes the selected objects. This will also remove entire modules, if the\n");
34 		log("whole module is selected.\n");
35 		log("\n");
36 		log("\n");
37 		log("    delete {-input|-output|-port} [selection]\n");
38 		log("\n");
39 		log("Does not delete any object but removes the input and/or output flag on the\n");
40 		log("selected wires, thus 'deleting' module ports.\n");
41 		log("\n");
42 	}
executeDeletePass43 	void execute(std::vector<std::string> args, RTLIL::Design *design) override
44 	{
45 		bool flag_input = false;
46 		bool flag_output = false;
47 
48 		size_t argidx;
49 		for (argidx = 1; argidx < args.size(); argidx++)
50 		{
51 			if (args[argidx] == "-input") {
52 				flag_input = true;
53 				continue;
54 			}
55 			if (args[argidx] == "-output") {
56 				flag_output = true;
57 				continue;
58 			}
59 			if (args[argidx] == "-port") {
60 				flag_input = true;
61 				flag_output = true;
62 				continue;
63 			}
64 			break;
65 		}
66 		extra_args(args, argidx, design);
67 
68 		std::vector<RTLIL::Module *> delete_mods;
69 		for (auto module : design->modules())
70 		{
71 			if (design->selected_whole_module(module->name) && !flag_input && !flag_output) {
72 				delete_mods.push_back(module);
73 				continue;
74 			}
75 
76 			if (!design->selected_module(module->name))
77 				continue;
78 
79 			if (flag_input || flag_output) {
80 				for (auto wire : module->wires())
81 					if (design->selected(module, wire)) {
82 						if (flag_input)
83 							wire->port_input = false;
84 						if (flag_output)
85 							wire->port_output = false;
86 					}
87 				module->fixup_ports();
88 				continue;
89 			}
90 
91 			pool<RTLIL::Wire*> delete_wires;
92 			pool<RTLIL::Cell*> delete_cells;
93 			pool<RTLIL::Process*> delete_procs;
94 			pool<RTLIL::IdString> delete_mems;
95 
96 			for (auto wire : module->selected_wires())
97 				delete_wires.insert(wire);
98 
99 			for (auto &it : module->memories)
100 				if (design->selected(module, it.second))
101 					delete_mems.insert(it.first);
102 
103 			for (auto cell : module->cells()) {
104 				if (design->selected(module, cell))
105 					delete_cells.insert(cell);
106 				if (cell->has_memid() &&
107 						delete_mems.count(cell->parameters.at(ID::MEMID).decode_string()) != 0)
108 					delete_cells.insert(cell);
109 			}
110 
111 			for (auto &it : module->processes)
112 				if (design->selected(module, it.second))
113 					delete_procs.insert(it.second);
114 
115 			for (auto &it : delete_mems) {
116 				delete module->memories.at(it);
117 				module->memories.erase(it);
118 			}
119 
120 			for (auto &it : delete_cells)
121 				module->remove(it);
122 
123 			for (auto &it : delete_procs)
124 				module->remove(it);
125 
126 			module->remove(delete_wires);
127 
128 			module->fixup_ports();
129 		}
130 
131 		for (auto mod : delete_mods) {
132 			design->remove(mod);
133 		}
134 	}
135 } DeletePass;
136 
137 PRIVATE_NAMESPACE_END
138