Merge pull request #702 from smunaut/min_ce_use

Add option to only use DFFE is the resulting E signal would be use > N times
This commit is contained in:
Clifford Wolf 2018-12-04 14:29:21 -08:00 committed by GitHub
commit 70c417174d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 1 deletions

View File

@ -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("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("$_DFF_P_, $_DFF_N_ and $_MUX_.\n");
log("\n"); log("\n");
log(" -unmap\n"); log(" -unmap");
log(" operate in the opposite direction: replace $dffe cells with combinations\n"); 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(" of $dff and $mux cells. the options below are ignore in unmap mode.\n");
log("\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(" -direct <internal_gate_type> <external_gate_type>\n");
log(" map directly to external gate type. <internal_gate_type> can\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"); 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"); log_header(design, "Executing DFF2DFFE pass (transform $dff to $dffe where applicable).\n");
bool unmap_mode = false; bool unmap_mode = false;
int min_ce_use = -1;
dict<IdString, IdString> direct_dict; dict<IdString, IdString> direct_dict;
size_t argidx; size_t argidx;
@ -297,6 +302,11 @@ struct Dff2dffePass : public Pass {
unmap_mode = true; unmap_mode = true;
continue; 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()) { if (args[argidx] == "-direct" && argidx + 2 < args.size()) {
string direct_from = RTLIL::escape_id(args[++argidx]); string direct_from = RTLIL::escape_id(args[++argidx]);
string direct_to = 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 (!mod->has_processes_warn())
{ {
if (unmap_mode) { if (unmap_mode) {
SigMap sigmap(mod);
for (auto cell : mod->selected_cells()) { for (auto cell : mod->selected_cells()) {
if (cell->type == "$dffe") { 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"))); 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()); mod->addDff(NEW_ID, cell->getPort("\\CLK"), tmp, cell->getPort("\\Q"), cell->getParam("\\CLK_POLARITY").as_bool());
if (cell->getParam("\\EN_POLARITY").as_bool()) if (cell->getParam("\\EN_POLARITY").as_bool())
@ -355,6 +378,18 @@ struct Dff2dffePass : public Pass {
continue; continue;
} }
if (cell->type.substr(0, 7) == "$_DFFE_") { 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 clk_pol = cell->type.substr(7, 1) == "P";
bool en_pol = cell->type.substr(8, 1) == "P"; bool en_pol = cell->type.substr(8, 1) == "P";
RTLIL::SigSpec tmp = mod->addWire(NEW_ID); RTLIL::SigSpec tmp = mod->addWire(NEW_ID);

View File

@ -69,6 +69,10 @@ struct SynthIce40Pass : public ScriptPass
log(" -nodffe\n"); log(" -nodffe\n");
log(" do not use SB_DFFE* cells in output netlist\n"); log(" do not use SB_DFFE* cells in output netlist\n");
log("\n"); log("\n");
log(" -dffe_min_ce_use <min_ce_use>\n");
log(" do not use SB_DFFE* cells if the resulting CE line would go to less\n");
log(" than min_ce_use SB_DFFE*in output netlist\n");
log("\n");
log(" -nobram\n"); log(" -nobram\n");
log(" do not use SB_RAM40_4K* cells in output netlist\n"); log(" do not use SB_RAM40_4K* cells in output netlist\n");
log("\n"); log("\n");
@ -87,6 +91,7 @@ struct SynthIce40Pass : public ScriptPass
string top_opt, blif_file, edif_file, json_file; string top_opt, blif_file, edif_file, json_file;
bool nocarry, nodffe, nobram, flatten, retime, abc2, vpr; bool nocarry, nodffe, nobram, flatten, retime, abc2, vpr;
int min_ce_use;
void clear_flags() YS_OVERRIDE void clear_flags() YS_OVERRIDE
{ {
@ -96,6 +101,7 @@ struct SynthIce40Pass : public ScriptPass
json_file = ""; json_file = "";
nocarry = false; nocarry = false;
nodffe = false; nodffe = false;
min_ce_use = -1;
nobram = false; nobram = false;
flatten = true; flatten = true;
retime = false; retime = false;
@ -155,6 +161,10 @@ struct SynthIce40Pass : public ScriptPass
nodffe = true; nodffe = true;
continue; continue;
} }
if (args[argidx] == "-dffe_min_ce_use" && argidx+1 < args.size()) {
min_ce_use = std::stoi(args[++argidx]);
continue;
}
if (args[argidx] == "-nobram") { if (args[argidx] == "-nobram") {
nobram = true; nobram = true;
continue; continue;
@ -228,6 +238,10 @@ struct SynthIce40Pass : public ScriptPass
run("dffsr2dff"); run("dffsr2dff");
if (!nodffe) if (!nodffe)
run("dff2dffe -direct-match $_DFF_*"); run("dff2dffe -direct-match $_DFF_*");
if (min_ce_use >= 0) {
run("opt_merge");
run(stringf("dff2dffe -unmap-mince %d", min_ce_use));
}
run("techmap -D NO_LUT -map +/ice40/cells_map.v"); run("techmap -D NO_LUT -map +/ice40/cells_map.v");
run("opt_expr -mux_undef"); run("opt_expr -mux_undef");
run("simplemap"); run("simplemap");