From 17372d8abde0139df4b8df3ebbeb71b222157200 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Feb 2016 12:40:32 +0100 Subject: [PATCH] Added "abc -luts" option, Improved Xilinx logic mapping --- passes/techmap/abc.cc | 50 ++++++++++++++++++++++++--------- techlibs/xilinx/synth_xilinx.cc | 4 +-- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 5c5148590..7da266026 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -592,7 +592,7 @@ struct abc_output_filter }; void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, int lut_mode2, bool dff_mode, std::string clk_str, + std::string liberty_file, std::string constr_file, bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, bool keepff, std::string delay_target, bool fast_mode, const std::vector &cells, bool show_tempdir) { module = current_module; @@ -626,7 +626,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (!constr_file.empty()) abc_script += stringf("read_constr -v %s; ", constr_file.c_str()); } else - if (lut_mode) + if (!lut_costs.empty()) abc_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); else abc_script += stringf("read_library %s/stdcells.genlib; ", tempdir_name.c_str()); @@ -642,7 +642,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin abc_script += script_file[i]; } else abc_script += stringf("source %s", script_file.c_str()); - } else if (lut_mode) + } else if (!lut_costs.empty()) abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; else if (!liberty_file.empty()) abc_script += constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); @@ -868,15 +868,13 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*get_cell_cost("$_MUX_")); fclose(f); - if (lut_mode) { + if (!lut_costs.empty()) { buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); if (f == NULL) log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); - for (int i = 0; i < lut_mode; i++) - fprintf(f, "%d 1.00 1.00\n", i+1); - for (int i = lut_mode; i < lut_mode2; i++) - fprintf(f, "%d %d.00 1.00\n", i+1, 2 << (i - lut_mode)); + for (int i = 0; i < GetSize(lut_costs); i++) + fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i)); fclose(f); } @@ -894,7 +892,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (ifs.fail()) log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - bool builtin_lib = liberty_file.empty() && script_file.empty() && !lut_mode; + bool builtin_lib = liberty_file.empty() && script_file.empty() && lut_costs.empty(); RTLIL::Design *mapped_design = new RTLIL::Design; parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_"); @@ -1238,6 +1236,10 @@ struct AbcPass : public Pass { log(" the area cost doubles with each additional input bit. the delay cost\n"); log(" is still constant for all lut widths.\n"); log("\n"); + log(" -luts ,,,:,..\n"); + log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); + log(" 2, 3, .. inputs.\n"); + log("\n"); // log(" -mux4, -mux8, -mux16\n"); // log(" try to extract 4-input, 8-input, and/or 16-input muxes\n"); // log(" (ignored when used with -liberty or -lut)\n"); @@ -1291,7 +1293,7 @@ struct AbcPass : public Pass { std::string script_file, liberty_file, constr_file, clk_str, delay_target; bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; bool show_tempdir = false; - int lut_mode = 0, lut_mode2 = 0; + vector lut_costs; markgroups = false; map_mux4 = false; @@ -1341,6 +1343,7 @@ struct AbcPass : public Pass { if (arg == "-lut" && argidx+1 < args.size()) { string arg = args[++argidx]; size_t pos = arg.find_first_of(':'); + int lut_mode = 0, lut_mode2 = 0; if (pos != string::npos) { lut_mode = atoi(arg.substr(0, pos).c_str()); lut_mode2 = atoi(arg.substr(pos+1).c_str()); @@ -1348,6 +1351,27 @@ struct AbcPass : public Pass { lut_mode = atoi(arg.c_str()); lut_mode2 = lut_mode; } + lut_costs.clear(); + for (int i = 0; i < lut_mode; i++) + lut_costs.push_back(1); + for (int i = lut_mode; i < lut_mode2; i++) + lut_costs.push_back(2 << (i - lut_mode)); + continue; + } + if (arg == "-luts" && argidx+1 < args.size()) { + lut_costs.clear(); + for (auto &tok : split_tokens(args[++argidx], ",")) { + auto parts = split_tokens(tok, ":"); + if (GetSize(parts) == 0 && !lut_costs.empty()) + lut_costs.push_back(lut_costs.back()); + else if (GetSize(parts) == 1) + lut_costs.push_back(atoi(parts.at(0).c_str())); + else if (GetSize(parts) == 2) + while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) + lut_costs.push_back(atoi(parts.at(1).c_str())); + else + log_cmd_error("Invalid -luts syntax.\n"); + } continue; } if (arg == "-mux4") { @@ -1414,7 +1438,7 @@ struct AbcPass : public Pass { } extra_args(args, argidx, design); - if (lut_mode != 0 && !liberty_file.empty()) + if (!lut_costs.empty() && !liberty_file.empty()) log_cmd_error("Got -lut and -liberty! This two options are exclusive.\n"); if (!constr_file.empty() && liberty_file.empty()) log_cmd_error("Got -constr but no -liberty!\n"); @@ -1423,7 +1447,7 @@ struct AbcPass : public Pass { if (mod->processes.size() > 0) log("Skipping module %s as it contains processes.\n", log_id(mod)); else if (!dff_mode || !clk_str.empty()) - abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, lut_mode2, dff_mode, clk_str, keepff, delay_target, fast_mode, mod->selected_cells(), show_tempdir); + abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, delay_target, fast_mode, mod->selected_cells(), show_tempdir); else { assign_map.set(mod); @@ -1567,7 +1591,7 @@ struct AbcPass : public Pass { clk_sig = assign_map(std::get<1>(it.first)); en_polarity = std::get<2>(it.first); en_sig = assign_map(std::get<3>(it.first)); - abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, lut_mode2, + abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", keepff, delay_target, fast_mode, it.second, show_tempdir); assign_map.set(mod); } diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index fbcc96014..6358a266b 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -97,7 +97,7 @@ struct SynthXilinxPass : public Pass { log(" opt -fast\n"); log("\n"); log(" map_luts:\n"); - log(" abc -lut 5:8 [-dff]\n"); + log(" abc -luts 2:2,3,6:5,10,20 [-dff]\n"); log(" clean\n"); log("\n"); log(" map_cells:\n"); @@ -204,7 +204,7 @@ struct SynthXilinxPass : public Pass { if (check_label(active, run_from, run_to, "map_luts")) { - Pass::call(design, "abc -lut 6:8" + string(retime ? " -dff" : "")); + Pass::call(design, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); Pass::call(design, "clean"); } -- 2.30.2