diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2018-11-15 02:48:44 +0100 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2018-11-27 21:50:42 +0100 |
commit | 8d3ab626ea39ed109ab061d69684a66fc2322ff2 (patch) | |
tree | 26377fb899b44d91c841c4085991bef3e5401518 /passes/techmap/dff2dffe.cc | |
parent | ab97eddee9b0ea0a772660731fe4c3270d2564e5 (diff) | |
download | yosys-8d3ab626ea39ed109ab061d69684a66fc2322ff2.tar.gz yosys-8d3ab626ea39ed109ab061d69684a66fc2322ff2.tar.bz2 yosys-8d3ab626ea39ed109ab061d69684a66fc2322ff2.zip |
dff2dffe: Add option for unmap to only remove DFFE with low CE signal use
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'passes/techmap/dff2dffe.cc')
-rw-r--r-- | passes/techmap/dff2dffe.cc | 37 |
1 files changed, 36 insertions, 1 deletions
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 <internal_gate_type> <external_gate_type>\n"); log(" map directly to external gate type. <internal_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<IdString, IdString> 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); |