From 274bcef66c4c70a15358e0c7b7e90aa8f8a668e6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Feb 2014 23:50:17 +0100 Subject: Improved detection of primary wire for a signal in opt_clean --- passes/opt/opt_clean.cc | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'passes') diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 051d8dc6..740185cb 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -29,7 +29,7 @@ using RTLIL::id2cstr; -static CellTypes ct, ct_reg; +static CellTypes ct, ct_reg, ct_all; 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, SigPool ®s, SigPool &conns) +static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2, SigPool ®s, SigPool &conns, std::set &direct_wires) { assert(s1.width == 1); assert(s2.width == 1); @@ -115,6 +115,8 @@ static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2, SigPool ® if (w1->name[0] == '\\' && w2->name[0] == '\\') { if (regs.check_any(s1) != regs.check_any(s2)) return regs.check_any(s2); + if (direct_wires.count(w1) != direct_wires.count(w2)) + return direct_wires.count(w2); if (conns.check_any(s1) != conns.check_any(s2)) return conns.check_any(s2); } @@ -157,13 +159,27 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it2 : cell->connections) connected_signals.add(it2.second); } - + SigMap assign_map(module); + std::set direct_sigs; + std::set direct_wires; + for (auto &it : module->cells) { + RTLIL::Cell *cell = it.second; + if (ct_all.cell_known(cell->type)) + for (auto &it2 : cell->connections) + if (ct_all.cell_output(cell->type, it2.first)) + direct_sigs.insert(assign_map(it2.second)); + } + for (auto &it : module->wires) { + if (direct_sigs.count(assign_map(it.second)) || it.second->port_input) + direct_wires.insert(it.second); + } + 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, register_signals, connected_signals)) + if (!compare_signals(s1, s2, register_signals, connected_signals, direct_wires)) assign_map.add(s1); } } @@ -377,6 +393,8 @@ struct CleanPass : public Pass { ct_reg.setup_internals_mem(); ct_reg.setup_stdcells_mem(); + ct_all.setup(design); + count_rm_cells = 0; count_rm_wires = 0; @@ -393,6 +411,7 @@ struct CleanPass : public Pass { ct.clear(); ct_reg.clear(); + ct_all.clear(); } } CleanPass; -- cgit v1.2.3