Be more precise when connecting during ABC9 re-integration
[yosys.git] / passes / techmap / abc9.cc
index 17d082833024531b15c89f8da733c21905b84f69..c3145dbe59416ed575927d73dd33e44ed17cb3a1 100644 (file)
@@ -2,7 +2,7 @@
  *  yosys -- Yosys Open SYnthesis Suite
  *
  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
- *  Copyright (C) 2019  Eddie Hung <eddie@fpgeh.com>
+ *                2019  Eddie Hung <eddie@fpgeh.com>
  *
  *  Permission to use, copy, modify, and/or distribute this software for any
  *  purpose with or without fee is hereby granted, provided that the above
@@ -25,7 +25,7 @@
 #define ABC_COMMAND_LIB "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put"
 #define ABC_COMMAND_CTR "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put; buffer; upsize {D}; dnsize {D}; stime -p"
 //#define ABC_COMMAND_LUT "strash; ifraig; scorr; dc2; dretime; strash; dch -f; if; mfs2"
-#define ABC_COMMAND_LUT "&st; &fraig; &scorr; &dc2; &retime; &dch -f; &if; &mfs"
+#define ABC_COMMAND_LUT "&st; &sweep; &scorr; "/*"&dc2; */"&retime; &dch -f; &ps -l; &if {W} -v; &ps -l"
 #define ABC_COMMAND_SOP "strash; ifraig; scorr; dc2; dretime; strash; dch -f; cover {I} {P}"
 #define ABC_COMMAND_DFL "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put"
 
@@ -246,33 +246,11 @@ struct abc_output_filter
        }
 };
 
-static std::pair<RTLIL::IdString, int> wideports_split(std::string name)
-{
-       int pos = -1;
-
-       if (name.empty() || name.back() != ']')
-               goto failed;
-
-       for (int i = 0; i+1 < GetSize(name); i++) {
-               if (name[i] == '[')
-                       pos = i;
-               else if (name[i] < '0' || name[i] > '9')
-                       pos = -1;
-               else if (i == pos+1 && name[i] == '0' && name[i+1] != ']')
-                       pos = -1;
-       }
-
-       if (pos >= 0)
-               return std::pair<RTLIL::IdString, int>(RTLIL::escape_id(name.substr(0, pos)), atoi(name.c_str() + pos+1));
-
-failed:
-       return std::pair<RTLIL::IdString, int>(name, 0);
-}
-
 void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file,
                std::string liberty_file, std::string constr_file, bool cleanup, 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)
+               const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, std::string box_file, std::string lut_file,
+               std::string wire_delay)
 {
        module = current_module;
        map_autoidx = autoidx++;
@@ -319,21 +297,32 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
        if (!cleanup)
                tempdir_name[0] = tempdir_name[4] = '_';
        tempdir_name = make_temp_dir(tempdir_name);
-       log_header(design, "Extracting gate netlist of module `%s' to `%s/input.aig'..\n",
+       log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n",
                        module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str());
 
-       std::string abc_script = stringf("read %s/input.aig; &get -n; ", tempdir_name.c_str());
+       std::string abc_script;
 
        if (!liberty_file.empty()) {
                abc_script += stringf("read_lib -w %s; ", liberty_file.c_str());
                if (!constr_file.empty())
                        abc_script += stringf("read_constr -v %s; ", constr_file.c_str());
        } else
-       if (!lut_costs.empty())
+       if (!lut_costs.empty()) {
                abc_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str());
+               if (!box_file.empty())
+                       abc_script += stringf("read_box -v %s; ", box_file.c_str());
+       }
+       else
+       if (!lut_file.empty()) {
+               abc_script += stringf("read_lut %s; ", lut_file.c_str());
+               if (!box_file.empty())
+                       abc_script += stringf("read_box -v %s; ", box_file.c_str());
+       }
        else
                abc_script += stringf("read_library %s/stdcells.genlib; ", tempdir_name.c_str());
 
