summaryrefslogtreecommitdiff
path: root/techlibs/ice40/ice40_opt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/ice40/ice40_opt.cc')
-rw-r--r--techlibs/ice40/ice40_opt.cc38
1 files changed, 25 insertions, 13 deletions
diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc
index 677ac8d7..ae72f5d6 100644
--- a/techlibs/ice40/ice40_opt.cc
+++ b/techlibs/ice40/ice40_opt.cc
@@ -26,7 +26,7 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-static void run_ice40_opts(Module *module)
+static void run_ice40_opts(Module *module, bool unlut_mode)
{
pool<SigBit> optimized_co;
vector<Cell*> sb_lut_cells;
@@ -84,6 +84,9 @@ static void run_ice40_opts(Module *module)
inbits.append(cell->getPort("\\I3"));
sigmap.apply(inbits);
+ if (unlut_mode)
+ goto remap_lut;
+
if (optimized_co.count(inbits[0])) goto remap_lut;
if (optimized_co.count(inbits[1])) goto remap_lut;
if (optimized_co.count(inbits[2])) goto remap_lut;
@@ -101,7 +104,7 @@ static void run_ice40_opts(Module *module)
cell->setParam("\\LUT", cell->getParam("\\LUT_INIT"));
cell->unsetParam("\\LUT_INIT");
- cell->setPort("\\A", SigSpec({cell->getPort("\\I0"), cell->getPort("\\I1"), cell->getPort("\\I2"), cell->getPort("\\I3")}));
+ cell->setPort("\\A", SigSpec({cell->getPort("\\I3"), cell->getPort("\\I2"), cell->getPort("\\I1"), cell->getPort("\\I0")}));
cell->setPort("\\Y", cell->getPort("\\O"));
cell->unsetPort("\\I0");
cell->unsetPort("\\I1");
@@ -127,23 +130,32 @@ struct Ice40OptPass : public Pass {
log("\n");
log(" do\n");
log(" <ice40 specific optimizations>\n");
- log(" opt_const -mux_undef -undriven [-full]\n");
- log(" opt_share\n");
+ log(" opt_expr -mux_undef -undriven [-full]\n");
+ log(" opt_merge\n");
log(" opt_rmdff\n");
log(" opt_clean\n");
log(" while <changed design>\n");
log("\n");
+ log("When called with the option -unlut, this command will transform all already\n");
+ log("mapped SB_LUT4 cells back to logic.\n");
+ log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{
- string opt_const_args = "-mux_undef -undriven";
- log_header("Executing ICE40_OPT pass (performing simple optimizations).\n");
+ string opt_expr_args = "-mux_undef -undriven";
+ bool unlut_mode = false;
+
+ log_header(design, "Executing ICE40_OPT pass (performing simple optimizations).\n");
log_push();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
if (args[argidx] == "-full") {
- opt_const_args += " -full";
+ opt_expr_args += " -full";
+ continue;
+ }
+ if (args[argidx] == "-unlut") {
+ unlut_mode = true;
continue;
}
break;
@@ -154,26 +166,26 @@ struct Ice40OptPass : public Pass {
{
design->scratchpad_unset("opt.did_something");
- log_header("Running ICE40 specific optimizations.\n");
+ log_header(design, "Running ICE40 specific optimizations.\n");
for (auto module : design->selected_modules())
- run_ice40_opts(module);
+ run_ice40_opts(module, unlut_mode);
- Pass::call(design, "opt_const " + opt_const_args);
- Pass::call(design, "opt_share");
+ Pass::call(design, "opt_expr " + opt_expr_args);
+ Pass::call(design, "opt_merge");
Pass::call(design, "opt_rmdff");
Pass::call(design, "opt_clean");
if (design->scratchpad_get_bool("opt.did_something") == false)
break;
- log_header("Rerunning OPT passes. (Removed registers in this run.)\n");
+ log_header(design, "Rerunning OPT passes. (Removed registers in this run.)\n");
}
design->optimize();
design->sort();
design->check();
- log_header("Finished OPT passes. (There is nothing left to do.)\n");
+ log_header(design, "Finished OPT passes. (There is nothing left to do.)\n");
log_pop();
}
} Ice40OptPass;