abc9: break SCC by setting (* keep *) on output wires
authorEddie Hung <eddie@fpgeh.com>
Tue, 14 Jan 2020 05:45:27 +0000 (21:45 -0800)
committerEddie Hung <eddie@fpgeh.com>
Tue, 14 Jan 2020 05:45:27 +0000 (21:45 -0800)
backends/aiger/xaiger.cc
frontends/aiger/aigerparse.cc
passes/techmap/abc9.cc
passes/techmap/abc9_ops.cc

index ed0e48e010339b1a2a80ab45a149563fdf4d72b6..8651f3a0116c7bf55fb795f987e149f5f43dbc6f 100644 (file)
@@ -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);
index b4304a581c91d73466f50123133f531175074086..f4decaf25142973900b3c176dd712e6cc1bb9cbb 100644 (file)
@@ -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));
                                }
index 2627ab9cad489b1f35d8df55055fdaaaea0d40fa..dad40be635eb5fd28d4fd5693c7f7de59fbb1dcd 100644 (file)
@@ -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
index 9cc58c99d896c2e01078d9896f0f6c73b7fbe585..4da10d94b612c379d04eaaf295c815c6ca870955 100644 (file)
@@ -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 {