aigmap everything
[yosys.git] / passes / techmap / abc9.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 Abc9Pass : public ScriptPass
33 {
34 Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { }
35
36 void help() YS_OVERRIDE
37 {
38 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
39 log("\n");
40 log(" abc9 [options] [selection]\n");
41 log("\n");
42 log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n");
43 log("library to a target architecture.\n");
44 log("\n");
45 log(" -exe <command>\n");
46 #ifdef ABCEXTERNAL
47 log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
48 #else
49 log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
50 #endif
51 log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
52 log("\n");
53 log(" -script <file>\n");
54 log(" use the specified ABC script file instead of the default script.\n");
55 log("\n");
56 log(" if <file> starts with a plus sign (+), then the rest of the filename\n");
57 log(" string is interpreted as the command string to be passed to ABC. The\n");
58 log(" leading plus sign is removed and all commas (,) in the string are\n");
59 log(" replaced with blanks before the string is passed to ABC.\n");
60 log("\n");
61 log(" if no -script parameter is given, the following scripts are used:\n");
62 log("\n");
63 log(" for -lut/-luts (only one LUT size):\n");
64 // FIXME
65 //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());
66 log("\n");
67 log(" for -lut/-luts (different LUT sizes):\n");
68 // FIXME
69 //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str());
70 log("\n");
71 log(" -fast\n");
72 log(" use different default scripts that are slightly faster (at the cost\n");
73 log(" of output quality):\n");
74 log("\n");
75 log(" for -lut/-luts:\n");
76 // FIXME
77 //log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());
78 log("\n");
79 log(" -D <picoseconds>\n");
80 log(" set delay target. the string {D} in the default scripts above is\n");
81 log(" replaced by this option when used, and an empty string otherwise\n");
82 log(" (indicating best possible delay).\n");
83 log("\n");
84 // log(" -S <num>\n");
85 // log(" maximum number of LUT inputs shared.\n");
86 // log(" (replaces {S} in the default scripts above, default: -S 1)\n");
87 // log("\n");
88 log(" -lut <width>\n");
89 log(" generate netlist using luts of (max) the specified width.\n");
90 log("\n");
91 log(" -lut <w1>:<w2>\n");
92 log(" generate netlist using luts of (max) the specified width <w2>. All\n");
93 log(" luts with width <= <w1> have constant cost. for luts larger than <w1>\n");
94 log(" the area cost doubles with each additional input bit. the delay cost\n");
95 log(" is still constant for all lut widths.\n");
96 log("\n");
97 log(" -lut <file>\n");
98 log(" pass this file with lut library to ABC.\n");
99 log("\n");
100 log(" -luts <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..\n");
101 log(" generate netlist using luts. Use the specified costs for luts with 1,\n");
102 log(" 2, 3, .. inputs.\n");
103 log("\n");
104 log(" -dff\n");
105 log(" also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n");
106 log(" domains are marked as such and automatically partitioned by ABC.\n");
107 log("\n");
108 log(" -nocleanup\n");
109 log(" when this option is used, the temporary files created by this pass\n");
110 log(" are not removed. this is useful for debugging.\n");
111 log("\n");
112 log(" -showtmp\n");
113 log(" print the temp dir name in log. usually this is suppressed so that the\n");
114 log(" command output is identical across runs.\n");
115 log("\n");
116 log(" -markgroups\n");
117 log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n");
118 log(" this attribute is a unique integer for each ABC process started. This\n");
119 log(" is useful for debugging the partitioning of clock domains.\n");
120 log("\n");
121 log(" -box <file>\n");
122 log(" pass this file with box library to ABC. Use with -lut.\n");
123 log("\n");
124 log("Note that this is a logic optimization pass within Yosys that is calling ABC\n");
125 log("internally. This is not going to \"run ABC on your design\". It will instead run\n");
126 log("ABC on logic snippets extracted from your design. You will not get any useful\n");
127 log("output when passing an ABC script that writes a file. Instead write your full\n");
128 log("design as an XAIGER file with `write_xaiger' and then load that into ABC\n");
129 log("externally if you want to use ABC to convert your design into another format.\n");
130 log("\n");
131 log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n");
132 log("\n");
133 help_script();
134 log("\n");
135 }
136
137 std::stringstream map_cmd;
138 bool dff_mode, cleanup;
139
140 void clear_flags() YS_OVERRIDE
141 {
142 map_cmd.str("");
143 map_cmd << "abc9_map";
144 dff_mode = false;
145 cleanup = true;
146 }
147
148 void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
149 {
150 std::string run_from, run_to;
151 clear_flags();
152
153 size_t argidx;
154 for (argidx = 1; argidx < args.size(); argidx++) {
155 std::string arg = args[argidx];
156 if ((arg == "-exe" || arg == "-script" || arg == "-D" ||
157 /* arg == "-S" || */ arg == "-lut" || arg == "-luts" ||
158 arg == "-box" || arg == "-W") &&
159 argidx+1 < args.size()) {
160 map_cmd << " " << arg << " " << args[++argidx];
161 continue;
162 }
163 if (arg == "-fast" || /* arg == "-dff" || */
164 /* arg == "-nocleanup" || */ arg == "-showtmp" || arg == "-markgroups" ||
165 arg == "-nomfs") {
166 map_cmd << " " << arg;
167 continue;
168 }
169 if (arg == "-dff") {
170 dff_mode = true;
171 continue;
172 }
173 if (arg == "-nocleanup") {
174 cleanup = false;
175 continue;
176 }
177 break;
178 }
179 extra_args(args, argidx, design);
180
181 log_header(design, "Executing ABC9 pass.\n");
182
183 run_script(design, run_from, run_to);
184 }
185
186 void script() YS_OVERRIDE
187 {
188 run("abc9_ops -prep_holes");
189 run("select -set abc9_holes A:abc9_holes");
190 run("flatten -wb @abc9_holes");
191 run("techmap @abc9_holes");
192 run("scc -set_attr abc9_scc_id {}");
193 run("abc9_ops -break_scc");
194 run("aigmap");
195 if (dff_mode)
196 run("abc9_ops -prep_dff");
197 run("opt -purge @abc9_holes");
198 run("wbflip @abc9_holes");
199
200 auto selected_modules = active_design->selected_modules();
201 active_design->selection_stack.emplace_back(false);
202
203 for (auto mod : selected_modules) {
204 if (mod->get_blackbox_attribute())
205 continue;
206
207 if (mod->processes.size() > 0) {
208 log("Skipping module %s as it contains processes.\n", log_id(mod));
209 continue;
210 }
211
212 active_design->selection().select(mod);
213
214 std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
215 if (!cleanup)
216 tempdir_name[0] = tempdir_name[4] = '_';
217 tempdir_name = make_temp_dir(tempdir_name);
218
219 run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()),
220 "write_xaiger -map <abc-temp-dir>/input.sym <abc-temp-dir>/input.xaig");
221 run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()),
222 "abc9_map [options] -tempdir <abc-temp-dir>");
223
224 if (cleanup)
225 {
226 log("Removing temp directory.\n");
227 remove_directory(tempdir_name);
228 }
229
230 active_design->selection().selected_modules.clear();
231 }
232
233 active_design->selection_stack.pop_back();
234
235 run("abc9_ops -unbreak_scc");
236 }
237 } Abc9Pass;
238
239 PRIVATE_NAMESPACE_END