42         if (cells.count(cell) == 0)
 
   47         std::set<RTLIL::SigBit> new_sig_a_bits;
 
   52                 if (cell->
type == 
"$reduce_and") {
 
   53                     new_sig_a_bits.
clear();
 
   60                 if (cell->
type == 
"$reduce_or") {
 
   61                     new_sig_a_bits.clear();
 
   67             if (bit.wire == 
NULL) {
 
   68                 new_sig_a_bits.insert(bit);
 
   72             bool imported_children = 
false;
 
   73             for (
auto child_cell : drivers.
find(bit)) {
 
   74                 if (child_cell->type == cell->
type) {
 
   76                     if (child_cell->getPort(
"\\Y")[0] == bit) {
 
   77                         std::set<RTLIL::SigBit> child_sig_a_bits = 
assign_map(child_cell->getPort(
"\\A")).to_sigbit_set();
 
   78                         new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end());
 
   81                     imported_children = 
true;
 
   84             if (!imported_children)
 
   85                 new_sig_a_bits.insert(bit);
 
   90         if (new_sig_a != sig_a || sig_a.
size() != cell->
getPort(
"\\A").
size()) {
 
   96         cell->
setPort(
"\\A", new_sig_a);
 
  108         std::set<RTLIL::SigSpec> handled_sig;
 
  110         handled_sig.insert(sig_a);
 
  111         for (
int i = 0; i < sig_s.size(); i++)
 
  114             if (handled_sig.count(this_b) > 0)
 
  118             for (
int j = i+1; j < sig_s.size(); j++) {
 
  120                 if (this_b == that_b)
 
  121                     this_s.
append(sig_s.extract(j, 1));
 
  124             if (this_s.
size() > 1)
 
  127                 reduce_or_cell->
setPort(
"\\A", this_s);
 
  134                 reduce_or_cell->
setPort(
"\\Y", this_s);
 
  137             new_sig_b.append(this_b);
 
  138             new_sig_s.append(this_s);
 
  139             handled_sig.insert(this_b);
 
  142         if (new_sig_s.size() != sig_s.size()) {
 
  148         if (new_sig_s.size() == 0)
 
  156             cell->
setPort(
"\\B", new_sig_b);
 
  157             cell->
setPort(
"\\S", new_sig_s);
 
  158             if (new_sig_s.size() > 1) {
 
  169         std::vector<RTLIL::SigBit> sig_a = 
assign_map(cell->
getPort(
"\\A")).to_sigbit_vector();
 
  170         std::vector<RTLIL::SigBit> sig_b = 
assign_map(cell->
getPort(
"\\B")).to_sigbit_vector();
 
  171         std::vector<RTLIL::SigBit> sig_y = 
assign_map(cell->
getPort(
"\\Y")).to_sigbit_vector();
 
  173         std::vector<RTLIL::SigBit> new_sig_y;
 
  176         std::vector<std::vector<RTLIL::SigBit>> consolidated_in_tuples;
 
  177         std::map<std::vector<RTLIL::SigBit>, 
RTLIL::SigBit> consolidated_in_tuples_map;
 
  179         for (
int i = 0; i < int(sig_y.size()); i++)
 
  181             std::vector<RTLIL::SigBit> in_tuple;
 
  182             bool all_tuple_bits_same = 
true;
 
  184             in_tuple.push_back(sig_a.at(i));
 
  185             for (
int j = i; j < int(sig_b.size()); j += int(sig_a.size())) {
 
  186                 if (sig_b.at(j) != sig_a.at(i))
 
  187                     all_tuple_bits_same = 
false;
 
  188                 in_tuple.push_back(sig_b.at(j));
 
  191             if (all_tuple_bits_same)
 
  193                 old_sig_conn.first.append_bit(sig_y.at(i));
 
  194                 old_sig_conn.second.append_bit(sig_a.at(i));
 
  196             else if (consolidated_in_tuples_map.count(in_tuple))
 
  198                 old_sig_conn.first.append_bit(sig_y.at(i));
 
  199                 old_sig_conn.second.append_bit(consolidated_in_tuples_map.at(in_tuple));
 
  203                 consolidated_in_tuples_map[in_tuple] = sig_y.at(i);
 
  204                 consolidated_in_tuples.push_back(in_tuple);
 
  205                 new_sig_y.push_back(sig_y.at(i));
 
  209         if (new_sig_y.size() != sig_y.size())
 
  216             for (
auto &in_tuple : consolidated_in_tuples) {
 
  218                 new_a.
append(in_tuple.at(0));
 
  223             for (
int i = 1; i <= cell->
getPort(
"\\S").
size(); i++)
 
  224                 for (
auto &in_tuple : consolidated_in_tuples) {
 
  226                     new_b.
append(in_tuple.at(i));
 
  231             cell->
setPort(
"\\Y", new_sig_y);
 
  246             design(design), module(module), 
assign_map(module)
 
  248         log(
"  Optimizing cells in module %s.\n", module->
name.
c_str());
 
  254         for (
auto &cell_it : module->
cells_) {
 
  256             if (cell->
type == 
"$mem")
 
  258             if (cell->
type == 
"$memwr")
 
  261         for (
auto &cell_it : module->
cells_) {
 
  267         bool keep_expanding_mem_wren_sigs = 
true;
 
  268         while (keep_expanding_mem_wren_sigs) {
 
  269             keep_expanding_mem_wren_sigs = 
false;
 
  270             for (
auto &cell_it : module->
cells_) {
 
  275                         keep_expanding_mem_wren_sigs = 
true;
 
  289             const char *type_list[] = { 
"$reduce_or", 
"$reduce_and" };
 
  290             for (
auto type : type_list)
 
  293                 std::set<RTLIL::Cell*> cells;
 
  295                 for (
auto &cell_it : module->
cells_) {
 
  297                     if (cell->
type != type || !design->
selected(module, cell))
 
  303                 while (cells.size() > 0) {
 
  311             std::vector<RTLIL::Cell*> cells;
 
  313             for (
auto &it : module->
cells_)
 
  314                 if ((it.second->type == 
"$mux" || it.second->type == 
"$pmux") && design->
selected(module, it.second))
 
  315                     cells.push_back(it.second);
 
  317             for (
auto cell : cells)
 
  336         log(
"    opt_reduce [options] [selection]\n");
 
  338         log(
"This pass performs two interlinked optimizations:\n");
 
  340         log(
"1. it consolidates trees of large AND gates or OR gates and eliminates\n");
 
  341         log(
"duplicated inputs.\n");
 
  343         log(
"2. it identifies duplicated inputs to MUXes and replaces them with a single\n");
 
  344         log(
"input with the original control signals OR'ed together.\n");
 
  347         log(
"      perform fine-grain optimizations\n");
 
  350         log(
"      alias for -fine\n");
 
  355         bool do_fine = 
false;
 
  357         log_header(
"Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs).\n");
 
  360         for (argidx = 1; argidx < args.size(); argidx++) {
 
  361             if (args[argidx] == 
"-fine") {
 
  365             if (args[argidx] == 
"-full") {
 
  374         for (
auto &mod_it : design->
modules_) {
 
  375             if (!design->
selected(mod_it.second))
 
  387         log(
"Performed a total of %d changes.\n", total_count);
 
const char * c_str() const 
bool selected(T1 *module) const 
OptReduceWorker(RTLIL::Design *design, RTLIL::Module *module, bool do_fine)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void log_header(const char *format,...)
std::set< RTLIL::SigBit > to_sigbit_set() const 
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
void opt_mux(RTLIL::Cell *cell)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
std::map< RTLIL::IdString, RTLIL::Const > parameters
bool check_any(RTLIL::SigSpec sig)
void connect(const RTLIL::SigSig &conn)
#define PRIVATE_NAMESPACE_BEGIN
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const 
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
void opt_reduce(std::set< RTLIL::Cell * > &cells, SigSet< RTLIL::Cell * > &drivers, RTLIL::Cell *cell)
#define PRIVATE_NAMESPACE_END
bool check_all(RTLIL::SigSpec sig)
void opt_mux_bits(RTLIL::Cell *cell)
void add(RTLIL::SigSpec sig)
#define USING_YOSYS_NAMESPACE
std::map< RTLIL::IdString, RTLIL::Module * > modules_
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
void remove(const std::set< RTLIL::Wire * > &wires)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
void log(const char *format,...)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const 
void scratchpad_set_bool(std::string varname, bool value)
void append(const RTLIL::SigSpec &signal)
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
std::pair< SigSpec, SigSpec > SigSig
void find(RTLIL::SigSpec sig, std::set< T > &result)
void insert(RTLIL::SigSpec sig, T data)
OptReducePass OptReducePass