1 /* 2 * yosys -- Yosys Open SYnthesis Suite 3 * 4 * Copyright (C) 2020 William D. Jones <wjones@wdj-consulting.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 SynthMachXO2Pass : public ScriptPass 29 { SynthMachXO2PassSynthMachXO2Pass30 SynthMachXO2Pass() : ScriptPass("synth_machxo2", "synthesis for MachXO2 FPGAs. This work is experimental.") { } 31 helpSynthMachXO2Pass32 void help() override 33 { 34 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| 35 log("\n"); 36 log(" synth_machxo2 [options]\n"); 37 log("\n"); 38 log("This command runs synthesis for MachXO2 FPGAs.\n"); 39 log("\n"); 40 log(" -top <module>\n"); 41 log(" use the specified module as top module\n"); 42 log("\n"); 43 log(" -blif <file>\n"); 44 log(" write the design to the specified BLIF file. writing of an output file\n"); 45 log(" is omitted if this parameter is not specified.\n"); 46 log("\n"); 47 log(" -edif <file>\n"); 48 log(" write the design to the specified EDIF file. writing of an output file\n"); 49 log(" is omitted if this parameter is not specified.\n"); 50 log("\n"); 51 log(" -json <file>\n"); 52 log(" write the design to the specified JSON file. writing of an output file\n"); 53 log(" is omitted if this parameter is not specified.\n"); 54 log("\n"); 55 log(" -run <from_label>:<to_label>\n"); 56 log(" only run the commands between the labels (see below). an empty\n"); 57 log(" from label is synonymous to 'begin', and empty to label is\n"); 58 log(" synonymous to the end of the command list.\n"); 59 log("\n"); 60 log(" -noflatten\n"); 61 log(" do not flatten design before synthesis\n"); 62 log("\n"); 63 log(" -noiopad\n"); 64 log(" do not insert IO buffers\n"); 65 log("\n"); 66 log(" -vpr\n"); 67 log(" generate an output netlist (and BLIF file) suitable for VPR\n"); 68 log(" (this feature is experimental and incomplete)\n"); 69 log("\n"); 70 log("\n"); 71 log("The following commands are executed by this synthesis command:\n"); 72 help_script(); 73 log("\n"); 74 } 75 76 string top_opt, blif_file, edif_file, json_file; 77 bool flatten, vpr, noiopad; 78 clear_flagsSynthMachXO2Pass79 void clear_flags() override 80 { 81 top_opt = "-auto-top"; 82 blif_file = ""; 83 edif_file = ""; 84 json_file = ""; 85 flatten = true; 86 vpr = false; 87 noiopad = false; 88 } 89 executeSynthMachXO2Pass90 void execute(std::vector<std::string> args, RTLIL::Design *design) override 91 { 92 string run_from, run_to; 93 clear_flags(); 94 95 size_t argidx; 96 for (argidx = 1; argidx < args.size(); argidx++) 97 { 98 if (args[argidx] == "-top" && argidx+1 < args.size()) { 99 top_opt = "-top " + args[++argidx]; 100 continue; 101 } 102 if (args[argidx] == "-blif" && argidx+1 < args.size()) { 103 blif_file = args[++argidx]; 104 continue; 105 } 106 if (args[argidx] == "-edif" && argidx+1 < args.size()) { 107 edif_file = args[++argidx]; 108 continue; 109 } 110 if (args[argidx] == "-json" && argidx+1 < args.size()) { 111 json_file = args[++argidx]; 112 continue; 113 } 114 if (args[argidx] == "-run" && argidx+1 < args.size()) { 115 size_t pos = args[argidx+1].find(':'); 116 if (pos == std::string::npos) 117 break; 118 run_from = args[++argidx].substr(0, pos); 119 run_to = args[argidx].substr(pos+1); 120 continue; 121 } 122 if (args[argidx] == "-flatten") { 123 flatten = true; 124 continue; 125 } 126 if (args[argidx] == "-noflatten") { 127 flatten = false; 128 continue; 129 } 130 if (args[argidx] == "-noiopad") { 131 noiopad = true; 132 continue; 133 } 134 if (args[argidx] == "-vpr") { 135 vpr = true; 136 continue; 137 } 138 break; 139 } 140 extra_args(args, argidx, design); 141 142 if (!design->full_selection()) 143 log_cmd_error("This command only operates on fully selected designs!\n"); 144 145 log_header(design, "Executing SYNTH_MACHXO2 pass.\n"); 146 log_push(); 147 148 run_script(design, run_from, run_to); 149 150 log_pop(); 151 } 152 scriptSynthMachXO2Pass153 void script() override 154 { 155 if (check_label("begin")) 156 { 157 run("read_verilog -lib -icells +/machxo2/cells_sim.v"); 158 run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); 159 } 160 161 if (check_label("flatten", "(unless -noflatten)")) 162 { 163 if (flatten || help_mode) { 164 run("proc"); 165 run("flatten"); 166 run("tribuf -logic"); 167 run("deminout"); 168 } 169 } 170 171 if (check_label("coarse")) 172 { 173 run("synth -run coarse"); 174 } 175 176 if (check_label("fine")) 177 { 178 run("memory_map"); 179 run("opt -full"); 180 run("techmap -map +/techmap.v"); 181 run("opt -fast"); 182 } 183 184 if (check_label("map_ios", "(unless -noiopad)")) 185 { 186 if (!noiopad || help_mode) 187 { 188 run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD ~T:I:O -tinoutpad $__FACADE_TINOUTPAD ~T:O:I:B A:top"); 189 run("attrmvcp -attr src -attr LOC t:$__FACADE_OUTPAD %x:+[O] t:$__FACADE_TOUTPAD %x:+[O] t:$__FACADE_TINOUTPAD %x:+[B]"); 190 run("attrmvcp -attr src -attr LOC -driven t:$__FACADE_INPAD %x:+[I]"); 191 } 192 } 193 194 if (check_label("map_ffs")) 195 { 196 run("dfflegalize -cell $_DFF_P_ 0"); 197 } 198 199 if (check_label("map_luts")) 200 { 201 run("abc -lut 4 -dress"); 202 run("clean"); 203 } 204 205 if (check_label("map_cells")) 206 { 207 run("techmap -map +/machxo2/cells_map.v"); 208 run("clean"); 209 } 210 211 if (check_label("check")) 212 { 213 run("hierarchy -check"); 214 run("stat"); 215 run("blackbox =A:whitebox"); 216 } 217 218 if (check_label("blif")) 219 { 220 if (!blif_file.empty() || help_mode) { 221 if (vpr || help_mode) { 222 run(stringf("opt_clean -purge"), 223 " (vpr mode)"); 224 run(stringf("write_blif -attr -cname -conn -param %s", 225 help_mode ? "<file-name>" : blif_file.c_str()), 226 " (vpr mode)"); 227 } 228 if (!vpr) 229 run(stringf("write_blif -gates -attr -param %s", 230 help_mode ? "<file-name>" : blif_file.c_str()), 231 " (non-vpr mode)"); 232 } 233 } 234 235 if (check_label("edif")) 236 { 237 if (!edif_file.empty() || help_mode) 238 run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str())); 239 } 240 241 if (check_label("json")) 242 { 243 if (!json_file.empty() || help_mode) 244 run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str())); 245 } 246 } 247 } SynthMachXO2Pass; 248 249 PRIVATE_NAMESPACE_END 250