std::set<RTLIL::Cell*> cells_to_remove;
std::set<RTLIL::Cell*> recursion_state;
+ std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> to_drivers_edges;
+
// ------------------------------------------------------------------------------
// Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree
}
- // ------------------------------------------------------------------------------------------------
- // Find SCCs (logic loops). This is only used to make sure that this pass does not introduce loops.
- // ------------------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------------------
+ // Helper functions used to make sure that this pass does not introduce new logic loops.
+ // -------------------------------------------------------------------------------------
- bool module_has_scc()
+ bool module_has_scc(std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> *edges = NULL)
{
SigMap sigmap(module);
toposort.edge(c1, c2);
}
- return !toposort.sort();
+ bool found_scc = !toposort.sort();
+ if (edges)
+ *edges = std::move(toposort.database);
+ return found_scc;
+ }
+
+ bool find_in_input_cone_worker(RTLIL::Cell *root, RTLIL::Cell *needle, std::set<RTLIL::Cell*> &stop)
+ {
+ if (root == needle)
+ return true;
+
+ if (stop.count(root))
+ return false;
+
+ stop.insert(root);
+
+ for (auto c : to_drivers_edges[root])
+ if (find_in_input_cone_worker(c, needle, stop))
+ return true;
+ return false;
+ }
+
+ bool find_in_input_cone(RTLIL::Cell *root, RTLIL::Cell *needle)
+ {
+ std::set<RTLIL::Cell*> stop;
+ return find_in_input_cone_worker(root, needle, stop);
}
ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) :
config(config), design(design), module(module)
{
- bool before_scc = module_has_scc();
+ bool before_scc = module_has_scc(&to_drivers_edges);
generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end());
generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end());
}
log(" According to the SAT solver this pair of cells can be shared.\n");
+
+ if (find_in_input_cone(cell, other_cell)) {
+ log(" Sharing not possible: %s is in input cone of %s.\n", log_id(other_cell), log_id(cell));
+ continue;
+ }
+
+ if (find_in_input_cone(other_cell, cell)) {
+ log(" Sharing not possible: %s is in input cone of %s.\n", log_id(cell), log_id(other_cell));
+ continue;
+ }
+
shareable_cells.erase(other_cell);
int cell_select_score = 0;
cells_to_remove.insert(cell);
cells_to_remove.insert(other_cell);
+
+ to_drivers_edges[cell].insert(to_drivers_edges[other_cell].begin(), to_drivers_edges[other_cell].end());
+ to_drivers_edges[other_cell] = to_drivers_edges[cell];
break;
}
}