3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-09-20 16:34:51 +00:00

abc_new: Hide buffered 'z drivers from read/write_xaiger2

With the updated bufnorm code, buffered 'z drivers are used as anchor
points for undirected connections. These are currently not supported by
read/write_xaiger2, so we temporarily replace those by roughly
equivalent $tribuf cells which will be handled as blackboxes that
properly roundtrip through the xaiger2 front and backend.
This commit is contained in:
Jannis Harder 2025-09-16 13:40:12 +02:00
parent 47b3ee8c8b
commit 4f239b536b
2 changed files with 83 additions and 1 deletions

View file

@ -1566,6 +1566,70 @@ clone_lut:
design->remove(mapped_mod);
}
static void replace_zbufs(Design *design)
{
design->bufNormalize(true);
std::vector<Cell *> 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<Cell *> 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)

View file

@ -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())