2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 * (C) 2019 Eddie Hung <eddie@fpgeh.com>
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.
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.
21 #include "kernel/register.h"
22 #include "kernel/celltypes.h"
23 #include "kernel/rtlil.h"
24 #include "kernel/log.h"
27 PRIVATE_NAMESPACE_BEGIN
29 struct SynthXilinxPass
: public ScriptPass
31 SynthXilinxPass() : ScriptPass("synth_xilinx", "synthesis for Xilinx FPGAs") { }
33 void on_register() YS_OVERRIDE
35 RTLIL::constpad
["synth_xilinx.abc9.xc7.W"] = "300"; // Number with which ABC will map a 6-input gate
36 // to one LUT6 (instead of a LUT5 + LUT2)
39 void help() YS_OVERRIDE
41 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
43 log(" synth_xilinx [options]\n");
45 log("This command runs synthesis for Xilinx FPGAs. This command does not operate on\n");
46 log("partly selected designs. At the moment this command creates netlists that are\n");
47 log("compatible with 7-Series Xilinx devices.\n");
49 log(" -top <module>\n");
50 log(" use the specified module as top module\n");
52 log(" -family <family>\n");
53 log(" run synthesis for the specified Xilinx architecture\n");
54 log(" generate the synthesis netlist for the specified family.\n");
55 log(" supported values:\n");
56 log(" - xcup: Ultrascale Plus\n");
57 log(" - xcu: Ultrascale\n");
58 log(" - xc7: Series 7 (default)\n");
59 log(" - xc6s: Spartan 6\n");
60 log(" - xc6v: Virtex 6\n");
61 log(" - xc5v: Virtex 5 (EXPERIMENTAL)\n");
62 log(" - xc4v: Virtex 4 (EXPERIMENTAL)\n");
63 log(" - xc3sda: Spartan 3A DSP (EXPERIMENTAL)\n");
64 log(" - xc3sa: Spartan 3A (EXPERIMENTAL)\n");
65 log(" - xc3se: Spartan 3E (EXPERIMENTAL)\n");
66 log(" - xc3s: Spartan 3 (EXPERIMENTAL)\n");
67 log(" - xc2vp: Virtex 2 Pro (EXPERIMENTAL)\n");
68 log(" - xc2v: Virtex 2 (EXPERIMENTAL)\n");
69 log(" - xcve: Virtex E, Spartan 2E (EXPERIMENTAL)\n");
70 log(" - xcv: Virtex, Spartan 2 (EXPERIMENTAL)\n");
72 log(" -edif <file>\n");
73 log(" write the design to the specified edif file. writing of an output file\n");
74 log(" is omitted if this parameter is not specified.\n");
76 log(" -blif <file>\n");
77 log(" write the design to the specified BLIF file. writing of an output file\n");
78 log(" is omitted if this parameter is not specified.\n");
81 log(" generate an output netlist (and BLIF file) suitable for VPR\n");
82 log(" (this feature is experimental and incomplete)\n");
85 log(" generate an output netlist suitable for ISE\n");
88 log(" do not use block RAM cells in output netlist\n");
91 log(" do not use distributed RAM cells in output netlist\n");
94 log(" do not use distributed SRL cells in output netlist\n");
97 log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n");
100 log(" do not use MUXF[5-9] resources to implement LUTs larger than native for the target\n");
103 log(" do not use DSP48*s to implement multipliers and associated logic\n");
106 log(" disable I/O buffer insertion (useful for hierarchical or \n");
107 log(" out-of-context flows)\n");
110 log(" disable automatic clock buffer insertion\n");
113 log(" infer URAM288s for large memories (xcup only)\n");
115 log(" -widemux <int>\n");
116 log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
117 log(" above this number of inputs (minimum value 2, recommended value >= 5).\n");
118 log(" default: 0 (no inference)\n");
120 log(" -run <from_label>:<to_label>\n");
121 log(" only run the commands between the labels (see below). an empty\n");
122 log(" from label is synonymous to 'begin', and empty to label is\n");
123 log(" synonymous to the end of the command list.\n");
126 log(" flatten design before synthesis\n");
129 log(" run 'abc'/'abc9' with -dff option\n");
132 log(" run 'abc' with '-D 1' option to enable flip-flop retiming.\n");
133 log(" implies -dff.\n");
136 log(" use new ABC9 flow (EXPERIMENTAL)\n");
139 log("The following commands are executed by this synthesis command:\n");
144 std::string top_opt
, edif_file
, blif_file
, family
;
145 bool flatten
, retime
, vpr
, ise
, noiopad
, noclkbuf
, nobram
, nolutram
, nosrl
, nocarry
, nowidelut
, nodsp
, uram
;
147 bool flatten_before_abc
;
152 void clear_flags() YS_OVERRIDE
154 top_opt
= "-auto-top";
174 flatten_before_abc
= false;
179 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
181 std::string run_from
, run_to
;
185 for (argidx
= 1; argidx
< args
.size(); argidx
++)
187 if (args
[argidx
] == "-top" && argidx
+1 < args
.size()) {
188 top_opt
= "-top " + args
[++argidx
];
191 if ((args
[argidx
] == "-family" || args
[argidx
] == "-arch") && argidx
+1 < args
.size()) {
192 family
= args
[++argidx
];
195 if (args
[argidx
] == "-edif" && argidx
+1 < args
.size()) {
196 edif_file
= args
[++argidx
];
199 if (args
[argidx
] == "-blif" && argidx
+1 < args
.size()) {
200 blif_file
= args
[++argidx
];
203 if (args
[argidx
] == "-run" && argidx
+1 < args
.size()) {
204 size_t pos
= args
[argidx
+1].find(':');
205 if (pos
== std::string::npos
)
207 run_from
= args
[++argidx
].substr(0, pos
);
208 run_to
= args
[argidx
].substr(pos
+1);
211 if (args
[argidx
] == "-flatten") {
215 if (args
[argidx
] == "-flatten_before_abc") {
216 flatten_before_abc
= true;
219 if (args
[argidx
] == "-retime") {
224 if (args
[argidx
] == "-nocarry") {
228 if (args
[argidx
] == "-nowidelut") {
232 if (args
[argidx
] == "-vpr") {
236 if (args
[argidx
] == "-ise") {
240 if (args
[argidx
] == "-iopad") {
243 if (args
[argidx
] == "-noiopad") {
247 if (args
[argidx
] == "-noclkbuf") {
251 if (args
[argidx
] == "-nocarry") {
255 if (args
[argidx
] == "-nobram") {
259 if (args
[argidx
] == "-nolutram" || /*deprecated alias*/ args
[argidx
] == "-nodram") {
263 if (args
[argidx
] == "-nosrl") {
267 if (args
[argidx
] == "-widemux" && argidx
+1 < args
.size()) {
268 widemux
= atoi(args
[++argidx
].c_str());
271 if (args
[argidx
] == "-abc9") {
275 if (args
[argidx
] == "-nodsp") {
279 if (args
[argidx
] == "-uram") {
283 if (args
[argidx
] == "-dff") {
289 extra_args(args
, argidx
, design
);
291 if (family
== "xcup" || family
== "xcu") {
294 } else if (family
== "xc7" ||
300 } else if (family
== "xc4v" ||
301 family
== "xc3sda" ||
309 } else if (family
== "xcve" || family
== "xcv") {
313 log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family
.c_str());
315 if (widemux
!= 0 && lut_size
!= 6)
316 log_cmd_error("-widemux is not currently supported for LUT4-based architectures.\n");
319 log_warning("Shift register inference not yet supported for family %s.\n", family
.c_str());
323 if (widemux
!= 0 && widemux
< 2)
324 log_cmd_error("-widemux value must be 0 or >= 2.\n");
326 if (!design
->full_selection())
327 log_cmd_error("This command only operates on fully selected designs!\n");
330 log_cmd_error("-retime option not currently compatible with -abc9!\n");
332 log_header(design
, "Executing SYNTH_XILINX pass.\n");
335 run_script(design
, run_from
, run_to
);
340 void script() YS_OVERRIDE
342 std::string lut_size_s
= std::to_string(lut_size
);
345 std::string ff_map_file
;
347 ff_map_file
= "+/xilinx/{family}_ff_map.v";
348 else if (family
== "xc6s")
349 ff_map_file
= "+/xilinx/xc6s_ff_map.v";
351 ff_map_file
= "+/xilinx/xc7_ff_map.v";
353 if (check_label("begin")) {
354 std::string read_args
;
356 read_args
+= " -D_EXPLICIT_CARRY";
357 read_args
+= " -lib -specify +/xilinx/cells_sim.v";
358 run("read_verilog" + read_args
);
360 run("read_verilog -lib +/xilinx/cells_xtra.v");
362 run(stringf("hierarchy -check %s", top_opt
.c_str()));
365 if (check_label("prepare")) {
367 if (flatten
|| help_mode
)
368 run("flatten", "(with '-flatten')");
370 active_design
->scratchpad_unset("tribuf.added_something");
371 run("tribuf -logic");
372 if (noiopad
&& active_design
&& active_design
->scratchpad_get_bool("tribuf.added_something"))
373 log_error("Tristate buffers are unsupported without the '-iopad' option.\n");
380 run("wreduce [-keepdc]", "(option for '-widemux')");
382 run("wreduce" + std::string(widemux
> 0 ? " -keepdc" : ""));
386 if (widemux
> 0 || help_mode
)
387 run("muxpack", " ('-widemux' only)");
389 // xilinx_srl looks for $shiftx cells for identifying variable-length
390 // shift registers, so attempt to convert $pmux-es to this
391 // Also: wide multiplexer inference benefits from this too
392 if (!(nosrl
&& widemux
== 0) || help_mode
) {
393 run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')");
394 run("clean", " (skip if '-nosrl' and '-widemux=0')");
397 run("techmap -map +/cmp2lut.v -D LUT_WIDTH=" + lut_size_s
);
400 if (check_label("map_dsp", "(skip if '-nodsp')")) {
401 if (!nodsp
|| help_mode
) {
402 run("memory_dff"); // xilinx_dsp will merge registers, reserve memory port registers first
403 // NB: Xilinx multipliers are signed only
405 run("techmap -map +/mul2dsp.v -map +/xilinx/{family}_dsp_map.v {options}");
406 else if (family
== "xc2v" || family
== "xc2vp" || family
== "xc3s" || family
== "xc3se" || family
== "xc3sa")
407 run("techmap -map +/mul2dsp.v -map +/xilinx/xc3s_mult_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
408 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
409 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
410 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
411 else if (family
== "xc3sda")
412 run("techmap -map +/mul2dsp.v -map +/xilinx/xc3sda_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
413 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
414 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
415 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
416 else if (family
== "xc6s")
417 run("techmap -map +/mul2dsp.v -map +/xilinx/xc6s_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
418 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
419 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
420 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
421 else if (family
== "xc4v")
422 run("techmap -map +/mul2dsp.v -map +/xilinx/xc4v_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
423 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
424 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
425 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
426 else if (family
== "xc5v")
427 run("techmap -map +/mul2dsp.v -map +/xilinx/xc5v_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
428 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
429 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
430 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
431 else if (family
== "xc6v" || family
== "xc7")
432 run("techmap -map +/mul2dsp.v -map +/xilinx/xc7_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
433 "-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
434 // limited to 18x18 in order to take
435 // advantage of the (PCOUT << 17) -> PCIN
436 // dedicated cascade chain capability
437 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
438 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
439 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
440 else if (family
== "xcu" || family
== "xcup")
441 run("techmap -map +/mul2dsp.v -map +/xilinx/xcu_dsp_map.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=18 "
442 "-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
443 // limited to 18x18 in order to take
444 // advantage of the (PCOUT << 17) -> PCIN
445 // dedicated cascade chain capability
446 "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
447 "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
448 "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL27X18");
449 run("select a:mul2dsp");
450 run("setattr -unset mul2dsp");
451 run("opt_expr -fine");
453 run("select -clear");
455 run("xilinx_dsp -family <family>");
457 run("xilinx_dsp -family " + family
);
458 run("chtype -set $mul t:$__soft_mul");
462 if (check_label("coarse")) {
468 run("memory -nomap");
472 if (check_label("map_uram", "(only if '-uram')")) {
474 run("memory_bram -rules +/xilinx/{family}_urams.txt");
475 run("techmap -map +/xilinx/{family}_urams_map.v");
477 if (family
== "xcup") {
478 run("memory_bram -rules +/xilinx/xcup_urams.txt");
479 run("techmap -map +/xilinx/xcup_urams_map.v");
481 log_warning("UltraRAM inference not supported for family %s.\n", family
.c_str());
486 if (check_label("map_bram", "(skip if '-nobram')")) {
488 run("memory_bram -rules +/xilinx/{family}_brams.txt");
489 run("techmap -map +/xilinx/{family}_brams_map.v");
490 } else if (!nobram
) {
491 if (family
== "xc2v" || family
== "xc2vp" || family
== "xc3s" || family
== "xc3se") {
492 run("memory_bram -rules +/xilinx/xc2v_brams.txt");
493 run("techmap -map +/xilinx/xc2v_brams_map.v");
494 } else if (family
== "xc3sa") {
495 // Superset of Virtex 2 primitives — uses common map file.
496 run("memory_bram -rules +/xilinx/xc3sa_brams.txt");
497 run("techmap -map +/xilinx/xc2v_brams_map.v");
498 } else if (family
== "xc3sda") {
499 // Supported block RAMs for Spartan 3A DSP are
500 // a subset of Spartan 6's ones.
501 run("memory_bram -rules +/xilinx/xc3sda_brams.txt");
502 run("techmap -map +/xilinx/xc6s_brams_map.v");
503 } else if (family
== "xc6s") {
504 run("memory_bram -rules +/xilinx/xc6s_brams.txt");
505 run("techmap -map +/xilinx/xc6s_brams_map.v");
506 } else if (family
== "xc6v" || family
== "xc7") {
507 run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
508 run("techmap -map +/xilinx/xc7_brams_map.v");
509 } else if (family
== "xcu" || family
== "xcup") {
510 run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
511 run("techmap -map +/xilinx/xcu_brams_map.v");
513 log_warning("Block RAM inference not yet supported for family %s.\n", family
.c_str());
518 if (check_label("map_lutram", "(skip if '-nolutram')")) {
519 if (!nolutram
|| help_mode
) {
520 run("memory_bram -rules +/xilinx/lut" + lut_size_s
+ "_lutrams.txt");
521 run("techmap -map +/xilinx/lutrams_map.v");
525 if (check_label("map_ffram")) {
526 // Required for dffsr2dff to work.
527 run("simplemap t:$dff t:$adff t:$mux");
528 // Needs to be done before opt -mux_bool happens.
531 run("dff2dffs [-match-init]", "(-match-init for xc6s only)");
532 else if (family
== "xc6s")
533 run("dff2dffs -match-init");
537 run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
538 // performs less efficiently
540 run("opt -fast -full");
544 if (check_label("fine")) {
545 run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
547 run("muxcover <internal options> ('-widemux' only)");
548 else if (widemux
> 0) {
549 constexpr int cost_mux2
= 100;
550 std::string muxcover_args
= stringf(" -nodecode -mux2=%d", cost_mux2
);
552 case 2: muxcover_args
+= stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2
+1, cost_mux2
+2, cost_mux2
+3); break;
554 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;
558 case 8: muxcover_args
+= stringf(" -mux8=%d -mux16=%d", cost_mux2
*(widemux
-1)-1, cost_mux2
*(widemux
-1)); break;
566 default: muxcover_args
+= stringf(" -mux16=%d", cost_mux2
*(widemux
-1)-1); break;
568 run("muxcover " + muxcover_args
);
572 if (!nosrl
|| help_mode
)
573 run("xilinx_srl -variable -minlen 3", "(skip if '-nosrl')");
575 std::string techmap_args
= " -map +/techmap.v -D LUT_SIZE=" + lut_size_s
;
577 techmap_args
+= " [-map +/xilinx/mux_map.v]";
578 else if (widemux
> 0)
579 techmap_args
+= stringf(" -D MIN_MUX_INPUTS=%d -map +/xilinx/mux_map.v", widemux
);
581 techmap_args
+= " -map +/xilinx/arith_map.v";
583 techmap_args
+= " -D _EXPLICIT_CARRY";
585 run("techmap " + techmap_args
);
589 if (check_label("map_cells")) {
590 // Needs to be done before logic optimization, so that inverters (OE vs T) are handled.
591 if (help_mode
|| !noiopad
)
592 run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(skip if '-noiopad')");
593 std::string techmap_args
= "-map +/techmap.v -map +/xilinx/cells_map.v";
595 techmap_args
+= stringf(" -D MIN_MUX_INPUTS=%d", widemux
);
596 run("techmap " + techmap_args
);
600 if (check_label("map_ffs")) {
601 if (abc9
|| help_mode
) {
602 run("techmap -map " + ff_map_file
, "('-abc9' only)");
606 if (check_label("map_luts")) {
607 run("opt_expr -mux_undef");
608 if (flatten_before_abc
)
611 run("abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1]", "(option for 'nowidelut', '-dff', '-retime')");
614 log_error("'synth_xilinx -abc9' not currently supported for LUT4-based devices.\n");
616 log_warning("'synth_xilinx -abc9' not currently supported for the '%s' family, "
617 "will use timing for 'xc7' instead.\n", family
.c_str());
618 std::string techmap_args
= "-map +/xilinx/abc9_map.v -max_iter 1";
620 techmap_args
+= " -D DFF_MODE";
621 run("techmap " + techmap_args
);
622 run("read_verilog -icells -lib -specify +/abc9_model.v +/xilinx/abc9_model.v");
623 std::string abc9_opts
;
624 auto k
= stringf("synth_xilinx.abc9.%s.W", family
.c_str());
625 if (active_design
->scratchpad
.count(k
))
626 abc9_opts
+= stringf(" -W %s", active_design
->scratchpad_get_string(k
).c_str());
628 abc9_opts
+= stringf(" -W %s", RTLIL::constpad
.at(k
, RTLIL::constpad
.at("synth_xilinx.abc9.xc7.W")).c_str());
630 abc9_opts
+= stringf(" -maxlut %d", lut_size
);
632 abc9_opts
+= " -dff";
633 run("abc9" + abc9_opts
);
634 run("techmap -map +/xilinx/abc9_unmap.v");
637 std::string abc_opts
;
640 abc_opts
+= " -lut " + lut_size_s
;
642 abc_opts
+= " -lut " + lut_size_s
+ ":" + std::to_string(widelut_size
);
645 abc_opts
+= " -luts 2:2,3,6:5";
646 else if (widelut_size
== 8)
647 abc_opts
+= " -luts 2:2,3,6:5,10,20";
649 abc_opts
+= " -luts 2:2,3,6:5,10,20,40";
655 run("abc" + abc_opts
);
659 // This shregmap call infers fixed length shift registers after abc
660 // has performed any necessary retiming
661 if (!nosrl
|| help_mode
)
662 run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
663 std::string techmap_args
= "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
664 if (help_mode
|| !abc9
)
665 techmap_args
+= stringf(" -map %s", ff_map_file
.c_str());
666 techmap_args
+= " -D LUT_WIDTH=" + lut_size_s
;
667 run("techmap " + techmap_args
);
669 run("xilinx_dffopt [-lut4]");
670 else if (lut_size
== 4)
671 run("xilinx_dffopt -lut4");
673 run("xilinx_dffopt");
674 run("opt_lut_ins -tech xilinx");
677 if (check_label("finalize")) {
678 if (help_mode
|| !noclkbuf
)
679 run("clkbufmap -buf BUFG O:I", "(skip if '-noclkbuf')");
680 if (help_mode
|| ise
)
681 run("extractinv -inv INV O:I", "(only if '-ise')");
685 if (check_label("check")) {
686 run("hierarchy -check");
687 run("stat -tech xilinx");
688 run("check -noinit");
691 if (check_label("edif")) {
692 if (!edif_file
.empty() || help_mode
)
693 run(stringf("write_edif -pvector bra %s", edif_file
.c_str()));
696 if (check_label("blif")) {
697 if (!blif_file
.empty() || help_mode
)
698 run(stringf("write_blif %s", edif_file
.c_str()));
703 PRIVATE_NAMESPACE_END