Added "abc -luts" option, Improved Xilinx logic mapping

This commit is contained in:
Clifford Wolf 2016-02-01 12:40:32 +01:00
parent 9251553592
commit 17372d8abd
2 changed files with 39 additions and 15 deletions

View File

@ -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<int> lut_costs, bool dff_mode, std::string clk_str,
bool keepff, std::string delay_target, bool fast_mode, const std::vector<RTLIL::Cell*> &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 <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..\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<int> 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);
}

View File

@ -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");
}