From 032ce573a3358d1eb5cd2d2f3ec724cc18b3626b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 24 Dec 2014 11:39:15 +0100 Subject: [PATCH] Added "dff2dffe -direct" for direct gate mapping --- passes/techmap/dff2dffe.cc | 42 +++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc index 03abde6f9..339007156 100644 --- a/passes/techmap/dff2dffe.cc +++ b/passes/techmap/dff2dffe.cc @@ -31,6 +31,8 @@ struct Dff2dffeWorker SigMap sigmap; CellTypes ct; + RTLIL::IdString direct_to; + typedef std::pair cell_int_t; std::map bit2mux; std::vector dff_cells; @@ -39,7 +41,9 @@ struct Dff2dffeWorker typedef std::map pattern_t; typedef std::set patterns_t; - Dff2dffeWorker(RTLIL::Module *module) : module(module), sigmap(module), ct(module->design) + + Dff2dffeWorker(RTLIL::Module *module, RTLIL::IdString direct_from, RTLIL::IdString direct_to) : + module(module), sigmap(module), ct(module->design), direct_to(direct_to) { for (auto wire : module->wires()) { if (wire->port_output) @@ -53,8 +57,13 @@ struct Dff2dffeWorker for (int i = 0; i < GetSize(sig_y); i++) bit2mux[sig_y[i]] = cell_int_t(cell, i); } - if (cell->type == "$dff" || cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") - dff_cells.push_back(cell); + if (direct_to.empty()) { + if (cell->type == "$dff" || cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") + dff_cells.push_back(cell); + } else { + if (cell->type == direct_from) + dff_cells.push_back(cell); + } for (auto conn : cell->connections()) { if (ct.cell_output(cell->type, conn.first)) continue; @@ -197,6 +206,11 @@ struct Dff2dffeWorker new_sig_d.append(sig_d[i]); new_sig_q.append(sig_q[i]); } + if (!direct_to.empty()) { + log(" converting %s cell %s to %s for %s -> %s.\n", log_id(dff_cell->type), log_id(dff_cell), log_id(direct_to), log_signal(new_sig_d), log_signal(new_sig_q)); + dff_cell->setPort("\\E", make_patterns_logic(it.first, true)); + dff_cell->type = direct_to; + } else if (dff_cell->type == "$dff") { RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort("\\CLK"), make_patterns_logic(it.first, false), new_sig_d, new_sig_q, dff_cell->getParam("\\CLK_POLARITY").as_bool(), true); @@ -208,6 +222,9 @@ struct Dff2dffeWorker } } + if (!direct_to.empty()) + return; + if (remaining_indices.empty()) { log(" removing now obsolete cell %s.\n", log_id(dff_cell)); module->remove(dff_cell); @@ -246,7 +263,16 @@ struct Dff2dffePass : public Pass { log("\n"); log(" -unmap\n"); log(" operate in the opposite direction: replace $dffe cells with combinations\n"); - log(" of $dff and $mux cells\n"); + log(" of $dff and $mux cells. the options below are ignore in unmap mode.\n"); + log("\n"); + log(" -direct \n"); + log(" map directly to external gate type. can\n"); + log(" be any internal gate-level FF cell (except $_DFFE_??_). the\n"); + log(" is the cell type name for a cell with an\n"); + log(" identical interface to the , except it\n"); + log(" also has an high-active enable port 'E'.\n"); + log(" Usually is an intemediate cell type\n"); + log(" that is then translated to the final type using 'techmap'.\n"); log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) @@ -254,6 +280,7 @@ struct Dff2dffePass : public Pass { log_header("Executing DFF2DFFE pass (transform $dff to $dffe where applicable).\n"); bool unmap_mode = false; + RTLIL::IdString direct_from, direct_to; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -261,6 +288,11 @@ struct Dff2dffePass : public Pass { unmap_mode = true; continue; } + if (args[argidx] == "-direct" && argidx + 2 < args.size()) { + direct_from = RTLIL::escape_id(args[++argidx]); + direct_to = RTLIL::escape_id(args[++argidx]); + continue; + } break; } extra_args(args, argidx, design); @@ -296,7 +328,7 @@ struct Dff2dffePass : public Pass { continue; } - Dff2dffeWorker worker(mod); + Dff2dffeWorker worker(mod, direct_from, direct_to); worker.run(); } } -- 2.30.2