mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-12 20:18:20 +00:00
Added opt_const -undriven
This commit is contained in:
parent
c526e56747
commit
594d52e0b6
|
@ -31,7 +31,7 @@ struct OptPass : public Pass {
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" opt [-mux_undef] [-mux_bool] [selection]\n");
|
log(" opt [-mux_undef] [-mux_bool] [-undriven] [selection]\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("This pass calls all the other opt_* passes in a useful order. This performs\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");
|
log("a series of trivial optimizations and cleanups. This pass executes the other\n");
|
||||||
|
@ -46,7 +46,7 @@ struct OptPass : public Pass {
|
||||||
log(" opt_share\n");
|
log(" opt_share\n");
|
||||||
log(" opt_rmdff\n");
|
log(" opt_rmdff\n");
|
||||||
log(" opt_clean\n");
|
log(" opt_clean\n");
|
||||||
log(" opt_const [-mux_undef] [-mux_bool]\n");
|
log(" opt_const [-mux_undef] [-mux_bool] [-undriven]\n");
|
||||||
log(" while [changed design]\n");
|
log(" while [changed design]\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,10 @@ struct OptPass : public Pass {
|
||||||
opt_const_args += " -mux_bool";
|
opt_const_args += " -mux_bool";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-undriven") {
|
||||||
|
opt_const_args += " -undriven";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "opt_status.h"
|
#include "opt_status.h"
|
||||||
#include "kernel/register.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/log.h"
|
#include "kernel/log.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -28,17 +29,59 @@
|
||||||
|
|
||||||
static bool did_something;
|
static bool did_something;
|
||||||
|
|
||||||
|
void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
|
||||||
|
{
|
||||||
|
CellTypes ct(design);
|
||||||
|
SigMap sigmap(module);
|
||||||
|
SigPool driven_signals;
|
||||||
|
SigPool used_signals;
|
||||||
|
SigPool all_signals;
|
||||||
|
|
||||||
|
for (auto &it : module->cells)
|
||||||
|
for (auto &conn : it.second->connections) {
|
||||||
|
if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first))
|
||||||
|
driven_signals.add(sigmap(conn.second));
|
||||||
|
if (!ct.cell_known(it.second->type) || ct.cell_input(it.second->type, conn.first))
|
||||||
|
used_signals.add(sigmap(conn.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &it : module->wires) {
|
||||||
|
if (it.second->port_input)
|
||||||
|
driven_signals.add(sigmap(it.second));
|
||||||
|
if (it.second->port_output)
|
||||||
|
used_signals.add(sigmap(it.second));
|
||||||
|
all_signals.add(sigmap(it.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
all_signals.del(driven_signals);
|
||||||
|
RTLIL::SigSpec undriven_signals = all_signals.export_all();
|
||||||
|
|
||||||
|
for (auto &c : undriven_signals.chunks)
|
||||||
|
{
|
||||||
|
RTLIL::SigSpec sig = c;
|
||||||
|
|
||||||
|
if (c.wire->name[0] == '$')
|
||||||
|
sig = used_signals.extract(sig);
|
||||||
|
if (sig.width == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
log("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c));
|
||||||
|
module->connections.push_back(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width)));
|
||||||
|
OPT_DID_SOMETHING = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val)
|
void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec Y = cell->connections[out_port];
|
RTLIL::SigSpec Y = cell->connections[out_port];
|
||||||
log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n",
|
log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n",
|
||||||
cell->type.c_str(), cell->name.c_str(), info.c_str(),
|
cell->type.c_str(), cell->name.c_str(), info.c_str(),
|
||||||
module->name.c_str(), log_signal(Y), log_signal(out_val));
|
module->name.c_str(), log_signal(Y), log_signal(out_val));
|
||||||
OPT_DID_SOMETHING = true;
|
|
||||||
// ILANG_BACKEND::dump_cell(stderr, "--> ", cell);
|
// ILANG_BACKEND::dump_cell(stderr, "--> ", cell);
|
||||||
module->connections.push_back(RTLIL::SigSig(Y, out_val));
|
module->connections.push_back(RTLIL::SigSig(Y, out_val));
|
||||||
module->cells.erase(cell->name);
|
module->cells.erase(cell->name);
|
||||||
delete cell;
|
delete cell;
|
||||||
|
OPT_DID_SOMETHING = true;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +119,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
cell->connections["\\A"] = cell->connections["\\B"];
|
cell->connections["\\A"] = cell->connections["\\B"];
|
||||||
cell->connections["\\B"] = tmp;
|
cell->connections["\\B"] = tmp;
|
||||||
cell->connections["\\S"] = invert_map.at(assign_map(cell->connections["\\S"]));
|
cell->connections["\\S"] = invert_map.at(assign_map(cell->connections["\\S"]));
|
||||||
|
OPT_DID_SOMETHING = true;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
goto next_cell;
|
goto next_cell;
|
||||||
}
|
}
|
||||||
|
@ -263,6 +307,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
cell->type = "$not";
|
cell->type = "$not";
|
||||||
} else
|
} else
|
||||||
cell->type = "$_INV_";
|
cell->type = "$_INV_";
|
||||||
|
OPT_DID_SOMETHING = true;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
goto next_cell;
|
goto next_cell;
|
||||||
}
|
}
|
||||||
|
@ -280,6 +325,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
cell->type = "$and";
|
cell->type = "$and";
|
||||||
} else
|
} else
|
||||||
cell->type = "$_AND_";
|
cell->type = "$_AND_";
|
||||||
|
OPT_DID_SOMETHING = true;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
goto next_cell;
|
goto next_cell;
|
||||||
}
|
}
|
||||||
|
@ -297,6 +343,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
cell->type = "$or";
|
cell->type = "$or";
|
||||||
} else
|
} else
|
||||||
cell->type = "$_or_";
|
cell->type = "$_or_";
|
||||||
|
OPT_DID_SOMETHING = true;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
goto next_cell;
|
goto next_cell;
|
||||||
}
|
}
|
||||||
|
@ -342,6 +389,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
cell->type = "$mux";
|
cell->type = "$mux";
|
||||||
cell->parameters.erase("\\S_WIDTH");
|
cell->parameters.erase("\\S_WIDTH");
|
||||||
}
|
}
|
||||||
|
OPT_DID_SOMETHING = true;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,11 +500,15 @@ struct OptConstPass : public Pass {
|
||||||
log(" -mux_bool\n");
|
log(" -mux_bool\n");
|
||||||
log(" replace $mux cells with inverters or buffers when possible\n");
|
log(" replace $mux cells with inverters or buffers when possible\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -undriven\n");
|
||||||
|
log(" replace undriven nets with undef (x) constants\n");
|
||||||
|
log("\n");
|
||||||
}
|
}
|
||||||
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
|
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
|
||||||
{
|
{
|
||||||
bool mux_undef = false;
|
bool mux_undef = false;
|
||||||
bool mux_bool = false;
|
bool mux_bool = false;
|
||||||
|
bool undriven = false;
|
||||||
|
|
||||||
log_header("Executing OPT_CONST pass (perform const folding).\n");
|
log_header("Executing OPT_CONST pass (perform const folding).\n");
|
||||||
log_push();
|
log_push();
|
||||||
|
@ -471,11 +523,19 @@ struct OptConstPass : public Pass {
|
||||||
mux_bool = true;
|
mux_bool = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-undriven") {
|
||||||
|
undriven = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
for (auto &mod_it : design->modules)
|
for (auto &mod_it : design->modules)
|
||||||
|
{
|
||||||
|
if (undriven)
|
||||||
|
replace_undriven(design, mod_it.second);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
do {
|
do {
|
||||||
did_something = false;
|
did_something = false;
|
||||||
|
@ -483,6 +543,7 @@ struct OptConstPass : public Pass {
|
||||||
} while (did_something);
|
} while (did_something);
|
||||||
replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool);
|
replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool);
|
||||||
} while (did_something);
|
} while (did_something);
|
||||||
|
}
|
||||||
|
|
||||||
log_pop();
|
log_pop();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue