205 bool arith_undef_handled =
false;
206 bool is_arith_compare = cell->
type.
in(
"$lt",
"$le",
"$ge",
"$gt");
208 if (
model_undef && (cell->
type.
in(
"$add",
"$sub",
"$mul",
"$div",
"$mod") || is_arith_compare))
213 if (is_arith_compare)
220 int undef_y_bit =
ez->
OR(undef_any_a, undef_any_b);
222 if (cell->
type ==
"$div" || cell->
type ==
"$mod") {
227 if (is_arith_compare) {
228 for (
size_t i = 1; i < undef_y.size(); i++)
230 ez->
SET(undef_y_bit, undef_y.at(0));
232 std::vector<int> undef_y_bits(undef_y.size(), undef_y_bit);
236 arith_undef_handled =
true;
239 if (cell->
type.
in(
"$_AND_",
"$_NAND_",
"$_OR_",
"$_NOR_",
"$_XOR_",
"$_XNOR_",
240 "$and",
"$or",
"$xor",
"$xnor",
"$add",
"$sub"))
249 if (cell->
type ==
"$and" || cell->
type ==
"$_AND_")
251 if (cell->
type ==
"$_NAND_")
253 if (cell->
type ==
"$or" || cell->
type ==
"$_OR_")
255 if (cell->
type ==
"$_NOR_")
257 if (cell->
type ==
"$xor" || cell->
type ==
"$_XOR_")
259 if (cell->
type ==
"$xnor" || cell->
type ==
"$_XNOR_")
261 if (cell->
type ==
"$add")
263 if (cell->
type ==
"$sub")
273 if (cell->
type.
in(
"$and",
"$_AND_",
"$_NAND_")) {
279 else if (cell->
type.
in(
"$or",
"$_OR_",
"$_NOR_")) {
285 else if (cell->
type.
in(
"$xor",
"$xnor",
"$_XOR_",
"$_XNOR_")) {
286 std::vector<int> yX =
ez->
vec_or(undef_a, undef_b);
302 if (cell->
type.
in(
"$_AOI3_",
"$_OAI3_",
"$_AOI4_",
"$_OAI4_"))
304 bool aoi_mode = cell->
type.
in(
"$_AOI3_",
"$_AOI4_");
305 bool three_mode = cell->
type.
in(
"$_AOI3_",
"$_OAI3_");
314 if (cell->
type.
in(
"$_AOI3_",
"$_AOI4_"))
351 int ab =
ez->
OR(a, b), cd =
ez->
OR(c, d);
368 if (cell->
type ==
"$_NOT_" || cell->
type ==
"$not")
387 if (cell->
type ==
"$_MUX_" || cell->
type ==
"$mux")
405 std::vector<int> undef_ab =
ez->
vec_or(unequal_ab,
ez->
vec_or(undef_a, undef_b));
406 std::vector<int> yX =
ez->
vec_ite(undef_s.at(0), undef_ab,
ez->
vec_ite(s.at(0), undef_b, undef_a));
413 if (cell->
type ==
"$pmux")
422 std::vector<int> tmp = a;
423 for (
size_t i = 0; i < s.size(); i++) {
424 std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size());
425 tmp =
ez->
vec_ite(s.at(i), part_of_b, tmp);
442 std::vector<int> bits_set = std::vector<int>(undef_y.size(),
ez->
CONST_FALSE);
443 std::vector<int> bits_clr = std::vector<int>(undef_y.size(),
ez->
CONST_FALSE);
445 for (
size_t i = 0; i < s.size(); i++)
447 std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size());
448 std::vector<int> part_of_undef_b(undef_b.begin()+i*a.size(), undef_b.begin()+(i+1)*a.size());
450 int maybe_s =
ez->
OR(s.at(i), undef_s.at(i));
451 int sure_s =
ez->
AND(s.at(i),
ez->
NOT(undef_s.at(i)));
453 maybe_one_hot =
ez->
OR(maybe_one_hot, maybe_s);
454 maybe_many_hot =
ez->
OR(maybe_many_hot,
ez->
AND(maybe_one_hot, maybe_s));
456 sure_one_hot =
ez->
OR(sure_one_hot, sure_s);
457 sure_many_hot =
ez->
OR(sure_many_hot,
ez->
AND(sure_one_hot, sure_s));
463 int maybe_a =
ez->
NOT(maybe_one_hot);
474 if (cell->
type ==
"$pos" || cell->
type ==
"$neg")
482 if (cell->
type ==
"$pos") {
495 if (cell->
type ==
"$pos") {
499 std::vector<int> undef_y_bits(undef_y.size(), undef_any_a);
508 if (cell->
type ==
"$reduce_and" || cell->
type ==
"$reduce_or" || cell->
type ==
"$reduce_xor" ||
509 cell->
type ==
"$reduce_xnor" || cell->
type ==
"$reduce_bool" || cell->
type ==
"$logic_not")
516 if (cell->
type ==
"$reduce_and")
518 if (cell->
type ==
"$reduce_or" || cell->
type ==
"$reduce_bool")
520 if (cell->
type ==
"$reduce_xor")
522 if (cell->
type ==
"$reduce_xnor")
524 if (cell->
type ==
"$logic_not")
526 for (
size_t i = 1; i < y.size(); i++)
535 if (cell->
type ==
"$reduce_and") {
539 else if (cell->
type ==
"$reduce_or" || cell->
type ==
"$reduce_bool" || cell->
type ==
"$logic_not") {
543 else if (cell->
type ==
"$reduce_xor" || cell->
type ==
"$reduce_xnor") {
548 for (
size_t i = 1; i < undef_y.size(); i++)
556 if (cell->
type ==
"$logic_and" || cell->
type ==
"$logic_or")
567 if (cell->
type ==
"$logic_and")
571 for (
size_t i = 1; i < y.size(); i++)
587 if (cell->
type ==
"$logic_and")
589 else if (cell->
type ==
"$logic_or")
594 for (
size_t i = 1; i < undef_y.size(); i++)
602 if (cell->
type ==
"$lt" || cell->
type ==
"$le" || cell->
type ==
"$eq" || cell->
type ==
"$ne" || cell->
type ==
"$eqx" || cell->
type ==
"$nex" || cell->
type ==
"$ge" || cell->
type ==
"$gt")
604 bool is_signed = cell->
parameters[
"\\A_SIGNED"].as_bool() && cell->
parameters[
"\\B_SIGNED"].as_bool();
620 if (cell->
type ==
"$lt")
622 if (cell->
type ==
"$le")
624 if (cell->
type ==
"$eq" || cell->
type ==
"$eqx")
626 if (cell->
type ==
"$ne" || cell->
type ==
"$nex")
628 if (cell->
type ==
"$ge")
630 if (cell->
type ==
"$gt")
632 for (
size_t i = 1; i < y.size(); i++)
642 if (cell->
type ==
"$eqx")
645 yy.at(0) =
ez->
OR(yy.at(0),
ez->
vec_ne(undef_a, undef_b));
647 for (
size_t i = 0; i < y.size(); i++)
661 int undef_any =
ez->
OR(undef_any_a, undef_any_b);
663 std::vector<int> masked_a_bits =
ez->
vec_or(a,
ez->
vec_or(undef_a, undef_b));
664 std::vector<int> masked_b_bits =
ez->
vec_or(b,
ez->
vec_or(undef_a, undef_b));
666 int masked_ne =
ez->
vec_ne(masked_a_bits, masked_b_bits);
667 int undef_y_bit =
ez->
AND(undef_any,
ez->
NOT(masked_ne));
669 for (
size_t i = 1; i < undef_y.size(); i++)
671 ez->
SET(undef_y_bit, undef_y.at(0));
686 if (cell->
type ==
"$shl" || cell->
type ==
"$shr" || cell->
type ==
"$sshl" || cell->
type ==
"$sshr" || cell->
type ==
"$shift" || cell->
type ==
"$shiftx")
694 if (!cell->
type.
in(
"$shift",
"$shiftx") && cell->
parameters[
"\\A_SIGNED"].as_bool())
695 extend_bit = a.back();
697 while (y.size() < a.size())
699 while (y.size() > a.size())
700 a.push_back(extend_bit);
703 std::vector<int> shifted_a;
705 if (cell->
type ==
"$shl" || cell->
type ==
"$sshl")
708 if (cell->
type ==
"$shr")
711 if (cell->
type ==
"$sshr")
714 if (cell->
type ==
"$shift" || cell->
type ==
"$shiftx")
724 std::vector<int> undef_a_shifted;
727 if (!cell->
type.
in(
"$shift",
"$shiftx") && cell->
parameters[
"\\A_SIGNED"].as_bool())
728 extend_bit = undef_a.back();
730 while (undef_y.size() < undef_a.size())
732 while (undef_y.size() > undef_a.size())
733 undef_a.push_back(extend_bit);
735 if (cell->
type ==
"$shl" || cell->
type ==
"$sshl")
738 if (cell->
type ==
"$shr")
741 if (cell->
type ==
"$sshr")
744 if (cell->
type ==
"$shift")
747 if (cell->
type ==
"$shiftx")
751 std::vector<int> undef_all_y_bits(undef_y.size(), undef_any_b);
758 if (cell->
type ==
"$mul")
768 for (
int i = 0; i < int(a.size()); i++)
771 for (
int j = i; j < int(a.size()); j++)
772 shifted_a.at(j) = a.at(j-i);
785 if (cell->
type ==
"$macc")
796 for (
auto &port : macc.ports)
802 in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() :
ez->
CONST_FALSE);
808 in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() :
ez->
CONST_FALSE);
811 for (
int i = 0; i <
GetSize(in_b); i++) {
813 for (
int j = i; j < int(in_a.size()); j++)
814 shifted_a.at(j) = in_a.at(j-i);
815 if (port.do_subtract)
823 if (port.do_subtract)
830 for (
int i = 0; i <
GetSize(b); i++) {
855 if (cell->
type ==
"$div" || cell->
type ==
"$mod")
864 std::vector<int> a_u, b_u;
873 std::vector<int> chain_buf = a_u;
875 for (
int i =
int(a.size())-1; i >= 0; i--)
877 chain_buf.insert(chain_buf.end(), chain_buf.size(),
ez->
CONST_FALSE);
880 b_shl.insert(b_shl.end(), b_u.begin(), b_u.end());
881 b_shl.insert(b_shl.end(), chain_buf.size()-b_shl.size(),
ez->
CONST_FALSE);
886 chain_buf.erase(chain_buf.begin() + a_u.size(), chain_buf.end());
890 if (cell->
type ==
"$div") {
905 std::vector<int> div_zero_result;
906 if (cell->
type ==
"$div") {
911 div_zero_result =
ez->
vec_ite(a.back(), only_first_one, all_ones);
914 div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(),
ez->
CONST_FALSE);
918 div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits);
920 div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back());
922 div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(),
ez->
CONST_FALSE);
935 if (cell->
type ==
"$lut")
940 std::vector<int> lut;
952 for (
int i =
GetSize(a)-1; i >= 0; i--)
954 std::vector<int> t0(t.begin(), t.begin() +
GetSize(t)/2);
955 std::vector<int> t1(t.begin() +
GetSize(t)/2, t.end());
957 std::vector<int> u0(u.begin(), u.begin() +
GetSize(u)/2);
958 std::vector<int> u1(u.begin() +
GetSize(u)/2, u.end());
971 std::vector<int> t = lut;
972 for (
int i =
GetSize(a)-1; i >= 0; i--)
974 std::vector<int> t0(t.begin(), t.begin() +
GetSize(t)/2);
975 std::vector<int> t1(t.begin() +
GetSize(t)/2, t.end());
985 if (cell->
type ==
"$fa")
1000 std::vector<int> t3 =
ez->
vec_and(c, t1);
1021 if (cell->
type ==
"$lcu")
1030 for (
int i = 0; i <
GetSize(co); i++)
1031 ez->
SET(yy[i],
ez->
OR(g[i],
ez->
AND(p[i], i ? yy[i-1] : ci[0])));
1043 int undef_co_bit =
ez->
OR(undef_any_p, undef_any_g, undef_any_ci);
1045 std::vector<int> undef_co_bits(undef_co.size(), undef_co_bit);
1053 if (cell->
type ==
"$alu")
1076 for (
int i = 0; i <
GetSize(y); i++)
1078 int s1 = a.at(i), s2 =
ez->
XOR(b.at(i), bi.at(0)), s3 = i ? co.at(i-1) : ci.at(0);
1080 ez->
SET(def_y.at(i),
ez->
XOR(def_x.at(i), s3));
1099 std::vector<int> all_inputs_undef;
1100 all_inputs_undef.insert(all_inputs_undef.end(), undef_a.begin(), undef_a.end());
1101 all_inputs_undef.insert(all_inputs_undef.end(), undef_b.begin(), undef_b.end());
1102 all_inputs_undef.insert(all_inputs_undef.end(), undef_ci.begin(), undef_ci.end());
1103 all_inputs_undef.insert(all_inputs_undef.end(), undef_bi.begin(), undef_bi.end());
1106 for (
int i = 0; i <
GetSize(undef_y); i++) {
1107 ez->
SET(undef_y.at(i), undef_any);
1108 ez->
SET(undef_x.at(i),
ez->
OR(undef_a.at(i), undef_b.at(i), undef_bi.at(0)));
1109 ez->
SET(undef_co.at(i), undef_any);
1119 if (cell->
type ==
"$slice")
1127 if (cell->
type ==
"$concat")
1140 if (timestep > 0 && (cell->
type ==
"$dff" || cell->
type ==
"$_DFF_N_" || cell->
type ==
"$_DFF_P_"))
1166 if (cell->
type ==
"$assert")
1168 std::string pf =
prefix + (timestep == -1 ?
"" :
stringf(
"@%d:", timestep));
std::vector< int > vec_sub(const std::vector< int > &vec1, const std::vector< int > &vec2)
void extendSignalWidth(std::vector< int > &vec_a, std::vector< int > &vec_b, RTLIL::Cell *cell, size_t y_width=0, bool forced_signed=false)
int vec_ge_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
std::string stringf(const char *fmt,...)
std::vector< int > vec_var(int numBits)
std::map< std::string, RTLIL::SigSpec > asserts_en
static const int CONST_FALSE
std::vector< int > vec_iff(const std::vector< int > &vec1, const std::vector< int > &vec2)
int vec_le_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
int vec_lt_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
std::vector< int > importSigSpec(RTLIL::SigSpec sig, int timestep=-1)
std::map< RTLIL::IdString, RTLIL::Const > parameters
int AND(_V a=0, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
std::vector< int > vec_or(const std::vector< int > &vec1, const std::vector< int > &vec2)
bool in(T first, Args...rest)
std::vector< int > importUndefSigSpec(RTLIL::SigSpec sig, int timestep=-1)
int vec_gt_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
std::vector< int > vec_neg(const std::vector< int > &vec)
std::vector< int > importDefSigSpec(RTLIL::SigSpec sig, int timestep=-1)
int vec_ne(const std::vector< int > &vec1, const std::vector< int > &vec2)
std::vector< int > vec_shift_left(const std::vector< int > &vec1, const std::vector< int > &vec2, bool vec2_signed, int extend_left, int extend_right)
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
int GetSize(RTLIL::Wire *wire)
#define log_assert(_assert_expr_)
std::vector< int > vec_shift_right(const std::vector< int > &vec1, const std::vector< int > &vec2, bool vec2_signed, int extend_left, int extend_right)
void from_cell(RTLIL::Cell *cell)
std::vector< int > vec_xor(const std::vector< int > &vec1, const std::vector< int > &vec2)
int vec_gt_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
std::map< std::string, RTLIL::SigSpec > asserts_a
void add(RTLIL::SigSpec sig)
static const int CONST_TRUE
std::vector< int > vec_add(const std::vector< int > &vec1, const std::vector< int > &vec2)
std::vector< int > vec_ite(const std::vector< int > &vec1, const std::vector< int > &vec2, const std::vector< int > &vec3)
const RTLIL::Const & getParam(RTLIL::IdString paramname) const
void undefGating(std::vector< int > &vec_y, std::vector< int > &vec_yy, std::vector< int > &vec_undef)
int XOR(_V a=0, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
int expression(OpId op, int a=0, int b=0, int c=0, int d=0, int e=0, int f=0)
std::vector< RTLIL::State > bits
int vec_eq(const std::vector< int > &vec1, const std::vector< int > &vec2)
int vec_lt_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
void append(const RTLIL::SigSpec &signal)
int OR(_V a=0, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
int IFF(_V a, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
std::vector< int > vec_not(const std::vector< int > &vec1)
int vec_ge_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
int vec_le_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
int signals_eq(RTLIL::SigSpec lhs, RTLIL::SigSpec rhs, int timestep_lhs=-1, int timestep_rhs=-1)
void extendSignalWidthUnary(std::vector< int > &vec_a, std::vector< int > &vec_y, RTLIL::Cell *cell, bool forced_signed=false)
std::vector< int > vec_and(const std::vector< int > &vec1, const std::vector< int > &vec2)