diff options
author | Eddie Hung <eddie@fpgeh.com> | 2019-05-31 13:03:03 -0700 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2019-05-31 13:03:03 -0700 |
commit | eb08e71bd10004cb37c3ceab37607866d9240630 (patch) | |
tree | 21754a7525d42c3662d081c7d9b995d731fae00f /backends | |
parent | a379234f56753c3d72a6966c380ac6f83fde789c (diff) | |
parent | ac2aff9e28a087a9a2697cd6ccf754af738903a7 (diff) | |
download | yosys-eb08e71bd10004cb37c3ceab37607866d9240630.tar.gz yosys-eb08e71bd10004cb37c3ceab37607866d9240630.tar.bz2 yosys-eb08e71bd10004cb37c3ceab37607866d9240630.zip |
Merge branch 'xaig' into xc7mux
Diffstat (limited to 'backends')
-rw-r--r-- | backends/aiger/xaiger.cc | 87 |
1 files changed, 79 insertions, 8 deletions
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index cd15b6160..7a139f68f 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -51,6 +51,7 @@ struct XAigerWriter //pool<SigBit> initstate_bits; vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits; vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits; + vector<std::pair<SigBit,SigBit>> ff_bits; vector<pair<int, int>> aig_gates; vector<int> aig_latchin, aig_latchinit, aig_outputs; @@ -180,6 +181,7 @@ struct XAigerWriter for (auto cell : module->cells()) { RTLIL::Module* inst_module = module->design->module(cell->type); + bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false; bool known_type = yosys_celltypes.cell_known(cell->type); if (!holes_mode) { @@ -256,7 +258,32 @@ struct XAigerWriter // continue; //} - if (inst_module && inst_module->attributes.count("\\abc_box_id")) { + if (inst_flop) { + SigBit d, q; + for (const auto &c : cell->connections()) { + for (auto b : c.second.bits()) { + auto is_input = cell->input(c.first); + auto is_output = cell->output(c.first); + log_assert(is_input || is_output); + if (is_input && inst_module->wire(c.first)->attributes.count("\\abc_flop_d")) { + SigBit I = sigmap(b); + if (I != b) + alias_map[b] = I; + d = b; + } + if (is_output && inst_module->wire(c.first)->attributes.count("\\abc_flop_q")) { + SigBit O = sigmap(b); + q = O; + } + } + } + if (!abc_box_seen) + abc_box_seen = inst_module->attributes.count("\\abc_box_id"); + + ff_bits.emplace_back(d, q); + undriven_bits.erase(q); + } + else if (inst_module && inst_module->attributes.count("\\abc_box_id")) { abc_box_seen = true; } else { @@ -479,11 +506,22 @@ struct XAigerWriter aig_map[bit] = 2*aig_m; } + for (auto &f : ff_bits) { + auto bit = f.second; + aig_m++, aig_i++; + aig_map[bit] = 2*aig_m; + } + + dict<SigBit, int> ff_aig_map; for (auto &c : ci_bits) { RTLIL::SigBit bit = std::get<0>(c); aig_m++, aig_i++; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; + //auto r = aig_map.insert(std::make_pair(c.first, c.second)); + //if (!r.second) { + // ff_aig_map[std::get<0>(c)] = 2*aig_m; + //} } if (imode && input_bits.empty()) { @@ -557,6 +595,11 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } + for (auto &f : ff_bits) { + aig_o++; + aig_outputs.push_back(ff_aig_map.at(f.second)); + } + if (omode && output_bits.empty()) { aig_o++; aig_outputs.push_back(0); @@ -714,7 +757,7 @@ struct XAigerWriter f << "c"; - if (!box_list.empty()) { + if (!box_list.empty() || !ff_bits.empty()) { std::stringstream h_buffer; auto write_h_buffer = [&h_buffer](int i32) { // TODO: Don't assume we're on little endian @@ -729,12 +772,12 @@ struct XAigerWriter if (omode && num_outputs == 0) num_outputs = 1; write_h_buffer(1); - log_debug("ciNum = %zu\n", input_bits.size() + ci_bits.size()); - write_h_buffer(input_bits.size() + ci_bits.size()); - log_debug("coNum = %zu\n", num_outputs + co_bits.size()); - write_h_buffer(num_outputs + co_bits.size()); - log_debug("piNum = %zu\n", input_bits.size()); - write_h_buffer(input_bits.size()); + log_debug("ciNum = %zu\n", input_bits.size() + ff_bits.size() + ci_bits.size()); + write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size()); + log_debug("coNum = %zu\n", num_outputs + ff_bits.size() + co_bits.size()); + write_h_buffer(num_outputs + ff_bits.size()+ co_bits.size()); + log_debug("piNum = %zu\n", input_bits.size() + ff_bits.size()); + write_h_buffer(input_bits.size()+ ff_bits.size()); log_debug("poNum = %d\n", num_outputs); write_h_buffer(num_outputs); log_debug("boxNum = %zu\n", box_list.size()); @@ -813,6 +856,34 @@ struct XAigerWriter f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + if (!ff_bits.empty()) { + std::stringstream r_buffer; + auto write_r_buffer = [&r_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 + r_buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be)); + }; + write_r_buffer(ff_bits.size()); + int mergeability_class = 1; + for (auto cell : ff_bits) + write_r_buffer(mergeability_class++); + + f << "r"; + std::string buffer_str = r_buffer.str(); + // TODO: Don't assume we're on little endian +#ifdef _WIN32 + int buffer_size_be = _byteswap_ulong(buffer_str.size()); +#else + int buffer_size_be = __builtin_bswap32(buffer_str.size()); +#endif + f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + } + if (holes_module) { // NB: fixup_ports() will sort ports by name //holes_module->fixup_ports(); |