3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-09-12 04:31:29 +00:00

Make Const::is_*() functions work on packed bits without decaying to vector<State>

This commit is contained in:
Robert O'Callahan 2025-08-29 04:50:35 +00:00
parent 9c96e61e9b
commit a515055be4
2 changed files with 120 additions and 15 deletions

View file

@ -632,10 +632,17 @@ RTLIL::State RTLIL::Const::const_iterator::operator*() const {
bool RTLIL::Const::is_fully_zero() const
{
bitvectorize_internal();
bitvectype& bv = get_bits();
cover("kernel.rtlil.const.is_fully_zero");
if (auto str = get_if_str()) {
for (char ch : *str)
if (ch != 0)
return false;
return true;
}
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::S0)
return false;
@ -645,10 +652,16 @@ bool RTLIL::Const::is_fully_zero() const
bool RTLIL::Const::is_fully_ones() const
{
bitvectorize_internal();
bitvectype& bv = get_bits();
cover("kernel.rtlil.const.is_fully_ones");
if (auto str = get_if_str()) {
for (char ch : *str)
if (ch != (char)0xff)
return false;
return true;
}
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::S1)
return false;
@ -660,9 +673,10 @@ bool RTLIL::Const::is_fully_def() const
{
cover("kernel.rtlil.const.is_fully_def");
bitvectorize_internal();
bitvectype& bv = get_bits();
if (is_str())
return true;
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false;
@ -674,9 +688,10 @@ bool RTLIL::Const::is_fully_undef() const
{
cover("kernel.rtlil.const.is_fully_undef");
bitvectorize_internal();
bitvectype& bv = get_bits();
if (auto str = get_if_str())
return str->empty();
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
return false;
@ -688,9 +703,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const
{
cover("kernel.rtlil.const.is_fully_undef_x_only");
bitvectorize_internal();
bitvectype& bv = get_bits();
if (auto str = get_if_str())
return str->empty();
bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::Sx)
return false;
@ -702,12 +718,10 @@ bool RTLIL::Const::is_onehot(int *pos) const
{
cover("kernel.rtlil.const.is_onehot");
bitvectorize_internal();
bitvectype& bv = get_bits();
bool found = false;
for (int i = 0; i < GetSize(*this); i++) {
auto &bit = bv[i];
int size = GetSize(*this);
for (int i = 0; i < size; i++) {
State bit = (*this)[i];
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false;
if (bit == RTLIL::State::S1) {

View file

@ -157,6 +157,50 @@ namespace RTLIL {
Const c(v);
EXPECT_EQ(c.decode_string(), " ");
}
{
Const c(" ");
EXPECT_TRUE(c.is_str());
EXPECT_FALSE(c.is_fully_zero());
EXPECT_TRUE(c.is_str());
}
{
Const c(" ");
EXPECT_TRUE(c.is_str());
EXPECT_FALSE(c.is_fully_ones());
EXPECT_TRUE(c.is_str());
}
{
Const c(" ");
EXPECT_TRUE(c.is_str());
EXPECT_TRUE(c.is_fully_def());
EXPECT_TRUE(c.is_str());
}
{
Const c(" ");
EXPECT_TRUE(c.is_str());
EXPECT_FALSE(c.is_fully_undef());
EXPECT_TRUE(c.is_str());
}
{
Const c(" ");
EXPECT_TRUE(c.is_str());
EXPECT_FALSE(c.is_fully_undef_x_only());
EXPECT_TRUE(c.is_str());
}
{
Const c(" ");
EXPECT_TRUE(c.is_str());
int pos;
EXPECT_TRUE(c.is_onehot(&pos));
EXPECT_EQ(pos, 5);
EXPECT_TRUE(c.is_str());
}
}
TEST_F(KernelRtlilTest, ConstConstIteratorWorks) {
@ -267,6 +311,53 @@ namespace RTLIL {
EXPECT_NE(hash(Const(v1)), hash(Const("a")));
}
TEST_F(KernelRtlilTest, ConstIsFullyZero) {
EXPECT_TRUE(Const(0, 8).is_fully_zero());
EXPECT_FALSE(Const(8, 8).is_fully_zero());
EXPECT_TRUE(Const().is_fully_zero());
}
TEST_F(KernelRtlilTest, ConstIsFullyOnes) {
EXPECT_TRUE(Const(0xf, 4).is_fully_ones());
EXPECT_FALSE(Const(3, 4).is_fully_ones());
EXPECT_TRUE(Const().is_fully_ones());
}
TEST_F(KernelRtlilTest, ConstIsFullyDef) {
EXPECT_TRUE(Const(0xf, 4).is_fully_def());
std::vector<State> v1 = {S0, Sx};
EXPECT_FALSE(Const(v1).is_fully_def());
EXPECT_TRUE(Const().is_fully_def());
}
TEST_F(KernelRtlilTest, ConstIsFullyUndef) {
std::vector<State> v1 = {S0, Sx};
EXPECT_FALSE(Const(v1).is_fully_undef());
EXPECT_TRUE(Const(Sz, 2).is_fully_undef());
EXPECT_TRUE(Const().is_fully_undef());
}
TEST_F(KernelRtlilTest, ConstIsFullyUndefXOnly) {
std::vector<State> v1 = {Sx, Sz};
EXPECT_FALSE(Const(v1).is_fully_undef_x_only());
EXPECT_TRUE(Const(Sx, 2).is_fully_undef_x_only());
EXPECT_TRUE(Const().is_fully_undef_x_only());
}
TEST_F(KernelRtlilTest, ConstIsOnehot) {
int pos;
EXPECT_TRUE(Const(0x80, 8).is_onehot(&pos));
EXPECT_EQ(pos, 7);
EXPECT_FALSE(Const(0x82, 8).is_onehot(&pos));
EXPECT_FALSE(Const(0, 8).is_onehot(&pos));
EXPECT_TRUE(Const(1, 1).is_onehot(&pos));
EXPECT_EQ(pos, 0);
EXPECT_FALSE(Const(Sx, 1).is_onehot(&pos));
std::vector<State> v1 = {Sx, S1};
EXPECT_FALSE(Const(v1).is_onehot(&pos));
EXPECT_FALSE(Const().is_onehot(&pos));
}
class WireRtlVsHdlIndexConversionTest :
public KernelRtlilTest,
public testing::WithParamInterface<std::tuple<bool, int, int>>