3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-24 01:25:33 +00:00

Merge branch 'YosysHQ:main' into main

This commit is contained in:
Akash Levy 2024-10-14 11:21:54 -07:00 committed by GitHub
commit 469f5a707a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
92 changed files with 970 additions and 652 deletions

View file

@ -80,7 +80,7 @@ struct BitPatternPool
bits_t sig2bits(RTLIL::SigSpec sig)
{
bits_t bits;
bits.bitdata = sig.as_const().bits;
bits.bitdata = sig.as_const().bits();
for (auto &b : bits.bitdata)
if (b > RTLIL::State::S1)
b = RTLIL::State::Sa;

View file

@ -30,13 +30,13 @@ static void extend_u0(RTLIL::Const &arg, int width, bool is_signed)
{
RTLIL::State padding = RTLIL::State::S0;
if (arg.bits.size() > 0 && is_signed)
padding = arg.bits.back();
if (arg.size() > 0 && is_signed)
padding = arg.back();
while (int(arg.bits.size()) < width)
arg.bits.push_back(padding);
while (int(arg.size()) < width)
arg.bits().push_back(padding);
arg.bits.resize(width);
arg.bits().resize(width);
}
static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_bit_pos)
@ -45,17 +45,17 @@ static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_
BigInteger::Sign sign = BigInteger::positive;
State inv_sign_bit = RTLIL::State::S1;
size_t num_bits = val.bits.size();
size_t num_bits = val.size();
if (as_signed && num_bits && val.bits[num_bits-1] == RTLIL::State::S1) {
if (as_signed && num_bits && val[num_bits-1] == RTLIL::State::S1) {
inv_sign_bit = RTLIL::State::S0;
sign = BigInteger::negative;
num_bits--;
}
for (size_t i = 0; i < num_bits; i++)
if (val.bits[i] == RTLIL::State::S0 || val.bits[i] == RTLIL::State::S1)
mag.setBit(i, val.bits[i] == inv_sign_bit);
if (val[i] == RTLIL::State::S0 || val[i] == RTLIL::State::S1)
mag.setBit(i, val[i] == inv_sign_bit);
else if (undef_bit_pos < 0)
undef_bit_pos = i;
@ -79,19 +79,19 @@ static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_b
{
mag--;
for (int i = 0; i < result_len; i++)
result.bits[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1;
result.bits()[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1;
}
else
{
for (int i = 0; i < result_len; i++)
result.bits[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0;
result.bits()[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0;
}
}
#if 0
if (undef_bit_pos >= 0)
for (int i = undef_bit_pos; i < result_len; i++)
result.bits[i] = RTLIL::State::Sx;
result[i] = RTLIL::State::Sx;
#endif
return result;
@ -132,19 +132,19 @@ static RTLIL::State logic_xnor(RTLIL::State a, RTLIL::State b)
RTLIL::Const RTLIL::const_not(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
{
if (result_len < 0)
result_len = arg1.bits.size();
result_len = arg1.size();
RTLIL::Const arg1_ext = arg1;
extend_u0(arg1_ext, result_len, signed1);
RTLIL::Const result(RTLIL::State::Sx, result_len);
for (size_t i = 0; i < size_t(result_len); i++) {
if (i >= arg1_ext.bits.size())
result.bits[i] = RTLIL::State::S0;
else if (arg1_ext.bits[i] == RTLIL::State::S0)
result.bits[i] = RTLIL::State::S1;
else if (arg1_ext.bits[i] == RTLIL::State::S1)
result.bits[i] = RTLIL::State::S0;
if (i >= arg1_ext.size())
result.bits()[i] = RTLIL::State::S0;
else if (arg1_ext.bits()[i] == RTLIL::State::S0)
result.bits()[i] = RTLIL::State::S1;
else if (arg1_ext.bits()[i] == RTLIL::State::S1)
result.bits()[i] = RTLIL::State::S0;
}
return result;
@ -154,16 +154,16 @@ static RTLIL::Const logic_wrapper(RTLIL::State(*logic_func)(RTLIL::State, RTLIL:
RTLIL::Const arg1, RTLIL::Const arg2, bool signed1, bool signed2, int result_len = -1)
{
if (result_len < 0)
result_len = max(arg1.bits.size(), arg2.bits.size());
result_len = max(arg1.size(), arg2.size());
extend_u0(arg1, result_len, signed1);
extend_u0(arg2, result_len, signed2);
RTLIL::Const result(RTLIL::State::Sx, result_len);
for (size_t i = 0; i < size_t(result_len); i++) {
RTLIL::State a = i < arg1.bits.size() ? arg1.bits[i] : RTLIL::State::S0;
RTLIL::State b = i < arg2.bits.size() ? arg2.bits[i] : RTLIL::State::S0;
result.bits[i] = logic_func(a, b);
RTLIL::State a = i < arg1.size() ? arg1.bits()[i] : RTLIL::State::S0;
RTLIL::State b = i < arg2.size() ? arg2.bits()[i] : RTLIL::State::S0;
result.bits()[i] = logic_func(a, b);
}
return result;
@ -193,12 +193,12 @@ static RTLIL::Const logic_reduce_wrapper(RTLIL::State initial, RTLIL::State(*log
{
RTLIL::State temp = initial;
for (size_t i = 0; i < arg1.bits.size(); i++)
temp = logic_func(temp, arg1.bits[i]);
for (size_t i = 0; i < arg1.size(); i++)
temp = logic_func(temp, arg1[i]);
RTLIL::Const result(temp);
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -220,11 +220,11 @@ RTLIL::Const RTLIL::const_reduce_xor(const RTLIL::Const &arg1, const RTLIL::Cons
RTLIL::Const RTLIL::const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Const&, bool, bool, int result_len)
{
RTLIL::Const buffer = logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len);
if (!buffer.bits.empty()) {
if (buffer.bits.front() == RTLIL::State::S0)
buffer.bits.front() = RTLIL::State::S1;
else if (buffer.bits.front() == RTLIL::State::S1)
buffer.bits.front() = RTLIL::State::S0;
if (!buffer.empty()) {
if (buffer.front() == RTLIL::State::S0)
buffer.bits().front() = RTLIL::State::S1;
else if (buffer.front() == RTLIL::State::S1)
buffer.bits().front() = RTLIL::State::S0;
}
return buffer;
}
@ -240,8 +240,8 @@ RTLIL::Const RTLIL::const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const
BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
RTLIL::Const result(a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S1 : RTLIL::State::S0);
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -255,8 +255,8 @@ RTLIL::Const RTLIL::const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const
RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
RTLIL::Const result(logic_and(bit_a, bit_b));
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -270,8 +270,8 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const
RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
RTLIL::Const result(logic_or(bit_a, bit_b));
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -286,7 +286,7 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co
BigInteger offset = const2big(arg2, signed2, undef_bit_pos) * direction;
if (result_len < 0)
result_len = arg1.bits.size();
result_len = arg1.size();
RTLIL::Const result(RTLIL::State::Sx, result_len);
if (undef_bit_pos >= 0)
@ -295,11 +295,11 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co
for (int i = 0; i < result_len; i++) {
BigInteger pos = BigInteger(i) + offset;
if (pos < 0)
result.bits[i] = vacant_bits;
else if (pos >= BigInteger(int(arg1.bits.size())))
result.bits[i] = sign_ext ? arg1.bits.back() : vacant_bits;
result.bits()[i] = vacant_bits;
else if (pos >= BigInteger(int(arg1.size())))
result.bits()[i] = sign_ext ? arg1.back() : vacant_bits;
else
result.bits[i] = arg1.bits[pos.toInt()];
result.bits()[i] = arg1[pos.toInt()];
}
return result;
@ -347,8 +347,8 @@ RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
bool y = const2big(arg1, signed1, undef_bit_pos) < const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -358,8 +358,8 @@ RTLIL::Const RTLIL::const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
bool y = const2big(arg1, signed1, undef_bit_pos) <= const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -369,31 +369,31 @@ RTLIL::Const RTLIL::const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
RTLIL::Const arg2_ext = arg2;
RTLIL::Const result(RTLIL::State::S0, result_len);
int width = max(arg1_ext.bits.size(), arg2_ext.bits.size());
int width = max(arg1_ext.size(), arg2_ext.size());
extend_u0(arg1_ext, width, signed1 && signed2);
extend_u0(arg2_ext, width, signed1 && signed2);
RTLIL::State matched_status = RTLIL::State::S1;
for (size_t i = 0; i < arg1_ext.bits.size(); i++) {
if (arg1_ext.bits.at(i) == RTLIL::State::S0 && arg2_ext.bits.at(i) == RTLIL::State::S1)
for (size_t i = 0; i < arg1_ext.size(); i++) {
if (arg1_ext.at(i) == RTLIL::State::S0 && arg2_ext.at(i) == RTLIL::State::S1)
return result;
if (arg1_ext.bits.at(i) == RTLIL::State::S1 && arg2_ext.bits.at(i) == RTLIL::State::S0)
if (arg1_ext.at(i) == RTLIL::State::S1 && arg2_ext.at(i) == RTLIL::State::S0)
return result;
if (arg1_ext.bits.at(i) > RTLIL::State::S1 || arg2_ext.bits.at(i) > RTLIL::State::S1)
if (arg1_ext.at(i) > RTLIL::State::S1 || arg2_ext.at(i) > RTLIL::State::S1)
matched_status = RTLIL::State::Sx;
}
result.bits.front() = matched_status;
result.bits().front() = matched_status;
return result;
}
RTLIL::Const RTLIL::const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{
RTLIL::Const result = RTLIL::const_eq(arg1, arg2, signed1, signed2, result_len);
if (result.bits.front() == RTLIL::State::S0)
result.bits.front() = RTLIL::State::S1;
else if (result.bits.front() == RTLIL::State::S1)
result.bits.front() = RTLIL::State::S0;
if (result.front() == RTLIL::State::S0)
result.bits().front() = RTLIL::State::S1;
else if (result.front() == RTLIL::State::S1)
result.bits().front() = RTLIL::State::S0;
return result;
}
@ -403,26 +403,26 @@ RTLIL::Const RTLIL::const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2
RTLIL::Const arg2_ext = arg2;
RTLIL::Const result(RTLIL::State::S0, result_len);
int width = max(arg1_ext.bits.size(), arg2_ext.bits.size());
int width = max(arg1_ext.size(), arg2_ext.size());
extend_u0(arg1_ext, width, signed1 && signed2);
extend_u0(arg2_ext, width, signed1 && signed2);
for (size_t i = 0; i < arg1_ext.bits.size(); i++) {
if (arg1_ext.bits.at(i) != arg2_ext.bits.at(i))
for (size_t i = 0; i < arg1_ext.size(); i++) {
if (arg1_ext.at(i) != arg2_ext.at(i))
return result;
}
result.bits.front() = RTLIL::State::S1;
result.bits().front() = RTLIL::State::S1;
return result;
}
RTLIL::Const RTLIL::const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{
RTLIL::Const result = RTLIL::const_eqx(arg1, arg2, signed1, signed2, result_len);
if (result.bits.front() == RTLIL::State::S0)
result.bits.front() = RTLIL::State::S1;
else if (result.bits.front() == RTLIL::State::S1)
result.bits.front() = RTLIL::State::S0;
if (result.front() == RTLIL::State::S0)
result.bits().front() = RTLIL::State::S1;
else if (result.front() == RTLIL::State::S1)
result.bits().front() = RTLIL::State::S0;
return result;
}
@ -432,8 +432,8 @@ RTLIL::Const RTLIL::const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
bool y = const2big(arg1, signed1, undef_bit_pos) >= const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -443,8 +443,8 @@ RTLIL::Const RTLIL::const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
bool y = const2big(arg1, signed1, undef_bit_pos) > const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (int(result.bits.size()) < result_len)
result.bits.push_back(RTLIL::State::S0);
while (int(result.size()) < result_len)
result.bits().push_back(RTLIL::State::S0);
return result;
}
@ -452,21 +452,21 @@ RTLIL::Const RTLIL::const_add(const RTLIL::Const &arg1, const RTLIL::Const &arg2
{
int undef_bit_pos = -1;
BigInteger y = const2big(arg1, signed1, undef_bit_pos) + const2big(arg2, signed2, undef_bit_pos);
return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), undef_bit_pos);
}
RTLIL::Const RTLIL::const_sub(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{
int undef_bit_pos = -1;
BigInteger y = const2big(arg1, signed1, undef_bit_pos) - const2big(arg2, signed2, undef_bit_pos);
return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), undef_bit_pos);
}
RTLIL::Const RTLIL::const_mul(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{
int undef_bit_pos = -1;
BigInteger y = const2big(arg1, signed1, undef_bit_pos) * const2big(arg2, signed2, undef_bit_pos);
return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0));
}
// truncating division
@ -480,7 +480,7 @@ RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2
bool result_neg = (a.getSign() == BigInteger::negative) != (b.getSign() == BigInteger::negative);
a = a.getSign() == BigInteger::negative ? -a : a;
b = b.getSign() == BigInteger::negative ? -b : b;
return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0));
}
// truncating modulo
@ -494,7 +494,7 @@ RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2
bool result_neg = a.getSign() == BigInteger::negative;
a = a.getSign() == BigInteger::negative ? -a : a;
b = b.getSign() == BigInteger::negative ? -b : b;
return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_divfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
@ -516,7 +516,7 @@ RTLIL::Const RTLIL::const_divfloor(const RTLIL::Const &arg1, const RTLIL::Const
// bigint division with negative numbers is wonky, make sure we only negate at the very end
result = -((a + b - 1) / b);
}
return big2const(result, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
return big2const(result, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_modfloor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
@ -539,7 +539,7 @@ RTLIL::Const RTLIL::const_modfloor(const RTLIL::Const &arg1, const RTLIL::Const
} else {
modulo = b_sign == BigInteger::negative ? truncated - b : truncated + b;
}
return big2const(modulo, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
return big2const(modulo, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
@ -590,7 +590,7 @@ RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2
y *= -1;
}
return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
return big2const(y, result_len >= 0 ? result_len : max(arg1.size(), arg2.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_pos(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
@ -628,7 +628,7 @@ RTLIL::Const RTLIL::const_mux(const RTLIL::Const &arg1, const RTLIL::Const &arg2
RTLIL::Const ret = arg1;
for (int i = 0; i < ret.size(); i++)
if (ret[i] != arg2[i])
ret[i] = State::Sx;
ret.bits()[i] = State::Sx;
return ret;
}
@ -642,18 +642,18 @@ RTLIL::Const RTLIL::const_pmux(const RTLIL::Const &arg1, const RTLIL::Const &arg
for (int i = 0; i < arg3.size(); i++)
if (arg3[i] == State::S1)
return RTLIL::Const(std::vector<RTLIL::State>(arg2.bits.begin() + i*arg1.bits.size(), arg2.bits.begin() + (i+1)*arg1.bits.size()));
return RTLIL::Const(std::vector<RTLIL::State>(arg2.begin() + i*arg1.size(), arg2.begin() + (i+1)*arg1.size()));
log_abort(); // unreachable
}
RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg2)
{
std::vector<RTLIL::State> t = arg1.bits;
std::vector<State> t = arg1.to_bits();
for (int i = GetSize(arg2)-1; i >= 0; i--)
{
RTLIL::State sel = arg2.bits.at(i);
RTLIL::State sel = arg2.at(i);
std::vector<RTLIL::State> new_t;
if (sel == State::S0)
new_t = std::vector<RTLIL::State>(t.begin(), t.begin() + GetSize(t)/2);
@ -689,10 +689,10 @@ RTLIL::Const RTLIL::const_demux(const RTLIL::Const &arg1, const RTLIL::Const &ar
res.push_back(State::S0);
} else if (x) {
for (int j = 0; j < width; j++)
res.push_back(arg1.bits[j] == State::S0 ? State::S0 : State::Sx);
res.push_back(arg1[j] == State::S0 ? State::S0 : State::Sx);
} else {
for (int j = 0; j < width; j++)
res.push_back(arg1.bits[j]);
res.push_back(arg1[j]);
}
}
return res;
@ -703,7 +703,7 @@ RTLIL::Const RTLIL::const_bweqx(const RTLIL::Const &arg1, const RTLIL::Const &ar
log_assert(arg2.size() == arg1.size());
RTLIL::Const result(RTLIL::State::S0, arg1.size());
for (int i = 0; i < arg1.size(); i++)
result[i] = arg1[i] == arg2[i] ? State::S1 : State::S0;
result.bits()[i] = arg1[i] == arg2[i] ? State::S1 : State::S0;
return result;
}
@ -715,7 +715,7 @@ RTLIL::Const RTLIL::const_bwmux(const RTLIL::Const &arg1, const RTLIL::Const &ar
RTLIL::Const result(RTLIL::State::Sx, arg1.size());
for (int i = 0; i < arg1.size(); i++) {
if (arg3[i] != State::Sx || arg1[i] == arg2[i])
result[i] = arg3[i] == State::S1 ? arg2[i] : arg1[i];
result.bits()[i] = arg3[i] == State::S1 ? arg2[i] : arg1[i];
}
return result;

View file

@ -325,7 +325,7 @@ struct CellTypes
static RTLIL::Const eval_not(RTLIL::Const v)
{
for (auto &bit : v.bits)
for (auto &bit : v.bits())
if (bit == State::S0) bit = State::S1;
else if (bit == State::S1) bit = State::S0;
return v;
@ -419,13 +419,13 @@ struct CellTypes
RTLIL::Const ret;
int width = cell->parameters.at(ID::Y_WIDTH).as_int();
int offset = cell->parameters.at(ID::OFFSET).as_int();
ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width);
ret.bits().insert(ret.bits().end(), arg1.begin()+offset, arg1.begin()+offset+width);
return ret;
}
if (cell->type == ID($concat)) {
RTLIL::Const ret = arg1;
ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end());
ret.bits().insert(ret.bits().end(), arg2.begin(), arg2.end());
return ret;
}
@ -448,7 +448,7 @@ struct CellTypes
{
int width = cell->parameters.at(ID::WIDTH).as_int();
std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).bits;
std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).to_bits();
while (GetSize(t) < (1 << width))
t.push_back(State::S0);
t.resize(1 << width);
@ -460,7 +460,7 @@ struct CellTypes
{
int width = cell->parameters.at(ID::WIDTH).as_int();
int depth = cell->parameters.at(ID::DEPTH).as_int();
std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).bits;
std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).to_bits();
while (GetSize(t) < width*depth*2)
t.push_back(State::S0);
@ -473,7 +473,7 @@ struct CellTypes
bool match_x = true;
for (int j = 0; j < width; j++) {
RTLIL::State a = arg1.bits.at(j);
RTLIL::State a = arg1.at(j);
if (t.at(2*width*i + 2*j + 0) == State::S1) {
if (a == State::S1) match_x = false;
if (a != State::S0) match = false;
@ -513,7 +513,7 @@ struct CellTypes
if (cell->type == ID($_OAI3_))
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));
log_assert(arg3.bits.size() == 0);
log_assert(arg3.size() == 0);
return eval(cell, arg1, arg2, errp);
}
@ -524,7 +524,7 @@ struct CellTypes
if (cell->type == ID($_OAI4_))
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1));
log_assert(arg4.bits.size() == 0);
log_assert(arg4.size() == 0);
return eval(cell, arg1, arg2, arg3, errp);
}
};

View file

@ -76,7 +76,7 @@ struct ConstEval
#ifndef NDEBUG
RTLIL::SigSpec current_val = values_map(sig);
for (int i = 0; i < GetSize(current_val); i++)
log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]);
log_assert(current_val[i].wire != NULL || current_val[i] == value[i]);
#endif
values_map.add(sig, RTLIL::SigSpec(value));
}
@ -115,7 +115,7 @@ struct ConstEval
for (int i = 0; i < GetSize(coval); i++) {
carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry);
coval.bits[i] = carry ? State::S1 : State::S0;
coval.bits()[i] = carry ? State::S1 : State::S0;
}
set(sig_co, coval);
@ -153,7 +153,7 @@ struct ConstEval
for (int i = 0; i < sig_s.size(); i++)
{
RTLIL::State s_bit = sig_s.extract(i, 1).as_const().bits.at(0);
RTLIL::State s_bit = sig_s.extract(i, 1).as_const().at(0);
RTLIL::SigSpec b_slice = sig_b.extract(sig_y.size()*i, sig_y.size());
if (s_bit == RTLIL::State::Sx || s_bit == RTLIL::State::S1)
@ -180,10 +180,10 @@ struct ConstEval
if (y_values.size() > 1)
{
std::vector<RTLIL::State> master_bits = y_values.at(0).bits;
std::vector<RTLIL::State> master_bits = y_values.at(0).to_bits();
for (size_t i = 1; i < y_values.size(); i++) {
std::vector<RTLIL::State> &slave_bits = y_values.at(i).bits;
std::vector<RTLIL::State> slave_bits = y_values.at(i).to_bits();
log_assert(master_bits.size() == slave_bits.size());
for (size_t j = 0; j < master_bits.size(); j++)
if (master_bits[j] != slave_bits[j])
@ -248,8 +248,8 @@ struct ConstEval
RTLIL::Const val_x = const_or(t2, t3, false, false, width);
for (int i = 0; i < GetSize(val_y); i++)
if (val_y.bits[i] == RTLIL::Sx)
val_x.bits[i] = RTLIL::Sx;
if (val_y[i] == RTLIL::Sx)
val_x.bits()[i] = RTLIL::Sx;
set(sig_y, val_y);
set(sig_x, val_x);

View file

@ -260,7 +260,7 @@ bool DriveChunkMultiple::try_append(DriveBitMultiple const &bit)
switch (single.type())
{
case DriveType::CONSTANT: {
single.constant().bits.push_back(constant);
single.constant().bits().push_back(constant);
} break;
case DriveType::WIRE: {
single.wire().width += 1;
@ -295,8 +295,8 @@ bool DriveChunkMultiple::try_append(DriveChunkMultiple const &chunk)
switch (single.type())
{
case DriveType::CONSTANT: {
auto &bits = single.constant().bits;
bits.insert(bits.end(), constant.bits.begin(), constant.bits.end());
auto &bits = single.constant().bits();
bits.insert(bits.end(), constant.bits().begin(), constant.bits().end());
} break;
case DriveType::WIRE: {
single.wire().width += width;
@ -349,7 +349,7 @@ bool DriveChunk::try_append(DriveBit const &bit)
none_ += 1;
return true;
case DriveType::CONSTANT:
constant_.bits.push_back(bit.constant());
constant_.bits().push_back(bit.constant());
return true;
case DriveType::WIRE:
return wire_.try_append(bit.wire());
@ -375,7 +375,7 @@ bool DriveChunk::try_append(DriveChunk const &chunk)
none_ += chunk.none_;
return true;
case DriveType::CONSTANT:
constant_.bits.insert(constant_.bits.end(), chunk.constant_.bits.begin(), chunk.constant_.bits.end());
constant_.bits().insert(constant_.bits().end(), chunk.constant_.begin(), chunk.constant_.end());
return true;
case DriveType::WIRE:
return wire_.try_append(chunk.wire());

View file

@ -302,11 +302,11 @@ FfData FfData::slice(const std::vector<int> &bits) {
res.sig_set.append(sig_set[i]);
}
if (has_arst)
res.val_arst.bits.push_back(val_arst[i]);
res.val_arst.bits().push_back(val_arst[i]);
if (has_srst)
res.val_srst.bits.push_back(val_srst[i]);
res.val_srst.bits().push_back(val_srst[i]);
if (initvals)
res.val_init.bits.push_back(val_init[i]);
res.val_init.bits().push_back(val_init[i]);
}
res.width = GetSize(res.sig_q);
return res;
@ -692,10 +692,10 @@ void FfData::flip_rst_bits(const pool<int> &bits) {
for (auto bit: bits) {
if (has_arst)
val_arst[bit] = invert(val_arst[bit]);
val_arst.bits()[bit] = invert(val_arst[bit]);
if (has_srst)
val_srst[bit] = invert(val_srst[bit]);
val_init[bit] = invert(val_init[bit]);
val_srst.bits()[bit] = invert(val_srst[bit]);
val_init.bits()[bit] = invert(val_init[bit]);
}
}
@ -764,7 +764,7 @@ void FfData::flip_bits(const pool<int> &bits) {
Const mask = Const(State::S0, width);
for (auto bit: bits)
mask.bits[bit] = State::S1;
mask.bits()[bit] = State::S1;
if (has_clk || has_gclk)
sig_d = module->Xor(NEW_ID, sig_d, mask);

View file

@ -76,7 +76,7 @@ struct FfInitVals
{
RTLIL::Const res;
for (auto bit : sig)
res.bits.push_back((*this)(bit));
res.bits().push_back((*this)(bit));
return res;
}
@ -93,12 +93,12 @@ struct FfInitVals
initbits[mbit] = std::make_pair(val,abit);
auto it2 = abit.wire->attributes.find(ID::init);
if (it2 != abit.wire->attributes.end()) {
it2->second[abit.offset] = val;
it2->second.bits()[abit.offset] = val;
if (it2->second.is_fully_undef())
abit.wire->attributes.erase(it2);
} else if (val != State::Sx) {
Const cval(State::Sx, GetSize(abit.wire));
cval[abit.offset] = val;
cval.bits()[abit.offset] = val;
abit.wire->attributes[ID::init] = cval;
}
}

View file

@ -42,9 +42,9 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pai
ff.sig_d.append(bit);
ff.sig_clr.append(State::Sx);
ff.sig_set.append(State::Sx);
ff.val_init.bits.push_back(State::Sx);
ff.val_srst.bits.push_back(State::Sx);
ff.val_arst.bits.push_back(State::Sx);
ff.val_init.bits().push_back(State::Sx);
ff.val_srst.bits().push_back(State::Sx);
ff.val_arst.bits().push_back(State::Sx);
continue;
}
@ -147,9 +147,9 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pai
ff.sig_q.append(cur_ff.sig_q[idx]);
ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0);
ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0);
ff.val_arst.bits.push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx);
ff.val_srst.bits.push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx);
ff.val_init.bits.push_back(cur_ff.val_init[idx]);
ff.val_arst.bits().push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx);
ff.val_srst.bits().push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx);
ff.val_init.bits().push_back(cur_ff.val_init[idx]);
found = true;
}
@ -174,9 +174,9 @@ bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair
// These two will be fixed up later.
ff.sig_clr.append(State::Sx);
ff.sig_set.append(State::Sx);
ff.val_init.bits.push_back(bit.data);
ff.val_srst.bits.push_back(bit.data);
ff.val_arst.bits.push_back(bit.data);
ff.val_init.bits().push_back(bit.data);
ff.val_srst.bits().push_back(bit.data);
ff.val_arst.bits().push_back(bit.data);
continue;
}
@ -274,9 +274,9 @@ bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair
ff.sig_q.append(cur_ff.sig_q[idx]);
ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0);
ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0);
ff.val_arst.bits.push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx);
ff.val_srst.bits.push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx);
ff.val_init.bits.push_back(cur_ff.val_init[idx]);
ff.val_arst.bits().push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx);
ff.val_srst.bits().push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx);
ff.val_init.bits().push_back(cur_ff.val_init[idx]);
found = true;
}

