From 83ae8aa633d5e3aac6bc54bdfa6c6b52f4fc3825 Mon Sep 17 00:00:00 2001 From: Lofty Date: Wed, 20 May 2026 14:30:09 +0100 Subject: [PATCH] wip --- frontends/aiger/aigerparse.cc | 104 ++++++++++++++++++++++++---- frontends/aiger2/xaiger.cc | 2 +- passes/techmap/abc_new.cc | 6 +- techlibs/gatemate/synth_gatemate.cc | 2 +- 4 files changed, 98 insertions(+), 16 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index b2cc613f2..25fef6796 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -23,6 +23,10 @@ // http://fmv.jku.at/papers/Biere-FMV-TR-07-1.pdf // https://stackoverflow.com/a/46137633 +#include "kernel/log.h" +#include "kernel/rtlil.h" +#include +#include #ifdef _MSC_VER #include #define __builtin_bswap32 _byteswap_ulong @@ -348,7 +352,7 @@ RTLIL::Wire* AigerReader::createWireIfNotExists(RTLIL::Module *module, unsigned RTLIL::IdString wire_name(stringf("$aiger%d$%d%s", aiger_autoidx, variable, invert ? "b" : "")); RTLIL::Wire *wire = module->wire(wire_name); if (wire) return wire; - log_debug2("Creating %s\n", wire_name.c_str()); + log_debug("Creating %s\n", wire_name.c_str()); wire = module->addWire(wire_name); wire->port_input = wire->port_output = false; if (!invert) return wire; @@ -358,12 +362,12 @@ RTLIL::Wire* AigerReader::createWireIfNotExists(RTLIL::Module *module, unsigned if (module->cell(wire_inv_name)) return wire; } else { - log_debug2("Creating %s\n", wire_inv_name.c_str()); + log_debug("Creating %s\n", wire_inv_name.c_str()); wire_inv = module->addWire(wire_inv_name); wire_inv->port_input = wire_inv->port_output = false; } - log_debug2("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str()); + log_debug("Creating cell \"$not$aiger%d$%d\" to represent %s = ~%s\n", aiger_autoidx, variable, wire_name.c_str(), wire_inv_name.c_str()); module->addNotGate(stringf("$not$aiger%d$%d", aiger_autoidx, variable), wire_inv, wire); return wire; @@ -406,7 +410,7 @@ void AigerReader::parse_xaiger() module->connect(n0, State::S0); int c = f.get(); - if (c != 'c') + if (c != 'c') // 'c'omment section (used for extensions) log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c); if (f.peek() == '\n') f.get(); @@ -415,7 +419,7 @@ void AigerReader::parse_xaiger() std::string s; for (int c = f.get(); c != EOF; c = f.get()) { // XAIGER extensions - if (c == 'm') { + if (c == 'm') { // LUT 'm'apping uint32_t dataSize = parse_xaiger_literal(f); uint32_t lutNum = parse_xaiger_literal(f); uint32_t lutSize = parse_xaiger_literal(f); @@ -461,7 +465,83 @@ void AigerReader::parse_xaiger() module->addLut(stringf("$lut$aiger%d$%d", aiger_autoidx, rootNodeID), input_sig, output_sig, std::move(lut_mask)); } } - else if (c == 'r') { + else if (c == 'M') { // cell 'M'apping + struct MappingCell { + RTLIL::IdString type; + RTLIL::IdString out; + std::vector ins; + }; + std::vector mapping_cells; + + uint32_t dataSize = parse_xaiger_literal(f); + uint32_t cellNum = parse_xaiger_literal(f); + uint32_t instanceNum = parse_xaiger_literal(f); + log_debug("M: dataSize=%u cellNum=%u instanceNum=%u\n", dataSize, cellNum, instanceNum); + + for (unsigned i = 0; i < cellNum; ++i) { + MappingCell mapping_cell{}; + auto cellName = std::string{}; // name of cell + auto outPinName = std::string{}; // name of cell output pin + std::getline(f, cellName, '\0'); + std::getline(f, outPinName, '\0'); + uint32_t inPinNum = parse_xaiger_literal(f); + log_debug("M: cellID=%u cellName=%s outPinName=%s inPinNum=%u\n", i, cellName, outPinName, inPinNum); + 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_debug("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(); + + mapping_cells.push_back(std::move(mapping_cell)); + } + + for (unsigned i = 0; i < instanceNum; ++i) { + uint32_t cellID = parse_xaiger_literal(f); + uint32_t rootNodeID = parse_xaiger_literal(f); + + log_assert(cellID < cellNum); + MappingCell &mapping_cell = mapping_cells.at(cellID); + + log_debug("M: instanceID=%u cellID=%u outPort=%s rootNodeID=%u\n", i, cellID, RTLIL::unescape_id(mapping_cell.out), rootNodeID); + + RTLIL::Wire *output_sig = createWireIfNotExists(module, rootNodeID); + log_assert(output_sig); + + { + RTLIL::IdString output_cell_name; + if ((rootNodeID & 1) == 0) { // uninverted + output_cell_name = stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID >> 1); + } else { // inverted + output_cell_name = stringf("$not$aiger%d$%d", aiger_autoidx, rootNodeID >> 1); + } + RTLIL::Cell *output_cell = module->cell(output_cell_name); + log_assert(output_cell); + module->remove(output_cell); + } + + RTLIL::Cell *cell = module->addCell(stringf("$sc$aiger%d$%d", aiger_autoidx, rootNodeID), mapping_cell.type); + cell->setPort(mapping_cell.out, output_sig); + + for (unsigned j = 0; j < mapping_cell.ins.size(); ++j) { + auto nodeID = parse_xaiger_literal(f); + log_debug("M: inPort=%s nodeID=%u\n", RTLIL::unescape_id(mapping_cell.ins.at(j)), nodeID); + RTLIL::Wire *input_sig = createWireIfNotExists(module, nodeID); + cell->setPort(mapping_cell.ins.at(j), input_sig); + } + } + } + else if (c == 'r') { // 'r'egister classes uint32_t dataSize = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_debug("flopNum = %u\n", flopNum); @@ -470,7 +550,7 @@ void AigerReader::parse_xaiger() for (unsigned i = 0; i < flopNum; i++) mergeability.emplace_back(parse_xaiger_literal(f)); } - else if (c == 's') { + else if (c == 's') { // register initial 's'tates uint32_t dataSize = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); @@ -478,13 +558,13 @@ void AigerReader::parse_xaiger() for (unsigned i = 0; i < flopNum; i++) initial_state.emplace_back(parse_xaiger_literal(f)); } - else if (c == 'n') { + else if (c == 'n') { // 'n'ame parse_xaiger_literal(f); f >> s; log_debug("n: '%s'\n", s); } - else if (c == 'h') { - f.ignore(sizeof(uint32_t)); + else if (c == 'h') { // 'h'ierarchy information + f.ignore(sizeof(uint32_t)); // length uint32_t version = parse_xaiger_literal(f); log_assert(version == 1); uint32_t ciNum = parse_xaiger_literal(f); @@ -510,7 +590,7 @@ void AigerReader::parse_xaiger() boxes.emplace_back(cell); } } - else if (c == 'a' || c == 'i' || c == 'o' || c == 's') { + else if (c == 'a' /* 'a'dditional AIG */ || c == 'i' /* 'i'nput arrival times */ || c == 'o' /* 'o'utput required times */) { uint32_t dataSize = parse_xaiger_literal(f); f.ignore(dataSize); log_debug("ignoring '%c'\n", c); @@ -634,7 +714,7 @@ void AigerReader::parse_aiger_ascii() log_error("Line %u cannot be interpreted as an AND!\n", line_count); std::getline(f, line); // Ignore up to start of next line - log_debug2("%d %d %d is an AND\n", l1, l2, l3); + log_debug("%d %d %d is an AND\n", l1, l2, l3); log_assert(!(l1 & 1)); RTLIL::Wire *o_wire = createWireIfNotExists(module, l1); RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2); diff --git a/frontends/aiger2/xaiger.cc b/frontends/aiger2/xaiger.cc index a62c52169..6cb15350f 100644 --- a/frontends/aiger2/xaiger.cc +++ b/frontends/aiger2/xaiger.cc @@ -187,7 +187,7 @@ struct Xaiger2Frontend : public Frontend { if (c == 'h') { uint32_t len, ci_num, co_num, pi_num, po_num, no_boxes; len = read_be32(*f); - read_be32(*f); + read_be32(*f); // version ci_num = read_be32(*f); co_num = read_be32(*f); pi_num = read_be32(*f); diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 0a312fb77..09fb0dd5b 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -193,8 +193,10 @@ 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_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.c_str(), tmpdir.c_str())); + run(stringf("abc9_ops -reintegrate")); if (!help_mode && mod->has_attribute(ID(abc9_script))) { if (script_save.empty()) active_design->scratchpad_unset("abc9.script"); diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc index f7cdcbd12..2a5ae7464 100644 --- a/techlibs/gatemate/synth_gatemate.cc +++ b/techlibs/gatemate/synth_gatemate.cc @@ -323,7 +323,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)"); }