From 8d3ab626ea39ed109ab061d69684a66fc2322ff2 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Thu, 15 Nov 2018 02:48:44 +0100 Subject: [PATCH] dff2dffe: Add option for unmap to only remove DFFE with low CE signal use Signed-off-by: Sylvain Munaut --- passes/techmap/dff2dffe.cc | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc index 3291f5a4a..3f5b48c75 100644 --- a/passes/techmap/dff2dffe.cc +++ b/passes/techmap/dff2dffe.cc @@ -263,10 +263,14 @@ struct Dff2dffePass : public Pass { log("more feedback paths to $dffe cells. It also works on gate-level cells such as\n"); log("$_DFF_P_, $_DFF_N_ and $_MUX_.\n"); log("\n"); - log(" -unmap\n"); + log(" -unmap"); log(" operate in the opposite direction: replace $dffe cells with combinations\n"); log(" of $dff and $mux cells. the options below are ignore in unmap mode.\n"); log("\n"); + log(" -unmap-mince N\n"); + log(" Same as -unmap but only unmap $dffe where the clock enable port\n"); + log(" signal is used by less $dffe than the specified number\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"); @@ -289,6 +293,7 @@ struct Dff2dffePass : public Pass { log_header(design, "Executing DFF2DFFE pass (transform $dff to $dffe where applicable).\n"); bool unmap_mode = false; + int min_ce_use = -1; dict direct_dict; size_t argidx; @@ -297,6 +302,11 @@ struct Dff2dffePass : public Pass { unmap_mode = true; continue; } + if (args[argidx] == "-unmap-mince" && argidx + 1 < args.size()) { + unmap_mode = true; + min_ce_use = std::stoi(args[++argidx]); + continue; + } if (args[argidx] == "-direct" && argidx + 2 < args.size()) { string direct_from = RTLIL::escape_id(args[++argidx]); string direct_to = RTLIL::escape_id(args[++argidx]); @@ -343,8 +353,21 @@ struct Dff2dffePass : public Pass { if (!mod->has_processes_warn()) { if (unmap_mode) { + SigMap sigmap(mod); for (auto cell : mod->selected_cells()) { if (cell->type == "$dffe") { + if (min_ce_use >= 0) { + int ce_use = 0; + for (auto cell_other : mod->selected_cells()) { + if (cell_other->type != cell->type) + continue; + if (sigmap(cell->getPort("\\EN")) == sigmap(cell_other->getPort("\\EN"))) + ce_use++; + } + if (ce_use >= min_ce_use) + continue; + } + RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort("\\D"))); mod->addDff(NEW_ID, cell->getPort("\\CLK"), tmp, cell->getPort("\\Q"), cell->getParam("\\CLK_POLARITY").as_bool()); if (cell->getParam("\\EN_POLARITY").as_bool()) @@ -355,6 +378,18 @@ struct Dff2dffePass : public Pass { continue; } if (cell->type.substr(0, 7) == "$_DFFE_") { + if (min_ce_use >= 0) { + int ce_use = 0; + for (auto cell_other : mod->selected_cells()) { + if (cell_other->type != cell->type) + continue; + if (sigmap(cell->getPort("\\E")) == sigmap(cell_other->getPort("\\E"))) + ce_use++; + } + if (ce_use >= min_ce_use) + continue; + } + bool clk_pol = cell->type.substr(7, 1) == "P"; bool en_pol = cell->type.substr(8, 1) == "P"; RTLIL::SigSpec tmp = mod->addWire(NEW_ID); -- 2.30.2