+       abc_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str());
+
        if (!script_file.empty()) {
                if (script_file[0] == '+') {
                        for (size_t i = 1; i < script_file.size(); i++)
@@ -345,11 +334,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                        abc_script += script_file[i];
                } else
                        abc_script += stringf("source %s", script_file.c_str());
-       } else if (!lut_costs.empty()) {
-               bool all_luts_cost_same = true;
-               for (int this_cost : lut_costs)
-                       if (this_cost != lut_costs.front())
-                               all_luts_cost_same = false;
+       } else if (!lut_costs.empty() || !lut_file.empty()) {
+               //bool all_luts_cost_same = true;
+               //for (int this_cost : lut_costs)
+               //      if (this_cost != lut_costs.front())
+               //              all_luts_cost_same = false;
                abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT;
                //if (all_luts_cost_same && !fast_mode)
                //      abc_script += "; lutpack {S}";
@@ -376,6 +365,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
        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("{W}"); pos != std::string::npos; pos = abc_script.find("{W}", pos))
+               abc_script = abc_script.substr(0, pos) + wire_delay + abc_script.substr(pos+3);
+
        abc_script += stringf("; &write %s/output.aig", tempdir_name.c_str());
        abc_script = add_echos_to_abc_cmd(abc_script);
 
@@ -399,87 +391,77 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                }
        }
 
-       design->selection_stack.emplace_back(false);
-       RTLIL::Selection& sel = design->selection_stack.back();
-       sel.select(module);
+       bool count_output = false;
+       for (auto port_name : module->ports) {
+               RTLIL::Wire *port_wire = module->wire(port_name);
+               log_assert(port_wire);
+               if (port_wire->port_output) {
+                       count_output = true;
+                       break;
+               }
+       }
 
-       Pass::call(design, "aigmap");
+       log_push();
 
-       handle_loops(design);
+       if (count_output)
+       {
+               design->selection_stack.emplace_back(false);
+               RTLIL::Selection& sel = design->selection_stack.back();
+               sel.select(module);
 
-       Pass::call(design, stringf("write_xaiger -O -map %s/input.sym %s/input.aig; ", tempdir_name.c_str(), tempdir_name.c_str()));
+               // Behave as for "abc" where BLIF writer implicitly outputs all undef as zero
+               Pass::call(design, "setundef -zero");
 
-       design->selection_stack.pop_back();
+               Pass::call(design, "aigmap");
+
+               handle_loops(design);
 
-       // Now 'unexpose' those wires by undoing
-       // the expose operation -- remove them from PO/PI
-       // and re-connecting them back together
-       for (auto wire : module->wires()) {
-               auto it = wire->attributes.find("\\abc_scc_break");
-               if (it != wire->attributes.end()) {
-                       wire->attributes.erase(it);
-                       log_assert(wire->port_output);
-                       wire->port_output = false;
-                       RTLIL::Wire *i_wire = module->wire(wire->name.str() + ".abci");
-                       log_assert(i_wire);
-                       log_assert(i_wire->port_input);
-                       i_wire->port_input = false;
-                       module->connect(i_wire, wire);
+               //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n",
+               //              count_gates, GetSize(signal_list), count_input, count_output);
+
+               Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig; ", tempdir_name.c_str(), tempdir_name.c_str()));
+
+               std::string buffer;
+               std::ifstream ifs;
+#if 0
+               buffer = stringf("%s/%s", tempdir_name.c_str(), "input.xaig");
+               ifs.open(buffer);
+               if (ifs.fail())
+                       log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
+               buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
+               log_assert(!design->module("$__abc9__"));
+               {
+                       AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
+                       reader.parse_xaiger();
                }
-       }
-       module->fixup_ports();
+               ifs.close();
+               Pass::call(design, stringf("write_verilog -noexpr -norename %s/%s", tempdir_name.c_str(), "input.v"));
+               design->remove(design->module("$__abc9__"));
+#endif
 
-       //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n",
-       //              count_gates, GetSize(signal_list), count_input, count_output);
+               design->selection_stack.pop_back();
+
+               // Now 'unexpose' those wires by undoing
+               // the expose operation -- remove them from PO/PI
+               // and re-connecting them back together
+               for (auto wire : module->wires()) {
+                       auto it = wire->attributes.find("\\abc_scc_break");
+                       if (it != wire->attributes.end()) {
+                               wire->attributes.erase(it);
+                               log_assert(wire->port_output);
+                               wire->port_output = false;
+                               RTLIL::Wire *i_wire = module->wire(wire->name.str() + ".abci");
+                               log_assert(i_wire);
+                               log_assert(i_wire->port_input);
+                               i_wire->port_input = false;
+                               module->connect(i_wire, wire);
+                       }
+               }
+               module->fixup_ports();
 
-       log_push();
 
-       //if (count_output > 0)
-       {
                log_header(design, "Executing ABC9.\n");
 
-               std::string buffer = stringf("%s/stdcells.genlib", tempdir_name.c_str());
-               f = fopen(buffer.c_str(), "wt");
-               if (f == NULL)
-                       log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
-               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", get_cell_cost("$_BUF_"));
-               fprintf(f, "GATE NOT    %d Y=!A;                 PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_NOT_"));
-               if (enabled_gates.empty() || enabled_gates.count("AND"))
-                       fprintf(f, "GATE AND    %d Y=A*B;                PIN * NONINV  1 999 1 0 1 0\n", get_cell_cost("$_AND_"));
-               if (enabled_gates.empty() || enabled_gates.count("NAND"))
-                       fprintf(f, "GATE NAND   %d Y=!(A*B);             PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_NAND_"));
-               if (enabled_gates.empty() || enabled_gates.count("OR"))
-                       fprintf(f, "GATE OR     %d Y=A+B;                PIN * NONINV  1 999 1 0 1 0\n", get_cell_cost("$_OR_"));
-               if (enabled_gates.empty() || enabled_gates.count("NOR"))
-                       fprintf(f, "GATE NOR    %d Y=!(A+B);             PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_NOR_"));
-               if (enabled_gates.empty() || enabled_gates.count("XOR"))
-                       fprintf(f, "GATE XOR    %d Y=(A*!B)+(!A*B);      PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XOR_"));
-               if (enabled_gates.empty() || enabled_gates.count("XNOR"))
-                       fprintf(f, "GATE XNOR   %d Y=(A*B)+(!A*!B);      PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XNOR_"));
-               if (enabled_gates.empty() || enabled_gates.count("ANDNOT"))
-                       fprintf(f, "GATE ANDNOT %d Y=A*!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_ANDNOT_"));
-               if (enabled_gates.empty() || enabled_gates.count("ORNOT"))
-                       fprintf(f, "GATE ORNOT  %d Y=A+!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_ORNOT_"));
-               if (enabled_gates.empty() || enabled_gates.count("AOI3"))
-                       fprintf(f, "GATE AOI3   %d Y=!((A*B)+C);         PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_AOI3_"));
-               if (enabled_gates.empty() || enabled_gates.count("OAI3"))
-                       fprintf(f, "GATE OAI3   %d Y=!((A+B)*C);         PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_OAI3_"));
-               if (enabled_gates.empty() || enabled_gates.count("AOI4"))
-                       fprintf(f, "GATE AOI4   %d Y=!((A*B)+(C*D));     PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_AOI4_"));
-               if (enabled_gates.empty() || enabled_gates.count("OAI4"))
-                       fprintf(f, "GATE OAI4   %d Y=!((A+B)*(C+D));     PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_OAI4_"));
-               if (enabled_gates.empty() || enabled_gates.count("MUX"))
-                       fprintf(f, "GATE MUX    %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_MUX_"));
-               if (map_mux4)
-                       fprintf(f, "GATE MUX4   %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*get_cell_cost("$_MUX_"));
-               if (map_mux8)
-                       fprintf(f, "GATE MUX8   %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*get_cell_cost("$_MUX_"));
-               if (map_mux16)
-                       fprintf(f, "GATE MUX16  %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*get_cell_cost("$_MUX_"));
-               fclose(f);
-
                if (!lut_costs.empty()) {
                        buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str());
                        f = fopen(buffer.c_str(), "wt");
@@ -515,24 +497,26 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                        log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret);
 
                buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig");
-               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_file.empty();
-               RTLIL::Design *mapped_design = new RTLIL::Design;
                //parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_", false, sop_mode);
                buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
-               AigerReader reader(mapped_design, ifs, "\\netlist", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
+               log_assert(!design->module("$__abc9__"));
+               AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
                reader.parse_xaiger();
-
                ifs.close();
 
+#if 0
+               Pass::call(design, stringf("write_verilog -noexpr -norename %s/%s", tempdir_name.c_str(), "output.v"));
+#endif
+
                log_header(design, "Re-integrating ABC9 results.\n");
-               RTLIL::Module *mapped_mod = mapped_design->modules_["\\netlist"];
+               RTLIL::Module *mapped_mod = design->module("$__abc9__");
                if (mapped_mod == NULL)
-                       log_error("ABC output file does not contain a module `netlist'.\n");
+                       log_error("ABC output file does not contain a module `$__abc9__'.\n");
 
                pool<RTLIL::SigBit> output_bits;
                for (auto &it : mapped_mod->wires_) {
@@ -541,29 +525,39 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                        if (markgroups) remap_wire->attributes["\\abcgroup"] = map_autoidx;
                        if (w->port_output) {
                                RTLIL::Wire *wire = module->wire(w->name);
-                               if (wire) {
-                                       for (int i = 0; i < GetSize(wire); i++)
-                                               output_bits.insert({wire, i});
-                               }
-                               else {
-                                       if (w->name.str() == "\\__dummy_o__") {
-                                               log("Don't call ABC as there is nothing to map.\n");
-                                               goto cleanup;
-                                       }
-
-                                       // Attempt another wideports_split here because there
-                                       // exists the possibility that different bits of a port
-                                       // could be an input and output, therefore parse_xiager()
-                                       // could not combine it into a wideport
-                                       auto r = wideports_split(w->name.str());
-                                       wire = module->wire(r.first);
-                                       log_assert(wire);
-                                       int i = r.second;
+                               log_assert(wire);
+                               for (int i = 0; i < GetSize(wire); i++)
                                        output_bits.insert({wire, i});
-                               }
                        }
                }
 
+               // Remove all AND, NOT, and ABC box instances
+               // in preparation for stitching mapped_mod in
+               dict<IdString, decltype(RTLIL::Cell::parameters)> erased_boxes;
+               for (auto it = module->cells_.begin(); it != module->cells_.end(); ) {
+                       RTLIL::Cell* cell = it->second;
+                       if (cell->type.in("$_AND_", "$_NOT_")) {
+                               it = module->cells_.erase(it);
+                               continue;
+                       }
+                       RTLIL::Module* box_module = design->module(cell->type);
+                       if (box_module && box_module->attributes.count("\\abc_box_id")) {
+                               erased_boxes.insert(std::make_pair(it->first, std::move(cell->parameters)));
+                               it = module->cells_.erase(it);
+                               continue;
+                       }
+                       ++it;
+               }
+               // Do the same for module connections
+               for (auto &it : module->connections_) {
+                       auto &signal = it.first;
+                       auto bits = signal.bits();
+                       for (auto &b : bits)
+                               if (output_bits.count(b))
+                                       b = module->addWire(NEW_ID);
+                       signal = std::move(bits);
+               }
+
                std::map<std::string, int> cell_stats;
                for (auto c : mapped_mod->cells())
                {
@@ -573,31 +567,41 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                        RTLIL::Cell *cell;
                                        RTLIL::SigBit a_bit = c->getPort("\\A").as_bit();
                                        RTLIL::SigBit y_bit = c->getPort("\\Y").as_bit();
-                                       if (!lut_costs.empty()) {
+                                       if (!a_bit.wire) {
+                                               c->setPort("\\Y", module->addWire(NEW_ID));
+                                               RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name));
+                                               log_assert(wire);
+                                               module->connect(RTLIL::SigBit(wire, y_bit.offset), RTLIL::S1);
+                                       }
+                                       else if (!lut_costs.empty() || !lut_file.empty()) {
+                                               RTLIL::Cell* driving_lut = nullptr;
                                                // ABC can return NOT gates that drive POs
-                                               if (a_bit.wire->port_input) {
-                                                       // If it's a NOT gate that comes from a primary input directly
-                                                       // then implement it using a LUT
-                                                       cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())),
-                                                                       RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset),
-                                                                       RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset),
-                                                                       1);
-                                               }
-                                               else {
-                                                       // Otherwise, clone the driving LUT to guarantee that we
-                                                       // won't increase the max logic depth
+                                               if (!a_bit.wire->port_input) {
+                                                       // If it's not a NOT gate that that comes from a PI directly,
+                                                       // find the driving LUT and clone that to guarantee that we won't
+                                                       // increase the max logic depth
                                                        // (TODO: Optimise by not cloning unless will increase depth)
                                                        RTLIL::IdString driver_name;
                                                        if (GetSize(a_bit.wire) == 1)
                                                                driver_name = stringf("%s$lut", a_bit.wire->name.c_str());
                                                        else
                                                                driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset);
-                                                       RTLIL::Cell* driver = mapped_mod->cell(driver_name);
-                                                       log_assert(driver);
-                                                       auto driver_a = driver->getPort("\\A").chunks();
+                                                       driving_lut = mapped_mod->cell(driver_name);
+                                               }
+
+                                               if (!driving_lut) {
+                                                       // If a driver couldn't be found (could be from PI,
+                                                       // or from a box) then implement using a LUT
+                                                       cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())),
+                                                                       RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset),
+                                                                       RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset),
+                                                                       1);
+                                               }
+                                               else {
+                                                       auto driver_a = driving_lut->getPort("\\A").chunks();
                                                        for (auto &chunk : driver_a)
                                                                chunk.wire = module->wires_[remap_name(chunk.wire->name)];
-                                                       RTLIL::Const driver_lut = driver->getParam("\\LUT");
+                                                       RTLIL::Const driver_lut = driving_lut->getParam("\\LUT");
                                                        for (auto &b : driver_lut.bits) {
                                                                if (b == RTLIL::State::S0) b = RTLIL::State::S1;
                                                                else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
@@ -607,7 +611,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                                                        RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset),
                                                                        driver_lut);
                                                }
