From c20571ca5e908d8fe85e41c1632e84de582dc68b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Oct 2013 20:48:40 +0200 Subject: [PATCH] Avoid re-arranging signals on register outputs --- passes/opt/opt_clean.cc | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index f8811baca..d76dafb3c 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 ®s, 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; -- 2.30.2