From ae86bbb1301d8e26327d40f0bb547b2c8e777ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Thu, 10 Sep 2026 09:09:13 +0200 Subject: [PATCH] Revert "Temporarily revert #6101 and #6077" --- backends/aiger2/aiger.cc | 11 +- .../more_scripting/load_design.rst | 1 - frontends/CMakeLists.txt | 1 - frontends/aiger/aigerparse.cc | 16 +- frontends/aiger2/CMakeLists.txt | 3 - frontends/aiger2/xaiger.cc | 470 ------------------ kernel/constids.inc | 1 + passes/techmap/CMakeLists.txt | 1 - passes/techmap/abc_new.cc | 5 +- passes/techmap/abc_ops_reintegrate.cc | 43 +- tests/techmap/abc_new.ys | 13 + tests/techmap/xaiger2-5169.ys | 2 +- 12 files changed, 74 insertions(+), 493 deletions(-) delete mode 100644 frontends/aiger2/CMakeLists.txt delete mode 100644 frontends/aiger2/xaiger.cc create mode 100644 tests/techmap/abc_new.ys diff --git a/backends/aiger2/aiger.cc b/backends/aiger2/aiger.cc index 0dceaedd6..f75def2bf 100644 --- a/backends/aiger2/aiger.cc +++ b/backends/aiger2/aiger.cc @@ -998,7 +998,7 @@ struct XAigerWriter : AigerWriter { if (map_file.is_open() && !box_port) { log_assert(cursor.is_top()); // TODO driven_by_opaque_box.insert(bit); - map_file << "pi " << pis.size() - 1 << " " << bit.offset + map_file << "input " << pis.size() - 1 << " " << bit.offset << " " << bit.wire->name.c_str() << "\n"; } } else { @@ -1273,11 +1273,8 @@ struct XAigerWriter : AigerWriter { for (auto w : top->wires()) if (w->port_output) for (int i = 0; i < w->width; i++) { - // When a module output is directly driven by an opaque box, we - // don't emit it to the mapping file to aid re-integration, but we - // do emit a proper PO. - if (map_file.is_open() && !driven_by_opaque_box.count(SigBit(w, i))) { - map_file << "po " << proper_pos_counter << " " << i + if (map_file.is_open()) { + map_file << "output " << proper_pos_counter << " " << i << " " << w->name.c_str() << "\n"; } proper_pos_counter++; @@ -1502,7 +1499,7 @@ struct XAiger2Backend : Backend { log(" (conflicts with -flatten)\n"); log("\n"); log(" -map2 \n"); - log(" write a map2 file which 'read_xaiger2 -sc_mapping' can read to\n"); + log(" write a map2 file which 'abc_ops_reintegrate' can read to\n"); log(" reintegrate a mapping\n"); log(" (conflicts with -flatten)\n"); log("\n"); diff --git a/docs/source/using_yosys/more_scripting/load_design.rst b/docs/source/using_yosys/more_scripting/load_design.rst index 178df5682..7ef1fd58e 100644 --- a/docs/source/using_yosys/more_scripting/load_design.rst +++ b/docs/source/using_yosys/more_scripting/load_design.rst @@ -128,7 +128,6 @@ Other built-in ``read_*`` commands - :cmd:title:`read_blif` - :cmd:title:`read_json` - :cmd:title:`read_liberty` -- :cmd:title:`read_xaiger2` .. TODO:: does `write_file` count? diff --git a/frontends/CMakeLists.txt b/frontends/CMakeLists.txt index 983fa2fd9..8abe1a112 100644 --- a/frontends/CMakeLists.txt +++ b/frontends/CMakeLists.txt @@ -1,5 +1,4 @@ add_subdirectory(aiger) -add_subdirectory(aiger2) add_subdirectory(ast) add_subdirectory(blif) add_subdirectory(json) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index cfa941c32..9c635a5a8 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -480,19 +480,22 @@ void AigerReader::parse_xaiger() mapping_cell.type = RTLIL::escape_id(cellName); mapping_cell.out = RTLIL::escape_id(outPinName); - auto module = design->addModule(RTLIL::escape_id(cellName)); - module->set_bool_attribute(ID::blackbox); - module->addWire(RTLIL::escape_id(outPinName))->port_output = true; - for (unsigned j = 0; j < inPinNum; ++j) { auto inPinName = std::string{}; std::getline(f, inPinName, '\0'); log_debug2("M: inPinName=%s\n", inPinName); mapping_cell.ins.push_back(RTLIL::escape_id(inPinName)); - module->addWire(RTLIL::escape_id(inPinName))->port_input = true; } - module->fixup_ports(); + if (!design->module(mapping_cell.type)) { + auto module = design->addModule(mapping_cell.type); + module->set_bool_attribute(ID::blackbox); + module->addWire(mapping_cell.out)->port_output = true; + for (unsigned j = 0; j < inPinNum; ++j) { + module->addWire(mapping_cell.ins.at(j))->port_input = true; + } + module->fixup_ports(); + } mapping_cells.push_back(std::move(mapping_cell)); } @@ -522,6 +525,7 @@ void AigerReader::parse_xaiger() } RTLIL::Cell *cell = module->addCell(stringf("$sc$aiger%d$%d", aiger_autoidx, rootNodeID), mapping_cell.type); + cell->set_bool_attribute(ID::abc9_cell); cell->setPort(mapping_cell.out, output_sig); for (unsigned j = 0; j < mapping_cell.ins.size(); ++j) { diff --git a/frontends/aiger2/CMakeLists.txt b/frontends/aiger2/CMakeLists.txt deleted file mode 100644 index 1eb31c25f..000000000 --- a/frontends/aiger2/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -yosys_frontend(xaiger2 - xaiger.cc -) diff --git a/frontends/aiger2/xaiger.cc b/frontends/aiger2/xaiger.cc deleted file mode 100644 index 6cb15350f..000000000 --- a/frontends/aiger2/xaiger.cc +++ /dev/null @@ -1,470 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) Martin PoviĊĦer - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/register.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -uint32_t read_be32(std::istream &f) { - return ((uint32_t) f.get() << 24) | - ((uint32_t) f.get() << 16) | - ((uint32_t) f.get() << 8) | (uint32_t) f.get(); -} - -IdString read_idstring(std::istream &f) -{ - std::string str; - std::getline(f, str, '\0'); - if (!f.good()) - log_error("failed to read string\n"); - return RTLIL::escape_id(str); -} - -struct Xaiger2Frontend : public Frontend { - Xaiger2Frontend() : Frontend("xaiger2", "(experimental) read XAIGER file") - { - experimental(); - } - - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" read_xaiger2 -sc_mapping [options] \n"); - log("\n"); - log("Read a standard cell mapping from a XAIGER file into an existing module.\n"); - log("\n"); - log(" -module_name \n"); - log(" name of the target module\n"); - log("\n"); - log(" -map2 \n"); - log(" read file with symbol information\n"); - log("\n"); - } - - void read_sc_mapping(std::istream *&f, std::string filename, std::vector args, Design *design) - { - IdString module_name; - std::string map_filename; - - size_t argidx; - for (argidx = 2; argidx < args.size(); argidx++) { - std::string arg = args[argidx]; - if (arg == "-module_name" && argidx + 1 < args.size()) { - module_name = RTLIL::escape_id(args[++argidx]); - continue; - } - if (arg == "-map2" && argidx + 1 < args.size()) { - map_filename = args[++argidx]; - continue; - } - break; - } - extra_args(f, filename, args, argidx, true); - - if (map_filename.empty()) - log_error("A '-map2' argument is required\n"); - if (module_name.empty()) - log_error("A '-module_name' argument is required\n"); - - Module *module = design->module(module_name); - if (!module) - log_error("Module '%s' not found\n", module_name.unescape()); - - std::ifstream map_file; - map_file.open(map_filename); - if (!map_file) - log_error("Failed to open map file '%s'\n", map_filename); - - unsigned int M, I, L, O, A; - std::string header; - if (!(*f >> header >> M >> I >> L >> O >> A) || header != "aig") - log_error("Bad header\n"); - std::string line; - std::getline(*f, line); - log_debug("M=%u I=%u L=%u O=%u A=%u\n", M, I, L, O, A); - - if (L != 0) - log_error("Latches unsupported\n"); - if (I + L + A != M) - log_error("Inconsistent header\n"); - - std::vector outputs; - for (int i = 0; i < (int) O; i++) { - int po; - *f >> po; - int c = f->get(); - log_assert(c == '\n'); - outputs.push_back(po); - } - - std::vector> boxes; - std::vector retained_boxes; - std::vector bits(2 + 2*M, RTLIL::Sm); - bits[0] = RTLIL::S0; - bits[1] = RTLIL::S1; - - std::string type; - while (map_file >> type) { - if (type == "pi") { - int pi_idx; - int woffset; - std::string name; - if (!(map_file >> pi_idx >> woffset >> name)) - log_error("Bad map file: couldn't read 'pi' line\n"); - int lit = (2 * pi_idx) + 2; - if (lit < 0 || lit >= (int) bits.size()) - log_error("Bad map file: primary input literal out of range\n"); - Wire *w = module->wire(name); - if (!w || woffset < 0 || woffset >= w->width) - log_error("Map file references non-existent signal bit %s[%d]\n", - name.c_str(), woffset); - bits[lit] = SigBit(w, woffset); - } else if (type == "box") { - int box_seq; - std::string name; - if (!(map_file >> box_seq >> name)) - log_error("Bad map file: couldn't read 'box' line\n"); - if (box_seq < 0) - log_error("Bad map file: box out of range\n"); - - Cell *box = module->cell(RTLIL::escape_id(name)); - if (!box) - log_error("Map file references non-existent box %s\n", - name.c_str()); - - Module *def = design->module(box->type); - if (def && !box->parameters.empty()) { - // TODO: This is potentially costly even if a cached derivation exists - def = design->module(def->derive(design, box->parameters)); - log_assert(def); - } - - if (!def) - log_error("Bad map file: no module found for box type '%s'\n", box->type.unescape()); - - if (box_seq >= (int) boxes.size()) { - boxes.resize(box_seq + 1); - retained_boxes.resize(box_seq + 1); - } - boxes[box_seq] = std::make_pair(box, def); - } else { - std::string scratch; - std::getline(map_file, scratch); - } - } - - for (int i = 0; i < (int) A; i++) { - while (f->get() & 0x80 && !f->eof()); - while (f->get() & 0x80 && !f->eof()); - } - - if (f->get() != 'c') - log_error("Missing 'c' ahead of extensions\n"); - if (f->peek() == '\n') - f->get(); - auto extensions_start = f->tellg(); - - log_debug("reading 'h' (first pass)\n"); - for (int c = f->get(); c != EOF; c = f->get()) { - if (c == 'h') { - uint32_t len, ci_num, co_num, pi_num, po_num, no_boxes; - len = read_be32(*f); - read_be32(*f); // version - ci_num = read_be32(*f); - co_num = read_be32(*f); - pi_num = read_be32(*f); - po_num = read_be32(*f); - no_boxes = read_be32(*f); - - log_debug("len=%u ci_num=%u co_num=%u pi_num=%u po_nun=%u no_boxes=%u\n", - len, ci_num, co_num, pi_num, po_num, no_boxes); - - int ci_counter = 0; - for (uint32_t i = 0; i < no_boxes; i++) { - /* unused box_inputs = */ read_be32(*f); - YS_MAYBE_UNUSED auto box_outputs = read_be32(*f); - /* unused box_id = */ read_be32(*f); - auto box_seq = read_be32(*f); - - log_assert(box_seq < boxes.size()); - - auto [cell, def] = boxes[box_seq]; - log_assert(cell && def); - retained_boxes[box_seq] = true; - - int box_ci_idx = 0; - for (auto port_id : def->ports) { - Wire *port = def->wire(port_id); - if (port->port_output) { - if (!cell->hasPort(port_id) || cell->getPort(port_id).size() != port->width) - log_error("Malformed design (1)\n"); - - SigSpec &conn = cell->connections_[port_id]; - for (int j = 0; j < port->width; j++) { - if (conn[j].wire && conn[j].wire->port_output) - conn[j] = module->addWire(module->uniquify( - stringf("$box$%s$%s$%d", - cell->name.isPublic() ? cell->name.c_str() + 1 : cell->name.c_str(), - port_id.isPublic() ? port_id.c_str() + 1 : port_id.c_str(), - j))); - - bits[2*(pi_num + ci_counter + box_ci_idx++) + 2] = conn[j]; - } - } - } - - log_assert(box_ci_idx == (int) box_outputs); - ci_counter += box_ci_idx; - } - log_assert(pi_num + ci_counter == ci_num); - } else if (c == '\n') { - break; - } else if (c == 'c') { - break; - } else { - uint32_t len = read_be32(*f); - f->ignore(len); - log_debug(" section '%c' (%d): ignoring %d bytes\n", c, c, len); - } - } - - log_debug("reading 'M' (second pass)\n"); - - f->seekg(extensions_start); - bool read_mapping = false; - uint32_t no_cells, no_instances; - for (int c = f->get(); c != EOF; c = f->get()) { - if (c == 'M') { - uint32_t len = read_be32(*f); - read_mapping = true; - - no_cells = read_be32(*f); - no_instances = read_be32(*f); - - log_debug("M: len=%u no_cells=%u no_instances=%u\n", len, no_cells, no_instances); - - struct MappingCell { - RTLIL::IdString type; - RTLIL::IdString out; - std::vector ins; - }; - std::vector cells; - cells.resize(no_cells); - - for (unsigned i = 0; i < no_cells; ++i) { - auto &cell = cells[i]; - cell.type = read_idstring(*f); - cell.out = read_idstring(*f); - uint32_t nins = read_be32(*f); - for (uint32_t j = 0; j < nins; j++) - cell.ins.push_back(read_idstring(*f)); - log_debug("M: Cell %s (out %s, ins", cell.type.unescape(), cell.out.unescape()); - for (auto in : cell.ins) - log_debug(" %s", in.unescape()); - log_debug(")\n"); - } - - for (unsigned i = 0; i < no_instances; ++i) { - uint32_t cell_id = read_be32(*f); - uint32_t out_lit = read_be32(*f); - - log_assert(out_lit < bits.size()); - log_assert(bits[out_lit] == RTLIL::Sm); - log_assert(cell_id < cells.size()); - auto &cell = cells[cell_id]; - Cell *instance = module->addCell(module->uniquify(stringf("$sc%d", out_lit)), cell.type); - auto out_w = module->addWire(module->uniquify(stringf("$lit%d", out_lit))); - instance->setPort(cell.out, out_w); - bits[out_lit] = out_w; - for (auto in : cell.ins) { - uint32_t in_lit = read_be32(*f); - log_assert(out_lit < bits.size()); - log_assert(bits[in_lit] != RTLIL::Sm); - instance->setPort(in, bits[in_lit]); - } - } - } else if (c == '\n') { - break; - } else if (c == 'c') { - break; - } else { - uint32_t len = read_be32(*f); - f->ignore(len); - log_debug(" section '%c' (%d): ignoring %d bytes\n", c, c, len); - } - } - - if (!read_mapping) - log_error("Missing mapping (no 'M' section)\n"); - - log("Read %d instances with cell library of size %d.\n", - no_instances, no_cells); - - f->seekg(extensions_start); - log_debug("reading 'h' (second pass)\n"); - int co_counter = 0; - for (int c = f->get(); c != EOF; c = f->get()) { - if (c == 'h') { - uint32_t len, ci_num, co_num, pi_num, po_num, no_boxes; - len = read_be32(*f); - read_be32(*f); - ci_num = read_be32(*f); - co_num = read_be32(*f); - pi_num = read_be32(*f); - po_num = read_be32(*f); - no_boxes = read_be32(*f); - - log_debug("len=%u ci_num=%u co_num=%u pi_num=%u po_nun=%u no_boxes=%u\n", - len, ci_num, co_num, pi_num, po_num, no_boxes); - - for (uint32_t i = 0; i < no_boxes; i++) { - YS_MAYBE_UNUSED auto box_inputs = read_be32(*f); - /* unused box_outputs = */ read_be32(*f); - /* unused box_id = */ read_be32(*f); - auto box_seq = read_be32(*f); - - log_assert(box_seq < boxes.size()); - - auto [cell, def] = boxes[box_seq]; - log_assert(cell && def); - - int box_co_idx = 0; - for (auto port_id : def->ports) { - Wire *port = def->wire(port_id); - SigSpec conn; - if (port->port_input) { - if (!cell->hasPort(port_id) || cell->getPort(port_id).size() != port->width) - log_error("Malformed design (2)\n"); - - SigSpec conn; - for (int j = 0; j < port->width; j++) { - log_assert(co_counter + box_co_idx < (int) outputs.size()); - int lit = outputs[co_counter + box_co_idx++]; - log_assert(lit >= 0 && lit < (int) bits.size()); - SigBit bit = bits[lit]; - if (bit == RTLIL::Sm) - log_error("Malformed mapping (1)\n"); - conn.append(bit); - } - cell->setPort(port_id, conn); - } - } - - log_assert(box_co_idx == (int) box_inputs); - co_counter += box_co_idx; - } - log_assert(po_num + co_counter == co_num); - } else if (c == '\n') { - break; - } else if (c == 'c') { - break; - } else { - uint32_t len = read_be32(*f); - f->ignore(len); - log_debug(" section '%c' (%d): ignoring %d bytes\n", c, c, len); - } - } - - while (true) { - std::string scratch; - std::getline(*f, scratch); - if (f->eof()) - break; - log_assert(!f->fail()); - log("input file: %s\n", scratch); - } - - log_debug("co_counter=%d\n", co_counter); - - // TODO: seek without close/open - map_file.close(); - map_file.open(map_filename); - while (map_file >> type) { - if (type == "po") { - int po_idx; - int woffset; - std::string name; - if (!(map_file >> po_idx >> woffset >> name)) - log_error("Bad map file: couldn't read 'po' line\n"); - po_idx += co_counter; - if (po_idx < 0 || po_idx >= (int) outputs.size()) - log_error("Bad map file: primary output index out of range\n"); - int lit = outputs[po_idx]; - if (lit < 0 || lit >= (int) bits.size()) - log_error("Bad map file: primary output literal out of range\n"); - if (bits[lit] == RTLIL::Sm) - log_error("Bad map file: primary output literal is a marker\n"); - Wire *w = module->wire(name); - if (!w || woffset < 0 || woffset >= w->width) - log_error("Map file references non-existent signal bit %s[%d]\n", - name.c_str(), woffset); - module->connect(SigBit(w, woffset), bits[lit]); - } else if (type == "pseudopo") { - int po_idx; - int poffset; - std::string box_name; - std::string box_port; - if (!(map_file >> po_idx >> poffset >> box_name >> box_port)) - log_error("Bad map file: couldn't read 'pseudopo' line\n"); - po_idx += co_counter; - if (po_idx < 0 || po_idx >= (int) outputs.size()) - log_error("Bad map file: pseudo primary output index out of range\n"); - int lit = outputs[po_idx]; - if (lit < 0 || lit >= (int) bits.size()) - log_error("Bad map file: pseudo primary output literal out of range\n"); - if (bits[lit] == RTLIL::Sm) - log_error("Bad map file: pseudo primary output literal is a marker\n"); - Cell *cell = module->cell(box_name); - if (!cell || !cell->hasPort(box_port)) - log_error("Map file references non-existent box port %s/%s\n", - box_name.c_str(), box_port.c_str()); - SigSpec &port = cell->connections_[box_port]; - if (poffset < 0 || poffset >= port.size()) - log_error("Map file references non-existent box port bit %s/%s[%d]\n", - box_name.c_str(), box_port.c_str(), poffset); - port[poffset] = bits[lit]; - } else { - std::string scratch; - std::getline(map_file, scratch); - } - } - - int box_seq = 0; - for (auto [cell, def] : boxes) { - if (!retained_boxes[box_seq++]) - module->remove(cell); - } - } - - void execute(std::istream *&f, std::string filename, std::vector args, Design *design) override - { - log_header(design, "Executing XAIGER2 frontend.\n"); - - if (args.size() > 1 && args[1] == "-sc_mapping") { - read_sc_mapping(f, filename, args, design); - return; - } - - log_cmd_error("Mode '-sc_mapping' must be selected\n"); - } -} Xaiger2Frontend; - -PRIVATE_NAMESPACE_END diff --git a/kernel/constids.inc b/kernel/constids.inc index e9e34d227..673a50e7c 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -827,6 +827,7 @@ X(abc9_box_id) X(abc9_box_seq) X(abc9_bypass) X(abc9_carry) +X(abc9_cell) X(abc9_deferred_box) X(abc9_flop) X(abc9_keep) diff --git a/passes/techmap/CMakeLists.txt b/passes/techmap/CMakeLists.txt index 4219a7234..8a6e11eef 100644 --- a/passes/techmap/CMakeLists.txt +++ b/passes/techmap/CMakeLists.txt @@ -102,7 +102,6 @@ yosys_pass(abc_new abc9_exe abc9_ops box_derive - read_xaiger2 write_xaiger2 ) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 91e17882f..f8df67b39 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -193,8 +193,9 @@ struct AbcNewPass : public ScriptPass { run(stringf(" abc9_ops -write_box %s/input.box", tmpdir)); run(stringf(" write_xaiger2 -mapping_prep -map2 %s/input.map2 %s/input.xaig", tmpdir, tmpdir)); run(stringf(" abc9_exe %s -cwd %s -box %s/input.box", exe_options, tmpdir, tmpdir)); - run(stringf(" read_xaiger2 -sc_mapping -module_name %s -map2 %s/input.map2 %s/output.aig", - modname.c_str(), tmpdir.c_str(), tmpdir.c_str())); + run(stringf(" read_aiger -xaiger -module_name %s$abc9 %s/output.aig", + modname, tmpdir)); + run(stringf(" abc_ops_reintegrate -map %s/input.map2", tmpdir)); if (!help_mode && mod->has_attribute(ID(abc9_script))) { if (script_save.empty()) active_design->scratchpad_unset("abc9.script"); diff --git a/passes/techmap/abc_ops_reintegrate.cc b/passes/techmap/abc_ops_reintegrate.cc index 3f55350fe..79084cdaa 100644 --- a/passes/techmap/abc_ops_reintegrate.cc +++ b/passes/techmap/abc_ops_reintegrate.cc @@ -50,6 +50,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename) int co_count = design->scratchpad_get_int("read_aiger.co_count", 0); dict> wideports_cache; + dict> pseudopos; if (!map_filename.empty()) { std::ifstream mf(map_filename); @@ -150,6 +151,28 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename) } } } + else if (type == "pseudopo") { + std::string port; + mf >> port; + RTLIL::IdString escaped_p = RTLIL::escape_id(port); + + log_assert(variable + co_count < output_count); + RTLIL::IdString wire_name = stringf("$aiger$o%d", variable + co_count); + RTLIL::Wire* wire = mapped_mod->wire(wire_name); + log_assert(wire); + log_assert(wire->port_output); + log_debug("Mapping pseudo output %s", wire); + + if (index == 0) { + pseudopos.insert({wire_name, std::make_pair(escaped_s, escaped_p)}); + log_debug(" -> %s.%s\n", escaped_s, escaped_p); + } + else { + RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index); + pseudopos.insert({wire_name, std::make_pair(indexed_name, escaped_p)}); + log_debug(" -> %s.%s\n", indexed_name, escaped_p); + } + } else if (type == "box") { RTLIL::Cell* cell = mapped_mod->cell(stringf("$box%d", variable)); if (!cell) @@ -352,7 +375,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename) continue; } - if (mapped_cell->type == ID($lut)) { + if (mapped_cell->type == ID($lut) || mapped_cell->get_bool_attribute(ID::abc9_cell)) { RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); cell->parameters = mapped_cell->parameters; cell->attributes = mapped_cell->attributes; @@ -506,6 +529,24 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, std::string map_filename) log("ABC RESULTS: %15s cells: %8d\n", it.first, it.second); int in_wires = 0, out_wires = 0; + for (auto pseudopo : pseudopos) { + auto wire_name = pseudopo.first; + auto box_name = pseudopo.second.first; + auto box_port_name = pseudopo.second.second; + + RTLIL::Wire *mapped_wire = mapped_mod->wire(wire_name); + log_assert(mapped_wire); + auto box = module->cell(box_name); + log_assert(box); + + RTLIL::Wire *remap_wire = module->wire(remap_name(wire_name)); + box->setPort(box_port_name, remap_wire); + + mapped_wire->port_output = false; + } + + mapped_mod->fixup_ports(); + // Stitch in mapped_mod's inputs/outputs into module for (auto port : mapped_mod->ports) { RTLIL::Wire *mapped_wire = mapped_mod->wire(port); diff --git a/tests/techmap/abc_new.ys b/tests/techmap/abc_new.ys new file mode 100644 index 000000000..9c70606ea --- /dev/null +++ b/tests/techmap/abc_new.ys @@ -0,0 +1,13 @@ +read_verilog <