mirror of https://github.com/YosysHQ/yosys.git
dff2dffe: Add option for unmap to only remove DFFE with low CE signal use
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
parent
ab97eddee9
commit
8d3ab626ea
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue