mirror of
https://github.com/YosysHQ/yosys
synced 2025-09-13 05:01:29 +00:00
Update Const API with alternatives to direct use of bits()
In particular, `Const::resize()`, `Const::set()`, and `Const::iterator`.
This commit is contained in:
parent
8bae779bb8
commit
e151fbc5df
2 changed files with 131 additions and 4 deletions
|
@ -743,13 +743,24 @@ public:
|
||||||
Const(const std::string &str);
|
Const(const std::string &str);
|
||||||
Const(long long val, int width = 32);
|
Const(long long val, int width = 32);
|
||||||
Const(RTLIL::State bit, int width = 1);
|
Const(RTLIL::State bit, int width = 1);
|
||||||
Const(const std::vector<RTLIL::State> &bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(bits) {}
|
Const(std::vector<RTLIL::State> bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::move(bits)) {}
|
||||||
Const(const std::vector<bool> &bits);
|
Const(const std::vector<bool> &bits);
|
||||||
Const(const RTLIL::Const &other);
|
Const(const RTLIL::Const &other);
|
||||||
Const(RTLIL::Const &&other);
|
Const(RTLIL::Const &&other);
|
||||||
RTLIL::Const &operator =(const RTLIL::Const &other);
|
RTLIL::Const &operator =(const RTLIL::Const &other);
|
||||||
~Const();
|
~Const();
|
||||||
|
|
||||||
|
struct Builder
|
||||||
|
{
|
||||||
|
Builder() {}
|
||||||
|
Builder(int expected_width) { bits.reserve(expected_width); }
|
||||||
|
void push_back(RTLIL::State b) { bits.push_back(b); }
|
||||||
|
int size() const { return static_cast<int>(bits.size()); }
|
||||||
|
Const build() { return Const(std::move(bits)); }
|
||||||
|
private:
|
||||||
|
std::vector<RTLIL::State> bits;
|
||||||
|
};
|
||||||
|
|
||||||
bool 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;
|
||||||
bool operator !=(const RTLIL::Const &other) const;
|
bool operator !=(const RTLIL::Const &other) const;
|
||||||
|
@ -786,6 +797,12 @@ public:
|
||||||
void bitvectorize() const;
|
void bitvectorize() const;
|
||||||
|
|
||||||
void append(const RTLIL::Const &other);
|
void append(const RTLIL::Const &other);
|
||||||
|
void set(int i, RTLIL::State state) {
|
||||||
|
bits()[i] = state;
|
||||||
|
}
|
||||||
|
void resize(int size, RTLIL::State fill) {
|
||||||
|
bits().resize(size, fill);
|
||||||
|
}
|
||||||
|
|
||||||
class const_iterator {
|
class const_iterator {
|
||||||
private:
|
private:
|
||||||
|
@ -828,12 +845,69 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class iterator {
|
||||||
|
private:
|
||||||
|
Const* parent;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class proxy {
|
||||||
|
private:
|
||||||
|
Const* parent;
|
||||||
|
size_t idx;
|
||||||
|
public:
|
||||||
|
proxy(Const* parent, size_t idx) : parent(parent), idx(idx) {}
|
||||||
|
operator State() const { return (*parent)[idx]; }
|
||||||
|
proxy& operator=(State s) { parent->set(idx, s); return *this; }
|
||||||
|
proxy& operator=(const proxy& other) { parent->set(idx, (*other.parent)[other.idx]); return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
using value_type = State;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = proxy*;
|
||||||
|
using reference = proxy;
|
||||||
|
|
||||||
|
iterator(Const& c, size_t i) : parent(&c), idx(i) {}
|
||||||
|
|
||||||
|
proxy operator*() const { return proxy(parent, idx); }
|
||||||
|
iterator& operator++() { ++idx; return *this; }
|
||||||
|
iterator& operator--() { --idx; return *this; }
|
||||||
|
iterator operator++(int) { iterator result(*this); ++idx; return result; }
|
||||||
|
iterator operator--(int) { iterator result(*this); --idx; return result; }
|
||||||
|
iterator& operator+=(int i) { idx += i; return *this; }
|
||||||
|
|
||||||
|
iterator operator+(int add) {
|
||||||
|
return iterator(*parent, idx + add);
|
||||||
|
}
|
||||||
|
iterator operator-(int sub) {
|
||||||
|
return iterator(*parent, idx - sub);
|
||||||
|
}
|
||||||
|
int operator-(const iterator& other) {
|
||||||
|
return idx - other.idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const iterator& other) const {
|
||||||
|
return idx == other.idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const iterator& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const_iterator begin() const {
|
const_iterator begin() const {
|
||||||
return const_iterator(*this, 0);
|
return const_iterator(*this, 0);
|
||||||
}
|
}
|
||||||
const_iterator end() const {
|
const_iterator end() const {
|
||||||
return const_iterator(*this, size());
|
return const_iterator(*this, size());
|
||||||
}
|
}
|
||||||
|
iterator begin() {
|
||||||
|
return iterator(*this, 0);
|
||||||
|
}
|
||||||
|
iterator end() {
|
||||||
|
return iterator(*this, size());
|
||||||
|
}
|
||||||
State back() const {
|
State back() const {
|
||||||
return *(end() - 1);
|
return *(end() - 1);
|
||||||
}
|
}
|
||||||
|
@ -865,12 +939,11 @@ public:
|
||||||
std::optional<int> as_int_compress(bool is_signed) const;
|
std::optional<int> as_int_compress(bool is_signed) const;
|
||||||
|
|
||||||
void extu(int width) {
|
void extu(int width) {
|
||||||
bits().resize(width, RTLIL::State::S0);
|
resize(width, RTLIL::State::S0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exts(int width) {
|
void exts(int width) {
|
||||||
bitvectype& bv = bits();
|
resize(width, empty() ? RTLIL::State::Sx : back());
|
||||||
bv.resize(width, bv.empty() ? RTLIL::State::Sx : bv.back());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Hasher hash_into(Hasher h) const {
|
[[nodiscard]] Hasher hash_into(Hasher h) const {
|
||||||
|
|
|
@ -114,6 +114,60 @@ namespace RTLIL {
|
||||||
EXPECT_EQ(*it++, State::S0);
|
EXPECT_EQ(*it++, State::S0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(KernelRtlilTest, ConstIteratorWorks) {
|
||||||
|
Const c(0x2, 2);
|
||||||
|
Const::iterator it = c.begin();
|
||||||
|
ASSERT_NE(it, c.end());
|
||||||
|
EXPECT_EQ(*it, State::S0);
|
||||||
|
++it;
|
||||||
|
ASSERT_NE(it, c.end());
|
||||||
|
EXPECT_EQ(*it, State::S1);
|
||||||
|
++it;
|
||||||
|
ASSERT_EQ(it, c.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(KernelRtlilTest, ConstIteratorPreincrement) {
|
||||||
|
Const c(0x2, 2);
|
||||||
|
Const::iterator it = c.begin();
|
||||||
|
EXPECT_EQ(*++it, State::S1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(KernelRtlilTest, ConstIteratorPostincrement) {
|
||||||
|
Const c(0x2, 2);
|
||||||
|
Const::iterator it = c.begin();
|
||||||
|
EXPECT_EQ(*it++, State::S0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(KernelRtlilTest, ConstIteratorWriteWorks) {
|
||||||
|
Const c(0x2, 2);
|
||||||
|
Const::iterator it = c.begin();
|
||||||
|
EXPECT_EQ(*it, State::S0);
|
||||||
|
*it = State::S1;
|
||||||
|
EXPECT_EQ(*it, State::S1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(KernelRtlilTest, ConstBuilder) {
|
||||||
|
Const::Builder b;
|
||||||
|
EXPECT_EQ(GetSize(b), 0);
|
||||||
|
b.push_back(S0);
|
||||||
|
EXPECT_EQ(GetSize(b), 1);
|
||||||
|
b.push_back(S1);
|
||||||
|
EXPECT_EQ(GetSize(b), 2);
|
||||||
|
EXPECT_EQ(b.build(), Const(0x2, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(KernelRtlilTest, ConstSet) {
|
||||||
|
Const c(0x2, 2);
|
||||||
|
c.set(0, S1);
|
||||||
|
EXPECT_EQ(c, Const(0x3, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(KernelRtlilTest, ConstResize) {
|
||||||
|
Const c(0x2, 2);
|
||||||
|
c.resize(4, S1);
|
||||||
|
EXPECT_EQ(c, Const(0xe, 4));
|
||||||
|
}
|
||||||
|
|
||||||
class WireRtlVsHdlIndexConversionTest :
|
class WireRtlVsHdlIndexConversionTest :
|
||||||
public KernelRtlilTest,
|
public KernelRtlilTest,
|
||||||
public testing::WithParamInterface<std::tuple<bool, int, int>>
|
public testing::WithParamInterface<std::tuple<bool, int, int>>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue