summaryrefslogtreecommitdiff
path: root/passes/opt
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-02-07 23:50:17 +0100
committerClifford Wolf <clifford@clifford.at>2014-02-07 23:50:17 +0100
commit274bcef66c4c70a15358e0c7b7e90aa8f8a668e6 (patch)
tree614b1555d0ffef6752a645574a135e0ddd3f7933 /passes/opt
parent244e8ce1f42bce47b3426e6679ed0ba5dadd8da6 (diff)
Improved detection of primary wire for a signal in opt_clean
Diffstat (limited to 'passes/opt')
-rw-r--r--passes/opt/opt_clean.cc27
1 files changed, 23 insertions, 4 deletions
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 &regs, SigPool &conns)
+static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2, SigPool &regs, SigPool &conns, std::set<RTLIL::Wire*> &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 &reg
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<RTLIL::SigSpec> direct_sigs;
+ std::set<RTLIL::Wire*> 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;