From c7483917307bd1c281b159fe15f0f79af4e305b3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Apr 2019 14:13:11 -0700 Subject: WIP --- backends/aiger/xaiger.cc | 82 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 14 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index bad9322bb..ce10028f7 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -61,6 +61,8 @@ struct XAigerWriter dict init_inputs; int initstate_ff = 0; + vector 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(&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(&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) -- cgit v1.2.3 From 686e772f0bb3129e7d6469dc25548497f107ebc5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Apr 2019 16:17:48 -0700 Subject: ci_bits and co_bits now a list, order is important for ABC --- backends/aiger/xaiger.cc | 58 ++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 24 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ce10028f7..f67f7620b 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -47,7 +47,7 @@ struct XAigerWriter dict not_map, ff_map, alias_map; dict> and_map; pool initstate_bits; - pool ci_bits, co_bits; + vector> ci_bits, co_bits; dict type_map; vector> aig_gates; @@ -226,13 +226,13 @@ struct XAigerWriter if (I != b) alias_map[b] = I; /*if (!output_bits.count(b))*/ - co_bits.insert(b); + co_bits.emplace_back(b, 0); } } if (is_output) { SigBit O = sigmap(b); /*if (!input_bits.count(O))*/ - ci_bits.insert(O); + ci_bits.emplace_back(O, 0); } } if (!type_map.count(cell->type)) @@ -240,7 +240,7 @@ struct XAigerWriter } box_list.emplace_back(cell); - log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); + //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } for (auto bit : input_bits) { @@ -274,8 +274,8 @@ struct XAigerWriter //for (auto bit : co_bits) // ci_bits.erase(bit); // CIs cannot be undriven - for (auto bit : ci_bits) - undriven_bits.erase(bit); + for (const auto &c : ci_bits) + undriven_bits.erase(c.first); for (auto bit : unused_bits) undriven_bits.erase(bit); @@ -299,9 +299,10 @@ struct XAigerWriter aig_map[State::S0] = 0; aig_map[State::S1] = 1; - for (auto bit : ci_bits) { + for (auto &c : ci_bits) { aig_m++, aig_i++; - aig_map[bit] = 2*aig_m; + c.second = 2*aig_m; + aig_map[c.first] = c.second; } for (auto bit : input_bits) { @@ -369,15 +370,15 @@ struct XAigerWriter if (!initstate_bits.empty() || !init_inputs.empty()) aig_latchin.push_back(1); - for (auto bit : co_bits) { - aig_o++; - ordered_outputs[bit] = aig_o-1; + for (auto &c : co_bits) { + RTLIL::SigBit bit = c.first; + c.second = aig_o++; + ordered_outputs[bit] = c.second; aig_outputs.push_back(bit2aig(bit)); } for (auto bit : output_bits) { - aig_o++; - ordered_outputs[bit] = aig_o-1; + ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } @@ -484,7 +485,7 @@ struct XAigerWriter for (int i = 0; i < GetSize(wire); i++) { RTLIL::SigBit b(wire, i); - if (input_bits.count(b) || ci_bits.count(b)) { + if (input_bits.count(b)) { int a = aig_map.at(sig[i]); log_assert((a & 1) == 0); if (GetSize(wire) != 1) @@ -493,10 +494,9 @@ struct XAigerWriter symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s", log_id(wire))); } - if (output_bits.count(b) || co_bits.count(b)) { + if (output_bits.count(b)) { int o = ordered_outputs.at(b); - if (output_seen && output_bits.count(b)) - output_seen = !miter_mode; + 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 @@ -603,18 +603,13 @@ struct XAigerWriter for (int i = 0; i < GetSize(wire); i++) { RTLIL::SigBit b(wire, i); - if (input_bits.count(b) || ci_bits.count(b)) { + if (input_bits.count(b)) { 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)); - - // 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)) { + if (output_bits.count(b)) { int o = ordered_outputs.at(b); output_lines[o] += stringf("output %d %d %s\n", o, i, log_id(wire)); continue; @@ -646,6 +641,21 @@ struct XAigerWriter } } + for (const auto &c : ci_bits) { + RTLIL::SigBit b = c.first; + RTLIL::Wire *wire = b.wire; + int i = b.offset; + int a = c.second; + log_assert((a & 1) == 0); + input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, i, log_id(wire)); + } + + for (const auto &c : co_bits) { + RTLIL::SigBit b = c.first; + int o = c.second; + output_lines[o] += stringf("output %d %d %s\n", o, b.offset, log_id(b.wire)); + } + input_lines.sort(); for (auto &it : input_lines) f << it.second; -- cgit v1.2.3 From fe0b421212a17dae32cd30a09dc43c688a285f8c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Apr 2019 18:16:25 -0700 Subject: Output __const0__ and __const1__ CIs --- backends/aiger/xaiger.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index f67f7620b..d3384e136 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -215,8 +215,6 @@ struct XAigerWriter for (const auto &c : cell->connections()) { /*if (c.second.is_fully_const()) continue;*/ for (auto b : c.second.bits()) { - Wire *w = b.wire; - if (!w) continue; auto is_input = cell->input(c.first); auto is_output = cell->output(c.first); log_assert(is_input || is_output); @@ -382,7 +380,7 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - if (omode && output_bits.empty() && co_bits.empty()) { + if (omode && output_bits.empty()) { aig_o++; aig_outputs.push_back(0); } @@ -561,11 +559,12 @@ struct XAigerWriter int box_id = 0; for (auto cell : box_list) { int box_inputs = 0, box_outputs = 0; - for (const auto &c : cell->connections()) + for (const auto &c : cell->connections()) { if (cell->input(c.first)) box_inputs += c.second.size(); - else + if (cell->output(c.first)) box_outputs += c.second.size(); + } write_h_buffer(box_inputs); write_h_buffer(box_outputs); write_h_buffer(box_id++); @@ -652,8 +651,12 @@ struct XAigerWriter for (const auto &c : co_bits) { RTLIL::SigBit b = c.first; + RTLIL::Wire *wire = b.wire; int o = c.second; - output_lines[o] += stringf("output %d %d %s\n", o, b.offset, log_id(b.wire)); + if (wire) + output_lines[o] += stringf("output %d %d %s\n", o, b.offset, log_id(wire)); + else + output_lines[o] += stringf("output %d %d __const%d__\n", o, 0, b.data); } input_lines.sort(); @@ -669,7 +672,7 @@ struct XAigerWriter for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size() + co_bits.size()); - if (omode && output_lines.empty()) + if (omode && output_bits.empty()) f << "output " << output_lines.size() << " 0 __dummy_o__\n"; latch_lines.sort(); -- cgit v1.2.3