diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 9a9f7dcb5..ecba519bf 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -1566,6 +1566,70 @@ clone_lut: design->remove(mapped_mod); } + +static void replace_zbufs(Design *design) +{ + design->bufNormalize(true); + std::vector zbufs; + + for (auto mod : design->modules()) { + zbufs.clear(); + for (auto cell : mod->cells()) { + if (cell->type != ID($buf)) + continue; + auto &sig = cell->getPort(ID::A); + for (int i = 0; i < GetSize(sig); ++i) { + if (sig[i] == State::Sz) { + zbufs.push_back(cell); + break; + } + } + } + + for (auto cell : zbufs) { + auto sig = cell->getPort(ID::A); + for (int i = 0; i < GetSize(sig); ++i) { + if (sig[i] == State::Sz) { + Wire *w = mod->addWire(NEW_ID); + Cell *ud = mod->addCell(NEW_ID, ID($tribuf)); + ud->set_bool_attribute(ID(aiger2_zbuf)); + ud->setParam(ID::WIDTH, 1); + ud->setPort(ID::Y, w); + ud->setPort(ID::EN, State::S0); + ud->setPort(ID::A, State::S0); + sig[i] = w; + } + } + log("XXX %s -> %s\n", log_signal(cell->getPort(ID::A)), log_signal(sig)); + cell->setPort(ID::A, sig); + } + + mod->bufNormalize(); + } +} + + + +static void restore_zbufs(Design *design) +{ + std::vector to_remove; + + for (auto mod : design->modules()) { + to_remove.clear(); + for (auto cell : mod->cells()) + if (cell->type == ID($tribuf) && cell->has_attribute(ID(aiger2_zbuf))) + to_remove.push_back(cell); + + for (auto cell : to_remove) { + SigSpec sig_y = cell->getPort(ID::Y); + mod->addBuf(NEW_ID, Const(State::Sz, GetSize(sig_y)), sig_y); + mod->remove(cell); + } + mod->bufNormalize(); + } +} + + struct Abc9OpsPass : public Pass { Abc9OpsPass() : Pass("abc9_ops", "helper functions for ABC9") { } void help() override @@ -1668,6 +1732,8 @@ struct Abc9OpsPass : public Pass { bool prep_lut_mode = false; bool prep_box_mode = false; bool reintegrate_mode = false; + bool replace_zbufs_mode = false; + bool restore_zbufs_mode = false; bool dff_mode = false; std::string write_lut_dst; int maxlut = 0; @@ -1754,16 +1820,30 @@ struct Abc9OpsPass : public Pass { dff_mode = true; continue; } + if (arg == "-replace_zbufs") { + replace_zbufs_mode = true; + valid = true; + continue; + } + if (arg == "-restore_zbufs") { + restore_zbufs_mode = true; + valid = true; + continue; + } break; } extra_args(args, argidx, design); if (!valid) - log_cmd_error("At least one of -check, -break_scc, -prep_{delays,xaiger,dff[123],lut,box}, -write_{lut,box}, -reintegrate must be specified.\n"); + log_cmd_error("At least one of -check, -break_scc, -prep_{delays,xaiger,dff[123],lut,box}, -write_{lut,box}, -reintegrate, -{replace,restore}_zbufs must be specified.\n"); if (dff_mode && !check_mode && !prep_hier_mode && !prep_delays_mode && !prep_xaiger_mode && !reintegrate_mode) log_cmd_error("'-dff' option is only relevant for -prep_{hier,delay,xaiger} or -reintegrate.\n"); + if (replace_zbufs_mode) + replace_zbufs(design); + if (restore_zbufs_mode) + restore_zbufs(design); if (check_mode) check(design, dff_mode); if (prep_hier_mode) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 286ab4d5b..c48295916 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -169,10 +169,12 @@ struct AbcNewPass : public ScriptPass { } run(stringf(" abc9_ops -write_box %s/input.box", tmpdir)); + run(" abc9_ops -replace_zbufs"); 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(" abc9_ops -restore_zbufs"); if (!help_mode && mod->has_attribute(ID(abc9_script))) { if (script_save.empty())