diff options
-rw-r--r-- | kernel/celltypes.h | 19 | ||||
-rw-r--r-- | kernel/consteval.h | 9 | ||||
-rw-r--r-- | passes/equiv/equiv_make.cc | 27 |
3 files changed, 36 insertions, 19 deletions
diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 6041168bb..8b8a56111 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -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); } }; diff --git a/kernel/consteval.h b/kernel/consteval.h index 0229f5045..154373a8d 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -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; diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index 66ee28aff..dbd8682e6 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -290,22 +290,29 @@ struct EquivMakeWorker init_bit2driven(); - pool<Cell*> visited_cells; + pool<Cell*> visited_cells; for (auto c : cells_list) for (auto &conn : c->connections()) if (!ct.cell_output(c->type, conn.first)) { SigSpec old_sig = assign_map(conn.second); SigSpec new_sig = rd_signal_map(old_sig); - - visited_cells.clear(); - if (old_sig != new_sig) { - if (check_signal_in_fanout(visited_cells, old_sig, new_sig)) - continue; - log("Changing input %s of cell %s (%s): %s -> %s\n", - log_id(conn.first), log_id(c), log_id(c->type), - log_signal(old_sig), log_signal(new_sig)); - c->setPort(conn.first, new_sig); + if(old_sig != new_sig) { + SigSpec tmp_sig = old_sig; + for (int i = 0; i < GetSize(old_sig); i++) { + SigBit old_bit = old_sig[i], new_bit = new_sig[i]; + + visited_cells.clear(); + if (check_signal_in_fanout(visited_cells, old_bit, new_bit)) + continue; + + log("Changing input %s of cell %s (%s): %s -> %s\n", + log_id(conn.first), log_id(c), log_id(c->type), + log_signal(old_bit), log_signal(new_bit)); + + tmp_sig[i] = new_bit; + } + c->setPort(conn.first, tmp_sig); } } |