Added wreduce $mul support and fixed signed $mul opt_const bug
authorClifford Wolf <clifford@clifford.at>
Fri, 25 Sep 2015 15:27:06 +0000 (17:27 +0200)
committerClifford Wolf <clifford@clifford.at>
Fri, 25 Sep 2015 15:27:06 +0000 (17:27 +0200)
passes/opt/opt_const.cc
passes/opt/wreduce.cc

index 6295b88814e721c45f07309613b2291bfe9bd41d..85e4c4c189a5d3f19e559b5c4db300e5345f700f 100644 (file)
@@ -228,6 +228,37 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, IdStrin
        }
 }
 
+bool is_one_or_minus_one(const Const &value, bool is_signed, bool &is_negative)
+{
+       bool all_bits_one = true;
+       bool last_bit_one = true;
+
+       if (GetSize(value.bits) < 1)
+               return false;
+
+       if (GetSize(value.bits) == 1) {
+               if (value.bits[0] != State::S1)
+                       return false;
+               if (is_signed)
+                       is_negative = true;
+               return true;
+       }
+
+       for (int i = 0; i < GetSize(value.bits); i++) {
+               if (value.bits[i] != State::S1)
+                       all_bits_one = false;
+               if (value.bits[i] != (i ? State::S0 : State::S1))
+                       last_bit_one = false;
+       }
+
+       if (all_bits_one && is_signed) {
+               is_negative = true;
+               return true;
+       }
+
+       return last_bit_one;
+}
+
 void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool clkinv)
 {
        if (!design->selected(module))
@@ -684,6 +715,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                {
                        bool identity_wrt_a = false;
                        bool identity_wrt_b = false;
+                       bool arith_inverse = false;
 
                        if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$or" || cell->type == "$xor")
                        {
@@ -710,10 +742,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                                RTLIL::SigSpec a = assign_map(cell->getPort("\\A"));
                                RTLIL::SigSpec b = assign_map(cell->getPort("\\B"));
 
-                               if (a.is_fully_const() && a.size() <= 32 && a.as_int() == 1)
+                               if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam("\\A_SIGNED").as_bool(), arith_inverse))
                                        identity_wrt_b = true;
-
-                               if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1)
+                               else
+                               if (b.is_fully_const() && is_one_or_minus_one(b.as_const(), cell->getParam("\\B_SIGNED").as_bool(), arith_inverse))
                                        identity_wrt_a = true;
                        }
 
@@ -741,7 +773,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                                        cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED");
                                }
 
-                               cell->type = "$pos";
+                               cell->type = arith_inverse ? "$neg" : "$pos";
                                cell->unsetPort("\\B");
                                cell->parameters.erase("\\B_WIDTH");
                                cell->parameters.erase("\\B_SIGNED");
index dfcfebf4bc3a6ac70597e48da455e581936cc83f..e551443ff4be1c3f62f06e375765a5ca2926b709 100644 (file)
@@ -37,7 +37,7 @@ struct WreduceConfig
                        "$and", "$or", "$xor", "$xnor",
                        "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
                        "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
-                       "$add", "$sub", // "$mul", "$div", "$mod", "$pow",
+                       "$add", "$sub", "$mul", // "$div", "$mod", "$pow",
                        "$mux", "$pmux"
                });
        }