Try new LUT delays
[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 abc9 instead of abc\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 log_header(design, "Executing SYNTH pass.\n");
178 log_push();
179
180 run_script(design, run_from, run_to);
181
182 log_pop();
183 }
184
185 void script() YS_OVERRIDE
186 {
187 if (check_label("begin"))
188 {
189 if (help_mode) {
190 run("hierarchy -check [-top <top> | -auto-top]");
191 } else {
192 if (top_module.empty()) {
193 if (flatten || autotop)
194 run("hierarchy -check -auto-top");
195 else
196 run("hierarchy -check");
197 } else
198 run(stringf("hierarchy -check -top %s", top_module.c_str()));
199 }
200 }
201
202 if (check_label("coarse"))
203 {
204 run("proc");
205 if (help_mode || flatten)
206 run("flatten", " (if -flatten)");
207 run("opt_expr");
208 run("opt_clean");
209 run("check");
210 run("opt");
211 run("wreduce");
212 run("peepopt");
213 run("opt_clean");
214 if (help_mode)
215 run("techmap -map +/cmp2lut.v", " (if -lut)");
216 else
217 run(stringf("techmap -map +/cmp2lut.v -D LUT_WIDTH=%d", lut));
218 if (!noalumacc)
219 run("alumacc", " (unless -noalumacc)");
220 if (!noshare)
221 run("share", " (unless -noshare)");
222 run("opt");
223 if (!nofsm)
224 run("fsm" + fsm_opts, " (unless -nofsm)");
225 run("opt -fast");
226 run("memory -nomap" + memory_opts);
227 run("opt_clean");
228 }
229
230 if (check_label("fine"))
231 {
232 run("opt -fast -full");
233 run("memory_map");
234 run("opt -full");
235 run("techmap");
236 if (help_mode)
237 {
238 run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
239 run("clean; opt_lut", " (if -noabc and -lut)");
240 }
241 else if (noabc && lut)
242 {
243 run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut));
244 run("clean; opt_lut");
245 }
246 run("opt -fast");
247
248 if (!noabc) {
249 #ifdef YOSYS_ENABLE_ABC
250 if (help_mode)
251 {
252 run(abc + " -fast", " (unless -noabc, unless -lut)");
253 run(abc + " -fast -lut k", "(unless -noabc, if -lut)");
254 }
255 else
256 {
257 if (lut)
258 run(stringf("%s -fast -lut %d", abc.c_str(), lut));
259 else
260 run(abc + " -fast");
261 }
262 run("opt -fast", " (unless -noabc)");
263 #endif
264 }
265 }
266
267 if (check_label("check"))
268 {
269 run("hierarchy -check");
270 run("stat");
271 run("check");
272 }
273 }
274 } SynthPass;
275
276 PRIVATE_NAMESPACE_END