WIP
authorEddie Hung <eddie@fpgeh.com>
Fri, 12 Apr 2019 21:13:11 +0000 (14:13 -0700)
committerEddie Hung <eddie@fpgeh.com>
Fri, 12 Apr 2019 21:13:11 +0000 (14:13 -0700)
backends/aiger/xaiger.cc

index bad9322bb40d188dd7c7dcb506f43cf027eac7aa..ce10028f7ea1a280f4b86991c38f668e632e754a 100644 (file)
@@ -61,6 +61,8 @@ struct XAigerWriter
        dict<SigBit, int> init_inputs;
        int initstate_ff = 0;
 
+       vector<Cell*> box_list;
+
        int mkgate(int a0, int a1)
        {
                aig_m++, aig_a++;
@@ -211,7 +213,7 @@ struct XAigerWriter
                        }
 
                        for (const auto &c : cell->connections()) {
-                               if (c.second.is_fully_const()) continue;
+                               /*if (c.second.is_fully_const()) continue;*/
                                for (auto b : c.second.bits()) {
                                        Wire *w = b.wire;
                                        if (!w) continue;
@@ -219,30 +221,32 @@ struct XAigerWriter
                                        auto is_output = cell->output(c.first);
                                        log_assert(is_input || is_output);
                                        if (is_input) {
-                                               if (!w->port_input) {
+                                               /*if (!w->port_input)*/ {
                                                        SigBit I = sigmap(b);
                                                        if (I != b)
                                                                alias_map[b] = I;
-                                                       if (!output_bits.count(b))
+                                                       /*if (!output_bits.count(b))*/
                                                                co_bits.insert(b);
                                                }
                                        }
                                        if (is_output) {
                                                SigBit O = sigmap(b);
-                                               if (!input_bits.count(O))
+                                               /*if (!input_bits.count(O))*/
                                                        ci_bits.insert(O);
                                        }
                                }
                                if (!type_map.count(cell->type))
                                        type_map[cell->type] = type_map.size()+1;
                        }
-                       //log_error("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
+
+                       box_list.emplace_back(cell);
+                       log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
                }
 
                for (auto bit : input_bits) {
                        RTLIL::Wire *wire = bit.wire;
                        // If encountering an inout port, then create a new wire with $inout.out
-                       // suffix, make it a CO driven by the existing inout, and inherit existing
+                       // suffix, make it a PO driven by the existing inout, and inherit existing
                        // inout's drivers
                        if (wire->port_input && wire->port_output && !undriven_bits.count(bit)) {
                                RTLIL::Wire *new_wire = module->wire(wire->name.str() + "$inout.out");
@@ -256,19 +260,19 @@ struct XAigerWriter
                                        and_map[new_bit] = and_map.at(bit);
                                else if (alias_map.count(bit))
                                        alias_map[new_bit] = alias_map.at(bit);
-                               co_bits.insert(new_bit);
+                               output_bits.insert(new_bit);
                        }
                }
 
                // Do some CI/CO post-processing:
                // Erase all POs and COs that are undriven
                for (auto bit : undriven_bits) {
-                       co_bits.erase(bit);
+                       //co_bits.erase(bit);
                        output_bits.erase(bit);
                }
                // Erase all CIs that are also COs
-               for (auto bit : co_bits)
-                       ci_bits.erase(bit);
+               //for (auto bit : co_bits)
+               //      ci_bits.erase(bit);
                // CIs cannot be undriven
                for (auto bit : ci_bits)
                        undriven_bits.erase(bit);
@@ -491,7 +495,8 @@ struct XAigerWriter
 
                                        if (output_bits.count(b) || co_bits.count(b)) {
                                                int o = ordered_outputs.at(b);
-                                               output_seen = !miter_mode;
+                                               if (output_seen && output_bits.count(b))
+                                                       output_seen = !miter_mode;
                                                if (GetSize(wire) != 1)
                                                        symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s[%d]", log_id(wire), i));
                                                else
@@ -532,7 +537,52 @@ struct XAigerWriter
                        }
                }
 
-               f << stringf("c\nGenerated by %s\n", yosys_version_str);
+               f << "c";
+
+               std::stringstream h_buffer;
+               auto write_h_buffer = [&h_buffer](int i32) {
+                       // TODO: Don't assume we're on little endian
+#ifdef _WIN32
+                       int i32_be = _byteswap_ulong(i32);
+#else
+                       int i32_be = __builtin_bswap32(i32);
+#endif
+                       h_buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be));
+               };
+               int num_outputs = output_bits.size();
+               if (omode && num_outputs == 0)
+                       num_outputs = 1;
+               write_h_buffer(1);
+               write_h_buffer(input_bits.size() + ci_bits.size());
+               write_h_buffer(num_outputs + co_bits.size());
+               write_h_buffer(input_bits.size());
+               write_h_buffer(num_outputs);
+               write_h_buffer(box_list.size());
+               int box_id = 0;
+               for (auto cell : box_list) {
+                       int box_inputs = 0, box_outputs = 0;
+                       for (const auto &c : cell->connections())
+                               if (cell->input(c.first))
+                                       box_inputs += c.second.size();
+                               else
+                                       box_outputs += c.second.size();
+                       write_h_buffer(box_inputs);
+                       write_h_buffer(box_outputs);
+                       write_h_buffer(box_id++);
+                       write_h_buffer(0 /* OldBoxNum */);
+               }
+               std::string h_buffer_str = h_buffer.str();
+               // TODO: Don't assume we're on little endian
+#ifdef _WIN32
+               int h_buffer_size_be = _byteswap_ulong(h_buffer_str.size());
+#else
+               int h_buffer_size_be = __builtin_bswap32(h_buffer_str.size());
+#endif
+               f << "h";
+               f.write(reinterpret_cast<const char*>(&h_buffer_size_be), sizeof(h_buffer_size_be));
+               f.write(h_buffer_str.data(), h_buffer_str.size());
+
+               f << stringf("Generated by %s\n", yosys_version_str);
        }
 
        void write_map(std::ostream &f, bool verbose_map, bool omode)
@@ -557,7 +607,11 @@ struct XAigerWriter
                                        int a = aig_map.at(sig[i]);
                                        log_assert((a & 1) == 0);
                                        input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, i, log_id(wire));
-                                       continue;
+
+                                       // Only continue if this input is not a CO,
+                                       // otherwise write as CO below
+                                       if (!co_bits.count(b))
+                                               continue;
                                }
 
                                if (output_bits.count(b) || co_bits.count(b)) {
@@ -606,7 +660,7 @@ struct XAigerWriter
                        f << it.second;
                log_assert(output_lines.size() == output_bits.size() + co_bits.size());
                if (omode && output_lines.empty())
-                       f << "output 0 0 __dummy_o__\n";
+                       f << "output " << output_lines.size() << " 0 __dummy_o__\n";
 
                latch_lines.sort();
                for (auto &it : latch_lines)