Fix issue #306, "Bug in opt -full"
authorC-Elegans <mtnolan2640@gmail.com>
Fri, 10 Feb 2017 15:28:19 +0000 (10:28 -0500)
committerC-Elegans <mtnolan2640@gmail.com>
Fri, 10 Feb 2017 15:38:02 +0000 (10:38 -0500)
Add check for whether the high bit in the constant expression is greater
than the width of the variable, and optimizes that to a constant 1 or
0

passes/opt/opt_expr.cc

index b3f2e87ed51cb1b31da276e164f8c5261d487225..7afb380a2d447f8b514602aa13bfb2ce8920439e 100644 (file)
@@ -1208,6 +1208,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 
                        //width of the variable port
                        int width;
+                       int const_width;
 
                        bool var_signed;
 
@@ -1216,6 +1217,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                                sigVar = cell->getPort("\\A");
                                sigConst = cell->getPort("\\B");
                                width = cell->parameters["\\A_WIDTH"].as_int();
+                               const_width = cell->parameters["\\B_WIDTH"].as_int();
                                var_signed = cell->parameters["\\A_SIGNED"].as_bool();
                        } else
                        if (cell->type == "$gt" || cell->type == "$le") {
@@ -1223,6 +1225,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                                sigVar = cell->getPort("\\B");
                                sigConst = cell->getPort("\\A");
                                width = cell->parameters["\\B_WIDTH"].as_int();
+                               const_width = cell->parameters["\\A_WIDTH"].as_int();
                                var_signed = cell->parameters["\\B_SIGNED"].as_bool();
                        }
 
@@ -1265,7 +1268,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                                }
 
                                int const_bit_set = get_onehot_bit_index(sigConst);
-                               if (const_bit_set >= 0) {
+                               if (const_bit_set >= 0 && const_bit_set < width) {
                                        int bit_set = const_bit_set;
                                        RTLIL::SigSpec a_prime(RTLIL::State::S0, width - bit_set);
                                        for (int i = bit_set; i < width; i++) {
@@ -1284,6 +1287,21 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
                                        did_something = true;
                                        goto next_cell;
                                }
+                               else if(const_bit_set >= width && const_bit_set >= 0){
+                                       RTLIL::SigSpec a_prime(RTLIL::State::S0, 1);
+                                       if(is_lt){
+                                               a_prime[0] = RTLIL::State::S1;
+                                               log("Replacing %s cell `%s' (implementing unsigned X[%d:0] < %s[%d:0]) with constant 0.\n", log_id(cell->type), log_id(cell), width-1, log_signal(sigConst),const_width-1); 
+                                       }
+                                       else{
+                                               log("Replacing %s cell `%s' (implementing unsigned X[%d:0]>= %s[%d:0]) with constant 1.\n", log_id(cell->type), log_id(cell), width-1, log_signal(sigConst),const_width-1); 
+                                       }
+                                       module->connect(cell->getPort("\\Y"), a_prime);
+                                       module->remove(cell);
+                                       did_something = true;
+                                       goto next_cell;
+
+                               }
                        }
                }