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:
commit
469f5a707a
92 changed files with 970 additions and 652 deletions
|
@ -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;
|
||||
|
|
170
kernel/calc.cc
170
kernel/calc.cc
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
14
kernel/ff.cc
14
kernel/ff.cc
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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), {});
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
304
kernel/rtlil.cc
304
kernel/rtlil.cc
|
@ -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;
|
||||
|
|
136
kernel/rtlil.h
136
kernel/rtlil.h
|
@ -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)) {}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue