aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap/abc9.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/techmap/abc9.cc')
-rw-r--r--passes/techmap/abc9.cc63
1 files changed, 53 insertions, 10 deletions
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 2aeda16d6..212e0692d 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -145,6 +145,11 @@ struct Abc9Pass : public ScriptPass
log(" generate netlist using luts. Use the specified costs for luts with 1,\n");
log(" 2, 3, .. inputs.\n");
log("\n");
+ log(" -maxlut <width>\n");
+ log(" when auto-generating the lut library, discard all luts equal to or\n");
+ log(" greater than this size (applicable when neither -lut nor -luts is\n");
+ log(" specified).\n");
+ log("\n");
log(" -dff\n");
log(" also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n");
log(" domains are marked as such and automatically partitioned by ABC.\n");
@@ -175,6 +180,9 @@ struct Abc9Pass : public ScriptPass
std::stringstream exe_cmd;
bool dff_mode, cleanup;
+ bool lut_mode;
+ int maxlut;
+ std::string box_file;
void clear_flags() YS_OVERRIDE
{
@@ -182,6 +190,9 @@ struct Abc9Pass : public ScriptPass
exe_cmd << "abc9_exe";
dff_mode = false;
cleanup = true;
+ lut_mode = false;
+ maxlut = 0;
+ box_file = "";
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -202,9 +213,11 @@ struct Abc9Pass : public ScriptPass
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
if ((arg == "-exe" || arg == "-script" || arg == "-D" ||
- /* arg == "-S" || */ arg == "-lut" || arg == "-luts" ||
- arg == "-box" || arg == "-W") &&
+ /*arg == "-S" ||*/ arg == "-lut" || arg == "-luts" ||
+ /*arg == "-box" ||*/ arg == "-W") &&
argidx+1 < args.size()) {
+ if (arg == "-lut" || arg == "-luts")
+ lut_mode = true;
exe_cmd << " " << arg << " " << args[++argidx];
continue;
}
@@ -222,6 +235,14 @@ struct Abc9Pass : public ScriptPass
cleanup = false;
continue;
}
+ if (arg == "-box" && argidx+1 < args.size()) {
+ box_file = args[++argidx];
+ continue;
+ }
+ if (arg == "-maxlut" && argidx+1 < args.size()) {
+ maxlut = atoi(args[++argidx].c_str());
+ continue;
+ }
if (arg == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
if (pos == std::string::npos)
@@ -234,6 +255,9 @@ struct Abc9Pass : public ScriptPass
}
extra_args(args, argidx, design);
+ if (maxlut && lut_mode)
+ log_cmd_error("abc9 '-maxlut' option only applicable without '-lut' nor '-luts'.\n");
+
log_assert(design);
if (design->selected_modules().empty()) {
log_warning("No modules selected for ABC9 techmapping.\n");
@@ -251,11 +275,20 @@ struct Abc9Pass : public ScriptPass
void script() YS_OVERRIDE
{
if (check_label("pre")) {
+ run("abc9_ops -check");
run("scc -set_attr abc9_scc_id {}");
if (help_mode)
- run("abc9_ops -mark_scc -prep_xaiger [-dff]", "(option for -dff)");
+ run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)");
else
- run("abc9_ops -mark_scc -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)");
+ run("abc9_ops -mark_scc -prep_delays -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)");
+ if (help_mode)
+ run("abc9_ops -prep_lut <maxlut>", "(skip if -lut or -luts)");
+ else if (!lut_mode)
+ run(stringf("abc9_ops -prep_lut %d", maxlut));
+ if (help_mode)
+ run("abc9_ops -prep_box [-dff]", "(skip if -box)");
+ else if (box_file.empty())
+ run(stringf("abc9_ops -prep_box %s", dff_mode ? "-dff" : ""));
run("select -set abc9_holes A:abc9_holes");
run("flatten -wb @abc9_holes");
run("techmap @abc9_holes");
@@ -269,8 +302,10 @@ struct Abc9Pass : public ScriptPass
if (check_label("map")) {
if (help_mode) {
run("foreach module in selection");
+ run(" abc9_ops -write_lut <abc-temp-dir>/input.lut", "(skip if '-lut' or '-luts')");
+ run(" abc9_ops -write_box <abc-temp-dir>/input.box");
run(" write_xaiger -map <abc-temp-dir>/input.sym <abc-temp-dir>/input.xaig");
- run(" abc9_exe -cwd <abc-temp-dir> [options]");
+ run(" abc9_exe [options] -cwd <abc-temp-dir> [-lut <abc-temp-dir>/input.lut] -box <abc-temp-dir>/input.box");
run(" read_aiger -xaiger -wideports -module_name <module-name>$abc9 -map <abc-temp-dir>/input.sym <abc-temp-dir>/output.aig");
run(" abc9_ops -reintegrate");
}
@@ -296,7 +331,10 @@ struct Abc9Pass : public ScriptPass
tempdir_name[0] = tempdir_name[4] = '_';
tempdir_name = make_temp_dir(tempdir_name);
- run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
+ if (!lut_mode)
+ run_nocheck(stringf("abc9_ops -write_lut %s/input.lut", tempdir_name.c_str()));
+ run_nocheck(stringf("abc9_ops -write_box %s/input.box", tempdir_name.c_str()));
+ run_nocheck(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs");
@@ -307,9 +345,14 @@ struct Abc9Pass : public ScriptPass
active_design->scratchpad_get_int("write_xaiger.num_inputs"),
num_outputs);
if (num_outputs) {
- run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()));
- run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
- run("abc9_ops -reintegrate");
+ std::string abc9_exe_cmd;
+ abc9_exe_cmd += stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str());
+ if (!lut_mode)
+ abc9_exe_cmd += stringf(" -lut %s/input.lut", tempdir_name.c_str());
+ abc9_exe_cmd += stringf(" -box %s/input.box", tempdir_name.c_str());
+ run_nocheck(abc9_exe_cmd);
+ run_nocheck(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
+ run_nocheck("abc9_ops -reintegrate");
}
else
log("Don't call ABC as there is nothing to map.\n");
@@ -318,7 +361,7 @@ struct Abc9Pass : public ScriptPass
log("Removing temp directory.\n");
remove_directory(tempdir_name);
}
-
+ mod->check();
active_design->selection().selected_modules.clear();
log_pop();
}