1082 log(
"Found %d cells in module %s that may be considered for resource sharing.\n",
1085 for (
auto cell : module->
cells())
1086 if (cell->type ==
"$pmux")
1087 for (
auto bit : cell->getPort(
"\\S"))
1088 for (
auto other_bit : cell->getPort(
"\\S"))
1089 if (bit < other_bit)
1090 exclusive_ctrls.push_back(std::pair<RTLIL::SigBit, RTLIL::SigBit>(bit, other_bit));
1097 log(
" Analyzing resource sharing options for %s:\n",
log_id(cell));
1102 if (cell_activation_patterns.empty()) {
1103 log(
" Cell is never active. Sharing is pointless, we simply remove it.\n");
1108 if (cell_activation_patterns.count(std::pair<RTLIL::SigSpec, RTLIL::Const>())) {
1109 log(
" Cell is always active. Therefore no sharing is possible.\n");
1113 log(
" Found %d activation_patterns using ctrl signal %s.\n",
GetSize(cell_activation_patterns),
log_signal(cell_activation_signals));
1115 std::vector<RTLIL::Cell*> candidates;
1118 if (candidates.empty()) {
1119 log(
" No candidates found.\n");
1123 log(
" Found %d candidates:",
GetSize(candidates));
1124 for (
auto c : candidates)
1128 for (
auto other_cell : candidates)
1130 log(
" Analyzing resource sharing with %s:\n",
log_id(other_cell));
1135 if (other_cell_activation_patterns.empty()) {
1136 log(
" Cell is never active. Sharing is pointless, we simply remove it.\n");
1142 if (other_cell_activation_patterns.count(std::pair<RTLIL::SigSpec, RTLIL::Const>())) {
1143 log(
" Cell is always active. Therefore no sharing is possible.\n");
1148 log(
" Found %d activation_patterns using ctrl signal %s.\n",
1149 GetSize(other_cell_activation_patterns),
log_signal(other_cell_activation_signals));
1154 std::set<RTLIL::SigBit> union_forbidden_controls;
1155 union_forbidden_controls.insert(cell_forbidden_controls.begin(), cell_forbidden_controls.end());
1156 union_forbidden_controls.insert(other_cell_forbidden_controls.begin(), other_cell_forbidden_controls.end());
1158 if (!union_forbidden_controls.empty())
1159 log(
" Forbidden control signals for this pair of cells: %s\n",
log_signal(union_forbidden_controls));
1161 std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> filtered_cell_activation_patterns;
1162 std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> filtered_other_cell_activation_patterns;
1165 filter_activation_patterns(filtered_other_cell_activation_patterns, other_cell_activation_patterns, union_forbidden_controls);
1173 std::set<RTLIL::Cell*> sat_cells;
1174 std::set<RTLIL::SigBit> bits_queue;
1176 std::vector<int> cell_active, other_cell_active;
1179 for (
auto &p : filtered_cell_activation_patterns) {
1181 cell_active.push_back(ez.vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second)));
1182 all_ctrl_signals.
append(p.first);
1185 for (
auto &p : filtered_other_cell_activation_patterns) {
1187 other_cell_active.push_back(ez.vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second)));
1188 all_ctrl_signals.
append(p.first);
1192 bits_queue.insert(bit);
1195 bits_queue.insert(bit);
1197 while (!bits_queue.empty())
1199 std::set<ModWalker::PortBit> portbits;
1203 for (
auto &pbit : portbits)
1209 satgen.importCell(pbit.cell);
1210 sat_cells.insert(pbit.cell);
1213 if (config.
opt_fast && sat_cells.size() > 100)
1218 if (satgen.importedSigBit(it.first) && satgen.importedSigBit(it.second)) {
1220 ez.assume(ez.NOT(ez.AND(satgen.importSigBit(it.first), satgen.importSigBit(it.second))));
1223 if (!ez.solve(ez.expression(ez.OpOr, cell_active))) {
1224 log(
" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n",
log_id(cell));
1229 if (!ez.solve(ez.expression(ez.OpOr, other_cell_active))) {
1230 log(
" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n",
log_id(other_cell));
1236 ez.non_incremental();
1239 std::vector<int> sat_model = satgen.importSigSpec(all_ctrl_signals);
1240 std::vector<bool> sat_model_values;
1242 ez.assume(ez.AND(ez.expression(ez.OpOr, cell_active), ez.expression(ez.OpOr, other_cell_active)));
1244 log(
" Size of SAT problem: %d cells, %d variables, %d clauses\n",
1245 GetSize(sat_cells), ez.numCnfVariables(), ez.numCnfClauses());
1247 if (ez.solve(sat_model, sat_model_values)) {
1248 log(
" According to the SAT solver this pair of cells can not be shared.\n");
1249 log(
" Model from SAT solver: %s = %d'",
log_signal(all_ctrl_signals),
GetSize(sat_model_values));
1250 for (
int i =
GetSize(sat_model_values)-1; i >= 0; i--)
1251 log(
"%c", sat_model_values[i] ?
'1' :
'0');
1256 log(
" According to the SAT solver this pair of cells can be shared.\n");
1259 log(
" Sharing not possible: %s is in input cone of %s.\n",
log_id(other_cell),
log_id(cell));
1264 log(
" Sharing not possible: %s is in input cone of %s.\n",
log_id(cell),
log_id(other_cell));
1270 int cell_select_score = 0;
1271 int other_cell_select_score = 0;
1273 for (
auto &p : filtered_cell_activation_patterns)
1274 cell_select_score += p.first.size();
1276 for (
auto &p : filtered_other_cell_activation_patterns)
1277 other_cell_select_score += p.first.size();
1280 std::set<RTLIL::Cell*> supercell_aux;
1281 if (cell_select_score <= other_cell_select_score) {
1283 supercell =
make_supercell(cell, other_cell, act, supercell_aux);
1287 supercell =
make_supercell(other_cell, cell, act, supercell_aux);
1296 for (
auto c : supercell_aux)
1302 log(
" New topology contains loops! Rolling back..\n");
1306 for (
auto cc : supercell_aux)
1311 std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> supercell_activation_patterns;
1312 supercell_activation_patterns.insert(filtered_cell_activation_patterns.begin(), filtered_cell_activation_patterns.end());
1313 supercell_activation_patterns.insert(filtered_other_cell_activation_patterns.begin(), filtered_other_cell_activation_patterns.end());
1328 if (config.
limit > 0)
bool find_in_input_cone(RTLIL::Cell *root, RTLIL::Cell *needle)
void find_terminal_bits()
std::map< RTLIL::Cell *, std::set< RTLIL::SigBit > > cell_outputs
void find_shareable_cells()
std::map< RTLIL::Cell *, std::set< RTLIL::Cell *, cell_ptr_cmp >, cell_ptr_cmp > topo_cell_drivers
std::set< RTLIL::IdString > generic_other_ops
bool is_part_of_scc(RTLIL::Cell *cell)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
std::set< RTLIL::IdString > generic_uni_ops
std::set< RTLIL::Cell * > recursion_state
bool get_drivers(std::set< PortBit > &result, RTLIL::SigBit bit) const
const std::set< std::pair< RTLIL::SigSpec, RTLIL::Const > > & find_cell_activation_patterns(RTLIL::Cell *cell, const char *indent)
void filter_activation_patterns(std::set< std::pair< RTLIL::SigSpec, RTLIL::Const >> &out, const std::set< std::pair< RTLIL::SigSpec, RTLIL::Const >> &in, const std::set< RTLIL::SigBit > &filter_bits)
YOSYS_NAMESPACE_BEGIN typedef ezMiniSAT ezDefaultSAT
std::map< RTLIL::IdString, CellType > cell_types
bool cell_known(RTLIL::IdString type)
std::map< RTLIL::SigBit, std::set< RTLIL::Cell *, cell_ptr_cmp > > topo_bit_drivers
int GetSize(RTLIL::Wire *wire)
#define log_assert(_assert_expr_)
std::map< RTLIL::Cell *, std::set< RTLIL::SigBit > > cell_inputs
std::map< RTLIL::Cell *, std::set< std::pair< RTLIL::SigSpec, RTLIL::Const > > > activation_patterns_cache
void optimize_activation_patterns(std::set< std::pair< RTLIL::SigSpec, RTLIL::Const >> &)
std::set< RTLIL::IdString > generic_cbin_ops
RTLIL::ObjRange< RTLIL::Cell * > cells()
std::set< RTLIL::Cell *, RTLIL::sort_by_name_str< RTLIL::Cell > > shareable_cells
void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct=NULL)
void remove(const std::set< RTLIL::Wire * > &wires)
std::set< RTLIL::Cell * > cells_to_remove
void log(const char *format,...)
RTLIL::SigSpec bits_from_activation_patterns(const std::set< std::pair< RTLIL::SigSpec, RTLIL::Const >> &activation_patterns)
RTLIL::SigSpec make_cell_activation_logic(const std::set< std::pair< RTLIL::SigSpec, RTLIL::Const >> &activation_patterns, std::set< RTLIL::Cell * > &supercell_aux)
void append(const RTLIL::SigSpec &signal)
RTLIL::Cell * make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act, std::set< RTLIL::Cell * > &supercell_aux)
void find_shareable_partners(std::vector< RTLIL::Cell * > &results, RTLIL::Cell *cell)
const char * log_id(RTLIL::IdString str)
std::vector< std::pair< RTLIL::SigBit, RTLIL::SigBit > > exclusive_ctrls
std::vector< RTLIL::SigBit > to_sigbit_vector() const
std::set< RTLIL::IdString > generic_ops
const std::set< RTLIL::SigBit > & find_forbidden_controls(RTLIL::Cell *cell)
std::set< RTLIL::IdString > generic_bin_ops