diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index b33e1a17df4..0130a23c3de 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -707,7 +707,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin std::vector &liberty_files, std::vector &genlib_files, std::string constr_file, bool cleanup, vector 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 &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector &dont_use_cells) + const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector &dont_use_cells, + std::string liberty_args) { module = current_module; map_autoidx = autoidx++; @@ -806,7 +807,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } 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) @@ -819,8 +820,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin 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 += "'\\''"; @@ -828,8 +831,17 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin 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()) { + user_script.assign( (std::istreambuf_iterator(ifs) ), + (std::istreambuf_iterator() ) ); + } 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) @@ -849,6 +861,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin 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 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); @@ -860,6 +873,25 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin 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()); @@ -876,6 +908,13 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin fprintf(f, "%s\n", abc_script.c_str()); fclose(f); + buffer = stringf("%s/user.script", tempdir_name.c_str()); + 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) @@ -1659,7 +1698,7 @@ struct AbcPass : public Pass { 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 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; @@ -1743,6 +1782,10 @@ struct AbcPass : public Pass { liberty_files.push_back(args[++argidx]); continue; } + if (arg == "-liberty_args" && argidx+1 < args.size()) { + liberty_args = args[++argidx]; + continue; + } if (arg == "-dont_use" && argidx+1 < args.size()) { dont_use_cells.push_back(args[++argidx]); continue; @@ -2053,7 +2096,7 @@ struct AbcPass : public Pass { 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; } @@ -2214,8 +2257,8 @@ struct AbcPass : public Pass { 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); } }