From d704eba595348dbda96e4662474a9a308c1a671d Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Thu, 25 Sep 2025 10:16:22 -0700 Subject: [PATCH] Fix traceability by reverting to old abc --- passes/techmap/abc.cc | 1282 +++++++++++++++++++---------------------- 1 file changed, 586 insertions(+), 696 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index dbb6080e1..998aeda1e 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -113,84 +113,25 @@ bool map_mux8; bool map_mux16; bool markgroups; - +int map_autoidx; +SigMap assign_map; +RTLIL::Module *module; +std::vector signal_list; +dict signal_map; +FfInitVals initvals; pool enabled_gates; bool cmos_cost; +bool had_init; -struct AbcConfig +bool clk_polarity, en_polarity, arst_polarity, srst_polarity; +RTLIL::SigSpec clk_sig, en_sig, arst_sig, srst_sig; +dict pi_map, po_map; + +int undef_bits_lost; + +int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1) { - std::string script_file; - std::string exe_file; - std::string map_src; - std::vector liberty_files; - std::vector genlib_files; - std::string constr_file; - std::vector lut_costs; - std::string delay_target; - std::string sop_inputs; - std::string sop_products; - std::string lutin_shared; - std::vector dont_use_cells; - bool cleanup = true; - bool keepff = false; - bool fast_mode = false; - bool show_tempdir = false; - bool sop_mode = false; - bool word_mode = false; - bool abc_dress = false; -}; - -struct AbcSigVal { - bool is_port; - - AbcSigVal(bool is_port = false) : is_port(is_port) {} - AbcSigVal &operator|=(const AbcSigVal &other) { - is_port |= other.is_port; - return *this; - } -}; - -using AbcSigMap = SigValMap; - -struct AbcModuleState { - const AbcConfig &config; - - int map_autoidx = 0; - std::vector signal_list; - dict signal_map; - FfInitVals &initvals; - bool had_init = false; - bool did_run_abc = false; - - bool clk_polarity = false; - bool en_polarity = false; - bool arst_polarity = false; - bool srst_polarity = false; - RTLIL::SigSpec clk_sig, en_sig, arst_sig, srst_sig; - dict pi_map, po_map; - - int undef_bits_lost = 0; - - std::string tempdir_name; - - AbcModuleState(const AbcConfig &config, FfInitVals &initvals) - : config(config), initvals(initvals) {} - - int map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1); - void mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig); - bool extract_cell(const AbcSigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff); - std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullptr); - void dump_loop_graph(FILE *f, int &nr, dict> &edges, pool &workpool, std::vector &in_counts); - void handle_loops(AbcSigMap &assign_map, RTLIL::Module *module); - void abc_module(RTLIL::Design *design, RTLIL::Module *module, AbcSigMap &assign_map, const std::vector &cells, - bool dff_mode, std::string clk_str); - void extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module); - void finish(); -}; - -int AbcModuleState::map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type, int in1, int in2, int in3, int in4) -{ - AbcSigVal val = assign_map.apply_and_get_value(bit); + assign_map.apply(bit); if (bit == State::Sx) undef_bits_lost++; @@ -203,7 +144,7 @@ int AbcModuleState::map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, g gate.in2 = -1; gate.in3 = -1; gate.in4 = -1; - gate.is_port = bit.wire != nullptr && val.is_port; + gate.is_port = false; gate.bit = bit; gate.init = initvals(bit); signal_list.push_back(gate); @@ -226,40 +167,40 @@ int AbcModuleState::map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, g return gate.id; } -void AbcModuleState::mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig) +void mark_port(RTLIL::SigSpec sig) { for (auto &bit : assign_map(sig)) if (bit.wire != nullptr && signal_map.count(bit) > 0) signal_list[signal_map[bit]].is_port = true; } -bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff) +void extract_cell(RTLIL::Cell *cell, bool keepff) { if (cell->is_builtin_ff()) { FfData ff(&initvals, cell); gate_type_t type = G(FF); if (!ff.has_clk) - return false; + return; if (ff.has_gclk) - return false; + return; if (ff.has_aload) - return false; + return; if (ff.has_sr) - return false; + return; if (!ff.is_fine) - return false; + return; if (clk_polarity != ff.pol_clk) - return false; + return; if (clk_sig != assign_map(ff.sig_clk)) - return false; + return; if (ff.has_ce) { if (en_polarity != ff.pol_ce) - return false; + return; if (en_sig != assign_map(ff.sig_ce)) - return false; + return; } else { if (GetSize(en_sig) != 0) - return false; + return; } if (ff.val_init == State::S1) { type = G(FF1); @@ -270,55 +211,50 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo } if (ff.has_arst) { if (arst_polarity != ff.pol_arst) - return false; + return; if (arst_sig != assign_map(ff.sig_arst)) - return false; + return; if (ff.val_arst == State::S1) { if (type == G(FF0)) - return false; + return; type = G(FF1); } else if (ff.val_arst == State::S0) { if (type == G(FF1)) - return false; + return; type = G(FF0); } } else { if (GetSize(arst_sig) != 0) - return false; + return; } if (ff.has_srst) { if (srst_polarity != ff.pol_srst) - return false; + return; if (srst_sig != assign_map(ff.sig_srst)) - return false; + return; if (ff.val_srst == State::S1) { if (type == G(FF0)) - return false; + return; type = G(FF1); } else if (ff.val_srst == State::S0) { if (type == G(FF1)) - return false; + return; type = G(FF0); } } else { if (GetSize(srst_sig) != 0) - return false; + return; } - int gate_id = map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d)); - if (keepff) { - SigBit bit = ff.sig_q; - if (assign_map(bit).wire != nullptr) { - signal_list[gate_id].is_port = true; - } - if (bit.wire != nullptr) - bit.wire->attributes[ID::keep] = 1; - } + if (keepff) + for (auto &c : ff.sig_q.chunks()) + if (c.wire != nullptr) + c.wire->attributes[ID::keep] = 1; - map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d)); + map_signal(ff.sig_q, type, map_signal(ff.sig_d)); ff.remove(); - return true; + return; } if (cell->type.in(ID($_BUF_), ID($_NOT_))) @@ -329,10 +265,10 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo assign_map.apply(sig_a); assign_map.apply(sig_y); - map_signal(assign_map, sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(assign_map, sig_a)); + map_signal(sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(sig_a)); module->remove(cell); - return true; + return; } if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) @@ -345,30 +281,30 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo assign_map.apply(sig_b); assign_map.apply(sig_y); - int mapped_a = map_signal(assign_map, sig_a); - int mapped_b = map_signal(assign_map, sig_b); + int mapped_a = map_signal(sig_a); + int mapped_b = map_signal(sig_b); if (cell->type == ID($_AND_)) - map_signal(assign_map, sig_y, G(AND), mapped_a, mapped_b); + map_signal(sig_y, G(AND), mapped_a, mapped_b); else if (cell->type == ID($_NAND_)) - map_signal(assign_map, sig_y, G(NAND), mapped_a, mapped_b); + map_signal(sig_y, G(NAND), mapped_a, mapped_b); else if (cell->type == ID($_OR_)) - map_signal(assign_map, sig_y, G(OR), mapped_a, mapped_b); + map_signal(sig_y, G(OR), mapped_a, mapped_b); else if (cell->type == ID($_NOR_)) - map_signal(assign_map, sig_y, G(NOR), mapped_a, mapped_b); + map_signal(sig_y, G(NOR), mapped_a, mapped_b); else if (cell->type == ID($_XOR_)) - map_signal(assign_map, sig_y, G(XOR), mapped_a, mapped_b); + map_signal(sig_y, G(XOR), mapped_a, mapped_b); else if (cell->type == ID($_XNOR_)) - map_signal(assign_map, sig_y, G(XNOR), mapped_a, mapped_b); + map_signal(sig_y, G(XNOR), mapped_a, mapped_b); else if (cell->type == ID($_ANDNOT_)) - map_signal(assign_map, sig_y, G(ANDNOT), mapped_a, mapped_b); + map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b); else if (cell->type == ID($_ORNOT_)) - map_signal(assign_map, sig_y, G(ORNOT), mapped_a, mapped_b); + map_signal(sig_y, G(ORNOT), mapped_a, mapped_b); else log_abort(); module->remove(cell); - return true; + return; } if (cell->type.in(ID($_MUX_), ID($_NMUX_))) @@ -383,14 +319,14 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo assign_map.apply(sig_s); assign_map.apply(sig_y); - int mapped_a = map_signal(assign_map, sig_a); - int mapped_b = map_signal(assign_map, sig_b); - int mapped_s = map_signal(assign_map, sig_s); + int mapped_a = map_signal(sig_a); + int mapped_b = map_signal(sig_b); + int mapped_s = map_signal(sig_s); - map_signal(assign_map, sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s); + map_signal(sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s); module->remove(cell); - return true; + return; } if (cell->type.in(ID($_AOI3_), ID($_OAI3_))) @@ -405,14 +341,14 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo assign_map.apply(sig_c); assign_map.apply(sig_y); - int mapped_a = map_signal(assign_map, sig_a); - int mapped_b = map_signal(assign_map, sig_b); - int mapped_c = map_signal(assign_map, sig_c); + int mapped_a = map_signal(sig_a); + int mapped_b = map_signal(sig_b); + int mapped_c = map_signal(sig_c); - map_signal(assign_map, sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c); + map_signal(sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c); module->remove(cell); - return true; + return; } if (cell->type.in(ID($_AOI4_), ID($_OAI4_))) @@ -429,21 +365,19 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo assign_map.apply(sig_d); assign_map.apply(sig_y); - int mapped_a = map_signal(assign_map, sig_a); - int mapped_b = map_signal(assign_map, sig_b); - int mapped_c = map_signal(assign_map, sig_c); - int mapped_d = map_signal(assign_map, sig_d); + int mapped_a = map_signal(sig_a); + int mapped_b = map_signal(sig_b); + int mapped_c = map_signal(sig_c); + int mapped_d = map_signal(sig_d); - map_signal(assign_map, sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d); + map_signal(sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d); module->remove(cell); - return true; + return; } - - return false; } -std::string AbcModuleState::remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire) +std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullptr) { std::string abc_sname = abc_name.substr(1); if (abc_sname.compare(0, 9, "new_ys__n") == 0) @@ -476,7 +410,7 @@ std::string AbcModuleState::remap_name(RTLIL::IdString abc_name, RTLIL::Wire **o return stringf("\\%s_ix%d", abc_sname.c_str(), map_autoidx); // SILIMATE: Improve the naming } -void AbcModuleState::dump_loop_graph(FILE *f, int &nr, dict> &edges, pool &workpool, std::vector &in_counts) +void dump_loop_graph(FILE *f, int &nr, dict> &edges, pool &workpool, std::vector &in_counts) { if (f == nullptr) return; @@ -505,13 +439,7 @@ void AbcModuleState::dump_loop_graph(FILE *f, int &nr, dict> &edg fprintf(f, "}\n"); } -void connect(AbcSigMap &assign_map, RTLIL::Module *module, const RTLIL::SigSig &conn) -{ - module->connect(conn); - assign_map.add(conn.first, conn.second); -} - -void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module) +void handle_loops() { // http://en.wikipedia.org/wiki/Topological_sorting // (Kahn, Arthur B. (1962), "Topological sorting of large networks") @@ -616,7 +544,7 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module) first_line = false; } - int id3 = map_signal(assign_map, RTLIL::SigSpec(wire)); + int id3 = map_signal(RTLIL::SigSpec(wire)); signal_list[id1].is_port = true; signal_list[id3].is_port = true; log_assert(id3 == int(in_edges_count.size())); @@ -635,7 +563,7 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module) } edges[id1].swap(edges[id3]); - connect(assign_map, module, RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); + module->connect(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count); } } @@ -712,15 +640,13 @@ std::string replace_tempdir(std::string text, std::string tempdir_name, bool sho struct abc_output_filter { - const AbcModuleState &state; bool got_cr; int escape_seq_state; std::string linebuf; std::string tempdir_name; bool show_tempdir; - abc_output_filter(const AbcModuleState& state, std::string tempdir_name, bool show_tempdir) - : state(state), tempdir_name(tempdir_name), show_tempdir(show_tempdir) + abc_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) { got_cr = false; escape_seq_state = 0; @@ -747,7 +673,7 @@ struct abc_output_filter return; } if (ch == '\n') { - log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir)); + log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); got_cr = false, linebuf.clear(); return; } @@ -761,8 +687,8 @@ struct abc_output_filter int pi, po; if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", - pi, state.pi_map.count(pi) ? state.pi_map.at(pi).c_str() : "???", - po, state.po_map.count(po) ? state.po_map.at(po).c_str() : "???"); + pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", + po, po_map.count(po) ? po_map.at(po).c_str() : "???"); return; } @@ -771,11 +697,37 @@ struct abc_output_filter } }; -void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, AbcSigMap &assign_map, const std::vector &cells, - bool dff_mode, std::string clk_str) +void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, + 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 word_mode, bool abc_dress, std::vector &dont_use_cells, const std::string& map_src) { + module = current_module; map_autoidx = autoidx++; + // SILIMATE: Create a map of all signals and their corresponding driver attributes + SigMap sigmap(module); + dict> sig_to_driver_attrs; + for (auto wire : module->wires()) + if (wire->port_input) + for (auto bit : sigmap(wire)) + sig_to_driver_attrs[bit] = wire->attributes; + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) { + if (GetSize(cell->attributes) > 0) + sig_to_driver_attrs[bit] = cell->attributes; + else + sig_to_driver_attrs[bit] = bit.wire->attributes; + } + + signal_map.clear(); + signal_list.clear(); + pi_map.clear(); + po_map.clear(); + if (clk_str != "$") { clk_polarity = true; @@ -846,39 +798,39 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab if (dff_mode && clk_sig.empty()) log_cmd_error("Clock domain %s not found.\n", clk_str.c_str()); - if (config.cleanup) + std::string tempdir_name; + if (cleanup) tempdir_name = get_base_tmpdir() + "/"; else tempdir_name = "_tmp_"; tempdir_name += proc_program_prefix() + "yosys-abc-XXXXXX"; tempdir_name = make_temp_dir(tempdir_name); log_header(design, "Extracting gate netlist of module `%s' to `%s/input.blif'..\n", - module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, config.show_tempdir).c_str()); + module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); - std::string abc_script = stringf("read_blif \"%s/input.blif\"; ", tempdir_name); + std::string abc_script = stringf("read_blif \"%s/input.blif\"; ", tempdir_name.c_str()); - if (!config.liberty_files.empty() || !config.genlib_files.empty()) { + if (!liberty_files.empty() || !genlib_files.empty()) { std::string dont_use_args; - for (std::string dont_use_cell : config.dont_use_cells) { - dont_use_args += stringf("-X \"%s\" ", dont_use_cell); + for (std::string dont_use_cell : dont_use_cells) { + dont_use_args += stringf("-X \"%s\" ", dont_use_cell.c_str()); } bool first_lib = true; - for (std::string liberty_file : config.liberty_files) { - abc_script += stringf("read_lib %s %s -w \"%s\" ; ", dont_use_args, first_lib ? "" : "-m", liberty_file); + 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()); first_lib = false; } - for (std::string liberty_file : config.genlib_files) - abc_script += stringf("read_library \"%s\"; ", liberty_file); - if (!config.constr_file.empty()) - abc_script += stringf("read_constr -v \"%s\"; ", config.constr_file); + for (std::string liberty_file : genlib_files) + abc_script += stringf("read_library \"%s\"; ", liberty_file.c_str()); + if (!constr_file.empty()) + abc_script += stringf("read_constr -v \"%s\"; ", constr_file.c_str()); } else - if (!config.lut_costs.empty()) - abc_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name); + 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); + abc_script += stringf("read_library %s/stdcells.genlib; ", tempdir_name.c_str()); - if (!config.script_file.empty()) { - const std::string &script_file = config.script_file; + if (!script_file.empty()) { if (script_file[0] == '+') { for (size_t i = 1; i < script_file.size(); i++) if (script_file[i] == '\'') @@ -888,51 +840,50 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab else abc_script += script_file[i]; } else - abc_script += stringf("source %s", script_file); - } else if (!config.lut_costs.empty()) { + abc_script += stringf("source %s", script_file.c_str()); + } else if (!lut_costs.empty()) { bool all_luts_cost_same = true; - for (int this_cost : config.lut_costs) - if (this_cost != config.lut_costs.front()) + for (int this_cost : lut_costs) + if (this_cost != lut_costs.front()) all_luts_cost_same = false; - abc_script += config.fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; - if (all_luts_cost_same && !config.fast_mode) + abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; + if (all_luts_cost_same && !fast_mode) abc_script += "; lutpack {S}"; - } else if (!config.liberty_files.empty() || !config.genlib_files.empty()) - abc_script += config.constr_file.empty() ? - (config.fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (config.fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); - else if (config.sop_mode) - abc_script += config.fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP; + } else if (!liberty_files.empty() || !genlib_files.empty()) + abc_script += constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); + else if (sop_mode) + abc_script += fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP; else - abc_script += config.fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL; + abc_script += fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL; - if (config.script_file.empty() && !config.delay_target.empty()) + if (script_file.empty() && !delay_target.empty()) 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); 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) + config.delay_target + abc_script.substr(pos+3); + abc_script = abc_script.substr(0, pos) + delay_target + abc_script.substr(pos+3); for (size_t pos = abc_script.find("{I}"); pos != std::string::npos; pos = abc_script.find("{I}", pos)) - abc_script = abc_script.substr(0, pos) + config.sop_inputs + abc_script.substr(pos+3); + abc_script = abc_script.substr(0, pos) + sop_inputs + abc_script.substr(pos+3); for (size_t pos = abc_script.find("{P}"); pos != std::string::npos; pos = abc_script.find("{P}", pos)) - abc_script = abc_script.substr(0, pos) + config.sop_products + abc_script.substr(pos+3); + abc_script = abc_script.substr(0, pos) + sop_products + abc_script.substr(pos+3); 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) + config.lutin_shared + abc_script.substr(pos+3); - if (config.abc_dress) - abc_script += stringf("; dress \"%s/input.blif\"", tempdir_name); - abc_script += stringf("; write_blif %s/output.blif", tempdir_name); + abc_script = abc_script.substr(0, pos) + lutin_shared + abc_script.substr(pos+3); + 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()); abc_script = add_echos_to_abc_cmd(abc_script); for (size_t i = 0; i+1 < abc_script.size(); i++) if (abc_script[i] == ';' && abc_script[i+1] == ' ') abc_script[i+1] = '\n'; - std::string buffer = stringf("%s/abc.script", tempdir_name); + std::string buffer = stringf("%s/abc.script", tempdir_name.c_str()); FILE *f = fopen(buffer.c_str(), "wt"); if (f == nullptr) - log_error("Opening %s for writing failed: %s\n", buffer, strerror(errno)); + log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); fprintf(f, "%s\n", abc_script.c_str()); fclose(f); @@ -955,39 +906,39 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab undef_bits_lost = 0; had_init = false; - std::vector kept_cells; for (auto c : cells) - if (!extract_cell(assign_map, module, c, config.keepff)) - kept_cells.push_back(c); + extract_cell(c, keepff); if (undef_bits_lost) log("Replacing %d occurrences of constant undef bits with constant zero bits\n", undef_bits_lost); - // Wires with port_id > 0, ID::keep, and connections to cells outside our cell set have already - // been accounted for via AbcSigVal::is_port. Now we just need to account for - // connections to cells inside our cell set that weren't removed by extract_cell(). - for (auto cell : kept_cells) - for (auto &port_it : cell->connections()) - mark_port(assign_map, port_it.second); + for (auto wire : module->wires()) { + if (wire->port_id > 0 || wire->get_bool_attribute(ID::keep)) + mark_port(wire); + } + + for (auto cell : module->cells()) + for (auto &port_it : cell->connections()) + mark_port(port_it.second); if (clk_sig.size() != 0) - mark_port(assign_map, clk_sig); + mark_port(clk_sig); if (en_sig.size() != 0) - mark_port(assign_map, en_sig); + mark_port(en_sig); if (arst_sig.size() != 0) - mark_port(assign_map, arst_sig); + mark_port(arst_sig); if (srst_sig.size() != 0) - mark_port(assign_map, srst_sig); + mark_port(srst_sig); - handle_loops(assign_map, module); + handle_loops(); - buffer = stringf("%s/input.blif", tempdir_name); + buffer = stringf("%s/input.blif", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); if (f == nullptr) - log_error("Opening %s for writing failed: %s\n", buffer, strerror(errno)); + log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); fprintf(f, ".model netlist\n"); @@ -1009,7 +960,7 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab if (!si.is_port || si.type == G(NONE)) continue; fprintf(f, " ys__n%d", si.id); - po_map[count_output++] = log_signal(si.bit); + po_map[count_output++] = log_signal(si.bit).c_str(); } fprintf(f, "\n"); @@ -1111,10 +1062,10 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab auto &cell_cost = cmos_cost ? CellCosts::cmos_gate_cost() : CellCosts::default_gate_cost(); - buffer = stringf("%s/stdcells.genlib", tempdir_name); + buffer = stringf("%s/stdcells.genlib", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); if (f == nullptr) - log_error("Opening %s for writing failed: %s\n", buffer, strerror(errno)); + log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); fprintf(f, "GATE ZERO 1 Y=CONST0;\n"); fprintf(f, "GATE ONE 1 Y=CONST1;\n"); fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_BUF_))); @@ -1155,24 +1106,24 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab 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*cell_cost.at(ID($_MUX_))); fclose(f); - if (!config.lut_costs.empty()) { - buffer = stringf("%s/lutdefs.txt", tempdir_name); + if (!lut_costs.empty()) { + buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); if (f == nullptr) - log_error("Opening %s for writing failed: %s\n", buffer, strerror(errno)); - for (int i = 0; i < GetSize(config.lut_costs); i++) - fprintf(f, "%d %d.00 1.00\n", i+1, config.lut_costs.at(i)); + log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); + 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); } - buffer = stringf("\"%s\" -s -f %s/abc.script 2>&1", config.exe_file, tempdir_name); - log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, config.show_tempdir)); + buffer = stringf("\"%s\" -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); + log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); #ifndef YOSYS_LINK_ABC - abc_output_filter filt(*this, tempdir_name, config.show_tempdir); + abc_output_filter filt(tempdir_name, show_tempdir); int ret = run_command(buffer, std::bind(&abc_output_filter::next_line, filt, std::placeholders::_1)); #else - string temp_stdouterr_name = stringf("%s/stdouterr.txt", tempdir_name); + string temp_stdouterr_name = stringf("%s/stdouterr.txt", tempdir_name.c_str()); FILE *temp_stdouterr_w = fopen(temp_stdouterr_name.c_str(), "w"); if (temp_stdouterr_w == NULL) log_error("ABC: cannot open a temporary file for output redirection"); @@ -1192,8 +1143,8 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab fclose(temp_stdouterr_w); // These needs to be mutable, supposedly due to getopt char *abc_argv[5]; - string tmp_script_name = stringf("%s/abc.script", tempdir_name); - abc_argv[0] = strdup(config.exe_file.c_str()); + string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); + abc_argv[0] = strdup(exe_file.c_str()); abc_argv[1] = strdup("-s"); abc_argv[2] = strdup("-f"); abc_argv[3] = strdup(tmp_script_name.c_str()); @@ -1210,232 +1161,251 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Ab fclose(old_stdout); fclose(old_stderr); std::ifstream temp_stdouterr_r(temp_stdouterr_name); - abc_output_filter filt(*this, tempdir_name, config.show_tempdir); + abc_output_filter filt(tempdir_name, show_tempdir); for (std::string line; std::getline(temp_stdouterr_r, line); ) filt.next_line(line + "\n"); temp_stdouterr_r.close(); #endif - if (ret != 0) { - log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer, ret); - return; - } - did_run_abc = true; - return; - } - log("Don't call ABC as there is nothing to map.\n"); -} + if (ret != 0) + log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); -void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module) -{ - // SILIMATE: Create a map of all signals and their corresponding driver attributes - SigMap sigmap(module); - dict> sig_to_driver_attrs; - for (auto wire : module->wires()) - if (wire->port_input) - for (auto bit : sigmap(wire)) - sig_to_driver_attrs[bit] = wire->attributes; - for (auto cell : module->cells()) { - for (auto &conn : cell->connections()) { - if (cell->output(conn.first)) { - for (auto bit : sigmap(conn.second)) { - if (GetSize(cell->attributes) > 0) - sig_to_driver_attrs[bit] = cell->attributes; - else - sig_to_driver_attrs[bit] = bit.wire->attributes; + buffer = stringf("%s/%s", tempdir_name.c_str(), "output.blif"); + std::ifstream ifs; + ifs.open(buffer); + if (ifs.fail()) + log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); + + bool builtin_lib = liberty_files.empty() && genlib_files.empty(); + RTLIL::Design *mapped_design = new RTLIL::Design; + parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, sop_mode); + + ifs.close(); + + log_header(design, "Re-integrating ABC results.\n"); + RTLIL::Module *mapped_mod = mapped_design->module(ID(netlist)); + SigMap mapped_sigmap(mapped_mod); + FfInitVals mapped_initvals(&mapped_sigmap, mapped_mod); + if (mapped_mod == nullptr) + log_error("ABC output file does not contain a module `netlist'.\n"); + for (auto w : mapped_mod->wires()) { + RTLIL::Wire *orig_wire = nullptr; + RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire)); + if (orig_wire != nullptr) { + if (sig_to_driver_attrs.count(sigmap(orig_wire))) { + wire->attributes = sig_to_driver_attrs[sigmap(orig_wire)]; + sig_to_driver_attrs[mapped_sigmap(wire)] = wire->attributes; + log_debug("Matched wire %s to driver attributes:\n", orig_wire->name.c_str()); + for (auto &attr : wire->attributes) + log_debug(" %s = %s\n", attr.first.c_str(), attr.second.decode_string().c_str()); + } else { + log_debug("No driver attributes found for wire %s\n", orig_wire->name.c_str()); } } + if (markgroups) wire->attributes[ID::abcgroup] = map_autoidx; + design->select(module, wire); } - } - if (!did_run_abc) { - return; - } - - std::string buffer = stringf("%s/%s", tempdir_name, "output.blif"); - std::ifstream ifs; - ifs.open(buffer); - if (ifs.fail()) - log_error("Can't open ABC output file `%s'.\n", buffer); - - bool builtin_lib = config.liberty_files.empty() && config.genlib_files.empty(); - RTLIL::Design *mapped_design = new RTLIL::Design; - parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, config.sop_mode); - - ifs.close(); - - log_header(design, "Re-integrating ABC results.\n"); - RTLIL::Module *mapped_mod = mapped_design->module(ID(netlist)); - SigMap mapped_sigmap(mapped_mod); - FfInitVals mapped_initvals(&mapped_sigmap, mapped_mod); - if (mapped_mod == nullptr) - log_error("ABC output file does not contain a module `netlist'.\n"); - for (auto w : mapped_mod->wires()) { - RTLIL::Wire *orig_wire = nullptr; - RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire)); - if (orig_wire != nullptr) { - if (sig_to_driver_attrs.count(sigmap(orig_wire))) { - wire->attributes = sig_to_driver_attrs[sigmap(orig_wire)]; - sig_to_driver_attrs[mapped_sigmap(wire)] = wire->attributes; - log_debug("Matched wire %s to driver attributes:\n", orig_wire->name.c_str()); - for (auto &attr : wire->attributes) - log_debug(" %s = %s\n", attr.first.c_str(), attr.second.decode_string().c_str()); - } else { - log_debug("No driver attributes found for wire %s\n", orig_wire->name.c_str()); - } - } - if (markgroups) wire->attributes[ID::abcgroup] = map_autoidx; - design->select(module, wire); - } - - dict cell_stats; - for (auto c : mapped_mod->cells()) - { - // SILIMATE: set output port to either Y or Q depending on the cell's ports - RTLIL::IdString output_port_name = (c->hasPort(ID::Y)) ? ID::Y : ID::Q; - c->attributes = sig_to_driver_attrs[mapped_sigmap(module->wire(remap_name(c->getPort(output_port_name).as_wire()->name)))]; - if (builtin_lib) + dict cell_stats; + for (auto c : mapped_mod->cells()) { - cell_stats[RTLIL::unescape_id(c->type)]++; - if (c->type.in(ID(ZERO), ID(ONE))) { - RTLIL::SigSig conn; - RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name); - conn.first = module->wire(name_y); - conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1); - connect(assign_map, module, conn); - continue; - } - if (c->type == ID(BUF)) { - RTLIL::SigSig conn; - RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name); - RTLIL::IdString name_a = remap_name(c->getPort(ID::A).as_wire()->name); - conn.first = module->wire(name_y); - conn.second = module->wire(name_a); - connect(assign_map, module, conn); - continue; - } - if (c->type == ID(NOT)) { - // SILIMATE: use word-level primitives - RTLIL::Cell *cell = module->addCell(remap_name(c->name), config.word_mode ? ID($not) : ID($_NOT_)); // SILIMATE: use word-level primitives - cell->attributes = c->attributes; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - for (auto name : {ID::A, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); + // SILIMATE: set output port to either Y or Q depending on the cell's ports + RTLIL::IdString output_port_name = (c->hasPort(ID::Y)) ? ID::Y : ID::Q; + c->attributes = sig_to_driver_attrs[mapped_sigmap(module->wire(remap_name(c->getPort(output_port_name).as_wire()->name)))]; + if (builtin_lib) + { + cell_stats[RTLIL::unescape_id(c->type)]++; + if (c->type.in(ID(ZERO), ID(ONE))) { + RTLIL::SigSig conn; + RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name); + conn.first = module->wire(name_y); + conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1); + module->connect(conn); + continue; } - cell->fixup_parameters(); - design->select(module, cell); - continue; - } - if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) { - // SILIMATE: use word-level primitives - std::string cell_type; - if (c->type == ID(AND) && config.word_mode) - cell_type = "$and"; - else if (c->type == ID(OR) && config.word_mode) - cell_type = "$or"; - else if (c->type == ID(XOR) && config.word_mode) - cell_type = "$xor"; - else - cell_type = stringf("$_%s_", c->type.c_str()+1); + if (c->type == ID(BUF)) { + RTLIL::SigSig conn; + RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name); + RTLIL::IdString name_a = remap_name(c->getPort(ID::A).as_wire()->name); + conn.first = module->wire(name_y); + conn.second = module->wire(name_a); + module->connect(conn); + continue; + } + if (c->type == ID(NOT)) { + // SILIMATE: use word-level primitives + RTLIL::Cell *cell = module->addCell(remap_name(c->name), word_mode ? ID($not) : ID($_NOT_)); // SILIMATE: use word-level primitives + cell->attributes = c->attributes; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + for (auto name : {ID::A, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + cell->fixup_parameters(); + design->select(module, cell); + continue; + } + if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) { + // SILIMATE: use word-level primitives + std::string cell_type; + if (c->type == ID(AND) && word_mode) + cell_type = "$and"; + else if (c->type == ID(OR) && word_mode) + cell_type = "$or"; + else if (c->type == ID(XOR) && word_mode) + cell_type = "$xor"; + else + cell_type = stringf("$_%s_", c->type.c_str()+1); - RTLIL::Cell *cell = module->addCell(remap_name(c->name), cell_type); - cell->attributes = c->attributes; - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - for (auto name : {ID::A, ID::B, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), cell_type); + cell->attributes = c->attributes; + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + for (auto name : {ID::A, ID::B, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + cell->fixup_parameters(); + design->select(module, cell); + continue; } - cell->fixup_parameters(); - design->select(module, cell); - continue; - } - if (c->type.in(ID(MUX), ID(NMUX))) { - // SILIMATE: use word-level primitives - std::string cell_type; - if (c->type == ID(MUX) && config.word_mode) - cell_type = "$mux"; - else - cell_type = stringf("$_%s_", c->type.c_str()+1); + if (c->type.in(ID(MUX), ID(NMUX))) { + // SILIMATE: use word-level primitives + std::string cell_type; + if (c->type == ID(MUX) && word_mode) + cell_type = "$mux"; + else + cell_type = stringf("$_%s_", c->type.c_str()+1); - RTLIL::Cell *cell = module->addCell(remap_name(c->name), cell_type); - cell->attributes = c->attributes; - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - for (auto name : {ID::A, ID::B, ID::S, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), cell_type); + cell->attributes = c->attributes; + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + for (auto name : {ID::A, ID::B, ID::S, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + cell->fixup_parameters(); + design->select(module, cell); + continue; } - cell->fixup_parameters(); - design->select(module, cell); + if (c->type == ID(MUX4)) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + design->select(module, cell); + continue; + } + if (c->type == ID(MUX8)) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + design->select(module, cell); + continue; + } + if (c->type == ID(MUX16)) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K, + ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + design->select(module, cell); + continue; + } + if (c->type.in(ID(AOI3), ID(OAI3))) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + for (auto name : {ID::A, ID::B, ID::C, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + design->select(module, cell); + continue; + } + if (c->type.in(ID(AOI4), ID(OAI4))) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::Y}) { + RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); + cell->setPort(name, module->wire(remapped_name)); + } + design->select(module, cell); + continue; + } + if (c->type == ID(DFF)) { + log_assert(clk_sig.size() == 1); + FfData ff(module, &initvals, remap_name(c->name)); + ff.width = 1; + ff.is_fine = true; + ff.has_clk = true; + ff.pol_clk = clk_polarity; + ff.sig_clk = clk_sig; + if (en_sig.size() != 0) { + log_assert(en_sig.size() == 1); + ff.has_ce = true; + ff.pol_ce = en_polarity; + ff.sig_ce = en_sig; + } + RTLIL::Const init = mapped_initvals(c->getPort(ID::Q)); + if (had_init) + ff.val_init = init; + else + ff.val_init = State::Sx; + if (arst_sig.size() != 0) { + log_assert(arst_sig.size() == 1); + ff.has_arst = true; + ff.pol_arst = arst_polarity; + ff.sig_arst = arst_sig; + ff.val_arst = init; + } + if (srst_sig.size() != 0) { + log_assert(srst_sig.size() == 1); + ff.has_srst = true; + ff.pol_srst = srst_polarity; + ff.sig_srst = srst_sig; + ff.val_srst = init; + } + ff.sig_d = module->wire(remap_name(c->getPort(ID::D).as_wire()->name)); + ff.sig_q = module->wire(remap_name(c->getPort(ID::Q).as_wire()->name)); + RTLIL::Cell *cell = ff.emit(); + if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + design->select(module, cell); + continue; + } + } + else + cell_stats[RTLIL::unescape_id(c->type)]++; + + if (c->type.in(ID(_const0_), ID(_const1_))) { + RTLIL::SigSig conn; + conn.first = module->wire(remap_name(c->connections().begin()->second.as_wire()->name)); + conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1); + module->connect(conn); continue; } - if (c->type == ID(MUX4)) { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_)); - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); - } - design->select(module, cell); - continue; - } - if (c->type == ID(MUX8)) { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_)); - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); - } - design->select(module, cell); - continue; - } - if (c->type == ID(MUX16)) { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_)); - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K, - ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); - } - design->select(module, cell); - continue; - } - if (c->type.in(ID(AOI3), ID(OAI3))) { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - for (auto name : {ID::A, ID::B, ID::C, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); - } - design->select(module, cell); - continue; - } - if (c->type.in(ID(AOI4), ID(OAI4))) { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); - if (!config.map_src.empty()) - cell->attributes[ID::src] = config.map_src; - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::Y}) { - RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); - cell->setPort(name, module->wire(remapped_name)); - } - design->select(module, cell); - continue; - } - if (c->type == ID(DFF)) { + + if (c->type == ID(_dff_)) { log_assert(clk_sig.size() == 1); FfData ff(module, &initvals, remap_name(c->name)); ff.width = 1; @@ -1445,7 +1415,6 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL ff.sig_clk = clk_sig; if (en_sig.size() != 0) { log_assert(en_sig.size() == 1); - ff.has_ce = true; ff.pol_ce = en_polarity; ff.sig_ce = en_sig; } @@ -1456,14 +1425,12 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL ff.val_init = State::Sx; if (arst_sig.size() != 0) { log_assert(arst_sig.size() == 1); - ff.has_arst = true; ff.pol_arst = arst_polarity; ff.sig_arst = arst_sig; ff.val_arst = init; } if (srst_sig.size() != 0) { log_assert(srst_sig.size() == 1); - ff.has_srst = true; ff.pol_srst = srst_polarity; ff.sig_srst = srst_sig; ff.val_srst = init; @@ -1475,117 +1442,73 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL design->select(module, cell); continue; } - } - else - cell_stats[RTLIL::unescape_id(c->type)]++; - if (c->type.in(ID(_const0_), ID(_const1_))) { - RTLIL::SigSig conn; - conn.first = module->wire(remap_name(c->connections().begin()->second.as_wire()->name)); - conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1); - connect(assign_map, module, conn); - continue; - } + if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) { + SigSpec my_a = module->wire(remap_name(c->getPort(ID::A).as_wire()->name)); + SigSpec my_y = module->wire(remap_name(c->getPort(ID::Y).as_wire()->name)); + module->connect(my_y, my_a); + continue; + } - if (c->type == ID(_dff_)) { - log_assert(clk_sig.size() == 1); - FfData ff(module, &initvals, remap_name(c->name)); - ff.width = 1; - ff.is_fine = true; - ff.has_clk = true; - ff.pol_clk = clk_polarity; - ff.sig_clk = clk_sig; - if (en_sig.size() != 0) { - log_assert(en_sig.size() == 1); - ff.pol_ce = en_polarity; - ff.sig_ce = en_sig; - } - RTLIL::Const init = mapped_initvals(c->getPort(ID::Q)); - if (had_init) - ff.val_init = init; - else - ff.val_init = State::Sx; - if (arst_sig.size() != 0) { - log_assert(arst_sig.size() == 1); - ff.pol_arst = arst_polarity; - ff.sig_arst = arst_sig; - ff.val_arst = init; - } - if (srst_sig.size() != 0) { - log_assert(srst_sig.size() == 1); - ff.pol_srst = srst_polarity; - ff.sig_srst = srst_sig; - ff.val_srst = init; - } - ff.sig_d = module->wire(remap_name(c->getPort(ID::D).as_wire()->name)); - ff.sig_q = module->wire(remap_name(c->getPort(ID::Q).as_wire()->name)); - RTLIL::Cell *cell = ff.emit(); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); + cell->attributes = c->attributes; + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + cell->parameters = c->parameters; + for (auto &conn : c->connections()) { + RTLIL::SigSpec newsig; + for (auto &c : conn.second.chunks()) { + if (c.width == 0) + continue; + log_assert(c.width == 1); + newsig.append(module->wire(remap_name(c.wire->name))); + } + cell->setPort(conn.first, newsig); + } design->select(module, cell); - continue; } - if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) { - SigSpec my_a = module->wire(remap_name(c->getPort(ID::A).as_wire()->name)); - SigSpec my_y = module->wire(remap_name(c->getPort(ID::Y).as_wire()->name)); - connect(assign_map, module, RTLIL::SigSig(my_a, my_y)); - continue; + for (auto conn : mapped_mod->connections()) { + if (!conn.first.is_fully_const()) + conn.first = module->wire(remap_name(conn.first.as_wire()->name)); + if (!conn.second.is_fully_const()) + conn.second = module->wire(remap_name(conn.second.as_wire()->name)); + module->connect(conn); } - RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); - if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; - cell->parameters = c->parameters; - for (auto &conn : c->connections()) { - RTLIL::SigSpec newsig; - for (auto &c : conn.second.chunks()) { - if (c.width == 0) - continue; - log_assert(c.width == 1); - newsig.append(module->wire(remap_name(c.wire->name))); + cell_stats.sort(); + for (auto &it : cell_stats) + log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); + int in_wires = 0, out_wires = 0; + for (auto &si : signal_list) + if (si.is_port) { + char buffer[100]; + snprintf(buffer, 100, "\\ys__n%d", si.id); + RTLIL::SigSig conn; + if (si.type != G(NONE)) { + conn.first = si.bit; + conn.second = module->wire(remap_name(buffer)); + out_wires++; + } else { + conn.first = module->wire(remap_name(buffer)); + conn.second = si.bit; + in_wires++; + } + module->connect(conn); } - cell->setPort(conn.first, newsig); - } - design->select(module, cell); + log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); + log("ABC RESULTS: input signals: %8d\n", in_wires); + log("ABC RESULTS: output signals: %8d\n", out_wires); + + delete mapped_design; + } + else + { + log("Don't call ABC as there is nothing to map.\n"); } - for (auto conn : mapped_mod->connections()) { - if (!conn.first.is_fully_const()) - conn.first = module->wire(remap_name(conn.first.as_wire()->name)); - if (!conn.second.is_fully_const()) - conn.second = module->wire(remap_name(conn.second.as_wire()->name)); - connect(assign_map, module, conn); - } - - cell_stats.sort(); - for (auto &it : cell_stats) - log("ABC RESULTS: %15s cells: %8d\n", it.first, it.second); - int in_wires = 0, out_wires = 0; - for (auto &si : signal_list) - if (si.is_port) { - char buffer[100]; - snprintf(buffer, 100, "\\ys__n%d", si.id); - RTLIL::SigSig conn; - if (si.type != G(NONE)) { - conn.first = si.bit; - conn.second = module->wire(remap_name(buffer)); - out_wires++; - } else { - conn.first = module->wire(remap_name(buffer)); - conn.second = si.bit; - in_wires++; - } - connect(assign_map, module, conn); - } - log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); - log("ABC RESULTS: input signals: %8d\n", in_wires); - log("ABC RESULTS: output signals: %8d\n", out_wires); - - delete mapped_design; -} - -void AbcModuleState::finish() -{ - if (config.cleanup) + if (cleanup) { log("Removing temp directory.\n"); remove_directory(tempdir_name); @@ -1594,47 +1517,6 @@ void AbcModuleState::finish() log_pop(); } -// For every signal that connects cells from different sets, or a cell in a set to a cell not in any set, -// mark it as a port in `assign_map`. -void assign_cell_connection_ports(RTLIL::Module *module, const std::vector *> &cell_sets, - AbcSigMap &assign_map) -{ - pool cells_in_no_set; - for (RTLIL::Cell *cell : module->cells()) { - cells_in_no_set.insert(cell); - } - // For every canonical signal in `assign_map`, the index of the set it is connected to, - // or -1 if it connects a cell in one set to a cell in another set or not in any set. - dict signal_cell_set; - for (int i = 0; i < int(cell_sets.size()); ++i) { - for (RTLIL::Cell *cell : *cell_sets[i]) { - cells_in_no_set.erase(cell); - for (auto &port_it : cell->connections()) { - for (SigBit bit : port_it.second) { - assign_map.apply(bit); - auto it = signal_cell_set.find(bit); - if (it == signal_cell_set.end()) - signal_cell_set[bit] = i; - else if (it->second >= 0 && it->second != i) { - it->second = -1; - assign_map.addVal(bit, AbcSigVal(true)); - } - } - } - } - } - for (RTLIL::Cell *cell : cells_in_no_set) { - for (auto &port_it : cell->connections()) { - for (SigBit bit : port_it.second) { - assign_map.apply(bit); - auto it = signal_cell_set.find(bit); - if (it != signal_cell_set.end() && it->second >= 0) - assign_map.addVal(bit, AbcSigVal(true)); - } - } - } -} - struct AbcPass : public Pass { AbcPass() : Pass("abc", "use ABC for technology mapping") { } void help() override @@ -1650,7 +1532,7 @@ struct AbcPass : public Pass { #ifdef ABCEXTERNAL log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); #else - log(" use the specified command instead of \"/%syosys-abc\" to execute ABC.\n", proc_program_prefix()); + log(" use the specified command instead of \"/%syosys-abc\" to execute ABC.\n", proc_program_prefix().c_str()); #endif log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); log("\n"); @@ -1665,41 +1547,41 @@ struct AbcPass : public Pass { log(" if no -script parameter is given, the following scripts are used:\n"); log("\n"); log(" for -liberty/-genlib without -constr:\n"); - log("%s\n", fold_abc_cmd(ABC_COMMAND_LIB)); + log("%s\n", fold_abc_cmd(ABC_COMMAND_LIB).c_str()); log("\n"); log(" for -liberty/-genlib with -constr:\n"); - log("%s\n", fold_abc_cmd(ABC_COMMAND_CTR)); + log("%s\n", fold_abc_cmd(ABC_COMMAND_CTR).c_str()); log("\n"); log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT "; lutpack {S}")); + log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT "; lutpack {S}").c_str()); log("\n"); log(" for -lut/-luts (different LUT sizes):\n"); - log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT)); + log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT).c_str()); log("\n"); log(" for -sop:\n"); - log("%s\n", fold_abc_cmd(ABC_COMMAND_SOP)); + log("%s\n", fold_abc_cmd(ABC_COMMAND_SOP).c_str()); log("\n"); log(" otherwise:\n"); - log("%s\n", fold_abc_cmd(ABC_COMMAND_DFL)); + log("%s\n", fold_abc_cmd(ABC_COMMAND_DFL).c_str()); log("\n"); log(" -fast\n"); log(" use different default scripts that are slightly faster (at the cost\n"); log(" of output quality):\n"); log("\n"); log(" for -liberty/-genlib without -constr:\n"); - log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_LIB)); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_LIB).c_str()); log("\n"); log(" for -liberty/-genlib with -constr:\n"); - log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_CTR)); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_CTR).c_str()); log("\n"); log(" for -lut/-luts:\n"); - log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_LUT)); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_LUT).c_str()); log("\n"); log(" for -sop:\n"); - log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_SOP)); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_SOP).c_str()); log("\n"); log(" otherwise:\n"); - log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_DFL)); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_DFL).c_str()); log("\n"); log(" -liberty \n"); log(" generate netlists for the specified cell library (using the liberty\n"); @@ -1758,6 +1640,8 @@ struct AbcPass : public Pass { log("\n"); log(" -sop\n"); log(" map to sum-of-product cells and inverters\n"); + log(" -map_src \n"); + log(" source attribution for cells created by ABC\n"); log("\n"); // log(" -mux4, -mux8, -mux16\n"); // log(" try to extract 4-input, 8-input, and/or 16-input muxes\n"); @@ -1836,52 +1720,72 @@ struct AbcPass : public Pass { log_header(design, "Executing ABC pass (technology mapping using ABC).\n"); log_push(); - AbcConfig config; + assign_map.clear(); + signal_list.clear(); + signal_map.clear(); + initvals.clear(); + pi_map.clear(); + po_map.clear(); + + std::string exe_file = yosys_abc_executable; + std::string script_file, default_liberty_file, constr_file, clk_str; + 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; + bool show_tempdir = false, sop_mode = false, word_mode = false; + bool abc_dress = false; + vector lut_costs; + markgroups = false; + std::string map_src; + map_mux4 = false; + map_mux8 = false; + map_mux16 = false; + enabled_gates.clear(); + cmos_cost = false; // get arguments from scratchpad first, then override by command arguments std::string lut_arg, luts_arg, g_arg; - config.exe_file = design->scratchpad_get_string("abc.exe", yosys_abc_executable /* inherit default value if not set */); - config.script_file = design->scratchpad_get_string("abc.script", ""); - std::string default_liberty_file = design->scratchpad_get_string("abc.liberty", ""); - config.constr_file = design->scratchpad_get_string("abc.constr", ""); + exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */); + script_file = design->scratchpad_get_string("abc.script", script_file); + default_liberty_file = design->scratchpad_get_string("abc.liberty", default_liberty_file); + constr_file = design->scratchpad_get_string("abc.constr", constr_file); if (design->scratchpad.count("abc.D")) { - config.delay_target = "-D " + design->scratchpad_get_string("abc.D"); + delay_target = "-D " + design->scratchpad_get_string("abc.D"); } if (design->scratchpad.count("abc.I")) { - config.sop_inputs = "-I " + design->scratchpad_get_string("abc.I"); + sop_inputs = "-I " + design->scratchpad_get_string("abc.I"); } if (design->scratchpad.count("abc.P")) { - config.sop_products = "-P " + design->scratchpad_get_string("abc.P"); + sop_products = "-P " + design->scratchpad_get_string("abc.P"); } if (design->scratchpad.count("abc.S")) { - config.lutin_shared = "-S " + design->scratchpad_get_string("abc.S"); - } else { - config.lutin_shared = "-S 1"; + lutin_shared = "-S " + design->scratchpad_get_string("abc.S"); } lut_arg = design->scratchpad_get_string("abc.lut", lut_arg); luts_arg = design->scratchpad_get_string("abc.luts", luts_arg); - config.sop_mode = design->scratchpad_get_bool("abc.sop", false); + sop_mode = design->scratchpad_get_bool("abc.sop", sop_mode); + word_mode = design->scratchpad_get_bool("abc.word", word_mode); map_mux4 = design->scratchpad_get_bool("abc.mux4", map_mux4); map_mux8 = design->scratchpad_get_bool("abc.mux8", map_mux8); map_mux16 = design->scratchpad_get_bool("abc.mux16", map_mux16); - config.abc_dress = design->scratchpad_get_bool("abc.dress", false); + abc_dress = design->scratchpad_get_bool("abc.dress", abc_dress); g_arg = design->scratchpad_get_string("abc.g", g_arg); - config.fast_mode = design->scratchpad_get_bool("abc.fast", false); - bool dff_mode = design->scratchpad_get_bool("abc.dff", false); - std::string clk_str; + fast_mode = design->scratchpad_get_bool("abc.fast", fast_mode); + dff_mode = design->scratchpad_get_bool("abc.dff", dff_mode); if (design->scratchpad.count("abc.clk")) { clk_str = design->scratchpad_get_string("abc.clk"); dff_mode = true; } - config.keepff = design->scratchpad_get_bool("abc.keepff", false); - config.cleanup = !design->scratchpad_get_bool("abc.nocleanup", false); - config.show_tempdir = design->scratchpad_get_bool("abc.showtmp", false); + keepff = design->scratchpad_get_bool("abc.keepff", keepff); + cleanup = !design->scratchpad_get_bool("abc.nocleanup", !cleanup); + keepff = design->scratchpad_get_bool("abc.keepff", keepff); + show_tempdir = design->scratchpad_get_bool("abc.showtmp", show_tempdir); markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups); if (design->scratchpad_get_bool("abc.debug")) { - config.cleanup = false; - config.show_tempdir = true; + cleanup = false; + show_tempdir = true; } size_t argidx, g_argidx = -1; @@ -1898,63 +1802,63 @@ struct AbcPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-exe" && argidx+1 < args.size()) { - config.exe_file = args[++argidx]; + exe_file = args[++argidx]; continue; } if (arg == "-script" && argidx+1 < args.size()) { - config.script_file = args[++argidx]; + script_file = args[++argidx]; continue; } if (arg == "-liberty" && argidx+1 < args.size()) { - config.liberty_files.push_back(args[++argidx]); + liberty_files.push_back(args[++argidx]); continue; } if (arg == "-dont_use" && argidx+1 < args.size()) { - config.dont_use_cells.push_back(args[++argidx]); + dont_use_cells.push_back(args[++argidx]); continue; } if (arg == "-genlib" && argidx+1 < args.size()) { - config.genlib_files.push_back(args[++argidx]); + genlib_files.push_back(args[++argidx]); continue; } if (arg == "-constr" && argidx+1 < args.size()) { - config.constr_file = args[++argidx]; + constr_file = args[++argidx]; continue; } if (arg == "-D" && argidx+1 < args.size()) { - config.delay_target = "-D " + args[++argidx]; + delay_target = "-D " + args[++argidx]; continue; } if (arg == "-I" && argidx+1 < args.size()) { - config.sop_inputs = "-I " + args[++argidx]; + sop_inputs = "-I " + args[++argidx]; continue; } if (arg == "-P" && argidx+1 < args.size()) { - config.sop_products = "-P " + args[++argidx]; + sop_products = "-P " + args[++argidx]; continue; } if (arg == "-S" && argidx+1 < args.size()) { - config.lutin_shared = "-S " + args[++argidx]; + lutin_shared = "-S " + args[++argidx]; continue; } if (arg == "-lut" && argidx+1 < args.size()) { lut_arg = args[++argidx]; continue; } + if (arg == "-map_src" && argidx+1 < args.size()) { + map_src = args[++argidx]; + continue; + } if (arg == "-luts" && argidx+1 < args.size()) { luts_arg = args[++argidx]; continue; } - if (arg == "-map_src" && argidx+1 < args.size()) { - config.map_src = args[++argidx]; - continue; - } if (arg == "-sop") { - config.sop_mode = true; + sop_mode = true; continue; } if (arg == "-word") { - config.word_mode = true; + word_mode = true; continue; } if (arg == "-mux4") { @@ -1970,7 +1874,7 @@ struct AbcPass : public Pass { continue; } if (arg == "-dress") { - config.abc_dress = true; + abc_dress = true; continue; } if (arg == "-g" && argidx+1 < args.size()) { @@ -1982,7 +1886,7 @@ struct AbcPass : public Pass { continue; } if (arg == "-fast") { - config.fast_mode = true; + fast_mode = true; continue; } if (arg == "-dff") { @@ -1995,15 +1899,15 @@ struct AbcPass : public Pass { continue; } if (arg == "-keepff") { - config.keepff = true; + keepff = true; continue; } if (arg == "-nocleanup") { - config.cleanup = false; + cleanup = false; continue; } if (arg == "-showtmp") { - config.show_tempdir = true; + show_tempdir = true; continue; } if (arg == "-markgroups") { @@ -2014,25 +1918,25 @@ struct AbcPass : public Pass { } extra_args(args, argidx, design); - if (config.genlib_files.empty() && config.liberty_files.empty() && !default_liberty_file.empty()) - config.liberty_files.push_back(default_liberty_file); + if (genlib_files.empty() && liberty_files.empty() && !default_liberty_file.empty()) + liberty_files.push_back(default_liberty_file); - rewrite_filename(config.script_file); - if (!config.script_file.empty() && !is_absolute_path(config.script_file) && config.script_file[0] != '+') - config.script_file = std::string(pwd) + "/" + config.script_file; - for (int i = 0; i < GetSize(config.liberty_files); i++) { - rewrite_filename(config.liberty_files[i]); - if (!config.liberty_files[i].empty() && !is_absolute_path(config.liberty_files[i])) - config.liberty_files[i] = std::string(pwd) + "/" + config.liberty_files[i]; + rewrite_filename(script_file); + if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') + script_file = std::string(pwd) + "/" + script_file; + for (int i = 0; i < GetSize(liberty_files); i++) { + rewrite_filename(liberty_files[i]); + if (!liberty_files[i].empty() && !is_absolute_path(liberty_files[i])) + liberty_files[i] = std::string(pwd) + "/" + liberty_files[i]; } - for (int i = 0; i < GetSize(config.genlib_files); i++) { - rewrite_filename(config.genlib_files[i]); - if (!config.genlib_files[i].empty() && !is_absolute_path(config.genlib_files[i])) - config.genlib_files[i] = std::string(pwd) + "/" + config.genlib_files[i]; + for (int i = 0; i < GetSize(genlib_files); i++) { + rewrite_filename(genlib_files[i]); + if (!genlib_files[i].empty() && !is_absolute_path(genlib_files[i])) + genlib_files[i] = std::string(pwd) + "/" + genlib_files[i]; } - rewrite_filename(config.constr_file); - if (!config.constr_file.empty() && !is_absolute_path(config.constr_file)) - config.constr_file = std::string(pwd) + "/" + config.constr_file; + rewrite_filename(constr_file); + if (!constr_file.empty() && !is_absolute_path(constr_file)) + constr_file = std::string(pwd) + "/" + constr_file; // handle -lut argument if (!lut_arg.empty()) { @@ -2045,24 +1949,24 @@ struct AbcPass : public Pass { lut_mode = atoi(lut_arg.c_str()); lut_mode2 = lut_mode; } - config.lut_costs.clear(); + lut_costs.clear(); for (int i = 0; i < lut_mode; i++) - config.lut_costs.push_back(1); + lut_costs.push_back(1); for (int i = lut_mode; i < lut_mode2; i++) - config.lut_costs.push_back(2 << (i - lut_mode)); + lut_costs.push_back(2 << (i - lut_mode)); } //handle -luts argument if (!luts_arg.empty()){ - config.lut_costs.clear(); + lut_costs.clear(); for (auto &tok : split_tokens(luts_arg, ",")) { auto parts = split_tokens(tok, ":"); - if (GetSize(parts) == 0 && !config.lut_costs.empty()) - config.lut_costs.push_back(config.lut_costs.back()); + if (GetSize(parts) == 0 && !lut_costs.empty()) + lut_costs.push_back(lut_costs.back()); else if (GetSize(parts) == 1) - config.lut_costs.push_back(atoi(parts.at(0).c_str())); + lut_costs.push_back(atoi(parts.at(0).c_str())); else if (GetSize(parts) == 2) - while (GetSize(config.lut_costs) < std::atoi(parts.at(0).c_str())) - config.lut_costs.push_back(atoi(parts.at(1).c_str())); + while (GetSize(lut_costs) < std::atoi(parts.at(0).c_str())) + lut_costs.push_back(atoi(parts.at(1).c_str())); else log_cmd_error("Invalid -luts syntax.\n"); } @@ -2178,7 +2082,7 @@ struct AbcPass : public Pass { goto ok_alias; } if (g_arg_from_cmd) - cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g)); + cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str())); else log_cmd_error("Unsupported gate type: %s", g.c_str()); ok_gate: @@ -2193,9 +2097,9 @@ struct AbcPass : public Pass { } } - if (!config.lut_costs.empty() && !(config.liberty_files.empty() && config.genlib_files.empty())) + if (!lut_costs.empty() && !(liberty_files.empty() && genlib_files.empty())) log_cmd_error("Got -lut and -liberty/-genlib! These two options are exclusive.\n"); - if (!config.constr_file.empty() && (config.liberty_files.empty() && config.genlib_files.empty())) + if (!constr_file.empty() && (liberty_files.empty() && genlib_files.empty())) log_cmd_error("Got -constr but no -liberty/-genlib!\n"); if (enabled_gates.empty()) { @@ -2222,26 +2126,12 @@ struct AbcPass : public Pass { continue; } - AbcSigMap assign_map; assign_map.set(mod); - // Create an FfInitVals and use it for all ABC runs. FfInitVals only cares about - // wires with the ID::init attribute and we don't add or remove any such wires - // in this pass. - FfInitVals initvals; initvals.set(&assign_map, mod); - for (auto wire : mod->wires()) - if (wire->port_id > 0 || wire->get_bool_attribute(ID::keep)) - assign_map.addVal(SigSpec(wire), AbcSigVal(true)); - if (!dff_mode || !clk_str.empty()) { - std::vector cells = mod->selected_cells(); - assign_cell_connection_ports(mod, {&cells}, assign_map); - - AbcModuleState state(config, initvals); - state.abc_module(design, mod, assign_map, cells, dff_mode, clk_str); - state.extract(assign_map, design, mod); - state.finish(); + 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, word_mode, abc_dress, dont_use_cells, map_src); continue; } @@ -2393,28 +2283,28 @@ struct AbcPass : public Pass { std::get<4>(it.first) ? "" : "!", log_signal(std::get<5>(it.first)), std::get<6>(it.first) ? "" : "!", log_signal(std::get<7>(it.first))); - { - std::vector*> cell_sets; - for (auto &it : assigned_cells) - cell_sets.push_back(&it.second); - assign_cell_connection_ports(mod, cell_sets, assign_map); - } for (auto &it : assigned_cells) { - AbcModuleState state(config, initvals); - state.clk_polarity = std::get<0>(it.first); - state.clk_sig = assign_map(std::get<1>(it.first)); - state.en_polarity = std::get<2>(it.first); - state.en_sig = assign_map(std::get<3>(it.first)); - state.arst_polarity = std::get<4>(it.first); - state.arst_sig = assign_map(std::get<5>(it.first)); - state.srst_polarity = std::get<6>(it.first); - state.srst_sig = assign_map(std::get<7>(it.first)); - state.abc_module(design, mod, assign_map, it.second, !state.clk_sig.empty(), "$"); - state.extract(assign_map, design, mod); - state.finish(); + clk_polarity = std::get<0>(it.first); + 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)); + arst_polarity = std::get<4>(it.first); + 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, word_mode, abc_dress, dont_use_cells, map_src); + assign_map.set(mod); } } + assign_map.clear(); + signal_list.clear(); + signal_map.clear(); + initvals.clear(); + pi_map.clear(); + po_map.clear(); + log_pop(); } } AbcPass;