-                                               cell_stats["$lut"]++;
                                        }
                                        else {
                                                cell = module->addCell(remap_name(c->name), "$_NOT_");
@@ -618,168 +621,24 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                        if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
                                        continue;
                                }
-
-                               cell_stats[RTLIL::unescape_id(c->type)]++;
-                               if (c->type == "\\ZERO" || c->type == "\\ONE") {
-                                       RTLIL::SigSig conn;
-                                       conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]);
-                                       conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1);
-                                       module->connect(conn);
-                                       continue;
-                               }
-                               if (c->type == "\\BUF") {
-                                       RTLIL::SigSig conn;
-                                       conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]);
-                                       conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]);
-                                       module->connect(conn);
-                                       continue;
-                               }
-
-                               if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR" || c->type == "\\NAND" || c->type == "\\NOR" ||
-                                               c->type == "\\XNOR" || c->type == "\\ANDNOT" || c->type == "\\ORNOT") {
-                                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_");
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
-                                       cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)]));
-                                       cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
-                                       continue;
-                               }
-                               if (c->type == "\\MUX") {
-                                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_");
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
-                                       cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)]));
-                                       cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)]));
-                                       cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
-                                       continue;
-                               }
-                               if (c->type == "\\MUX4") {
-                                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX4_");
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
-                                       cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)]));
-                                       cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)]));
-                                       cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)]));
-                                       cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)]));
-                                       cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)]));
-                                       cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
-                                       continue;
-                               }
-                               if (c->type == "\\MUX8") {
-                                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX8_");
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
-                                       cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)]));
-                                       cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)]));
-                                       cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)]));
-                                       cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)]));
-                                       cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)]));
-                                       cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)]));
-                                       cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)]));
-                                       cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)]));
-                                       cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)]));
-                                       cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)]));
-                                       cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
-                                       continue;
-                               }
-                               if (c->type == "\\MUX16") {
-                                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX16_");
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
-                                       cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)]));
-                                       cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)]));
-                                       cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)]));
-                                       cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)]));
-                                       cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)]));
-                                       cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)]));
-                                       cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)]));
-                                       cell->setPort("\\I", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\I").as_wire()->name)]));
-                                       cell->setPort("\\J", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\J").as_wire()->name)]));
-                                       cell->setPort("\\K", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\K").as_wire()->name)]));
-                                       cell->setPort("\\L", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\L").as_wire()->name)]));
-                                       cell->setPort("\\M", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\M").as_wire()->name)]));
-                                       cell->setPort("\\N", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\N").as_wire()->name)]));
-                                       cell->setPort("\\O", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\O").as_wire()->name)]));
-                                       cell->setPort("\\P", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\P").as_wire()->name)]));
-                                       cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)]));
-                                       cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)]));
-                                       cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)]));
-                                       cell->setPort("\\V", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\V").as_wire()->name)]));
-                                       cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
-                                       continue;
-                               }
-                               if (c->type == "\\AOI3" || c->type == "\\OAI3") {
-                                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_");
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
-                                       cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)]));
-                                       cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)]));
-                                       cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
-                                       continue;
-                               }
-                               if (c->type == "\\AOI4" || c->type == "\\OAI4") {
-                                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_");
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
-                                       cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)]));
-                                       cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)]));
-                                       cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)]));
-                                       cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
-                                       continue;
-                               }
-                               if (c->type == "\\DFF") {
-                                       log_assert(clk_sig.size() == 1);
-                                       RTLIL::Cell *cell;
-                                       if (en_sig.size() == 0) {
-                                               cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_");
-                                       } else {
-                                               log_assert(en_sig.size() == 1);
-                                               cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
-                                               cell->setPort("\\E", en_sig);
-                                       }
-                                       if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                                       cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)]));
-                                       cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)]));
-                                       cell->setPort("\\C", clk_sig);
-                                       continue;
-                               }
                        }
