From ffa52738fba1264ef2eb37d5333babfa0758fe48 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Apr 2020 14:26:52 -0700 Subject: [PATCH] xaiger: output $_DFF_[NP]_ with mergeability if -dff option --- backends/aiger/xaiger.cc | 86 ++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 1fb7210cb..d014c4ec6 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -137,7 +137,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) + XAigerWriter(Module *module, bool dff_mode, bool holes_mode=false) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -212,10 +212,7 @@ struct XAigerWriter continue; } - if (cell->type == ID($__ABC9_FF_) && - // The presence of an abc9_mergeability attribute indicates - // that we do want to pass this flop to ABC - cell->attributes.count(ID::abc9_mergeability)) + if (dff_mode && cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) { SigBit D = sigmap(cell->getPort(ID::D).as_bit()); SigBit Q = sigmap(cell->getPort(ID::Q).as_bit()); @@ -233,7 +230,11 @@ struct XAigerWriter RTLIL::Module* inst_module = module->design->module(cell->type); if (inst_module) { - IdString derived_type = inst_module->derive(module->design, cell->parameters); + IdString derived_type; + if (cell->parameters.empty()) + derived_type = cell->type; + else + derived_type = inst_module->derive(module->design, cell->parameters); inst_module = module->design->module(derived_type); log_assert(inst_module); @@ -319,7 +320,7 @@ struct XAigerWriter RTLIL::Module* box_module = module->design->module(cell->type); log_assert(box_module); - log_assert(box_module->attributes.count(ID::abc9_box_id) || box_module->get_bool_attribute(ID::abc9_flop)); + log_assert(box_module->attributes.count(ID::abc9_box_id)); auto r = box_ports.insert(cell->type); if (r.second) { @@ -383,27 +384,6 @@ struct XAigerWriter undriven_bits.erase(O); } } - - // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box - if (box_module->get_bool_attribute(ID::abc9_flop)) { - SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str())); - if (rhs.empty()) - log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); - - for (auto b : rhs) { - SigBit I = sigmap(b); - if (b == RTLIL::Sx) - b = State::S0; - else if (I != b) { - if (I == RTLIL::Sx) - alias_map[b] = State::S0; - else - alias_map[b] = I; - } - co_bits.emplace_back(b); - unused_bits.erase(I); - } - } } for (auto bit : input_bits) @@ -593,7 +573,11 @@ struct XAigerWriter RTLIL::Module* box_module = module->design->module(cell->type); log_assert(box_module); - IdString derived_type = box_module->derive(box_module->design, cell->parameters); + IdString derived_type; + if (cell->parameters.empty()) + derived_type = cell->type; + else + derived_type = box_module->derive(module->design, cell->parameters); box_module = box_module->design->module(derived_type); log_assert(box_module); @@ -610,11 +594,6 @@ struct XAigerWriter box_outputs += GetSize(w); } - // For flops only, create an extra 1-bit input that drives a new wire - // called ".abc9_ff.Q" that is used below - if (box_module->get_bool_attribute(ID::abc9_flop)) - box_inputs++; - std::get<0>(v) = box_inputs; std::get<1>(v) = box_outputs; std::get<2>(v) = box_module->attributes.at(ID::abc9_box_id).as_int(); @@ -635,18 +614,34 @@ struct XAigerWriter auto write_s_buffer = std::bind(write_buffer, std::ref(s_buffer), std::placeholders::_1); write_s_buffer(ff_bits.size()); + dict clk_to_mergeability; + + bool nonzero_warned = false; for (const auto &i : ff_bits) { const SigBit &d = i.first; const Cell *cell = i.second; - int mergeability = cell->attributes.at(ID::abc9_mergeability).as_int(); + log_assert(cell->type.in(ID($_DFF_N_), ID($_DFF_P_))); + + SigBit clock = sigmap(cell->getPort(ID::C)); + auto r = clk_to_mergeability.insert(std::make_pair(clock, clk_to_mergeability.size() + 1)); + int mergeability = r.first->second; log_assert(mergeability > 0); - write_r_buffer(mergeability); + if (cell->type == ID($_DFF_N_)) + write_r_buffer(-mergeability); + else if (cell->type == ID($_DFF_P_)) + write_r_buffer(mergeability); + else log_abort(); Const init = cell->attributes.at(ID::abc9_init, State::Sx); log_assert(GetSize(init) == 1); - if (init == State::S1) + if (init == State::S1) { + if (!nonzero_warned) { + log_warning("Module '%s' contains $_DFF_[NP]_ cell with non-zero initial state -- unsupported by ABC9.\n", log_id(module)); + nonzero_warned = true; + } write_s_buffer(1); + } else if (init == State::S0) write_s_buffer(0); else { @@ -674,7 +669,7 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); if (holes_module) { std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); + XAigerWriter writer(holes_module, false /* dff_mode */, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); f << "a"; @@ -761,8 +756,8 @@ struct XAigerBackend : public Backend { log(" write_xaiger [options] [filename]\n"); log("\n"); log("Write the top module (according to the (* top *) attribute or if only one module\n"); - log("is currently selected) to an XAIGER file. Any non $_NOT_, $_AND_, $_ABC9_FF_, or"); - log("non (* abc9_box_id *) cells will be converted into psuedo-inputs and\n"); + log("is currently selected) to an XAIGER file. Any non $_NOT_, $_AND_, $_DFF_N_,\n"); + log(" $_DFF_P_, or non (* abc9_box_id *) cells will be converted into psuedo-inputs and\n"); log("pseudo-outputs. Whitebox contents will be taken from the '$holes'\n"); log("module, if it exists.\n"); log("\n"); @@ -772,10 +767,13 @@ struct XAigerBackend : public Backend { log(" -map \n"); log(" write an extra file with port and box symbols\n"); log("\n"); + log(" -dff\n"); + log(" write $_DFF_[NP]_ cells\n"); + log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) YS_OVERRIDE { - bool ascii_mode = false; + bool ascii_mode = false, dff_mode = false; std::string map_filename; log_header(design, "Executing XAIGER backend.\n"); @@ -791,6 +789,10 @@ struct XAigerBackend : public Backend { map_filename = args[++argidx]; continue; } + if (args[argidx] == "-dff") { + dff_mode = true; + continue; + } break; } extra_args(f, filename, args, argidx, !ascii_mode); @@ -808,7 +810,7 @@ struct XAigerBackend : public Backend { if (!top_module->memories.empty()) log_error("Found unmapped memories in module %s: unmapped memories are not supported in XAIGER backend!\n", log_id(top_module)); - XAigerWriter writer(top_module); + XAigerWriter writer(top_module, dff_mode); writer.write_aiger(*f, ascii_mode); if (!map_filename.empty()) { -- 2.30.2