Merge pull request #1167 from YosysHQ/eddie/xc7srl_cleanup
[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(" -keepdc\n");
82 log(" do not optimize explicit don't-care values on $mux cells.\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, keepdc;
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 abc = "abc";
108 keepdc = false;
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] == "-keepdc") {
175 keepdc = 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)");
187
188 log_header(design, "Executing SYNTH pass.\n");
189 log_push();
190
191 run_script(design, run_from, run_to);
192
193 log_pop();
194 }
195
196 void script() YS_OVERRIDE
197 {
198 if (check_label("begin"))
199 {
200 if (help_mode) {
201 run("hierarchy -check [-top <top> | -auto-top]");
202 } else {
203 if (top_module.empty()) {
204 if (flatten || autotop)
205 run("hierarchy -check -auto-top");
206 else
207 run("hierarchy -check");
208 } else
209 run(stringf("hierarchy -check -top %s", top_module.c_str()));
210 }
211 }
212
213 if (check_label("coarse"))
214 {
215 run("proc");
216 if (help_mode || flatten)
217 run("flatten", " (if -flatten)");
218 run("opt_expr");
219 run("opt_clean");
220 run("check");
221 run("opt");
222 if (help_mode)
223 run("wreduce [-keepdc]");
224 else
225 run("wreduce" + std::string(keepdc ? " -keepdc" : ""));
226 run("peepopt");
227 run("opt_clean");
228 if (help_mode)
229 run("techmap -map +/cmp2lut.v", " (if -lut)");
230 else
231 run(stringf("techmap -map +/cmp2lut.v -D LUT_WIDTH=%d", lut));
232 if (!noalumacc)
233 run("alumacc", " (unless -noalumacc)");
234 if (!noshare)
235 run("share", " (unless -noshare)");
236 run("opt");
237 if (!nofsm)
238 run("fsm" + fsm_opts, " (unless -nofsm)");
239 run("opt -fast");
240 run("memory -nomap" + memory_opts);
241 run("opt_clean");
242 }
243
244 if (check_label("fine"))
245 {
246 run("opt -fast -full");
247 run("memory_map");
248 run("opt -full");
249 run("techmap");
250 if (help_mode)
251 {
252 run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
253 run("clean; opt_lut", " (if -noabc 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 run("opt -fast");
261
262 if (!noabc) {
263 #ifdef YOSYS_ENABLE_ABC
264 if (help_mode)
265 {
266 run(abc + " -fast", " (unless -noabc, unless -lut)");
267 run(abc + " -fast -lut k", "(unless -noabc, if -lut)");
268 }
269 else
270 {
271 if (lut)
272 run(stringf("%s -fast -lut %d", abc.c_str(), lut));
273 else
274 run(abc + " -fast");
275 }
276 run("opt -fast", " (unless -noabc)");
277 #endif
278 }
279 }
280
281 if (check_label("check"))
282 {
283 run("hierarchy -check");
284 run("stat");
285 run("check");
286 }
287 }
288 } SynthPass;
289
290 PRIVATE_NAMESPACE_END