diff options
Diffstat (limited to 'backends/aiger/xaiger.cc')
-rw-r--r-- | backends/aiger/xaiger.cc | 93 |
1 files changed, 54 insertions, 39 deletions
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index b72dd6890..cde6d066a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -47,6 +47,7 @@ inline static uint32_t bswap32(uint32_t x) #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/utils.h" +#include "kernel/timinginfo.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -173,20 +174,21 @@ struct XAigerWriter undriven_bits.insert(bit); unused_bits.insert(bit); - bool keep = wire->get_bool_attribute(ID::keep); - if (wire->port_input || keep) + bool scc = wire->attributes.count(ID(abc9_scc)); + if (wire->port_input || scc) input_bits.insert(bit); - if (wire->port_output || keep) { + bool keep = wire->get_bool_attribute(ID::keep); + if (wire->port_output || keep || scc) { if (bit != wirebit) alias_map[wirebit] = bit; output_bits.insert(wirebit); } } - dict<IdString,dict<IdString,int>> arrival_cache; + TimingInfo timing; + for (auto cell : module->cells()) { - RTLIL::Module* inst_module = module->design->module(cell->type); if (!cell->has_keep_attr()) { if (cell->type == "$_NOT_") { @@ -222,13 +224,21 @@ struct XAigerWriter alias_map[Q] = D; auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); log_assert(r.second); - if (input_bits.erase(Q)) - log_assert(Q.wire->attributes.count(ID::keep)); continue; } - if (inst_module) { - bool abc9_flop = false; + if (cell->type.in("$specify2", "$specify3", "$specrule")) + continue; + } + + RTLIL::Module* inst_module = module->design->module(cell->type); + if (inst_module) { + IdString derived_type = inst_module->derive(module->design, cell->parameters); + inst_module = module->design->module(derived_type); + log_assert(inst_module); + + bool abc9_flop = false; + if (!cell->has_keep_attr()) { auto it = cell->attributes.find("\\abc9_box_seq"); if (it != cell->attributes.end()) { int abc9_box_seq = it->second.as_int(); @@ -236,34 +246,39 @@ struct XAigerWriter box_list.resize(abc9_box_seq+1); box_list[abc9_box_seq] = cell; // Only flop boxes may have arrival times + // (all others are combinatorial) abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); if (!abc9_flop) continue; } + } + + if (!timing.count(derived_type)) + timing.setup_module(inst_module); + auto &t = timing.at(derived_type).arrival; + for (const auto &conn : cell->connections()) { + auto port_wire = inst_module->wire(conn.first); + if (!port_wire->port_output) + continue; + + for (int i = 0; i < GetSize(conn.second); i++) { + auto d = t.at(TimingInfo::NameBit(conn.first,i), 0); + if (d == 0) + continue; - auto &cell_arrivals = arrival_cache[cell->type]; - for (const auto &conn : cell->connections()) { - auto r = cell_arrivals.insert(conn.first); - auto &arrival = r.first->second; - if (r.second) { - auto port_wire = inst_module->wire(conn.first); - if (port_wire->port_output) { - auto it = port_wire->attributes.find("\\abc9_arrival"); - if (it != port_wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type)); - arrival = it->second.as_int(); - } - } +#ifndef NDEBUG + if (ys_debug(1)) { + static std::set<std::tuple<IdString,IdString,int>> seen; + if (seen.emplace(derived_type, conn.first, i).second) log("%s.%s[%d] abc9_arrival = %d\n", + log_id(cell->type), log_id(conn.first), i, d); } - if (arrival) - for (auto bit : sigmap(conn.second)) - arrival_times[bit] = arrival; +#endif + arrival_times[conn.second[i]] = d; } - - if (abc9_flop) - continue; } + + if (abc9_flop) + continue; } bool cell_known = inst_module || cell->known(); @@ -300,7 +315,7 @@ struct XAigerWriter RTLIL::Module* box_module = module->design->module(cell->type); log_assert(box_module); - log_assert(box_module->attributes.count("\\abc9_box_id")); + log_assert(box_module->attributes.count("\\abc9_box_id") || box_module->get_bool_attribute("\\abc9_flop")); auto r = box_ports.insert(cell->type); if (r.second) { @@ -362,11 +377,6 @@ struct XAigerWriter alias_map[O] = b; ci_bits.emplace_back(b); undriven_bits.erase(O); - // If PI and CI, then must be a (* keep *) wire - if (input_bits.erase(O)) { - log_assert(output_bits.count(O)); - log_assert(O.wire->get_bool_attribute(ID::keep)); - } } } @@ -451,8 +461,8 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; int aig; - // Unlike bit2aig() which checks aig_map first, for - // inout/keep bits, since aig_map will point to + // Unlike bit2aig() which checks aig_map first for + // inout/scc 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) @@ -579,7 +589,11 @@ struct XAigerWriter RTLIL::Module* box_module = module->design->module(cell->type); log_assert(box_module); - auto r = cell_cache.insert(cell->type); + IdString derived_type = box_module->derive(box_module->design, cell->parameters); + box_module = box_module->design->module(derived_type); + log_assert(box_module); + + auto r = cell_cache.insert(derived_type); auto &v = r.first->second; if (r.second) { int box_inputs = 0, box_outputs = 0; @@ -625,7 +639,7 @@ struct XAigerWriter log_assert(mergeability > 0); write_r_buffer(mergeability); - Const init = cell->attributes.at(ID(abc9_init)); + Const init = cell->attributes.at(ID(abc9_init), State::Sx); log_assert(GetSize(init) == 1); if (init == State::S1) write_s_buffer(1); @@ -636,6 +650,7 @@ struct XAigerWriter write_s_buffer(0); } + // Use arrival time from output of flop box write_i_buffer(arrival_times.at(d, 0)); //write_o_buffer(0); } |