summaryrefslogtreecommitdiff
path: root/passes
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-02-02 22:11:08 +0100
committerClifford Wolf <clifford@clifford.at>2014-02-02 22:11:08 +0100
commit9d0b69edaafa98c4bb67974415f354a344a5821d (patch)
treee92069608ade11767f6f113def21679154fb9c0f /passes
parentbee4450c4c24a5b09a8723331cf66e0542f0e9f9 (diff)
Added opt_const -mux_bool
Diffstat (limited to 'passes')
-rw-r--r--passes/opt/opt.cc22
-rw-r--r--passes/opt/opt_const.cc32
2 files changed, 47 insertions, 7 deletions
diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc
index 467baf23..53c27e0f 100644
--- a/passes/opt/opt.cc
+++ b/passes/opt/opt.cc
@@ -31,7 +31,7 @@ struct OptPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" opt [selection]\n");
+ log(" opt [-mux_undef] [-mux_bool] [selection]\n");
log("\n");
log("This pass calls all the other opt_* passes in a useful order. This performs\n");
log("a series of trivial optimizations and cleanups. This pass executes the other\n");
@@ -46,16 +46,30 @@ struct OptPass : public Pass {
log(" opt_share\n");
log(" opt_rmdff\n");
log(" opt_clean\n");
- log(" opt_const\n");
+ log(" opt_const [-mux_undef] [-mux_bool]\n");
log(" while [changed design]\n");
log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{
+ std::string opt_const_args;
+
log_header("Executing OPT pass (performing simple optimizations).\n");
log_push();
- extra_args(args, 1, design);
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ if (args[argidx] == "-mux_undef") {
+ opt_const_args += " -mux_undef";
+ continue;
+ }
+ if (args[argidx] == "-mux_bool") {
+ opt_const_args += " -mux_bool";
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
log_header("Optimizing in-memory representation of design.\n");
design->optimize();
@@ -69,7 +83,7 @@ struct OptPass : public Pass {
Pass::call(design, "opt_share");
Pass::call(design, "opt_rmdff");
Pass::call(design, "opt_clean");
- Pass::call(design, "opt_const");
+ Pass::call(design, "opt_const" + opt_const_args);
if (OPT_DID_SOMETHING == false)
break;
log_header("Rerunning OPT passes. (Maybe there is more to do..)\n");
diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc
index 2b2c83a5..535dd02f 100644
--- a/passes/opt/opt_const.cc
+++ b/passes/opt/opt_const.cc
@@ -42,7 +42,7 @@ void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, st
did_something = true;
}
-void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef)
+void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool)
{
if (!design->selected(module))
return;
@@ -244,6 +244,24 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
}
+ if (mux_bool && cell->type == "$mux" && cell->connections["\\A"] == RTLIL::SigSpec(0, 1) && cell->connections["\\B"] == RTLIL::SigSpec(1, 1)) {
+ replace_cell(module, cell, "mux_bool", "\\Y", cell->connections["\\S"]);
+ goto next_cell;
+ }
+
+ if (mux_bool && cell->type == "$mux" && cell->connections["\\A"] == RTLIL::SigSpec(1, 1) && cell->connections["\\B"] == RTLIL::SigSpec(0, 1)) {
+ cell->connections["\\A"] = cell->connections["\\S"];
+ cell->connections.erase("\\B");
+ cell->connections.erase("\\S");
+ cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"];
+ cell->parameters["\\Y_WIDTH"] = cell->parameters["\\WIDTH"];
+ cell->parameters["\\A_SIGNED"] = 0;
+ cell->parameters.erase("\\WIDTH");
+ cell->type = "$not";
+ did_something = true;
+ goto next_cell;
+ }
+
if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) {
RTLIL::SigSpec new_a, new_b, new_s;
int width = cell->connections.at("\\A").width;
@@ -392,10 +410,14 @@ struct OptConstPass : public Pass {
log(" -mux_undef\n");
log(" remove 'undef' inputs from $mux, $pmux and $_MUX_ cells\n");
log("\n");
+ log(" -mux_bool\n");
+ log(" replace $mux cells with inverters or buffers when possible\n");
+ log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{
bool mux_undef = false;
+ bool mux_bool = false;
log_header("Executing OPT_CONST pass (perform const folding).\n");
log_push();
@@ -406,6 +428,10 @@ struct OptConstPass : public Pass {
mux_undef = true;
continue;
}
+ if (args[argidx] == "-mux_bool") {
+ mux_bool = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -414,9 +440,9 @@ struct OptConstPass : public Pass {
do {
do {
did_something = false;
- replace_const_cells(design, mod_it.second, false, mux_undef);
+ replace_const_cells(design, mod_it.second, false, mux_undef, mux_bool);
} while (did_something);
- replace_const_cells(design, mod_it.second, true, mux_undef);
+ replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool);
} while (did_something);
log_pop();