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/sigtools.h"
24 PRIVATE_NAMESPACE_BEGIN
28 RTLIL::Design
*design
;
29 RTLIL::Module
*module
;
33 dict
<IdString
, vector
<IdString
>> memrd
, memwr
, meminit
;
34 pool
<IdString
> remove_mem
, remove_cells
;
36 OptMemWorker(RTLIL::Module
*module
) : design(module
->design
), module(module
), sigmap(module
), restart(false)
38 for (auto &it
: module
->memories
)
45 for (auto cell
: module
->cells())
47 if (cell
->type
== ID($memrd
)) {
48 IdString id
= cell
->getParam(ID::MEMID
).decode_string();
49 memrd
.at(id
).push_back(cell
->name
);
52 if (cell
->type
== ID($memwr
)) {
53 IdString id
= cell
->getParam(ID::MEMID
).decode_string();
54 memwr
.at(id
).push_back(cell
->name
);
57 if (cell
->type
== ID($meminit
)) {
58 IdString id
= cell
->getParam(ID::MEMID
).decode_string();
59 meminit
.at(id
).push_back(cell
->name
);
66 for (auto it
: remove_mem
)
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
));
75 delete module
->memories
.at(it
);
76 module
->memories
.erase(it
);
79 for (auto cell_name
: remove_cells
)
80 module
->remove(module
->cell(cell_name
));
83 int run(RTLIL::Memory
*mem
)
85 if (restart
|| remove_mem
.count(mem
->name
))
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
);
98 struct OptMemPass
: public Pass
{
99 OptMemPass() : Pass("opt_mem", "optimize memories") { }
100 void help() YS_OVERRIDE
102 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
104 log(" opt_mem [options] [selection]\n");
106 log("This pass performs various optimizations on memories in the design.\n");
109 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
111 log_header(design
, "Executing OPT_MEM pass (optimize memories).\n");
114 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
115 // if (args[argidx] == "-nomux") {
116 // mode_nomux = true;
121 extra_args(args
, argidx
, design
);
124 for (auto module
: design
->selected_modules()) {
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
)
138 design
->scratchpad_set_bool("opt.did_something", true);
139 log("Performed a total of %d transformations.\n", total_count
);
143 PRIVATE_NAMESPACE_END