1 /* 2 * yosys -- Yosys Open SYnthesis Suite 3 * 4 * Copyright (C) 2019 Miodrag Milanovic <micko@yosyshq.com> 5 * Copyright (C) 2019 Claire Xenia Wolf <claire@yosyshq.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 struct SynthEfinixPass : public ScriptPass 30 { SynthEfinixPassSynthEfinixPass31 SynthEfinixPass() : ScriptPass("synth_efinix", "synthesis for Efinix FPGAs") { } 32 helpSynthEfinixPass33 void help() override 34 { 35 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| 36 log("\n"); 37 log(" synth_efinix [options]\n"); 38 log("\n"); 39 log("This command runs synthesis for Efinix FPGAs.\n"); 40 log("\n"); 41 log(" -top <module>\n"); 42 log(" use the specified module as top module\n"); 43 log("\n"); 44 log(" -edif <file>\n"); 45 log(" write the design to the specified EDIF file. writing of an output file\n"); 46 log(" is omitted if this parameter is not specified.\n"); 47 log("\n"); 48 log(" -json <file>\n"); 49 log(" write the design to the specified JSON file. writing of an output file\n"); 50 log(" is omitted if this parameter is not specified.\n"); 51 log("\n"); 52 log(" -run <from_label>:<to_label>\n"); 53 log(" only run the commands between the labels (see below). an empty\n"); 54 log(" from label is synonymous to 'begin', and empty to label is\n"); 55 log(" synonymous to the end of the command list.\n"); 56 log("\n"); 57 log(" -noflatten\n"); 58 log(" do not flatten design before synthesis\n"); 59 log("\n"); 60 log(" -retime\n"); 61 log(" run 'abc' with '-dff -D 1' options\n"); 62 log("\n"); 63 log(" -nobram\n"); 64 log(" do not use EFX_RAM_5K cells in output netlist\n"); 65 log("\n"); 66 log("\n"); 67 log("The following commands are executed by this synthesis command:\n"); 68 help_script(); 69 log("\n"); 70 } 71 72 string top_opt, edif_file, json_file; 73 bool flatten, retime, nobram; 74 clear_flagsSynthEfinixPass75 void clear_flags() override 76 { 77 top_opt = "-auto-top"; 78 edif_file = ""; 79 json_file = ""; 80 flatten = true; 81 retime = false; 82 nobram = false; 83 } 84 executeSynthEfinixPass85 void execute(std::vector<std::string> args, RTLIL::Design *design) override 86 { 87 string run_from, run_to; 88 clear_flags(); 89 90 size_t argidx; 91 for (argidx = 1; argidx < args.size(); argidx++) 92 { 93 if (args[argidx] == "-top" && argidx+1 < args.size()) { 94 top_opt = "-top " + args[++argidx]; 95 continue; 96 } 97 if (args[argidx] == "-edif" && argidx+1 < args.size()) { 98 edif_file = args[++argidx]; 99 continue; 100 } 101 if (args[argidx] == "-json" && argidx+1 < args.size()) { 102 json_file = args[++argidx]; 103 continue; 104 } 105 if (args[argidx] == "-run" && argidx+1 < args.size()) { 106 size_t pos = args[argidx+1].find(':'); 107 if (pos == std::string::npos) 108 break; 109 run_from = args[++argidx].substr(0, pos); 110 run_to = args[argidx].substr(pos+1); 111 continue; 112 } 113 if (args[argidx] == "-noflatten") { 114 flatten = false; 115 continue; 116 } 117 if (args[argidx] == "-retime") { 118 retime = true; 119 continue; 120 } 121 if (args[argidx] == "-nobram") { 122 nobram = true; 123 continue; 124 } 125 break; 126 } 127 extra_args(args, argidx, design); 128 129 if (!design->full_selection()) 130 log_cmd_error("This command only operates on fully selected designs!\n"); 131 132 log_header(design, "Executing SYNTH_EFINIX pass.\n"); 133 log_push(); 134 135 run_script(design, run_from, run_to); 136 137 log_pop(); 138 } 139 scriptSynthEfinixPass140 void script() override 141 { 142 if (check_label("begin")) 143 { 144 run("read_verilog -lib +/efinix/cells_sim.v"); 145 run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); 146 } 147 148 if (flatten && check_label("flatten", "(unless -noflatten)")) 149 { 150 run("proc"); 151 run("flatten"); 152 run("tribuf -logic"); 153 run("deminout"); 154 } 155 156 if (check_label("coarse")) 157 { 158 run("synth -run coarse"); 159 } 160 161 if (!nobram || check_label("map_bram", "(skip if -nobram)")) 162 { 163 run("memory_bram -rules +/efinix/brams.txt"); 164 run("techmap -map +/efinix/brams_map.v"); 165 run("setundef -zero -params t:EFX_RAM_5K"); 166 } 167 168 if (check_label("map_ffram")) 169 { 170 run("opt -fast -mux_undef -undriven -fine"); 171 run("memory_map"); 172 run("opt -undriven -fine"); 173 } 174 175 if (check_label("map_gates")) 176 { 177 run("techmap -map +/techmap.v -map +/efinix/arith_map.v"); 178 run("opt -fast"); 179 if (retime || help_mode) 180 run("abc -dff -D 1", "(only if -retime)"); 181 } 182 183 if (check_label("map_ffs")) 184 { 185 run("dfflegalize -cell $_DFFE_????_ 0 -cell $_SDFFE_????_ 0 -cell $_SDFFCE_????_ 0 -cell $_DLATCH_?_ x"); 186 run("techmap -D NO_LUT -map +/efinix/cells_map.v"); 187 run("opt_expr -mux_undef"); 188 run("simplemap"); 189 } 190 191 if (check_label("map_luts")) 192 { 193 run("abc -lut 4"); 194 run("clean"); 195 } 196 197 if (check_label("map_cells")) 198 { 199 run("techmap -map +/efinix/cells_map.v"); 200 run("clean"); 201 } 202 203 if (check_label("map_gbuf")) 204 { 205 run("clkbufmap -buf $__EFX_GBUF O:I"); 206 run("techmap -map +/efinix/gbuf_map.v"); 207 run("efinix_fixcarry"); 208 run("clean"); 209 } 210 211 if (check_label("check")) 212 { 213 run("hierarchy -check"); 214 run("stat"); 215 run("check -noinit"); 216 run("blackbox =A:whitebox"); 217 } 218 219 if (check_label("edif")) 220 { 221 if (!edif_file.empty() || help_mode) 222 run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str())); 223 } 224 225 if (check_label("json")) 226 { 227 if (!json_file.empty() || help_mode) 228 run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str())); 229 } 230 } 231 } SynthEfinixPass; 232 233 PRIVATE_NAMESPACE_END 234