From: Eddie Hung Date: Tue, 14 Jan 2020 05:45:27 +0000 (-0800) Subject: abc9: break SCC by setting (* keep *) on output wires X-Git-Tag: working-ls180~849^2~30 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2c65e1abacc4401c4fd3e9b48f52c4de120bc511;p=yosys.git abc9: break SCC by setting (* keep *) on output wires --- diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ed0e48e01..8651f3a01 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -436,15 +436,22 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; int aig; - // For inout/keep bits only, the output bit - // should be driven by logic, not the PI, - // so temporarily swap that out + // Unlike bit2aig() which checks aig_map first, for + // inout/keep bits, since aig_map will point to + // the PI, first attempt to find the NOT/AND driver + // before resorting to an aig_map lookup (which + // could be another PO) if (input_bits.count(bit)) { - auto it = aig_map.find(bit); - int input_aig = it->second; - aig_map.erase(it); - aig = bit2aig(bit); - aig_map.at(bit) = input_aig; + if (not_map.count(bit)) { + aig = bit2aig(not_map.at(bit)) ^ 1; + } else if (and_map.count(bit)) { + auto args = and_map.at(bit); + int a0 = bit2aig(args.first); + int a1 = bit2aig(args.second); + aig = mkgate(a0, a1); + } + else + aig = aig_map.at(bit); } else aig = bit2aig(bit); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index b4304a581..f4decaf25 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -831,6 +831,7 @@ void AigerReader::post_process() } else { wire->port_output = false; + existing->port_output = true; module->connect(wire, existing); wire = existing; } @@ -845,8 +846,9 @@ void AigerReader::post_process() wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index); } else { - module->connect(wire, existing); wire->port_output = false; + existing->port_output = true; + module->connect(wire, existing); } log_debug(" -> %s\n", log_id(indexed_name)); } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2627ab9ca..dad40be63 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -298,7 +298,7 @@ struct Abc9Pass : public ScriptPass num_outputs); if (num_outputs) { run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str())); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str())); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str())); run("abc9_ops -reintegrate"); } else diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 9cc58c99d..4da10d94b 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -53,30 +53,7 @@ void break_scc(RTLIL::Module *module) if (cell->output(c.first)) { SigBit b = c.second.as_bit(); Wire *w = b.wire; - if (w->port_input) { - // In this case, hopefully the loop break has been already created - // Get the non-prefixed wire - Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); - log_assert(wo != nullptr); - log_assert(wo->port_output); - log_assert(b.offset < GetSize(wo)); - c.second = RTLIL::SigBit(wo, b.offset); - } - else { - // Create a new output/input loop break - w->port_input = true; - w = module->wire(stringf("%s.abco", w->name.c_str())); - if (!w) { - w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); - w->port_output = true; - } - else { - log_assert(w->port_input); - log_assert(b.offset < GetSize(w)); - } - w->set_bool_attribute(ID(abc9_scc_break)); - c.second = RTLIL::SigBit(w, b.offset); - } + w->set_bool_attribute(ID::keep); } } } @@ -586,7 +563,9 @@ void reintegrate(RTLIL::Module *module) } if (cell->output(mapped_conn.first)) for (auto i : mapped_conn.second) - bit_drivers[i].insert(mapped_cell->name); + // Ignore inouts for topo ordering + if (i.wire && !(i.wire->port_input && i.wire->port_output)) + bit_drivers[i].insert(mapped_cell->name); } } else {