From 7d96a7f73c63c02921f00149ebc1dc37fa38e722 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Sun, 1 Mar 2026 22:35:06 -0800 Subject: [PATCH] Update aigmap to go a lot faster using aig template cache and uniquify cache --- kernel/rtlil.cc | 2 +- kernel/rtlil.h | 1 + passes/techmap/aigmap.cc | 52 +++++++++++++++++++++++++++++++--------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 40a1dd2f8..266aedfe0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3151,7 +3151,7 @@ void RTLIL::Module::swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2) RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name) { - int index = 0; + int &index = uniquify_cache_[name]; return uniquify(name, index); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ef9a077f3..9dfe0c570 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -2168,6 +2168,7 @@ public: void swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2); void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2); + dict uniquify_cache_; RTLIL::IdString uniquify(RTLIL::IdString name); RTLIL::IdString uniquify(RTLIL::IdString name, int &index); diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 0932562e4..269df6db9 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -72,16 +72,46 @@ struct AigmapPass : public Pass { dict stat_not_replaced; int orig_num_cells = GetSize(module->cells()); + dict aig_cache; + pool new_sel; for (auto cell : module->selected_cells()) { - Aig aig(cell); + if (cell->type.in(ID($_AND_), ID($_NOT_))) { + not_replaced_count++; + stat_not_replaced[cell->type]++; + if (select_mode) + new_sel.insert(cell->name); + continue; + } - if (cell->type.in(ID($_AND_), ID($_NOT_))) - aig.name.clear(); + if (nand_mode && cell->type == ID($_NAND_)) { + not_replaced_count++; + stat_not_replaced[cell->type]++; + if (select_mode) + new_sel.insert(cell->name); + continue; + } - if (nand_mode && cell->type == ID($_NAND_)) - aig.name.clear(); + if (cell->type[0] != '$') { + not_replaced_count++; + stat_not_replaced[cell->type]++; + if (select_mode) + new_sel.insert(cell->name); + continue; + } + + std::string cache_key = cell->type.str(); + cell->parameters.sort(); + for (auto &p : cell->parameters) + cache_key += stringf(":%s=%s", p.first.c_str(), p.second.as_string().c_str()); + + auto cache_it = aig_cache.find(cache_key); + if (cache_it == aig_cache.end()) { + auto r = aig_cache.insert(std::make_pair(cache_key, Aig(cell))); + cache_it = r.first; + } + const Aig &aig = cache_it->second; if (aig.name.empty()) { not_replaced_count++; @@ -110,8 +140,8 @@ struct AigmapPass : public Pass { if (nand_mode && node.inverter) { bit = module->addWire(NEW_ID2_SUFFIX("bit")); auto gate = module->addNandGate(NEW_ID2_SUFFIX("nand"), A, B, bit); - for (auto attr : cell->attributes) - gate->attributes[attr.first] = attr.second; + for (const auto &attr : cell->attributes) + gate->attributes[attr.first] = attr.second; if (select_mode) new_sel.insert(gate->name); @@ -123,8 +153,8 @@ struct AigmapPass : public Pass { else { bit = module->addWire(NEW_ID2_SUFFIX("bit")); auto gate = module->addAndGate(NEW_ID2_SUFFIX("and"), A, B, bit); - for (auto attr : cell->attributes) - gate->attributes[attr.first] = attr.second; + for (const auto &attr : cell->attributes) + gate->attributes[attr.first] = attr.second; if (select_mode) new_sel.insert(gate->name); } @@ -134,8 +164,8 @@ struct AigmapPass : public Pass { if (node.inverter) { SigBit new_bit = module->addWire(NEW_ID2_SUFFIX("new_bit")); auto gate = module->addNotGate(NEW_ID2_SUFFIX("inv"), bit, new_bit); - for (auto attr : cell->attributes) - gate->attributes[attr.first] = attr.second; + for (const auto &attr : cell->attributes) + gate->attributes[attr.first] = attr.second; bit = new_bit; if (select_mode) new_sel.insert(gate->name);