Add optimization of (a && 1'b1) and (a || 1'b0)
authorClifford Wolf <clifford@clifford.at>
Sat, 11 Feb 2017 09:01:17 +0000 (10:01 +0100)
committerClifford Wolf <clifford@clifford.at>
Sat, 11 Feb 2017 09:05:00 +0000 (10:05 +0100)
passes/opt/opt_expr.cc

index 7afb380a2d447f8b514602aa13bfb2ce8920439e..9ccc230e88f5fade14f20872e078bbd4371f39f3 100644 (file)
@@ -383,7 +383,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                if (detect_const_and || detect_const_or)
                {
                        pool<SigBit> input_bits = assign_map(cell->getPort("\\A")).to_sigbit_pool();
-                       bool found_zero = false, found_one = false, found_inv = false;
+                       bool found_zero = false, found_one = false, found_undef = false, found_inv = false, many_conconst = false;
+                       SigBit non_const_input = State::Sm;
 
                        if (cell->hasPort("\\B")) {
                                vector<SigBit> more_bits = assign_map(cell->getPort("\\B")).to_sigbit_vector();
@@ -391,12 +392,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                        }
 
                        for (auto bit : input_bits) {
-                               if (bit == State::S0)
-                                       found_zero = true;
-                               if (bit == State::S1)
-                                       found_one = true;
-                               if (invert_map.count(bit) && input_bits.count(invert_map.at(bit)))
-                                       found_inv = true;
+                               if (bit.wire) {
+                                       if (invert_map.count(bit) && input_bits.count(invert_map.at(bit)))
+                                               found_inv = true;
+                                       if (non_const_input != State::Sm)
+                                               many_conconst = true;
+                                       non_const_input = many_conconst ? State::Sm : bit;
+                               } else {
+                                       if (bit == State::S0)
+                                               found_zero = true;
+                                       else if (bit == State::S1)
+                                               found_one = true;
+                                       else
+                                               found_undef = true;
+                               }
                        }
 
                        if (detect_const_and && (found_zero || found_inv)) {
@@ -410,6 +419,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                                replace_cell(assign_map, module, cell, "const_or", "\\Y", RTLIL::State::S1);
                                goto next_cell;
                        }
+
+                       if (non_const_input != State::Sm && !found_undef) {
+                               cover("opt.opt_expr.and_or_buffer");
+                               replace_cell(assign_map, module, cell, "and_or_buffer", "\\Y", non_const_input);
+                               goto next_cell;
+                       }
                }
 
                if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool", "$reduce_xor", "$reduce_xnor", "$neg") &&