summaryrefslogtreecommitdiff
path: root/passes/opt/opt_clean.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-10-17 20:48:40 +0200
committerClifford Wolf <clifford@clifford.at>2013-10-17 20:48:40 +0200
commitc20571ca5e908d8fe85e41c1632e84de582dc68b (patch)
treed998b4ff1708cc42fec869071ea322f0c361170c /passes/opt/opt_clean.cc
parentf5c0ed6c79010df60cdb7ab3ea4c26ed3d61e2f1 (diff)
Avoid re-arranging signals on register outputs
Diffstat (limited to 'passes/opt/opt_clean.cc')
-rw-r--r--passes/opt/opt_clean.cc34
1 files changed, 31 insertions, 3 deletions
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index f8811bac..d76dafb3 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -29,7 +29,7 @@
using RTLIL::id2cstr;
-static CellTypes ct;
+static CellTypes ct, ct_reg;
static int count_rm_cells, count_rm_wires;
static void rmunused_module_cells(RTLIL::Module *module, bool verbose)
@@ -96,7 +96,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose)
}
}
-static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2)
+static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2, SigPool &regs, SigPool &conns)
{
assert(s1.width == 1);
assert(s2.width == 1);
@@ -112,6 +112,12 @@ static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2)
if (w1->port_input != w2->port_input)
return w2->port_input;
+ if (regs.check_any(s1) != regs.check_any(s2))
+ return regs.check_any(s2);
+
+ if (conns.check_any(s1) != conns.check_any(s2))
+ return conns.check_any(s2);
+
if (w1->port_output != w2->port_output)
return w2->port_output;
@@ -137,12 +143,26 @@ static bool check_public_name(RTLIL::IdString id)
static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbose)
{
+ SigPool register_signals;
+ SigPool connected_signals;
+
+ if (!purge_mode)
+ for (auto &it : module->cells) {
+ RTLIL::Cell *cell = it.second;
+ if (ct_reg.cell_known(cell->type))
+ for (auto &it2 : cell->connections)
+ if (ct_reg.cell_output(cell->type, it2.first))
+ register_signals.add(it2.second);
+ for (auto &it2 : cell->connections)
+ connected_signals.add(it2.second);
+ }
+
SigMap assign_map(module);
for (auto &it : module->wires) {
RTLIL::Wire *wire = it.second;
for (int i = 0; i < wire->width; i++) {
RTLIL::SigSpec s1 = RTLIL::SigSpec(wire, 1, i), s2 = assign_map(s1);
- if (!compare_signals(s1, s2))
+ if (!compare_signals(s1, s2, register_signals, connected_signals))
assign_map.add(s1);
}
}
@@ -289,6 +309,9 @@ struct OptCleanPass : public Pass {
ct.setup_stdcells();
ct.setup_stdcells_mem();
+ ct_reg.setup_internals_mem();
+ ct_reg.setup_stdcells_mem();
+
for (auto &mod_it : design->modules) {
if (!design->selected_whole_module(mod_it.first)) {
if (design->selected(mod_it.second))
@@ -303,6 +326,7 @@ struct OptCleanPass : public Pass {
}
ct.clear();
+ ct_reg.clear();
log_pop();
}
} OptCleanPass;
@@ -344,6 +368,9 @@ struct CleanPass : public Pass {
ct.setup_stdcells();
ct.setup_stdcells_mem();
+ ct_reg.setup_internals_mem();
+ ct_reg.setup_stdcells_mem();
+
count_rm_cells = 0;
count_rm_wires = 0;
@@ -359,6 +386,7 @@ struct CleanPass : public Pass {
log("Removed %d unused cells and %d unused wires.\n", count_rm_cells, count_rm_wires);
ct.clear();
+ ct_reg.clear();
}
} CleanPass;