Move 'clean' from map_luts to finalize
[yosys.git] / techlibs / xilinx / synth_xilinx.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 * (C) 2019 Eddie Hung <eddie@fpgeh.com>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21 #include "kernel/register.h"
22 #include "kernel/celltypes.h"
23 #include "kernel/rtlil.h"
24 #include "kernel/log.h"
25
26 USING_YOSYS_NAMESPACE
27 PRIVATE_NAMESPACE_BEGIN
28
29 #define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate
30 // to one LUT6 (instead of a LUT5 + LUT2)
31
32 struct SynthXilinxPass : public ScriptPass
33 {
34 SynthXilinxPass() : ScriptPass("synth_xilinx", "synthesis for Xilinx FPGAs") { }
35
36 void help() YS_OVERRIDE
37 {
38 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
39 log("\n");
40 log(" synth_xilinx [options]\n");
41 log("\n");
42 log("This command runs synthesis for Xilinx FPGAs. This command does not operate on\n");
43 log("partly selected designs. At the moment this command creates netlists that are\n");
44 log("compatible with 7-Series Xilinx devices.\n");
45 log("\n");
46 log(" -top <module>\n");
47 log(" use the specified module as top module\n");
48 log("\n");
49 log(" -family {xcup|xcu|xc7|xc6v|xc5v|xc6s}\n");
50 log(" run synthesis for the specified Xilinx architecture\n");
51 log(" generate the synthesis netlist for the specified family.\n");
52 log(" default: xc7\n");
53 log("\n");
54 log(" -edif <file>\n");
55 log(" write the design to the specified edif file. writing of an output file\n");
56 log(" is omitted if this parameter is not specified.\n");
57 log("\n");
58 log(" -blif <file>\n");
59 log(" write the design to the specified BLIF file. writing of an output file\n");
60 log(" is omitted if this parameter is not specified.\n");
61 log("\n");
62 log(" -vpr\n");
63 log(" generate an output netlist (and BLIF file) suitable for VPR\n");
64 log(" (this feature is experimental and incomplete)\n");
65 log("\n");
66 log(" -ise\n");
67 log(" generate an output netlist suitable for ISE (enables -iopad)\n");
68 log("\n");
69 log(" -nobram\n");
70 log(" do not use block RAM cells in output netlist\n");
71 log("\n");
72 log(" -nolutram\n");
73 log(" do not use distributed RAM cells in output netlist\n");
74 log("\n");
75 log(" -nosrl\n");
76 log(" do not use distributed SRL cells in output netlist\n");
77 log("\n");
78 log(" -nocarry\n");
79 log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n");
80 log("\n");
81 log(" -nowidelut\n");
82 log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
83 log("\n");
84 log(" -nodsp\n");
85 log(" do not use DSP48E1s to implement multipliers and associated logic\n");
86 log("\n");
87 log(" -iopad\n");
88 log(" enable I/O buffer insertion (selected automatically by -ise)\n");
89 log("\n");
90 log(" -noiopad\n");
91 log(" disable I/O buffer insertion (only useful with -ise)\n");
92 log("\n");
93 log(" -noclkbuf\n");
94 log(" disable automatic clock buffer insertion\n");
95 log("\n");
96 log(" -uram\n");
97 log(" infer URAM288s for large memories (xcup only)\n");
98 log("\n");
99 log(" -widemux <int>\n");
100 log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
101 log(" above this number of inputs (minimum value 2, recommended value >= 5).\n");
102 log(" default: 0 (no inference)\n");
103 log("\n");
104 log(" -run <from_label>:<to_label>\n");
105 log(" only run the commands between the labels (see below). an empty\n");
106 log(" from label is synonymous to 'begin', and empty to label is\n");
107 log(" synonymous to the end of the command list.\n");
108 log("\n");
109 log(" -flatten\n");
110 log(" flatten design before synthesis\n");
111 log("\n");
112 log(" -retime\n");
113 log(" run 'abc' with -dff option\n");
114 log("\n");
115 log(" -abc9\n");
116 log(" use new ABC9 flow (EXPERIMENTAL)\n");
117 log("\n");
118 log("\n");
119 log("The following commands are executed by this synthesis command:\n");
120 help_script();
121 log("\n");
122 }
123
124 std::string top_opt, edif_file, blif_file, family;
125 bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram, abc9;
126 bool flatten_before_abc;
127 int widemux;
128
129 void clear_flags() YS_OVERRIDE
130 {
131 top_opt = "-auto-top";
132 edif_file.clear();
133 blif_file.clear();
134 family = "xc7";
135 flatten = false;
136 retime = false;
137 vpr = false;
138 ise = false;
139 iopad = false;
140 noiopad = false;
141 noclkbuf = false;
142 nocarry = false;
143 nobram = false;
144 nolutram = false;
145 nosrl = false;
146 nocarry = false;
147 nowidelut = false;
148 nodsp = false;
149 uram = false;
150 abc9 = false;
151 flatten_before_abc = false;
152 widemux = 0;
153 }
154
155 void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
156 {
157 std::string run_from, run_to;
158 clear_flags();
159
160 size_t argidx;
161 for (argidx = 1; argidx < args.size(); argidx++)
162 {
163 if (args[argidx] == "-top" && argidx+1 < args.size()) {
164 top_opt = "-top " + args[++argidx];
165 continue;
166 }
167 if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) {
168 family = args[++argidx];
169 continue;
170 }
171 if (args[argidx] == "-edif" && argidx+1 < args.size()) {
172 edif_file = args[++argidx];
173 continue;
174 }
175 if (args[argidx] == "-blif" && argidx+1 < args.size()) {
176 blif_file = args[++argidx];
177 continue;
178 }
179 if (args[argidx] == "-run" && argidx+1 < args.size()) {
180 size_t pos = args[argidx+1].find(':');
181 if (pos == std::string::npos)
182 break;
183 run_from = args[++argidx].substr(0, pos);
184 run_to = args[argidx].substr(pos+1);
185 continue;
186 }
187 if (args[argidx] == "-flatten") {
188 flatten = true;
189 continue;
190 }
191 if (args[argidx] == "-flatten_before_abc") {
192 flatten_before_abc = true;
193 continue;
194 }
195 if (args[argidx] == "-retime") {
196 retime = true;
197 continue;
198 }
199 if (args[argidx] == "-nocarry") {
200 nocarry = true;
201 continue;
202 }
203 if (args[argidx] == "-nowidelut") {
204 nowidelut = true;
205 continue;
206 }
207 if (args[argidx] == "-vpr") {
208 vpr = true;
209 continue;
210 }
211 if (args[argidx] == "-ise") {
212 ise = true;
213 continue;
214 }
215 if (args[argidx] == "-iopad") {
216 iopad = true;
217 continue;
218 }
219 if (args[argidx] == "-noiopad") {
220 noiopad = true;
221 continue;
222 }
223 if (args[argidx] == "-noclkbuf") {
224 noclkbuf = true;
225 continue;
226 }
227 if (args[argidx] == "-nocarry") {
228 nocarry = true;
229 continue;
230 }
231 if (args[argidx] == "-nobram") {
232 nobram = true;
233 continue;
234 }
235 if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") {
236 nolutram = true;
237 continue;
238 }
239 if (args[argidx] == "-nosrl") {
240 nosrl = true;
241 continue;
242 }
243 if (args[argidx] == "-widemux" && argidx+1 < args.size()) {
244 widemux = atoi(args[++argidx].c_str());
245 continue;
246 }
247 if (args[argidx] == "-abc9") {
248 abc9 = true;
249 continue;
250 }
251 if (args[argidx] == "-nodsp") {
252 nodsp = true;
253 continue;
254 }
255 if (args[argidx] == "-uram") {
256 uram = true;
257 continue;
258 }
259 break;
260 }
261 extra_args(args, argidx, design);
262
263 if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc5v" && family != "xc6s")
264 log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
265
266 if (widemux != 0 && widemux < 2)
267 log_cmd_error("-widemux value must be 0 or >= 2.\n");
268
269 if (!design->full_selection())
270 log_cmd_error("This command only operates on fully selected designs!\n");
271
272 if (abc9 && retime)
273 log_cmd_error("-retime option not currently compatible with -abc9!\n");
274
275 log_header(design, "Executing SYNTH_XILINX pass.\n");
276 log_push();
277
278 run_script(design, run_from, run_to);
279
280 log_pop();
281 }
282
283 void script() YS_OVERRIDE
284 {
285 std::string ff_map_file;
286 if (help_mode)
287 ff_map_file = "+/xilinx/{family}_ff_map.v";
288 else if (family == "xc6s")
289 ff_map_file = "+/xilinx/xc6s_ff_map.v";
290 else
291 ff_map_file = "+/xilinx/xc7_ff_map.v";
292
293 if (check_label("begin")) {
294 std::string read_args;
295 if (vpr)
296 read_args += " -D_EXPLICIT_CARRY";
297 read_args += " -lib +/xilinx/cells_sim.v";
298 run("read_verilog" + read_args);
299
300 run("read_verilog -lib +/xilinx/cells_xtra.v");
301
302 run(stringf("hierarchy -check %s", top_opt.c_str()));
303 }
304
305 if (check_label("prepare")) {
306 run("proc");
307 if (flatten || help_mode)
308 run("flatten", "(with '-flatten')");
309 run("opt_expr");
310 run("opt_clean");
311 run("check");
312 run("opt");
313 if (help_mode)
314 run("wreduce [-keepdc]", "(option for '-widemux')");
315 else
316 run("wreduce" + std::string(widemux > 0 ? " -keepdc" : ""));
317 run("peepopt");
318 run("opt_clean");
319
320 if (widemux > 0 || help_mode)
321 run("muxpack", " ('-widemux' only)");
322
323 // xilinx_srl looks for $shiftx cells for identifying variable-length
324 // shift registers, so attempt to convert $pmux-es to this
325 // Also: wide multiplexer inference benefits from this too
326 if (!(nosrl && widemux == 0) || help_mode) {
327 run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')");
328 run("clean", " (skip if '-nosrl' and '-widemux=0')");
329 }
330
331 run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6");
332 }
333
334 if (check_label("map_dsp", "(skip if '-nodsp')")) {
335 if (!nodsp || help_mode) {
336 run("memory_dff"); // xilinx_dsp will merge registers, reserve memory port registers first
337 // NB: Xilinx multipliers are signed only
338 if (help_mode)
339 run("techmap -map +/mul2dsp.v -map +/xilinx/{family}_dsp_map.v {options}");
340 else if (family == "xc2v" || family == "xc3s" || family == "xc3se" || family == "xc3sa")
341 run("techmap -map +/mul2dsp.v -map +/xilinx/xc3s_mult_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
342 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
343 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
344 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
345 else if (family == "xc3sda")
346 run("techmap -map +/mul2dsp.v -map +/xilinx/xc3sda_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
347 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
348 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
349 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
350 else if (family == "xc6s")
351 run("techmap -map +/mul2dsp.v -map +/xilinx/xc6s_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
352 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
353 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
354 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
355 else if (family == "xc4v")
356 run("techmap -map +/mul2dsp.v -map +/xilinx/xc4v_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
357 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
358 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
359 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
360 else if (family == "xc5v")
361 run("techmap -map +/mul2dsp.v -map +/xilinx/xc5v_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
362 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
363 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
364 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
365 else if (family == "xc6v" || family == "xc7")
366 run("techmap -map +/mul2dsp.v -map +/xilinx/xc7_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
367 "-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
368 // limited to 18x18 in order to take
369 // advantage of the (PCOUT << 17) -> PCIN
370 // dedicated cascade chain capability
371 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
372 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
373 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
374 else if (family == "xcu" || family == "xcup")
375 run("techmap -map +/mul2dsp.v -map +/xilinx/xcu_dsp_map.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=18 "
376 "-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
377 // limited to 18x18 in order to take
378 // advantage of the (PCOUT << 17) -> PCIN
379 // dedicated cascade chain capability
380 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
381 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
382 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL27X18");
383 run("select a:mul2dsp");
384 run("setattr -unset mul2dsp");
385 run("opt_expr -fine");
386 run("wreduce");
387 run("select -clear");
388 run("xilinx_dsp");
389 run("chtype -set $mul t:$__soft_mul");
390 }
391 }
392
393 if (check_label("coarse")) {
394 run("alumacc");
395 run("share");
396 run("opt");
397 run("fsm");
398 run("opt -fast");
399 run("memory -nomap");
400 run("opt_clean");
401 }
402
403 if (check_label("map_uram", "(only if '-uram')")) {
404 if (help_mode) {
405 run("memory_bram -rules +/xilinx/{family}_urams.txt");
406 run("techmap -map +/xilinx/{family}_urams_map.v");
407 } else if (uram) {
408 if (family == "xcup") {
409 run("memory_bram -rules +/xilinx/xcup_urams.txt");
410 run("techmap -map +/xilinx/xcup_urams_map.v");
411 } else {
412 log_warning("UltraRAM inference not supported for family %s.\n", family.c_str());
413 }
414 }
415 }
416
417 if (check_label("map_bram", "(skip if '-nobram')")) {
418 if (help_mode) {
419 run("memory_bram -rules +/xilinx/{family}_brams.txt");
420 run("techmap -map +/xilinx/{family}_brams_map.v");
421 } else if (!nobram) {
422 if (family == "xc6s") {
423 run("memory_bram -rules +/xilinx/xc6s_brams.txt");
424 run("techmap -map +/xilinx/xc6s_brams_map.v");
425 } else if (family == "xc6v" || family == "xc7") {
426 run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
427 run("techmap -map +/xilinx/xc7_brams_map.v");
428 } else if (family == "xcu" || family == "xcup") {
429 run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
430 run("techmap -map +/xilinx/xcu_brams_map.v");
431 } else {
432 log_warning("Block RAM inference not yet supported for family %s.\n", family.c_str());
433 }
434 }
435 }
436
437 if (check_label("map_lutram", "(skip if '-nolutram')")) {
438 if (!nolutram || help_mode) {
439 run("memory_bram -rules +/xilinx/lutrams.txt");
440 run("techmap -map +/xilinx/lutrams_map.v");
441 }
442 }
443
444 if (check_label("map_ffram")) {
445 if (widemux > 0)
446 run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
447 // performs less efficiently
448 else
449 run("opt -fast -full");
450 run("memory_map");
451 }
452
453 if (check_label("fine")) {
454 run("dffsr2dff");
455 run("dff2dffe");
456 if (help_mode) {
457 run("simplemap t:$mux", " ('-widemux' only)");
458 run("muxcover <internal options>, ('-widemux' only)");
459 }
460 else if (widemux > 0) {
461 run("simplemap t:$mux");
462 constexpr int cost_mux2 = 100;
463 std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2);
464 switch (widemux) {
465 case 2: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2+1, cost_mux2+2, cost_mux2+3); break;
466 case 3:
467 case 4: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-2, cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break;
468 case 5:
469 case 6:
470 case 7:
471 case 8: muxcover_args += stringf(" -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break;
472 case 9:
473 case 10:
474 case 11:
475 case 12:
476 case 13:
477 case 14:
478 case 15:
479 default: muxcover_args += stringf(" -mux16=%d", cost_mux2*(widemux-1)-1); break;
480 }
481 run("muxcover " + muxcover_args);
482 }
483 run("opt -full");
484
485 if (!nosrl || help_mode)
486 run("xilinx_srl -variable -minlen 3", "(skip if '-nosrl')");
487
488 std::string techmap_args = " -map +/techmap.v";
489 if (help_mode)
490 techmap_args += " [-map +/xilinx/mux_map.v]";
491 else if (widemux > 0)
492 techmap_args += stringf(" -D MIN_MUX_INPUTS=%d -map +/xilinx/mux_map.v", widemux);
493 if (help_mode)
494 techmap_args += " [-map +/xilinx/arith_map.v]";
495 else if (!nocarry) {
496 techmap_args += " -map +/xilinx/arith_map.v";
497 if (vpr)
498 techmap_args += " -D _EXPLICIT_CARRY";
499 else if (abc9)
500 techmap_args += " -D _CLB_CARRY";
501 }
502 run("techmap " + techmap_args);
503 run("opt -fast");
504 }
505
506 if (check_label("map_cells")) {
507 std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v";
508 if (widemux > 0)
509 techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
510 run("techmap " + techmap_args);
511 run("clean");
512 }
513
514 if (check_label("map_ffs")) {
515 if (abc9 || help_mode) {
516 run("clkpart -set_attr clkpart 1", "('-abc9' only)");
517 run("techmap -map " + ff_map_file, "('-abc9' only)");
518 }
519 }
520
521 if (check_label("map_luts")) {
522 run("opt_expr -mux_undef");
523 if (flatten_before_abc)
524 run("flatten");
525 if (help_mode)
526 run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut'; option for '-retime')");
527 else if (abc9) {
528 if (family != "xc7")
529 log_warning("'synth_xilinx -abc9' not currently supported for the '%s' family, "
530 "will use timing for 'xc7' instead.\n", family.c_str());
531 run("techmap -map +/xilinx/abc9_map.v -max_iter 1");
532 run("read_verilog -icells -lib +/xilinx/abc9_model.v");
533 std::string abc9_opts = " -box +/xilinx/abc9_xc7.box";
534 abc9_opts += stringf(" -W %d", XC7_WIRE_DELAY);
535 abc9_opts += " -nomfs";
536 if (nowidelut)
537 abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut";
538 else
539 abc9_opts += " -lut +/xilinx/abc9_xc7.lut";
540 run("abc9" + abc9_opts);
541 run("clkpart -unpart clkpart");
542 }
543 else {
544 if (nowidelut)
545 run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : ""));
546 else
547 run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
548 }
549 run("clean");
550
551 // This shregmap call infers fixed length shift registers after abc
552 // has performed any necessary retiming
553 if (!nosrl || help_mode)
554 run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
555 std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
556 if (help_mode)
557 techmap_args += " [-map " + ff_map_file + "]";
558 else if (abc9)
559 techmap_args += " -map +/xilinx/abc9_unmap.v";
560 else
561 techmap_args += " -map " + ff_map_file;
562 run("techmap " + techmap_args);
563 }
564
565 if (check_label("finalize")) {
566 bool do_iopad = iopad || (ise && !noiopad);
567 if (help_mode || !noclkbuf) {
568 if (help_mode || do_iopad)
569 run("clkbufmap -buf BUFG O:I -inpad IBUFG O:I", "(skip if '-noclkbuf', '-inpad' passed if '-iopad' or '-ise' and not '-noiopad')");
570 else
571 run("clkbufmap -buf BUFG O:I");
572 }
573 if (help_mode || do_iopad)
574 run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
575 if (help_mode || ise)
576 run("extractinv -inv INV O:I", "(only if '-ise')");
577 run("clean");
578 }
579
580 if (check_label("check")) {
581 run("hierarchy -check");
582 run("stat -tech xilinx");
583 run("check -noinit");
584 }
585
586 if (check_label("edif")) {
587 if (!edif_file.empty() || help_mode)
588 run(stringf("write_edif -pvector bra %s", edif_file.c_str()));
589 }
590
591 if (check_label("blif")) {
592 if (!blif_file.empty() || help_mode)
593 run(stringf("write_blif %s", edif_file.c_str()));
594 }
595 }
596 } SynthXilinxPass;
597
598 PRIVATE_NAMESPACE_END