View file

@ -537,7 +537,8 @@ namespace Functional {
return add(Fn::memory_write, mem.sort(), {mem, addr, data});
}
Node constant(RTLIL::Const value) {
return add(IR::NodeData(Fn::constant, std::move(value)), Sort(value.size()), {});
int s = value.size();
return add(IR::NodeData(Fn::constant, std::move(value)), Sort(s), {});
}
Node create_pending(int width) {
return add(Fn::buf, Sort(width), {});

View file

@ -104,7 +104,7 @@ struct Macc
ports.clear();
bit_ports = cell->getPort(ID::B);
std::vector<RTLIL::State> config_bits = cell->getParam(ID::CONFIG).bits;
auto config_bits = cell->getParam(ID::CONFIG);
int config_cursor = 0;
int config_width = cell->getParam(ID::CONFIG_WIDTH).as_int();
@ -199,7 +199,7 @@ struct Macc
bool eval(RTLIL::Const &result) const
{
for (auto &bit : result.bits)
for (auto &bit : result.bits())
bit = State::S0;
for (auto &port : ports)

View file

@ -157,10 +157,10 @@ void Mem::emit() {
}
for (int sub = 0; sub < (1 << port.wide_log2); sub++)
{
rd_wide_continuation.bits.push_back(State(sub != 0));
rd_clk_enable.bits.push_back(State(port.clk_enable));
rd_clk_polarity.bits.push_back(State(port.clk_polarity));
rd_ce_over_srst.bits.push_back(State(port.ce_over_srst));
rd_wide_continuation.bits().push_back(State(sub != 0));
rd_clk_enable.bits().push_back(State(port.clk_enable));
rd_clk_polarity.bits().push_back(State(port.clk_polarity));
rd_ce_over_srst.bits().push_back(State(port.ce_over_srst));
rd_clk.append(port.clk);
rd_arst.append(port.arst);
rd_srst.append(port.srst);
@ -170,17 +170,17 @@ void Mem::emit() {
rd_addr.append(addr);
log_assert(GetSize(addr) == abits);
for (auto idx : wr_port_xlat) {
rd_transparency_mask.bits.push_back(State(bool(port.transparency_mask[idx])));
rd_collision_x_mask.bits.push_back(State(bool(port.collision_x_mask[idx])));
rd_transparency_mask.bits().push_back(State(bool(port.transparency_mask[idx])));
rd_collision_x_mask.bits().push_back(State(bool(port.collision_x_mask[idx])));
}
}
rd_data.append(port.data);
for (auto &bit : port.arst_value)
rd_arst_value.bits.push_back(bit);
for (auto &bit : port.srst_value)
rd_srst_value.bits.push_back(bit);
for (auto &bit : port.init_value)
rd_init_value.bits.push_back(bit);
for (auto bit : port.arst_value)
rd_arst_value.bits().push_back(bit);
for (auto bit : port.srst_value)
rd_srst_value.bits().push_back(bit);
for (auto bit : port.init_value)
rd_init_value.bits().push_back(bit);
}
if (rd_ports.empty()) {
rd_wide_continuation = State::S0;
@ -222,12 +222,12 @@ void Mem::emit() {
}
for (int sub = 0; sub < (1 << port.wide_log2); sub++)
{
wr_wide_continuation.bits.push_back(State(sub != 0));
wr_clk_enable.bits.push_back(State(port.clk_enable));
wr_clk_polarity.bits.push_back(State(port.clk_polarity));
wr_wide_continuation.bits().push_back(State(sub != 0));
wr_clk_enable.bits().push_back(State(port.clk_enable));
wr_clk_polarity.bits().push_back(State(port.clk_polarity));
wr_clk.append(port.clk);
for (auto idx : wr_port_xlat)
wr_priority_mask.bits.push_back(State(bool(port.priority_mask[idx])));
wr_priority_mask.bits().push_back(State(bool(port.priority_mask[idx])));
SigSpec addr = port.sub_addr(sub);
addr.extend_u0(abits, false);
wr_addr.append(addr);
@ -414,7 +414,7 @@ void Mem::coalesce_inits() {
if (!init.en.is_fully_ones()) {
for (int i = 0; i < GetSize(init.data); i++)
if (init.en[i % width] != State::S1)
init.data[i] = State::Sx;
init.data.bits()[i] = State::Sx;
init.en = Const(State::S1, width);
}
continue;
@ -427,7 +427,7 @@ void Mem::coalesce_inits() {
log_assert(offset + GetSize(init.data) <= GetSize(cdata));
for (int i = 0; i < GetSize(init.data); i++)
if (init.en[i % width] == State::S1)
cdata.bits[i+offset] = init.data.bits[i];
cdata.bits()[i+offset] = init.data[i];
init.removed = true;
}
MemInit new_init;
@ -446,7 +446,7 @@ Const Mem::get_init_data() const {
int offset = (init.addr.as_int() - start_offset) * width;
for (int i = 0; i < GetSize(init.data); i++)
if (0 <= i+offset && i+offset < GetSize(init_data) && init.en[i % width] == State::S1)
init_data.bits[i+offset] = init.data.bits[i];
init_data.bits()[i+offset] = init.data[i];
}
return init_data;
}
@ -1702,7 +1702,7 @@ MemContents::MemContents(Mem *mem) :
RTLIL::Const previous = (*this)[addr + i];
for(int j = 0; j < _data_width; j++)
if(init.en[j] != State::S1)
data[_data_width * i + j] = previous[j];
data.bits()[_data_width * i + j] = previous[j];
}
insert_concatenated(init.addr.as_int(), data);
}
@ -1848,7 +1848,7 @@ std::map<addr_t, RTLIL::Const>::iterator MemContents::_reserve_range(addr_t begi
// we have two different ranges touching at either end, we need to merge them
auto upper_end = _range_end(upper_it);
// make range bigger (maybe reserve here instead of resize?)
lower_it->second.bits.resize(_range_offset(lower_it, upper_end), State::Sx);
lower_it->second.bits().resize(_range_offset(lower_it, upper_end), State::Sx);
// copy only the data beyond our range
std::copy(_range_data(upper_it, end_addr), _range_data(upper_it, upper_end), _range_data(lower_it, end_addr));
// keep lower_it, but delete upper_it
@ -1856,7 +1856,7 @@ std::map<addr_t, RTLIL::Const>::iterator MemContents::_reserve_range(addr_t begi
return lower_it;
} else if (lower_touch) {
// we have a range to the left, just make it bigger and delete any other that may exist.
lower_it->second.bits.resize(_range_offset(lower_it, end_addr), State::Sx);
lower_it->second.bits().resize(_range_offset(lower_it, end_addr), State::Sx);
// keep lower_it and upper_it
_values.erase(std::next(lower_it), upper_it);
return lower_it;
@ -1865,7 +1865,7 @@ std::map<addr_t, RTLIL::Const>::iterator MemContents::_reserve_range(addr_t begi
// since we need to erase and reinsert to a new address, steal the data
RTLIL::Const data = std::move(upper_it->second);
// note that begin_addr is not in upper_it, otherwise the whole range covered check would have tripped
data.bits.insert(data.bits.begin(), (_range_begin(upper_it) - begin_addr) * _data_width, State::Sx);
data.bits().insert(data.bits().begin(), (_range_begin(upper_it) - begin_addr) * _data_width, State::Sx);
// delete lower_it and upper_it, then reinsert
_values.erase(lower_it, std::next(upper_it));
return _values.emplace(begin_addr, std::move(data)).first;
@ -1883,14 +1883,14 @@ void MemContents::insert_concatenated(addr_t addr, RTLIL::Const const &values) {
log_assert(words <= (addr_t)(1<<_addr_width) - addr);
auto it = _reserve_range(addr, addr + words);
auto to_begin = _range_data(it, addr);
std::copy(values.bits.begin(), values.bits.end(), to_begin);
std::copy(values.begin(), values.end(), to_begin);
// if values is not word-aligned, fill any missing bits with 0
std::fill(to_begin + values.size(), to_begin + words * _data_width, State::S0);
}
std::vector<State>::iterator MemContents::_range_write(std::vector<State>::iterator it, RTLIL::Const const &word) {
auto from_end = word.size() <= _data_width ? word.bits.end() : word.bits.begin() + _data_width;
auto to_end = std::copy(word.bits.begin(), from_end, it);
auto from_end = word.size() <= _data_width ? word.end() : word.begin() + _data_width;
auto to_end = std::copy(word.begin(), from_end, it);
auto it_next = std::next(it, _data_width);
std::fill(to_end, it_next, State::S0);
return it_next;

View file

@ -255,7 +255,7 @@ private:
// return the offset the addr would have in the range at `it`
size_t _range_offset(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) const { return (addr - it->first) * _data_width; }
// assuming _range_contains(it, addr), return an iterator pointing to the data at addr
std::vector<State>::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) { return it->second.bits.begin() + _range_offset(it, addr); }
std::vector<State>::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) { return it->second.bits().begin() + _range_offset(it, addr); }
// internal version of reserve_range that returns an iterator to the range
std::map<addr_t, RTLIL::Const>::iterator _reserve_range(addr_t begin_addr, addr_t end_addr);
// write a single word at addr, return iterator to next word

View file

@ -202,25 +202,34 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
return res;
}
#define check(condition) log_assert(condition && "malformed Const union")
Const::bitvectype& Const::get_bits() const {
check(is_bits());
return *get_if_bits();
}
std::string& Const::get_str() const {
check(is_str());
return *get_if_str();
}
RTLIL::Const::Const(const std::string &str)
{
flags = RTLIL::CONST_FLAG_STRING;
bits.reserve(str.size() * 8);
for (int i = str.size()-1; i >= 0; i--) {
unsigned char ch = str[i];
for (int j = 0; j < 8; j++) {
bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);
ch = ch >> 1;
}
}
new ((void*)&str_) std::string(str);
tag = backing_tag::string;
}
RTLIL::Const::Const(int val, int width)
{
flags = RTLIL::CONST_FLAG_NONE;
bits.reserve(width);
new ((void*)&bits_) bitvectype();
tag = backing_tag::bits;
bitvectype& bv = get_bits();
bv.reserve(width);
for (int i = 0; i < width; i++) {
bits.push_back((val & 1) != 0 ? State::S1 : State::S0);
bv.push_back((val & 1) != 0 ? State::S1 : State::S0);
val = val >> 1;
}
}
@ -228,77 +237,167 @@ RTLIL::Const::Const(int val, int width)
RTLIL::Const::Const(RTLIL::State bit, int width)
{
flags = RTLIL::CONST_FLAG_NONE;
bits.reserve(width);
new ((void*)&bits_) bitvectype();
tag = backing_tag::bits;
bitvectype& bv = get_bits();
bv.reserve(width);
for (int i = 0; i < width; i++)
bits.push_back(bit);
bv.push_back(bit);
}
RTLIL::Const::Const(const std::vector<bool> &bits)
{
flags = RTLIL::CONST_FLAG_NONE;
this->bits.reserve(bits.size());
new ((void*)&bits_) bitvectype();
tag = backing_tag::bits;
bitvectype& bv = get_bits();
bv.reserve(bits.size());
for (const auto &b : bits)
this->bits.emplace_back(b ? State::S1 : State::S0);
bv.emplace_back(b ? State::S1 : State::S0);
}
bool RTLIL::Const::operator <(const RTLIL::Const &other) const
RTLIL::Const::Const(const RTLIL::Const &other) {
tag = other.tag;
flags = other.flags;
if (is_str())
new ((void*)&str_) std::string(other.get_str());
else if (is_bits())
new ((void*)&bits_) bitvectype(other.get_bits());
else
check(false);
}
RTLIL::Const::Const(RTLIL::Const &&other) {
tag = other.tag;
flags = other.flags;
if (is_str())
new ((void*)&str_) std::string(std::move(other.get_str()));
else if (is_bits())
new ((void*)&bits_) bitvectype(std::move(other.get_bits()));
else
check(false);
}
RTLIL::Const &RTLIL::Const::operator =(const RTLIL::Const &other) {
flags = other.flags;
if (other.is_str()) {
if (!is_str()) {
// sketchy zone
check(is_bits());
bits_.~bitvectype();
(void)new ((void*)&str_) std::string();
}
tag = other.tag;
get_str() = other.get_str();
} else if (other.is_bits()) {
if (!is_bits()) {
// sketchy zone
check(is_str());
str_.~string();
(void)new ((void*)&bits_) bitvectype();
}
tag = other.tag;
get_bits() = other.get_bits();
} else {
check(false);
}
return *this;
}
RTLIL::Const::~Const() {
if (is_bits())
bits_.~bitvectype();
else if (is_str())
str_.~string();
else
check(false);
}
bool RTLIL::Const::operator<(const RTLIL::Const &other) const
{
if (bits.size() != other.bits.size())
return bits.size() < other.bits.size();
for (size_t i = 0; i < bits.size(); i++)
if (bits[i] != other.bits[i])
return bits[i] < other.bits[i];
if (size() != other.size())
return size() < other.size();
for (int i = 0; i < size(); i++)
if ((*this)[i] != other[i])
return (*this)[i] < other[i];
return false;
}
bool RTLIL::Const::operator ==(const RTLIL::Const &other) const
{
return bits == other.bits;
if (size() != other.size())
return false;
for (int i = 0; i < size(); i++)
if ((*this)[i] != other[i])
return false;
return true;
}
bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
{
return bits != other.bits;
return !(*this == other);
}
std::vector<RTLIL::State>& RTLIL::Const::bits()
{
bitvectorize();
return get_bits();
}
std::vector<RTLIL::State> RTLIL::Const::to_bits() const
{
std::vector<State> v;
for (auto bit : *this)
v.push_back(bit);
return v;
}
bool RTLIL::Const::as_bool() const
{
for (size_t i = 0; i < bits.size(); i++)
if (bits[i] == State::S1)
bitvectorize();
bitvectype& bv = get_bits();
for (size_t i = 0; i < bv.size(); i++)
if (bv[i] == State::S1)
return true;
return false;
}
int RTLIL::Const::as_int(bool is_signed) const
{
bitvectorize();
bitvectype& bv = get_bits();
int32_t ret = 0;
for (size_t i = 0; i < bits.size() && i < 32; i++)
if (bits[i] == State::S1)
for (size_t i = 0; i < bv.size() && i < 32; i++)
if (bv[i] == State::S1)
ret |= 1 << i;
if (is_signed && bits.back() == State::S1)
for (size_t i = bits.size(); i < 32; i++)
if (is_signed && bv.back() == State::S1)
for (size_t i = bv.size(); i < 32; i++)
ret |= 1 << i;
return ret;
}
size_t RTLIL::Const::get_min_size(bool is_signed) const
{
if (bits.empty()) return 0;
if (empty()) return 0;
// back to front (MSB to LSB)
RTLIL::State leading_bit;
if (is_signed)
leading_bit = (bits.back() == RTLIL::State::Sx) ? RTLIL::State::S0 : bits.back();
leading_bit = (back() == RTLIL::State::Sx) ? RTLIL::State::S0 : back();
else
leading_bit = RTLIL::State::S0;
size_t idx = bits.size();
while (idx > 0 && bits[idx -1] == leading_bit) {
size_t idx = size();
while (idx > 0 && (*this)[idx -1] == leading_bit) {
idx--;
}
// signed needs one leading bit
if (is_signed && idx < bits.size()) {
if (is_signed && idx < size()) {
idx++;
}
// must be at least one bit
@ -308,7 +407,7 @@ size_t RTLIL::Const::get_min_size(bool is_signed) const
void RTLIL::Const::compress(bool is_signed)
{
size_t idx = get_min_size(is_signed);
bits.erase(bits.begin() + idx, bits.end());
bits().erase(bits().begin() + idx, bits().end());
}
std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const
@ -316,28 +415,30 @@ std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const
size_t size = get_min_size(is_signed);
if(size == 0 || size > 32)
return std::nullopt;
int32_t ret = 0;
for (size_t i = 0; i < size && i < 32; i++)
if (bits[i] == State::S1)
if ((*this)[i] == State::S1)
ret |= 1 << i;
if (is_signed && bits[size-1] == State::S1)
if (is_signed && (*this)[size-1] == State::S1)
for (size_t i = size; i < 32; i++)
ret |= 1 << i;
return ret;
}
std::string RTLIL::Const::as_string() const
std::string RTLIL::Const::as_string(const char* any) const
{
bitvectorize();
bitvectype& bv = get_bits();
std::string ret;
ret.reserve(bits.size());
for (size_t i = bits.size(); i > 0; i--)
switch (bits[i-1]) {
ret.reserve(bv.size());
for (size_t i = bv.size(); i > 0; i--)
switch (bv[i-1]) {
case S0: ret += "0"; break;
case S1: ret += "1"; break;
case Sx: ret += "x"; break;
case Sz: ret += "z"; break;
case Sa: ret += "-"; break;
case Sa: ret += any; break;
case Sm: ret += "m"; break;
}
return ret;
@ -346,22 +447,28 @@ std::string RTLIL::Const::as_string() const
RTLIL::Const RTLIL::Const::from_string(const std::string &str)
{
Const c;
c.bits.reserve(str.size());
bitvectype& bv = c.get_bits();
bv.reserve(str.size());
for (auto it = str.rbegin(); it != str.rend(); it++)
switch (*it) {
case '0': c.bits.push_back(State::S0); break;
case '1': c.bits.push_back(State::S1); break;
case 'x': c.bits.push_back(State::Sx); break;
case 'z': c.bits.push_back(State::Sz); break;
case 'm': c.bits.push_back(State::Sm); break;
default: c.bits.push_back(State::Sa);
case '0': bv.push_back(State::S0); break;
case '1': bv.push_back(State::S1); break;
case 'x': bv.push_back(State::Sx); break;
case 'z': bv.push_back(State::Sz); break;
case 'm': bv.push_back(State::Sm); break;
default: bv.push_back(State::Sa);
}
return c;
}
std::string RTLIL::Const::decode_string() const
{
const int n = GetSize(bits);
if (auto str = get_if_str())
return *str;
bitvectorize();
bitvectype& bv = get_bits();
const int n = GetSize(bv);
const int n_over_8 = n / 8;
std::string s;
s.reserve(n_over_8);
@ -369,7 +476,7 @@ std::string RTLIL::Const::decode_string() const
if (i < n) {
char ch = 0;
for (int j = 0; j < (n - i); j++) {
if (bits[i + j] == RTLIL::State::S1) {
if (bv[i + j] == RTLIL::State::S1) {
ch |= 1 << j;
}
}
@ -380,7 +487,7 @@ std::string RTLIL::Const::decode_string() const
for (; i >= 0; i -= 8) {
char ch = 0;
for (int j = 0; j < 8; j++) {
if (bits[i + j] == RTLIL::State::S1) {
if (bv[i + j] == RTLIL::State::S1) {
ch |= 1 << j;
}
}
@ -390,11 +497,65 @@ std::string RTLIL::Const::decode_string() const
return s;
}
int RTLIL::Const::size() const {
if (is_str())
return 8 * str_.size();
else {
check(is_bits());
return bits_.size();
}
}
bool RTLIL::Const::empty() const {
if (is_str())
return str_.empty();
else {
check(is_bits());
return bits_.empty();
}
}
void RTLIL::Const::bitvectorize() const {
if (tag == backing_tag::bits)
return;
check(is_str());
bitvectype new_bits;
new_bits.reserve(str_.size() * 8);
for (int i = str_.size() - 1; i >= 0; i--) {
unsigned char ch = str_[i];
for (int j = 0; j < 8; j++) {
new_bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);
ch = ch >> 1;
}
}
{
// sketchy zone
str_.~string();
(void)new ((void*)&bits_) bitvectype(std::move(new_bits));
tag = backing_tag::bits;
}
}
RTLIL::State RTLIL::Const::const_iterator::operator*() const {
if (auto bv = parent.get_if_bits())
return (*bv)[idx];
int char_idx = parent.get_str().size() - idx / 8 - 1;
bool bit = (parent.get_str()[char_idx] & (1 << (idx % 8)));
return bit ? State::S1 : State::S0;
}
bool RTLIL::Const::is_fully_zero() const
{
bitvectorize();
bitvectype& bv = get_bits();
cover("kernel.rtlil.const.is_fully_zero");
for (const auto &bit : bits)
for (const auto &bit : bv)
if (bit != RTLIL::State::S0)
return false;
@ -403,9 +564,11 @@ bool RTLIL::Const::is_fully_zero() const
bool RTLIL::Const::is_fully_ones() const
{
bitvectorize();
bitvectype& bv = get_bits();
cover("kernel.rtlil.const.is_fully_ones");
for (const auto &bit : bits)
for (const auto &bit : bv)
if (bit != RTLIL::State::S1)
return false;
@ -416,7 +579,10 @@ bool RTLIL::Const::is_fully_def() const
{
cover("kernel.rtlil.const.is_fully_def");
for (const auto &bit : bits)
bitvectorize();
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false;
@ -427,7 +593,10 @@ bool RTLIL::Const::is_fully_undef() const
{
cover("kernel.rtlil.const.is_fully_undef");
for (const auto &bit : bits)
bitvectorize();
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
return false;
@ -438,7 +607,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const
{
cover("kernel.rtlil.const.is_fully_undef_x_only");
for (const auto &bit : bits)
bitvectorize();
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::Sx)
return false;
@ -449,9 +621,12 @@ bool RTLIL::Const::is_onehot(int *pos) const
{
cover("kernel.rtlil.const.is_onehot");
bitvectorize();
bitvectype& bv = get_bits();
bool found = false;
for (int i = 0; i < GetSize(*this); i++) {
auto &bit = bits[i];
auto &bit = bv[i];
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false;
if (bit == RTLIL::State::S1) {
@ -465,6 +640,15 @@ bool RTLIL::Const::is_onehot(int *pos) const
return found;
}
RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) const {
bitvectype ret_bv;
ret_bv.reserve(len);
for (int i = offset; i < offset + len; i++)
ret_bv.push_back(i < GetSize(*this) ? (*this)[i] : padding);
return RTLIL::Const(ret_bv);
}
#undef check /* check(condition) for Const */
bool RTLIL::AttrObject::has_attribute(const RTLIL::IdString &id) const
{
return attributes.count(id);
@ -1112,7 +1296,7 @@ namespace {
void param_bits(const RTLIL::IdString& name, int width)
{
param(name);
if (GetSize(cell->parameters.at(name).bits) != width)
if (GetSize(cell->parameters.at(name)) != width)
error(__LINE__);
}
@ -3940,7 +4124,7 @@ RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit)
wire = bit.wire;
offset = 0;
if (wire == NULL)
data = RTLIL::Const(bit.data).bits;
data = {bit.data};
else
offset = bit.offset;
width = 1;

View file

@ -47,13 +47,21 @@ namespace RTLIL
STi = 7 // init
};
// Semantic metadata - how can this constant be interpreted?
// Values may be generally non-exclusive
enum ConstFlags : unsigned char {
CONST_FLAG_NONE = 0,
CONST_FLAG_STRING = 1,
CONST_FLAG_SIGNED = 2, // only used for parameters
CONST_FLAG_REAL = 4 // only used for parameters
CONST_FLAG_REAL = 4, // only used for parameters
};
// // Union discriminator. Values are exclusive
// enum ConstRepr : unsigned char {
// CONST_REPR_BITS = 1,
// CONST_REPR_STRING = 2,
// };
struct Const;
struct AttrObject;
struct Selection;
@ -658,35 +666,115 @@ namespace RTLIL
struct RTLIL::Const
{
int flags;
std::vector<RTLIL::State> bits;
short flags;
private:
friend class KernelRtlilTest;
FRIEND_TEST(KernelRtlilTest, ConstStr);
using bitvectype = std::vector<RTLIL::State>;
enum class backing_tag: bool { bits, string };
// Do not access the union or tag even in Const methods unless necessary
mutable backing_tag tag;
union {
mutable bitvectype bits_;
mutable std::string str_;
};
Const() : flags(RTLIL::CONST_FLAG_NONE) {}
// Use these private utilities instead
bool is_bits() const { return tag == backing_tag::bits; }
bool is_str() const { return tag == backing_tag::string; }
bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; }
std::string* get_if_str() const { return is_str() ? &str_ : NULL; }
bitvectype& get_bits() const;
std::string& get_str() const;
public:
Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector<RTLIL::State>()) {}
Const(const std::string &str);
Const(int val, int width = 32);
Const(RTLIL::State bit, int width = 1);
Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; }
Const(const std::vector<RTLIL::State> &bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(bits) {}
Const(const std::vector<bool> &bits);
Const(const RTLIL::Const &c) = default;
RTLIL::Const &operator =(const RTLIL::Const &other) = default;
Const(const RTLIL::Const &other);
Const(RTLIL::Const &&other);
RTLIL::Const &operator =(const RTLIL::Const &other);
~Const();
bool operator <(const RTLIL::Const &other) const;
bool operator ==(const RTLIL::Const &other) const;
bool operator !=(const RTLIL::Const &other) const;
std::vector<RTLIL::State>& bits();
bool as_bool() const;
int as_int(bool is_signed = false) const;
std::string as_string() const;
std::string as_string(const char* any = "-") const;
static Const from_string(const std::string &str);
std::vector<RTLIL::State> to_bits() const;
std::string decode_string() const;
int size() const;
bool empty() const;
void bitvectorize() const;
inline int size() const { return bits.size(); }
inline bool empty() const { return bits.empty(); }
inline RTLIL::State &operator[](int index) { return bits.at(index); }
inline const RTLIL::State &operator[](int index) const { return bits.at(index); }
inline decltype(bits)::iterator begin() { return bits.begin(); }
inline decltype(bits)::iterator end() { return bits.end(); }
class const_iterator {
private:
const Const& parent;
size_t idx;
public:
using iterator_category = std::input_iterator_tag;
using value_type = State;
using difference_type = std::ptrdiff_t;
using pointer = const State*;
using reference = const State&;
const_iterator(const Const& c, size_t i) : parent(c), idx(i) {}
State operator*() const;
const_iterator& operator++() { ++idx; return *this; }
const_iterator& operator--() { --idx; return *this; }
const_iterator& operator++(int) { ++idx; return *this; }
const_iterator& operator--(int) { --idx; return *this; }
const_iterator& operator+=(int i) { idx += i; return *this; }
const_iterator operator+(int add) {
return const_iterator(parent, idx + add);
}
const_iterator operator-(int sub) {
return const_iterator(parent, idx - sub);
}
int operator-(const const_iterator& other) {
return idx - other.idx;
}
bool operator==(const const_iterator& other) const {
return idx == other.idx;
}
bool operator!=(const const_iterator& other) const {
return !(*this == other);
}
};
const_iterator begin() const {
return const_iterator(*this, 0);
}
const_iterator end() const {
return const_iterator(*this, size());
}
State back() const {
return *(end() - 1);
}
State front() const {
return *begin();
}
State at(size_t i) const {
return *const_iterator(*this, i);
}
State operator[](size_t i) const {
return *const_iterator(*this, i);
}
bool is_fully_zero() const;
bool is_fully_ones() const;
@ -695,13 +783,7 @@ struct RTLIL::Const
bool is_fully_undef_x_only() const;
bool is_onehot(int *pos = nullptr) const;
inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const {
RTLIL::Const ret;
ret.bits.reserve(len);
for (int i = offset; i < offset + len; i++)
ret.bits.push_back(i < GetSize(bits) ? bits[i] : padding);
return ret;
}
RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const;
// find the MSB without redundant leading bits
size_t get_min_size(bool is_signed) const;
@ -712,16 +794,18 @@ struct RTLIL::Const
std::optional<int> as_int_compress(bool is_signed) const;
void extu(int width) {
bits.resize(width, RTLIL::State::S0);
bits().resize(width, RTLIL::State::S0);
}
void exts(int width) {
bits.resize(width, bits.empty() ? RTLIL::State::Sx : bits.back());
bitvectype& bv = bits();
bv.resize(width, bv.empty() ? RTLIL::State::Sx : bv.back());
}
inline unsigned int hash() const {
unsigned int h = mkhash_init;
for (auto b : bits)
for (State b : *this)
h = mkhash(h, b);
return h;
}
@ -768,8 +852,8 @@ struct RTLIL::SigChunk
int width, offset;
SigChunk() : wire(nullptr), width(0), offset(0) {}
SigChunk(const RTLIL::Const &value) : wire(nullptr), data(value.bits), width(GetSize(data)), offset(0) {}
SigChunk(RTLIL::Const &&value) : wire(nullptr), data(std::move(value.bits)), width(GetSize(data)), offset(0) {}
SigChunk(const RTLIL::Const &value) : wire(nullptr), data(value.to_bits()), width(GetSize(data)), offset(0) {}
SigChunk(RTLIL::Const &&value) : wire(nullptr), data(value.to_bits()), width(GetSize(data)), offset(0) {}
SigChunk(RTLIL::Wire *wire) : wire(wire), width(GetSize(wire)), offset(0) {}
SigChunk(RTLIL::Wire *wire, int offset, int width = 1) : wire(wire), width(width), offset(offset) {}
SigChunk(const std::string &str) : SigChunk(RTLIL::Const(str)) {}

View file

@ -922,7 +922,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> lut;
for (auto bit : cell->getParam(ID::LUT).bits)
for (auto bit : cell->getParam(ID::LUT))
lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE);
while (GetSize(lut) < (1 << GetSize(a)))
lut.push_back(ez->CONST_FALSE);
@ -974,7 +974,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
int width = cell->getParam(ID::WIDTH).as_int();
int depth = cell->getParam(ID::DEPTH).as_int();
vector<State> table_raw = cell->getParam(ID::TABLE).bits;
vector<State> table_raw = cell->getParam(ID::TABLE).to_bits();
while (GetSize(table_raw) < 2*width*depth)
table_raw.push_back(State::S0);

View file

@ -62,6 +62,9 @@
defines the Yosys Makefile would set for your build configuration.
#endif
#define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test
#ifdef YOSYS_ENABLE_TCL
# include <tcl.h>
# ifdef YOSYS_MXE_HACKS

View file

@ -185,7 +185,7 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const
const std::string &bits = steps[t].bits;
RTLIL::Const result(State::Sa, width);
result.bits.reserve(width);
result.bits().reserve(width);
int read_begin = GetSize(bits) - 1 - bits_offset;
int read_end = max(-1, read_begin - width);
@ -200,7 +200,7 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const
default:
log_abort();
}
result.bits[j] = bit;
result.bits()[j] = bit;
}
return result;