1 /* 2 * yosys -- Yosys Open SYnthesis Suite 3 * 4 * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com> 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 { SynthPassSynthPass30 SynthPass() : ScriptPass("synth", "generic synthesis script") { } 31 helpSynthPass32 void help() 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(" -flowmap\n"); 82 log(" use FlowMap LUT techmapping instead of ABC\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, flowmap; 92 int lut; 93 clear_flagsSynthPass94 void clear_flags() 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 flowmap = false; 108 abc = "abc"; 109 } 110 executeSynthPass111 void execute(std::vector<std::string> args, RTLIL::Design *design) 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] == "-flowmap") { 175 flowmap = 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)\n"); 187 if (flowmap && !lut) 188 log_cmd_error("FlowMap is only supported for FPGA synthesis (using '-lut' option)\n"); 189 190 log_header(design, "Executing SYNTH pass.\n"); 191 log_push(); 192 193 run_script(design, run_from, run_to); 194 195 log_pop(); 196 } 197 scriptSynthPass198 void script() override 199 { 200 if (check_label("begin")) 201 { 202 if (help_mode) { 203 run("hierarchy -check [-top <top> | -auto-top]"); 204 } else { 205 if (top_module.empty()) { 206 if (flatten || autotop) 207 run("hierarchy -check -auto-top"); 208 else 209 run("hierarchy -check"); 210 } else 211 run(stringf("hierarchy -check -top %s", top_module.c_str())); 212 } 213 } 214 215 if (check_label("coarse")) 216 { 217 run("proc"); 218 if (help_mode || flatten) 219 run("flatten", " (if -flatten)"); 220 run("opt_expr"); 221 run("opt_clean"); 222 run("check"); 223 run("opt -nodffe -nosdff"); 224 if (!nofsm) 225 run("fsm" + fsm_opts, " (unless -nofsm)"); 226 run("opt"); 227 run("wreduce"); 228 run("peepopt"); 229 run("opt_clean"); 230 if (help_mode) 231 run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)"); 232 else if (lut) 233 run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut)); 234 if (!noalumacc) 235 run("alumacc", " (unless -noalumacc)"); 236 if (!noshare) 237 run("share", " (unless -noshare)"); 238 run("opt"); 239 run("memory -nomap" + memory_opts); 240 run("opt_clean"); 241 } 242 243 if (check_label("fine")) 244 { 245 run("opt -fast -full"); 246 run("memory_map"); 247 run("opt -full"); 248 run("techmap"); 249 if (help_mode) 250 { 251 run("techmap -map +/gate2lut.v", "(if -noabc and -lut)"); 252 run("clean; opt_lut", " (if -noabc and -lut)"); 253 run("flowmap -maxlut K", " (if -flowmap 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 else if (flowmap) 261 { 262 run(stringf("flowmap -maxlut %d", lut)); 263 } 264 run("opt -fast"); 265 266 if (!noabc && !flowmap) { 267 #ifdef YOSYS_ENABLE_ABC 268 if (help_mode) 269 { 270 run(abc + " -fast", " (unless -noabc, unless -lut)"); 271 run(abc + " -fast -lut k", "(unless -noabc, if -lut)"); 272 } 273 else 274 { 275 if (lut) 276 run(stringf("%s -fast -lut %d", abc.c_str(), lut)); 277 else 278 run(abc + " -fast"); 279 } 280 run("opt -fast", " (unless -noabc)"); 281 #endif 282 } 283 } 284 285 if (check_label("check")) 286 { 287 run("hierarchy -check"); 288 run("stat"); 289 run("check"); 290 } 291 } 292 } SynthPass; 293 294 PRIVATE_NAMESPACE_END 295