abc9: generate $abc9_holes design instead of <name>$holes
[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(" -flowmap\n");
82 log(" use FlowMap LUT techmapping instead of ABC\n");
83 log("\n");
84 log("\n");
85 log("The following commands are executed by this synthesis command:\n");
86 help_script();
87 log("\n");
88 }
89
90 string top_module, fsm_opts, memory_opts, abc;
91 bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap;
92 int lut;
93
94 void clear_flags() YS_OVERRIDE
95 {
96 top_module.clear();
97 fsm_opts.clear();
98 memory_opts.clear();
99
100 autotop = false;
101 flatten = false;
102 lut = 0;
103 noalumacc = false;
104 nofsm = false;
105 noabc = false;
106 noshare = false;
107 flowmap = false;
108 abc = "abc";
109 }
110
111 void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
112 {
113 string run_from, run_to;
114 clear_flags();
115
116 size_t argidx;
117 for (argidx = 1; argidx < args.size(); argidx++)
118 {
119 if (args[argidx] == "-top" && argidx+1 < args.size()) {
120 top_module = args[++argidx];
121 continue;
122 }
123 if (args[argidx] == "-encfile" && argidx+1 < args.size()) {
124 fsm_opts = " -encfile " + args[++argidx];
125 continue;
126 }
127 if (args[argidx] == "-run" && argidx+1 < args.size()) {
128 size_t pos = args[argidx+1].find(':');
129 if (pos == std::string::npos) {
130 run_from = args[++argidx];
131 run_to = args[argidx];
132 } else {
133 run_from = args[++argidx].substr(0, pos);
134 run_to = args[argidx].substr(pos+1);
135 }
136 continue;
137 }
138 if (args[argidx] == "-auto-top") {
139 autotop = true;
140 continue;
141 }
142 if (args[argidx] == "-flatten") {
143 flatten = true;
144 continue;
145 }
146 if (args[argidx] == "-lut") {
147 lut = atoi(args[++argidx].c_str());
148 continue;
149 }
150 if (args[argidx] == "-nofsm") {
151 nofsm = true;
152 continue;
153 }
154 if (args[argidx] == "-noabc") {
155 noabc = true;
156 continue;
157 }
158 if (args[argidx] == "-noalumacc") {
159 noalumacc = true;
160 continue;
161 }
162 if (args[argidx] == "-nordff") {
163 memory_opts += " -nordff";
164 continue;
165 }
166 if (args[argidx] == "-noshare") {
167 noshare = true;
168 continue;
169 }
170 if (args[argidx] == "-abc9") {
171 abc = "abc9";
172 continue;
173 }
174 if (args[argidx] == "-flowmap") {
175 flowmap = true;
176 continue;
177 }
178 break;
179 }
180 extra_args(args, argidx, design);
181
182 if (!design->full_selection())
183 log_cmd_error("This command only operates on fully selected designs!\n");
184
185 if (abc == "abc9" && !lut)
186 log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)\n");
187 if (flowmap && !lut)
188 log_cmd_error("FlowMap is only supported for FPGA synthesis (using '-lut' option)\n");
189
190 log_header(design, "Executing SYNTH pass.\n");
191 log_push();
192
193 run_script(design, run_from, run_to);
194
195 log_pop();
196 }
197
198 void script() YS_OVERRIDE
199 {
200 if (check_label("begin"))
201 {
202 if (help_mode) {
203 run("hierarchy -check [-top <top> | -auto-top]");
204 } else {
205 if (top_module.empty()) {
206 if (flatten || autotop)
207 run("hierarchy -check -auto-top");
208 else
209 run("hierarchy -check");
210 } else
211 run(stringf("hierarchy -check -top %s", top_module.c_str()));
212 }
213 }
214
215 if (check_label("coarse"))
216 {
217 run("proc");
218 if (help_mode || flatten)
219 run("flatten", " (if -flatten)");
220 run("opt_expr");
221 run("opt_clean");
222 run("check");
223 run("opt");
224 run("wreduce");
225 run("peepopt");
226 run("opt_clean");
227 if (help_mode)
228 run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)");
229 else if (lut)
230 run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut));
231 if (!noalumacc)
232 run("alumacc", " (unless -noalumacc)");
233 if (!noshare)
234 run("share", " (unless -noshare)");
235 run("opt");
236 if (!nofsm)
237 run("fsm" + fsm_opts, " (unless -nofsm)");
238 run("opt -fast");
239 run("memory -nomap" + memory_opts);
240 run("opt_clean");
241 }
242
243 if (check_label("fine"))
244 {
245 run("opt -fast -full");
246 run("memory_map");
247 run("opt -full");
248 run("techmap");
249 if (help_mode)
250 {
251 run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
252 run("clean; opt_lut", " (if -noabc and -lut)");
253 run("flowmap -maxlut K", " (if -flowmap and -lut)");
254 }
255 else if (noabc && lut)
256 {
257 run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut));
258 run("clean; opt_lut");
259 }
260 else if (flowmap)
261 {
262 run(stringf("flowmap -maxlut %d", lut));
263 }
264 run("opt -fast");
265
266 if (!noabc && !flowmap) {
267 #ifdef YOSYS_ENABLE_ABC
268 if (help_mode)
269 {
270 run(abc + " -fast", " (unless -noabc, unless -lut)");
271 run(abc + " -fast -lut k", "(unless -noabc, if -lut)");
272 }
273 else
274 {
275 if (lut)
276 run(stringf("%s -fast -lut %d", abc.c_str(), lut));
277 else
278 run(abc + " -fast");
279 }
280 run("opt -fast", " (unless -noabc)");
281 #endif
282 }
283 }
284
285 if (check_label("check"))
286 {
287 run("hierarchy -check");
288 run("stat");
289 run("check");
290 }
291 }
292 } SynthPass;
293
294 PRIVATE_NAMESPACE_END