Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ABC: read_lib args and placeholders #4343

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 52 additions & 9 deletions passes/techmap/abc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,8 @@
std::vector<std::string> &liberty_files, std::vector<std::string> &genlib_files, std::string constr_file,
bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str, bool keepff, std::string delay_target,
std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode,
const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector<std::string> &dont_use_cells)
const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector<std::string> &dont_use_cells,
std::string liberty_args)
{
module = current_module;
map_autoidx = autoidx++;
Expand Down Expand Up @@ -806,7 +807,7 @@
}
bool first_lib = true;
for (std::string liberty_file : liberty_files) {
abc_script += stringf("read_lib %s %s -w \"%s\" ; ", dont_use_args.c_str(), first_lib ? "" : "-m", liberty_file.c_str());
abc_script += stringf("read_lib %s %s -w %s \"%s\" ; ", dont_use_args.c_str(), first_lib ? "" : "-m", liberty_args.c_str(), liberty_file.c_str());
first_lib = false;
}
for (std::string liberty_file : genlib_files)
Expand All @@ -819,17 +820,28 @@
else
abc_script += stringf("read_library %s/stdcells.genlib; ", tempdir_name.c_str());

std::string user_script;

if (!script_file.empty()) {
if (script_file[0] == '+') {
if (script_file[0] == '+') { // inline user script
for (size_t i = 1; i < script_file.size(); i++)
if (script_file[i] == '\'')
abc_script += "'\\''";
else if (script_file[i] == ',')
abc_script += " ";
else
abc_script += script_file[i];
} else
abc_script += stringf("source %s", script_file.c_str());
} else {
// read in user script
std::ifstream ifs(script_file.c_str());
if(ifs.is_open()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix whitespace/indentation in this block

user_script.assign( (std::istreambuf_iterator<char>(ifs) ),
(std::istreambuf_iterator<char>() ) );
} else {
log_error("Opening %s for reading failed\n", script_file.c_str());
}
abc_script += stringf("source %s/user.script", tempdir_name.c_str());
}
} else if (!lut_costs.empty()) {
bool all_luts_cost_same = true;
for (int this_cost : lut_costs)
Expand All @@ -849,6 +861,7 @@
for (size_t pos = abc_script.find("dretime;"); pos != std::string::npos; pos = abc_script.find("dretime;", pos+1))
abc_script = abc_script.substr(0, pos) + "dretime; retime -o {D};" + abc_script.substr(pos+8);

// replace placeholders in abc.script and user.script
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please factor out the substitution operation so that it's not open-coded many times

for (size_t pos = abc_script.find("{D}"); pos != std::string::npos; pos = abc_script.find("{D}", pos))
abc_script = abc_script.substr(0, pos) + delay_target + abc_script.substr(pos+3);

Expand All @@ -860,6 +873,25 @@

for (size_t pos = abc_script.find("{S}"); pos != std::string::npos; pos = abc_script.find("{S}", pos))
abc_script = abc_script.substr(0, pos) + lutin_shared + abc_script.substr(pos+3);

for (size_t pos = abc_script.find("{tmpdir}"); pos != std::string::npos; pos = abc_script.find("{tmpdir}", pos))
abc_script = abc_script.substr(0, pos) + tempdir_name.c_str() + abc_script.substr(pos+ strlen("{tmpdir}"));

for (size_t pos = user_script.find("{D}"); pos != std::string::npos; pos = user_script.find("{D}", pos))
user_script = user_script.substr(0, pos) + delay_target + user_script.substr(pos+3);

for (size_t pos = user_script.find("{I}"); pos != std::string::npos; pos = user_script.find("{I}", pos))
user_script = user_script.substr(0, pos) + sop_inputs + user_script.substr(pos+3);

for (size_t pos = user_script.find("{P}"); pos != std::string::npos; pos = user_script.find("{P}", pos))
user_script = user_script.substr(0, pos) + sop_products + user_script.substr(pos+3);

for (size_t pos = user_script.find("{S}"); pos != std::string::npos; pos = user_script.find("{S}", pos))
user_script = user_script.substr(0, pos) + lutin_shared + user_script.substr(pos+3);

for (size_t pos = user_script.find("{tmpdir}"); pos != std::string::npos; pos = user_script.find("{tmpdir}", pos))
user_script = user_script.substr(0, pos) + tempdir_name.c_str() + user_script.substr(pos+ strlen("{tmpdir}"));

if (abc_dress)
abc_script += stringf("; dress \"%s/input.blif\"", tempdir_name.c_str());
abc_script += stringf("; write_blif %s/output.blif", tempdir_name.c_str());
Expand All @@ -876,6 +908,13 @@
fprintf(f, "%s\n", abc_script.c_str());
fclose(f);

buffer = stringf("%s/user.script", tempdir_name.c_str());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the abc.script/user.script separation? Why not write both to the same file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The abc.script and user.script separation is how it currently works. It basically separates the setup (loading the network and library and later writing it out) from the actual optimization and mapping script.

A different approach (and the one I would like to move in) is to give an option to not use the abc.script part and instead expect it to be part of the custom user.script and then just replace the placeholders in user.script.

This would give full freedom in what people do with ABC, going as far as invoking multiple ABC scripts in parallel and selecting one based one some criteria before returning to Yosys.

f = fopen(buffer.c_str(), "wt");
if (f == nullptr)
log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
fprintf(f, "%s\n", user_script.c_str());
fclose(f);

if (dff_mode || !clk_str.empty())
{
if (clk_sig.size() == 0)
Expand Down Expand Up @@ -1659,7 +1698,7 @@
po_map.clear();

std::string exe_file = yosys_abc_executable;
std::string script_file, default_liberty_file, constr_file, clk_str;
std::string script_file, default_liberty_file, constr_file, clk_str, liberty_args;
std::vector<std::string> liberty_files, genlib_files, dont_use_cells;
std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1";
bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true;
Expand Down Expand Up @@ -1743,6 +1782,10 @@
liberty_files.push_back(args[++argidx]);
continue;
}
if (arg == "-liberty_args" && argidx+1 < args.size()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document this option

liberty_args = args[++argidx];
continue;
}
if (arg == "-dont_use" && argidx+1 < args.size()) {
dont_use_cells.push_back(args[++argidx]);
continue;
Expand Down Expand Up @@ -2004,7 +2047,7 @@
goto ok_alias;
}
if (g_arg_from_cmd)
cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str()));

Check warning on line 2050 in passes/techmap/abc.cc

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

‘g_argidx’ may be used uninitialized in this function [-Wmaybe-uninitialized]
else
log_cmd_error("Unsupported gate type: %s", g.c_str());
ok_gate:
Expand Down Expand Up @@ -2053,7 +2096,7 @@

if (!dff_mode || !clk_str.empty()) {
abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress, dont_use_cells);
delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress, dont_use_cells, liberty_args);
continue;
}

Expand Down Expand Up @@ -2214,8 +2257,8 @@
arst_sig = assign_map(std::get<5>(it.first));
srst_polarity = std::get<6>(it.first);
srst_sig = assign_map(std::get<7>(it.first));
abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$",
keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress, dont_use_cells);
abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", keepff,
delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress, dont_use_cells, liberty_args);
assign_map.set(mod);
}
}
Expand Down
Loading