mirror of
https://github.com/YosysHQ/yosys
synced 2025-11-05 22:06:04 +00:00
Make SigSpec::chunks() return an object that can be iterated over without packing the SigSpec
This commit is contained in:
parent
c4f3e61339
commit
37e4c2e8f8
4 changed files with 104 additions and 9 deletions
|
|
@ -4648,6 +4648,31 @@ RTLIL::SigSpec::SigSpec(bool bit)
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RTLIL::SigSpec::Chunks::const_iterator::next_chunk_bits()
|
||||||
|
{
|
||||||
|
int bits_size = GetSize(spec.bits_);
|
||||||
|
if (bit_index >= bits_size)
|
||||||
|
return;
|
||||||
|
int i = bit_index;
|
||||||
|
const SigBit &bit = spec.bits_[i++];
|
||||||
|
chunk.wire = bit.wire;
|
||||||
|
chunk.data.clear();
|
||||||
|
if (bit.is_wire()) {
|
||||||
|
chunk.offset = bit.offset;
|
||||||
|
while (i < bits_size && spec.bits_[i].wire == bit.wire &&
|
||||||
|
spec.bits_[i].offset == bit.offset + i - bit_index)
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
chunk.offset = 0;
|
||||||
|
chunk.data.push_back(bit.data);
|
||||||
|
while (i < bits_size && !spec.bits_[i].is_wire()) {
|
||||||
|
chunk.data.push_back(spec.bits_[i].data);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chunk.width = i - bit_index;
|
||||||
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::pack() const
|
void RTLIL::SigSpec::pack() const
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
|
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
|
||||||
|
|
|
||||||
|
|
@ -1275,7 +1275,75 @@ public:
|
||||||
SigSpec &operator=(const SigSpec &rhs) = default;
|
SigSpec &operator=(const SigSpec &rhs) = default;
|
||||||
SigSpec &operator=(SigSpec &&rhs) = default;
|
SigSpec &operator=(SigSpec &&rhs) = default;
|
||||||
|
|
||||||
inline const std::vector<RTLIL::SigChunk> &chunks() const { pack(); return chunks_; }
|
struct Chunks {
|
||||||
|
const SigSpec &spec;
|
||||||
|
|
||||||
|
struct const_iterator {
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
using value_type = const SigChunk &;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = const SigChunk *;
|
||||||
|
using reference = const SigChunk &;
|
||||||
|
|
||||||
|
const SigSpec &spec;
|
||||||
|
int chunk_index;
|
||||||
|
int bit_index;
|
||||||
|
SigChunk chunk;
|
||||||
|
|
||||||
|
const_iterator(const SigSpec &spec) : spec(spec) {
|
||||||
|
chunk_index = 0;
|
||||||
|
bit_index = 0;
|
||||||
|
if (!spec.packed())
|
||||||
|
next_chunk_bits();
|
||||||
|
}
|
||||||
|
void next_chunk_bits();
|
||||||
|
|
||||||
|
const SigChunk &operator*() {
|
||||||
|
if (spec.packed())
|
||||||
|
return spec.chunks_[chunk_index];
|
||||||
|
return chunk;
|
||||||
|
};
|
||||||
|
const SigChunk *operator->() { return &**this; }
|
||||||
|
const_iterator &operator++() {
|
||||||
|
bit_index += (**this).width;
|
||||||
|
++chunk_index;
|
||||||
|
if (!spec.packed())
|
||||||
|
next_chunk_bits();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator==(const const_iterator &rhs) const { return bit_index == rhs.bit_index; }
|
||||||
|
bool operator!=(const const_iterator &rhs) const { return !(*this == rhs); }
|
||||||
|
};
|
||||||
|
const_iterator begin() const { return const_iterator(spec); }
|
||||||
|
const_iterator end() const {
|
||||||
|
const_iterator it(spec);
|
||||||
|
it.bit_index = spec.size();
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
std::vector<RTLIL::SigChunk>::const_reverse_iterator rbegin() const {
|
||||||
|
spec.pack();
|
||||||
|
return spec.chunks_.rbegin();
|
||||||
|
}
|
||||||
|
std::vector<RTLIL::SigChunk>::const_reverse_iterator rend() const {
|
||||||
|
spec.pack();
|
||||||
|
return spec.chunks_.rend();
|
||||||
|
}
|
||||||
|
int size() const {
|
||||||
|
spec.pack();
|
||||||
|
return spec.chunks_.size();
|
||||||
|
}
|
||||||
|
const SigChunk &at(int index) const {
|
||||||
|
spec.pack();
|
||||||
|
return spec.chunks_.at(index);
|
||||||
|
}
|
||||||
|
operator const std::vector<RTLIL::SigChunk>&() const {
|
||||||
|
spec.pack();
|
||||||
|
return spec.chunks_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
friend struct Chunks::const_iterator;
|
||||||
|
|
||||||
|
inline Chunks chunks() const { return {*this}; }
|
||||||
inline const std::vector<RTLIL::SigBit> &bits() const { inline_unpack(); return bits_; }
|
inline const std::vector<RTLIL::SigBit> &bits() const { inline_unpack(); return bits_; }
|
||||||
|
|
||||||
inline int size() const { return width_; }
|
inline int size() const { return width_; }
|
||||||
|
|
@ -1402,7 +1470,7 @@ public:
|
||||||
static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str);
|
static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str);
|
||||||
static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
|
static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
|
||||||
|
|
||||||
operator std::vector<RTLIL::SigChunk>() const { return chunks(); }
|
operator std::vector<RTLIL::SigChunk>() const { pack(); return chunks_; }
|
||||||
operator std::vector<RTLIL::SigBit>() const { return bits(); }
|
operator std::vector<RTLIL::SigBit>() const { return bits(); }
|
||||||
const RTLIL::SigBit &at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }
|
const RTLIL::SigBit &at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }
|
||||||
|
|
||||||
|
|
@ -2315,8 +2383,9 @@ inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {
|
inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {
|
||||||
log_assert(sig.size() == 1 && sig.chunks().size() == 1);
|
log_assert(sig.size() == 1);
|
||||||
*this = SigBit(sig.chunks().front());
|
auto it = sig.chunks().begin();
|
||||||
|
*this = SigBit(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -278,11 +278,12 @@ struct ShowWorker
|
||||||
std::vector<std::string> label_pieces;
|
std::vector<std::string> label_pieces;
|
||||||
int bitpos = sig.size()-1;
|
int bitpos = sig.size()-1;
|
||||||
|
|
||||||
for (int rep, chunk_idx = ((int) sig.chunks().size()) - 1; chunk_idx >= 0; chunk_idx -= rep) {
|
RTLIL::SigSpec::Chunks sig_chunks = sig.chunks();
|
||||||
const RTLIL::SigChunk &c = sig.chunks().at(chunk_idx);
|
for (int rep, chunk_idx = ((int) sig_chunks.size()) - 1; chunk_idx >= 0; chunk_idx -= rep) {
|
||||||
|
const RTLIL::SigChunk &c = sig_chunks.at(chunk_idx);
|
||||||
|
|
||||||
// Find the number of times this chunk is repeating
|
// Find the number of times this chunk is repeating
|
||||||
for (rep = 1; chunk_idx - rep >= 0 && c == sig.chunks().at(chunk_idx - rep); rep++);
|
for (rep = 1; chunk_idx - rep >= 0 && c == sig_chunks.at(chunk_idx - rep); rep++);
|
||||||
|
|
||||||
int cl, cr;
|
int cl, cr;
|
||||||
cl = c.offset + c.width - 1;
|
cl = c.offset + c.width - 1;
|
||||||
|
|
|
||||||
|
|
@ -1428,13 +1428,13 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
|
||||||
// Copy connections (and rename) from mapped_mod to module
|
// Copy connections (and rename) from mapped_mod to module
|
||||||
for (auto conn : mapped_mod->connections()) {
|
for (auto conn : mapped_mod->connections()) {
|
||||||
if (!conn.first.is_fully_const()) {
|
if (!conn.first.is_fully_const()) {
|
||||||
auto chunks = conn.first.chunks();
|
std::vector<RTLIL::SigChunk> chunks = conn.first.chunks();
|
||||||
for (auto &c : chunks)
|
for (auto &c : chunks)
|
||||||
c.wire = module->wires_.at(remap_name(c.wire->name));
|
c.wire = module->wires_.at(remap_name(c.wire->name));
|
||||||
conn.first = std::move(chunks);
|
conn.first = std::move(chunks);
|
||||||
}
|
}
|
||||||
if (!conn.second.is_fully_const()) {
|
if (!conn.second.is_fully_const()) {
|
||||||
auto chunks = conn.second.chunks();
|
std::vector<RTLIL::SigChunk> chunks = conn.second.chunks();
|
||||||
for (auto &c : chunks)
|
for (auto &c : chunks)
|
||||||
if (c.wire)
|
if (c.wire)
|
||||||
c.wire = module->wires_.at(remap_name(c.wire->name));
|
c.wire = module->wires_.at(remap_name(c.wire->name));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue