Skip to content

Commit 3196d14

Browse files
committed
Make Const::is_*() functions work on packed bits without decaying to vector<State>
1 parent 448f01c commit 3196d14

File tree

2 files changed

+120
-15
lines changed

2 files changed

+120
-15
lines changed

kernel/rtlil.cc

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,17 @@ RTLIL::State RTLIL::Const::const_iterator::operator*() const {
669669

670670
bool RTLIL::Const::is_fully_zero() const
671671
{
672-
bitvectorize_internal();
673-
bitvectype& bv = get_bits();
674672
cover("kernel.rtlil.const.is_fully_zero");
675673

674+
if (auto str = get_if_str()) {
675+
for (char ch : *str)
676+
if (ch != 0)
677+
return false;
678+
return true;
679+
}
680+
681+
bitvectype& bv = get_bits();
682+
676683
for (const auto &bit : bv)
677684
if (bit != RTLIL::State::S0)
678685
return false;
@@ -682,10 +689,16 @@ bool RTLIL::Const::is_fully_zero() const
682689

683690
bool RTLIL::Const::is_fully_ones() const
684691
{
685-
bitvectorize_internal();
686-
bitvectype& bv = get_bits();
687692
cover("kernel.rtlil.const.is_fully_ones");
688693

694+
if (auto str = get_if_str()) {
695+
for (char ch : *str)
696+
if (ch != (char)0xff)
697+
return false;
698+
return true;
699+
}
700+
701+
bitvectype& bv = get_bits();
689702
for (const auto &bit : bv)
690703
if (bit != RTLIL::State::S1)
691704
return false;
@@ -697,9 +710,10 @@ bool RTLIL::Const::is_fully_def() const
697710
{
698711
cover("kernel.rtlil.const.is_fully_def");
699712

700-
bitvectorize_internal();
701-
bitvectype& bv = get_bits();
713+
if (is_str())
714+
return true;
702715

716+
bitvectype& bv = get_bits();
703717
for (const auto &bit : bv)
704718
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
705719
return false;
@@ -711,9 +725,10 @@ bool RTLIL::Const::is_fully_undef() const
711725
{
712726
cover("kernel.rtlil.const.is_fully_undef");
713727

714-
bitvectorize_internal();
715-
bitvectype& bv = get_bits();
728+
if (auto str = get_if_str())
729+
return str->empty();
716730

731+
bitvectype& bv = get_bits();
717732
for (const auto &bit : bv)
718733
if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
719734
return false;
@@ -725,9 +740,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const
725740
{
726741
cover("kernel.rtlil.const.is_fully_undef_x_only");
727742

728-
bitvectorize_internal();
729-
bitvectype& bv = get_bits();
743+
if (auto str = get_if_str())
744+
return str->empty();
730745

746+
bitvectype& bv = get_bits();
731747
for (const auto &bit : bv)
732748
if (bit != RTLIL::State::Sx)
733749
return false;
@@ -739,12 +755,10 @@ bool RTLIL::Const::is_onehot(int *pos) const
739755
{
740756
cover("kernel.rtlil.const.is_onehot");
741757

742-
bitvectorize_internal();
743-
bitvectype& bv = get_bits();
744-
745758
bool found = false;
746-
for (int i = 0; i < GetSize(*this); i++) {
747-
auto &bit = bv[i];
759+
int size = GetSize(*this);
760+
for (int i = 0; i < size; i++) {
761+
State bit = (*this)[i];
748762
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
749763
return false;
750764
if (bit == RTLIL::State::S1) {

tests/unit/kernel/rtlilTest.cc

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,50 @@ namespace RTLIL {
157157
Const c(v);
158158
EXPECT_EQ(c.decode_string(), " ");
159159
}
160+
161+
{
162+
Const c(" ");
163+
EXPECT_TRUE(c.is_str());
164+
EXPECT_FALSE(c.is_fully_zero());
165+
EXPECT_TRUE(c.is_str());
166+
}
167+
168+
{
169+
Const c(" ");
170+
EXPECT_TRUE(c.is_str());
171+
EXPECT_FALSE(c.is_fully_ones());
172+
EXPECT_TRUE(c.is_str());
173+
}
174+
175+
{
176+
Const c(" ");
177+
EXPECT_TRUE(c.is_str());
178+
EXPECT_TRUE(c.is_fully_def());
179+
EXPECT_TRUE(c.is_str());
180+
}
181+
182+
{
183+
Const c(" ");
184+
EXPECT_TRUE(c.is_str());
185+
EXPECT_FALSE(c.is_fully_undef());
186+
EXPECT_TRUE(c.is_str());
187+
}
188+
189+
{
190+
Const c(" ");
191+
EXPECT_TRUE(c.is_str());
192+
EXPECT_FALSE(c.is_fully_undef_x_only());
193+
EXPECT_TRUE(c.is_str());
194+
}
195+
196+
{
197+
Const c(" ");
198+
EXPECT_TRUE(c.is_str());
199+
int pos;
200+
EXPECT_TRUE(c.is_onehot(&pos));
201+
EXPECT_EQ(pos, 5);
202+
EXPECT_TRUE(c.is_str());
203+
}
160204
}
161205

162206
TEST_F(KernelRtlilTest, ConstConstIteratorWorks) {
@@ -267,6 +311,53 @@ namespace RTLIL {
267311
EXPECT_NE(hash(Const(v1)), hash(Const("a")));
268312
}
269313

314+
TEST_F(KernelRtlilTest, ConstIsFullyZero) {
315+
EXPECT_TRUE(Const(0, 8).is_fully_zero());
316+
EXPECT_FALSE(Const(8, 8).is_fully_zero());
317+
EXPECT_TRUE(Const().is_fully_zero());
318+
}
319+
320+
TEST_F(KernelRtlilTest, ConstIsFullyOnes) {
321+
EXPECT_TRUE(Const(0xf, 4).is_fully_ones());
322+
EXPECT_FALSE(Const(3, 4).is_fully_ones());
323+
EXPECT_TRUE(Const().is_fully_ones());
324+
}
325+
326+
TEST_F(KernelRtlilTest, ConstIsFullyDef) {
327+
EXPECT_TRUE(Const(0xf, 4).is_fully_def());
328+
std::vector<State> v1 = {S0, Sx};
329+
EXPECT_FALSE(Const(v1).is_fully_def());
330+
EXPECT_TRUE(Const().is_fully_def());
331+
}
332+
333+
TEST_F(KernelRtlilTest, ConstIsFullyUndef) {
334+
std::vector<State> v1 = {S0, Sx};
335+
EXPECT_FALSE(Const(v1).is_fully_undef());
336+
EXPECT_TRUE(Const(Sz, 2).is_fully_undef());
337+
EXPECT_TRUE(Const().is_fully_undef());
338+
}
339+
340+
TEST_F(KernelRtlilTest, ConstIsFullyUndefXOnly) {
341+
std::vector<State> v1 = {Sx, Sz};
342+
EXPECT_FALSE(Const(v1).is_fully_undef_x_only());
343+
EXPECT_TRUE(Const(Sx, 2).is_fully_undef_x_only());
344+
EXPECT_TRUE(Const().is_fully_undef_x_only());
345+
}
346+
347+
TEST_F(KernelRtlilTest, ConstIsOnehot) {
348+
int pos;
349+
EXPECT_TRUE(Const(0x80, 8).is_onehot(&pos));
350+
EXPECT_EQ(pos, 7);
351+
EXPECT_FALSE(Const(0x82, 8).is_onehot(&pos));
352+
EXPECT_FALSE(Const(0, 8).is_onehot(&pos));
353+
EXPECT_TRUE(Const(1, 1).is_onehot(&pos));
354+
EXPECT_EQ(pos, 0);
355+
EXPECT_FALSE(Const(Sx, 1).is_onehot(&pos));
356+
std::vector<State> v1 = {Sx, S1};
357+
EXPECT_FALSE(Const(v1).is_onehot(&pos));
358+
EXPECT_FALSE(Const().is_onehot(&pos));
359+
}
360+
270361
class WireRtlVsHdlIndexConversionTest :
271362
public KernelRtlilTest,
272363
public testing::WithParamInterface<std::tuple<bool, int, int>>

0 commit comments

Comments
 (0)