Revert "Merge pull request #1917 from YosysHQ/eddie/abc9_delay_check"
[yosys.git] / passes / opt / opt_mem.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/sigtools.h"
22
23 USING_YOSYS_NAMESPACE
24 PRIVATE_NAMESPACE_BEGIN
25
26 struct OptMemWorker
27 {
28 RTLIL::Design *design;
29 RTLIL::Module *module;
30 SigMap sigmap;
31 bool restart;
32
33 dict<IdString, vector<IdString>> memrd, memwr, meminit;
34 pool<IdString> remove_mem, remove_cells;
35
36 OptMemWorker(RTLIL::Module *module) : design(module->design), module(module), sigmap(module), restart(false)
37 {
38 for (auto &it : module->memories)
39 {
40 memrd[it.first];
41 memwr[it.first];
42 meminit[it.first];
43 }
44
45 for (auto cell : module->cells())
46 {
47 if (cell->type == ID($memrd)) {
48 IdString id = cell->getParam(ID::MEMID).decode_string();
49 memrd.at(id).push_back(cell->name);
50 }
51
52 if (cell->type == ID($memwr)) {
53 IdString id = cell->getParam(ID::MEMID).decode_string();
54 memwr.at(id).push_back(cell->name);
55 }
56
57 if (cell->type == ID($meminit)) {
58 IdString id = cell->getParam(ID::MEMID).decode_string();
59 meminit.at(id).push_back(cell->name);
60 }
61 }
62 }
63
64 ~OptMemWorker()
65 {
66 for (auto it : remove_mem)
67 {
68 for (auto cell_name : memrd[it])
69 module->remove(module->cell(cell_name));
70 for (auto cell_name : memwr[it])
71 module->remove(module->cell(cell_name));
72 for (auto cell_name : meminit[it])
73 module->remove(module->cell(cell_name));
74
75 delete module->memories.at(it);
76 module->memories.erase(it);
77 }
78
79 for (auto cell_name : remove_cells)
80 module->remove(module->cell(cell_name));
81 }
82
83 int run(RTLIL::Memory *mem)
84 {
85 if (restart || remove_mem.count(mem->name))
86 return 0;
87
88 if (memwr.at(mem->name).empty() && meminit.at(mem->name).empty()) {
89 log("Removing memory %s.%s with no write ports or init data.\n", log_id(module), log_id(mem));
90 remove_mem.insert(mem->name);
91 return 1;
92 }
93
94 return 0;
95 }
96 };
97
98 struct OptMemPass : public Pass {
99 OptMemPass() : Pass("opt_mem", "optimize memories") { }
100 void help() YS_OVERRIDE
101 {
102 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
103 log("\n");
104 log(" opt_mem [options] [selection]\n");
105 log("\n");
106 log("This pass performs various optimizations on memories in the design.\n");
107 log("\n");
108 }
109 void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
110 {
111 log_header(design, "Executing OPT_MEM pass (optimize memories).\n");
112
113 size_t argidx;
114 for (argidx = 1; argidx < args.size(); argidx++) {
115 // if (args[argidx] == "-nomux") {
116 // mode_nomux = true;
117 // continue;
118 // }
119 break;
120 }
121 extra_args(args, argidx, design);
122
123 int total_count = 0;
124 for (auto module : design->selected_modules()) {
125 while (1) {
126 int cnt = 0;
127 OptMemWorker worker(module);
128 for (auto &it : module->memories)
129 if (module->selected(it.second))
130 cnt += worker.run(it.second);
131 if (!cnt && !worker.restart)
132 break;
133 total_count += cnt;
134 }
135 }
136
137 if (total_count)
138 design->scratchpad_set_bool("opt.did_something", true);
139 log("Performed a total of %d transformations.\n", total_count);
140 }
141 } OptMemPass;
142
143 PRIVATE_NAMESPACE_END