Improve ConstEval error handling for non-eval cell types
authorClifford Wolf <clifford@clifford.at>
Thu, 29 Nov 2018 04:07:40 +0000 (05:07 +0100)
committerClifford Wolf <clifford@clifford.at>
Thu, 29 Nov 2018 04:07:40 +0000 (05:07 +0100)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
kernel/celltypes.h
kernel/consteval.h

index 6041168bb7274e49b218fe0eb88bb403287d81ad..8b8a561118b866dbe76d17b7cec336b8db0123fd 100644 (file)
@@ -257,7 +257,7 @@ struct CellTypes
                return v;
        }
 
-       static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
+       static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)
        {
                if (type == "$sshr" && !signed1)
                        type = "$shr";
@@ -329,10 +329,15 @@ struct CellTypes
                if (type == "$_ORNOT_")
                        return const_or(arg1, eval_not(arg2), false, false, 1);
 
+               if (errp != nullptr) {
+                       *errp = true;
+                       return State::Sm;
+               }
+
                log_abort();
        }
 
-       static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2)
+       static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)
        {
                if (cell->type == "$slice") {
                        RTLIL::Const ret;
@@ -415,10 +420,10 @@ struct CellTypes
                bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool();
                bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool();
                int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1;
-               return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len);
+               return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
        }
 
-       static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
+       static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
        {
                if (cell->type.in("$mux", "$pmux", "$_MUX_")) {
                        RTLIL::Const ret = arg1;
@@ -436,10 +441,10 @@ struct CellTypes
                        return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));
 
                log_assert(arg3.bits.size() == 0);
-               return eval(cell, arg1, arg2);
+               return eval(cell, arg1, arg2, errp);
        }
 
-       static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4)
+       static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr)
        {
                if (cell->type == "$_AOI4_")
                        return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
@@ -447,7 +452,7 @@ struct CellTypes
                        return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
 
                log_assert(arg4.bits.size() == 0);
-               return eval(cell, arg1, arg2, arg3);
+               return eval(cell, arg1, arg2, arg3, errp);
        }
 };
 
index 0229f5045419abcbc42ae77bb22007605b17782a..154373a8deeef29bb2223ae6029d4ffeb167a31c 100644 (file)
@@ -321,8 +321,13 @@ struct ConstEval
                        if (sig_d.size() > 0 && !eval(sig_d, undef, cell))
                                return false;
 
-                       set(sig_y, CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(),
-                                       sig_c.as_const(), sig_d.as_const()));
+                       bool eval_err = false;
+                       RTLIL::Const eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_c.as_const(), sig_d.as_const(), &eval_err);
+
+                       if (eval_err)
+                               return false;
+
+                       set(sig_y, eval_ret);
                }
 
                return true;