-                       else
-                               cell_stats[RTLIL::unescape_id(c->type)]++;
+                       cell_stats[RTLIL::unescape_id(c->type)]++;
 
-                       if (c->type == "\\_const0_" || c->type == "\\_const1_") {
-                               RTLIL::SigSig conn;
-                               conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->connections().begin()->second.as_wire()->name)]);
-                               conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1);
-                               module->connect(conn);
-                               continue;
-                       }
-
-                       if (c->type == "\\_dff_") {
-                               log_assert(clk_sig.size() == 1);
-                               RTLIL::Cell *cell;
-                               if (en_sig.size() == 0) {
-                                       cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_");
-                               } else {
-                                       log_assert(en_sig.size() == 1);
-                                       cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
-                                       cell->setPort("\\E", en_sig);
+                       if (c->type == "$lut") {
+                               if (GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT").as_int() == 2) {
+                                       SigSpec my_a = module->wires_[remap_name(c->getPort("\\A").as_wire()->name)];
+                                       SigSpec my_y = module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)];
+                                       module->connect(my_y, my_a);
+                                       continue;
                                }
-                               if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
-                               cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)]));
-                               cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)]));
-                               cell->setPort("\\C", clk_sig);
-                               continue;
                        }
-
-                       if (c->type == "$lut" && GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT").as_int() == 2) {
-                               SigSpec my_a = module->wires_[remap_name(c->getPort("\\A").as_wire()->name)];
-                               SigSpec my_y = module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)];
-                               module->connect(my_y, my_a);
-                               continue;
+                       else {
+                               auto it = erased_boxes.find(c->name);
+                               log_assert(it != erased_boxes.end());
+                               c->parameters = std::move(it->second);
                        }
 
