Call opt_expr -mux_undef to get rid of 1'bx in muxes prior to abc
[yosys.git] / techlibs / common / synth.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/celltypes.h"
22 #include "kernel/rtlil.h"
23 #include "kernel/log.h"
24
25 USING_YOSYS_NAMESPACE
26 PRIVATE_NAMESPACE_BEGIN
27
28 struct SynthPass : public ScriptPass
29 {
30 SynthPass() : ScriptPass("synth", "generic synthesis script") { }
31
32 void help() YS_OVERRIDE
33 {
34 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
35 log("\n");
36 log(" synth [options]\n");
37 log("\n");
38 log("This command runs the default synthesis script. This command does not operate\n");
39 log("on partly selected designs.\n");
40 log("\n");
41 log(" -top <module>\n");
42 log(" use the specified module as top module (default='top')\n");
43 log("\n");
44 log(" -auto-top\n");
45 log(" automatically determine the top of the design hierarchy\n");
46 log("\n");
47 log(" -flatten\n");
48 log(" flatten the design before synthesis. this will pass '-auto-top' to\n");
49 log(" 'hierarchy' if no top module is specified.\n");
50 log("\n");
51 log(" -encfile <file>\n");
52 log(" passed to 'fsm_recode' via 'fsm'\n");
53 log("\n");
54 log(" -lut <k>\n");
55 log(" perform synthesis for a k-LUT architecture.\n");
56 log("\n");
57 log(" -nofsm\n");
58 log(" do not run FSM optimization\n");
59 log("\n");
60 log(" -noabc\n");
61 log(" do not run abc (as if yosys was compiled without ABC support)\n");
62 log("\n");
63 log(" -noalumacc\n");
64 log(" do not run 'alumacc' pass. i.e. keep arithmetic operators in\n");
65 log(" their direct form ($add, $sub, etc.).\n");
66 log("\n");
67 log(" -nordff\n");
68 log(" passed to 'memory'. prohibits merging of FFs into memory read ports\n");
69 log("\n");
70 log(" -noshare\n");
71 log(" do not run SAT-based resource sharing\n");
72 log("\n");
73 log(" -run <from_label>[:<to_label>]\n");
74 log(" only run the commands between the labels (see below). an empty\n");
75 log(" from label is synonymous to 'begin', and empty to label is\n");
76 log(" synonymous to the end of the command list.\n");
77 log("\n");
78 log(" -abc9\n");
79 log(" use new ABC9 flow (EXPERIMENTAL)\n");
80 log("\n");
81 log("\n");
82 log("The following commands are executed by this synthesis command:\n");
83 help_script();
84 log("\n");
85 }
86
87 string top_module, fsm_opts, memory_opts, abc;
88 bool autotop, flatten, noalumacc, nofsm, noabc, noshare;
89 int lut;
90
91 void clear_flags() YS_OVERRIDE
92 {
93 top_module.clear();
94 fsm_opts.clear();
95 memory_opts.clear();
96
97 autotop = false;
98 flatten = false;
99 lut = 0;
100 noalumacc = false;
101 nofsm = false;
102 noabc = false;
103 noshare = false;
104 abc = "abc";
105 }
106
107 void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
108 {
109 string run_from, run_to;
110 clear_flags();
111
112 size_t argidx;
113 for (argidx = 1; argidx < args.size(); argidx++)
114 {
115 if (args[argidx] == "-top" && argidx+1 < args.size()) {
116 top_module = args[++argidx];
117 continue;
118 }
119 if (args[argidx] == "-encfile" && argidx+1 < args.size()) {
120 fsm_opts = " -encfile " + args[++argidx];
121 continue;
122 }
123 if (args[argidx] == "-run" && argidx+1 < args.size()) {
124 size_t pos = args[argidx+1].find(':');
125 if (pos == std::string::npos) {
126 run_from = args[++argidx];
127 run_to = args[argidx];
128 } else {
129 run_from = args[++argidx].substr(0, pos);
130 run_to = args[argidx].substr(pos+1);
131 }
132 continue;
133 }
134 if (args[argidx] == "-auto-top") {
135 autotop = true;
136 continue;
137 }
138 if (args[argidx] == "-flatten") {
139 flatten = true;
140 continue;
141 }
142 if (args[argidx] == "-lut") {
143 lut = atoi(args[++argidx].c_str());
144 continue;
145 }
146 if (args[argidx] == "-nofsm") {
147 nofsm = true;
148 continue;
149 }
150 if (args[argidx] == "-noabc") {
151 noabc = true;
152 continue;
153 }
154 if (args[argidx] == "-noalumacc") {
155 noalumacc = true;
156 continue;
157 }
158 if (args[argidx] == "-nordff") {
159 memory_opts += " -nordff";
160 continue;
161 }
162 if (args[argidx] == "-noshare") {
163 noshare = true;
164 continue;
165 }
166 if (args[argidx] == "-abc9") {
167 abc = "abc9";
168 continue;
169 }
170 break;
171 }
172 extra_args(args, argidx, design);
173
174 if (!design->full_selection())
175 log_cmd_error("This command only operates on fully selected designs!\n");
176
177 if (abc == "abc9" && !lut)
178 log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)");
179
180 log_header(design, "Executing SYNTH pass.\n");
181 log_push();
182
183 run_script(design, run_from, run_to);
184
185 log_pop();
186 }
187
188 void script() YS_OVERRIDE
189 {
190 if (check_label("begin"))
191 {
192 if (help_mode) {
193 run("hierarchy -check [-top <top> | -auto-top]");
194 } else {
195 if (top_module.empty()) {
196 if (flatten || autotop)
197 run("hierarchy -check -auto-top");
198 else
199 run("hierarchy -check");
200 } else
201 run(stringf("hierarchy -check -top %s", top_module.c_str()));
202 }
203 }
204
205 if (check_label("coarse"))
206 {
207 run("proc");
208 if (help_mode || flatten)
209 run("flatten", " (if -flatten)");
210 run("opt_expr");
211 run("opt_clean");
212 run("check");
213 run("opt");
214 run("wreduce");
215 run("peepopt");
216 run("opt_clean");
217 if (help_mode)
218 run("techmap -map +/cmp2lut.v", " (if -lut)");
219 else
220 run(stringf("techmap -map +/cmp2lut.v -D LUT_WIDTH=%d", lut));
221 if (!noalumacc)
222 run("alumacc", " (unless -noalumacc)");
223 if (!noshare)
224 run("share", " (unless -noshare)");
225 run("opt");
226 if (!nofsm)
227 run("fsm" + fsm_opts, " (unless -nofsm)");
228 run("opt -fast");
229 run("memory -nomap" + memory_opts);
230 run("opt_clean");
231 }
232
233 if (check_label("fine"))
234 {
235 run("opt -fast -full");
236 run("memory_map");
237 run("opt -full");
238 run("techmap");
239 if (help_mode)
240 {
241 run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
242 run("clean; opt_lut", " (if -noabc and -lut)");
243 }
244 else if (noabc && lut)
245 {
246 run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut));
247 run("clean; opt_lut");
248 }
249 run("opt -fast");
250
251 if (!noabc) {
252 #ifdef YOSYS_ENABLE_ABC
253 if (help_mode)
254 {
255 run(abc + " -fast", " (unless -noabc, unless -lut)");
256 run(abc + " -fast -lut k", "(unless -noabc, if -lut)");
257 }
258 else
259 {
260 if (lut)
261 run(stringf("%s -fast -lut %d", abc.c_str(), lut));
262 else
263 run(abc + " -fast");
264 }
265 run("opt -fast", " (unless -noabc)");
266 #endif
267 }
268 }
269
270 if (check_label("check"))
271 {
272 run("hierarchy -check");
273 run("stat");
274 run("check");
275 }
276 }
277 } SynthPass;
278
279 PRIVATE_NAMESPACE_END