From e178a8223a7c0dc164a26a26758b2ab2ecb65556 Mon Sep 17 00:00:00 2001 From: Lofty Date: Thu, 9 Jul 2026 10:05:02 +0100 Subject: [PATCH] wip --- backends/aiger2/aiger.cc | 4 +- frontends/aiger/aigerparse.cc | 1 + frontends/aiger2/xaiger.cc | 4 +- kernel/constids.inc | 1 + passes/techmap/abc_new.cc | 9 ++-- passes/techmap/abc_ops_reintegrate.cc | 64 ++++++++++++++++++++++++++- techlibs/gatemate/synth_gatemate.cc | 2 +- tests/arch/gatemate/logic.ys | 4 +- tests/arch/gatemate/luttrees.ys | 4 +- tests/arch/ice40/fsm.ys | 2 + 10 files changed, 82 insertions(+), 13 deletions(-) diff --git a/backends/aiger2/aiger.cc b/backends/aiger2/aiger.cc index 0dceaedd6..afcec2fbf 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 { @@ -1277,7 +1277,7 @@ struct XAigerWriter : AigerWriter { // 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 + map_file << "output " << proper_pos_counter << " " << i << " " << w->name.c_str() << "\n"; } proper_pos_counter++; diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index cfa941c32..460bc50ba 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -522,6 +522,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/xaiger.cc b/frontends/aiger2/xaiger.cc index 6cb15350f..3488809b6 100644 --- a/frontends/aiger2/xaiger.cc +++ b/frontends/aiger2/xaiger.cc @@ -123,7 +123,7 @@ struct Xaiger2Frontend : public Frontend { std::string type; while (map_file >> type) { - if (type == "pi") { + if (type == "input") { int pi_idx; int woffset; std::string name; @@ -398,7 +398,7 @@ struct Xaiger2Frontend : public Frontend { map_file.close(); map_file.open(map_filename); while (map_file >> type) { - if (type == "po") { + if (type == "output") { int po_idx; int woffset; std::string name; diff --git a/kernel/constids.inc b/kernel/constids.inc index cfd12e3fb..6e6b40bc0 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -822,6 +822,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/abc_new.cc b/passes/techmap/abc_new.cc index 91e17882f..477a46134 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -191,10 +191,13 @@ 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(" debug 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(" debug abc_ops_reintegrate -map %s/input.map2", tmpdir)); + //run(stringf(" debug read_xaiger2 -sc_mapping -module_name %s -map2 %s/input.map2 %s/output.aig", + // modname, tmpdir, 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..a4812b99a 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,10 +529,49 @@ 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 port_name = pseudopo.first; + auto box_name = pseudopo.second.first; + auto box_port_name = pseudopo.second.second; + + RTLIL::Wire *mapped_wire = mapped_mod->wire(port_name); + if (!mapped_wire) + continue; + + auto box = module->cell(box_name); + auto box_port = box->getPort(box_port_name); + + RTLIL::Wire *remap_wire = module->wire(remap_name(port_name)); + log_assert(GetSize(box_port) >= GetSize(remap_wire)); + + RTLIL::SigSig conn; + if (mapped_wire->port_output) { + conn.first = box_port; + conn.second = remap_wire; + out_wires++; + module->connect(conn); + } + else if (mapped_wire->port_input) { + conn.first = remap_wire; + conn.second = box_port; + in_wires++; + module->connect(conn); + } + + 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); RTLIL::Wire *wire = module->wire(port); + + if (!wire) { + log_debug("looking for port %s\n", port); + continue; + } log_assert(wire); RTLIL::Wire *remap_wire = module->wire(remap_name(port)); diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc index aa002c272..4f2b27d4e 100644 --- a/techlibs/gatemate/synth_gatemate.cc +++ b/techlibs/gatemate/synth_gatemate.cc @@ -332,7 +332,7 @@ struct SynthGateMatePass : public ScriptPass abc_args += " -dff"; } if (abc_new) { - run("abc_new " + abc_args, "(with -luttree and -abc_new)"); + run("abc_new -nocleanup " + abc_args, "(with -luttree and -abc_new)"); } else { run("abc " + abc_args, "(with -luttree, without -abc_new)"); } diff --git a/tests/arch/gatemate/logic.ys b/tests/arch/gatemate/logic.ys index e6204cdca..646c24202 100644 --- a/tests/arch/gatemate/logic.ys +++ b/tests/arch/gatemate/logic.ys @@ -27,7 +27,7 @@ design -load orig equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 1 t:CC_LUT1 -select -assert-count 6 t:CC_LUT2 +select -assert-count 4 t:CC_LUT1 +select -assert-count 3 t:CC_LUT2 select -assert-count 2 t:CC_L2T4 select -assert-none t:CC_LUT1 t:CC_LUT2 t:CC_L2T4 %% t:* %D diff --git a/tests/arch/gatemate/luttrees.ys b/tests/arch/gatemate/luttrees.ys index f3a61ee60..d87b66154 100644 --- a/tests/arch/gatemate/luttrees.ys +++ b/tests/arch/gatemate/luttrees.ys @@ -30,5 +30,5 @@ equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopa design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd luttrees # Constrain all select calls below inside the top module -select -assert-count 750 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% -select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D +select -assert-count 917 t:CC_LUT1 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% +select -assert-none t:CC_LUT1 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D diff --git a/tests/arch/ice40/fsm.ys b/tests/arch/ice40/fsm.ys index b01d34bba..2c2a9107d 100644 --- a/tests/arch/ice40/fsm.ys +++ b/tests/arch/ice40/fsm.ys @@ -1,3 +1,5 @@ +scratchpad -set abc9.nocleanup 1 + read_verilog ../common/fsm.v hierarchy -top fsm proc