-                       RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
+                       RTLIL::Cellcell = module->addCell(remap_name(c->name), c->type);
                        if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
                        cell->parameters = c->parameters;
                        for (auto &conn : c->connections()) {
@@ -788,7 +647,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                        if (c.width == 0)
                                                continue;
                                        //log_assert(c.width == 1);
-                                       c.wire = module->wires_[remap_name(c.wire->name)];
+                                       if (c.wire)
+                                               c.wire = module->wires_[remap_name(c.wire->name)];
                                        newsig.append(c);
                                }
                                cell->setPort(conn.first, newsig);
@@ -825,49 +685,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                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, "\\n%d", si.id);
-               //              RTLIL::SigSig conn;
-               //              if (si.type != G(NONE)) {
-               //                      conn.first = si.bit;
-               //                      conn.second = RTLIL::SigSpec(module->wires_[remap_name(buffer)]);
-               //                      out_wires++;
-               //              } else {
-               //                      conn.first = RTLIL::SigSpec(module->wires_[remap_name(buffer)]);
-               //                      conn.second = si.bit;
-               //                      in_wires++;
-               //              }
-               //              module->connect(conn);
-               //      }
-
-               // Go through all AND and NOT output connections,
-               // and for those output ports driving wires
-               // also driven by mapped_mod, disconnect them
-               for (auto cell : module->cells()) {
-                       if (!cell->type.in("$_AND_", "$_NOT_"))
-                               continue;
-                       for (auto &it : cell->connections_) {
-                               auto port_name = it.first;
-                               if (!cell->output(port_name)) continue;
-                               auto &signal = it.second;
-                               auto bits = signal.bits();
-                               for (auto &b : bits)
-                                       if (output_bits.count(b))
-                                               b = module->addWire(NEW_ID);
-                               signal = std::move(bits);
-                       }
-               }
-               // Do the same for module connections
-               for (auto &it : module->connections_) {
-                       auto &signal = it.first;
-                       auto bits = signal.bits();
-                       for (auto &b : bits)
-                               if (output_bits.count(b))
-                                       b = module->addWire(NEW_ID);
-                       signal = std::move(bits);
-               }
 
                // Stitch in mapped_mod's inputs/outputs into module
                for (auto &it : mapped_mod->wires_) {
@@ -875,22 +692,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                        if (!w->port_input && !w->port_output)
                                continue;
                        RTLIL::Wire *wire = module->wire(w->name);
+                       log_assert(wire);
                        RTLIL::Wire *remap_wire = module->wire(remap_name(w->name));
-                       RTLIL::SigSpec signal;
-                       if (wire) {
-                               signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire));
-                       }
-                       else {
-                               // Attempt another wideports_split here because there
-                               // exists the possibility that different bits of a port
-                               // could be an input and output, therefore parse_xiager()
-                               // could not combine it into a wideport
-                               auto r = wideports_split(w->name.str());
-                               wire = module->wire(r.first);
-                               log_assert(wire);
-                               int i = r.second;
-                               signal = RTLIL::SigSpec(wire, i);
-                       }
+                       RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire));
                        log_assert(GetSize(signal) >= GetSize(remap_wire));
 
                        log_assert(w->port_input || w->port_output);
@@ -913,14 +717,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                log("ABC RESULTS:           input signals: %8d\n", in_wires);
                log("ABC RESULTS:          output signals: %8d\n", out_wires);
 
-               delete mapped_design;
+               design->remove(mapped_mod);
+       }
+       else
+       {
+               log("Don't call ABC as there is nothing to map.\n");
        }
-       //else
-       //{
-       //      log("Don't call ABC as there is nothing to map.\n");
-       //}
 
-cleanup:
        if (cleanup)
        {
                log("Removing temp directory.\n");
@@ -1001,7 +804,7 @@ struct Abc9Pass : public Pass {
                log("        file format).\n");
                log("\n");
                log("    -constr <file>\n");
-               log("        pass this file with timing constraints to ABC. use with -liberty.\n");
+               log("        pass this file with timing constraints to ABC. Use with -liberty.\n");
                log("\n");
                log("        a constr file contains two lines:\n");
                log("            set_driving_cell <cell_name>\n");
@@ -1038,6 +841,9 @@ struct Abc9Pass : public Pass {
                log("        the area cost doubles with each additional input bit. the delay cost\n");
                log("        is still constant for all lut widths.\n");
                log("\n");
+               log("    -lut <file>\n");
+               log("        pass this file with lut library to ABC.\n");
+               log("\n");
                log("    -luts <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..\n");
                log("        generate netlist using luts. Use the specified costs for luts with 1,\n");
                log("        2, 3, .. inputs.\n");
@@ -1091,6 +897,9 @@ struct Abc9Pass : public Pass {
                log("        this attribute is a unique integer for each ABC process started. This\n");
                log("        is useful for debugging the partitioning of clock domains.\n");
                log("\n");
+               log("    -box <file>\n");
+               log("        pass this file with box library to ABC. Use with -lut.\n");
+               log("\n");
                log("When neither -liberty nor -lut is used, the Yosys standard cell library is\n");
                log("loaded into ABC before the ABC script is executed.\n");
                log("\n");
@@ -1120,13 +929,18 @@ struct Abc9Pass : public Pass {
 #else
                std::string exe_file = proc_self_dirname() + "yosys-abc";
 #endif
-               std::string script_file, liberty_file, constr_file, clk_str;
-               std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1";
+               std::string script_file, liberty_file, constr_file, clk_str, box_file, lut_file;
+               std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1", wire_delay;
                bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true;
                bool show_tempdir = false, sop_mode = false;
                vector<int> lut_costs;
                markgroups = false;
 
+#if 0
+               cleanup = false;
+               show_tempdir = true;
+#endif
+
                map_mux4 = false;
                map_mux8 = false;
                map_mux16 = false;
@@ -1166,8 +980,8 @@ struct Abc9Pass : public Pass {
                                continue;
                        }
                        if (arg == "-constr" && argidx+1 < args.size()) {
-                               rewrite_filename(constr_file);
                                constr_file = args[++argidx];
+                               rewrite_filename(constr_file);
                                if (!constr_file.empty() && !is_absolute_path(constr_file))
                                        constr_file = std::string(pwd) + "/" + constr_file;
                                continue;
@@ -1196,8 +1010,17 @@ struct Abc9Pass : public Pass {
                                        lut_mode = atoi(arg.substr(0, pos).c_str());
                                        lut_mode2 = atoi(arg.substr(pos+1).c_str());
                                } else {
-                                       lut_mode = atoi(arg.c_str());
-                                       lut_mode2 = lut_mode;
+                                       pos = arg.find_first_of('.');
+                                       if (pos != string::npos) {
+                                               lut_file = arg;
+                                               rewrite_filename(lut_file);
+                                               if (!lut_file.empty() && !is_absolute_path(lut_file))
+                                                       lut_file = std::string(pwd) + "/" + lut_file;
+                                       }
+                                       else {
+                                               lut_mode = atoi(arg.c_str());
+                                               lut_mode2 = lut_mode;
+                                       }
                                }
                                lut_costs.clear();
                                for (int i = 0; i < lut_mode; i++)
@@ -1354,17 +1177,31 @@ struct Abc9Pass : public Pass {
                                markgroups = true;
                                continue;
                        }
+                       if (arg == "-box" && argidx+1 < args.size()) {
+                               box_file = args[++argidx];
+                               rewrite_filename(box_file);
+                               if (!box_file.empty() && !is_absolute_path(box_file))
+                                       box_file = std::string(pwd) + "/" + box_file;
+                               continue;
+                       }
+                       if (arg == "-W" && argidx+1 < args.size()) {
+                               wire_delay = "-W " + args[++argidx];
+                               continue;
+                       }
                        break;
                }
                extra_args(args, argidx, design);
 
-               if (!lut_costs.empty() && !liberty_file.empty())
+               if ((!lut_costs.empty() || !lut_file.empty()) && !liberty_file.empty())
                        log_cmd_error("Got -lut and -liberty! This two options are exclusive.\n");
                if (!constr_file.empty() && liberty_file.empty())
                        log_cmd_error("Got -constr but no -liberty!\n");
 
                for (auto mod : design->selected_modules())
                {
+                       if (mod->attributes.count("\\abc_box_id"))
+                               continue;
+
                        if (mod->processes.size() > 0) {
                                log("Skipping module %s as it contains processes.\n", log_id(mod));
                                continue;
@@ -1392,7 +1229,8 @@ struct Abc9Pass : public Pass {
 
                        if (!dff_mode || !clk_str.empty()) {
                                abc9_module(design, mod, script_file, exe_file, liberty_file, 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);
+                                               delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode,
+                                               box_file, lut_file, wire_delay);
                                continue;
                        }
 
@@ -1537,7 +1375,8 @@ struct Abc9Pass : public Pass {
                                en_polarity = std::get<2>(it.first);
                                en_sig = assign_map(std::get<3>(it.first));
                                abc9_module(design, mod, script_file, exe_file, liberty_file, 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);
+                                               keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode,
+                                               box_file, lut_file, wire_delay);
                                assign_map.set(mod);
                        }
                }