mirror of https://github.com/YosysHQ/yosys.git
SigSpec refactoring: rewrote some RTLIL::SigSpec methods to use unpacked form
This commit is contained in:
parent
a97be0828a
commit
fd4cbe6275
297
kernel/rtlil.cc
297
kernel/rtlil.cc
|
@ -1566,27 +1566,13 @@ RTLIL::SigSpec RTLIL::SigSpec::optimized() const
|
|||
|
||||
void RTLIL::SigSpec::sort()
|
||||
{
|
||||
pack();
|
||||
expand();
|
||||
std::sort(chunks_.begin(), chunks_.end());
|
||||
optimize();
|
||||
unpack();
|
||||
std::sort(bits_.begin(), bits_.end());
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::sort_and_unify()
|
||||
{
|
||||
pack();
|
||||
expand();
|
||||
std::sort(chunks_.begin(), chunks_.end());
|
||||
for (size_t i = 1; i < chunks_.size(); i++) {
|
||||
RTLIL::SigChunk &ch1 = chunks_[i-1];
|
||||
RTLIL::SigChunk &ch2 = chunks_[i];
|
||||
if (ch1 == ch2) {
|
||||
chunks_.erase(chunks_.begin()+i);
|
||||
width_ -= chunks_[i].width;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
optimize();
|
||||
*this = this->to_sigbit_set();
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
|
||||
|
@ -1596,36 +1582,26 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec
|
|||
|
||||
void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const
|
||||
{
|
||||
pack();
|
||||
pattern.pack();
|
||||
with.pack();
|
||||
unpack();
|
||||
pattern.unpack();
|
||||
with.unpack();
|
||||
|
||||
if (other != NULL)
|
||||
other->pack();
|
||||
assert(other != NULL);
|
||||
assert(width_ == other->width_);
|
||||
other->unpack();
|
||||
|
||||
int pos = 0, restart_pos = 0;
|
||||
assert(other == NULL || width_ == other->width_);
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
restart:
|
||||
const RTLIL::SigChunk &ch1 = chunks_[i];
|
||||
if (chunks_[i].wire != NULL && pos >= restart_pos)
|
||||
for (size_t j = 0, poff = 0; j < pattern.chunks_.size(); j++) {
|
||||
const RTLIL::SigChunk &ch2 = pattern.chunks_[j];
|
||||
assert(ch2.wire != NULL);
|
||||
if (ch1.wire == ch2.wire) {
|
||||
int lower = std::max(ch1.offset, ch2.offset);
|
||||
int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width);
|
||||
if (lower < upper) {
|
||||
restart_pos = pos+upper-ch1.offset;
|
||||
other->replace(pos+lower-ch1.offset, with.extract(poff+lower-ch2.offset, upper-lower));
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
poff += ch2.width;
|
||||
}
|
||||
pos += chunks_[i].width;
|
||||
}
|
||||
check();
|
||||
assert(pattern.width_ == with.width_);
|
||||
|
||||
std::map<RTLIL::SigBit, RTLIL::SigBit> pattern_map;
|
||||
for (int i = 0; i < SIZE(pattern.bits_); i++)
|
||||
if (pattern.bits_[i].wire != NULL)
|
||||
pattern_map[pattern.bits_[i]] = with.bits_[i];
|
||||
|
||||
for (int i = 0; i < SIZE(bits_); i++)
|
||||
if (pattern_map.count(bits_[i]))
|
||||
other->bits_[i] = pattern_map.at(bits_[i]);
|
||||
|
||||
other->check();
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern)
|
||||
|
@ -1641,36 +1617,32 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other
|
|||
|
||||
void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
|
||||
{
|
||||
pack();
|
||||
pattern.pack();
|
||||
unpack();
|
||||
|
||||
if (other != NULL)
|
||||
other->pack();
|
||||
|
||||
int pos = 0;
|
||||
assert(other == NULL || width_ == other->width_);
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
restart:
|
||||
const RTLIL::SigChunk &ch1 = chunks_[i];
|
||||
if (chunks_[i].wire != NULL)
|
||||
for (size_t j = 0; j < pattern.chunks_.size(); j++) {
|
||||
const RTLIL::SigChunk &ch2 = pattern.chunks_[j];
|
||||
assert(ch2.wire != NULL);
|
||||
if (ch1.wire == ch2.wire) {
|
||||
int lower = std::max(ch1.offset, ch2.offset);
|
||||
int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width);
|
||||
if (lower < upper) {
|
||||
if (other)
|
||||
other->remove(pos+lower-ch1.offset, upper-lower);
|
||||
remove(pos+lower-ch1.offset, upper-lower);
|
||||
if (i == chunks_.size())
|
||||
break;
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos += chunks_[i].width;
|
||||
if (other != NULL) {
|
||||
assert(width_ == other->width_);
|
||||
other->unpack();
|
||||
}
|
||||
|
||||
std::set<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_set();
|
||||
std::vector<RTLIL::SigBit> new_bits, new_other_bits;
|
||||
|
||||
for (int i = 0; i < SIZE(bits_); i++) {
|
||||
if (bits_[i].wire != NULL && pattern_bits.count(bits_[i]))
|
||||
continue;
|
||||
if (other != NULL)
|
||||
new_other_bits.push_back(other->bits_[i]);
|
||||
new_bits.push_back(bits_[i]);
|
||||
}
|
||||
|
||||
bits_.swap(new_bits);
|
||||
width_ = SIZE(bits_);
|
||||
|
||||
if (other != NULL) {
|
||||
other->bits_.swap(new_other_bits);
|
||||
other->width_ = SIZE(other->bits_);
|
||||
}
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
|
@ -1705,109 +1677,54 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o
|
|||
|
||||
void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
|
||||
{
|
||||
pack();
|
||||
with.pack();
|
||||
unpack();
|
||||
with.unpack();
|
||||
|
||||
int pos = 0;
|
||||
assert(offset >= 0);
|
||||
assert(with.width_ >= 0);
|
||||
assert(offset+with.width_ <= width_);
|
||||
remove(offset, with.width_);
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
if (pos == offset) {
|
||||
chunks_.insert(chunks_.begin()+i, with.chunks_.begin(), with.chunks_.end());
|
||||
width_ += with.width_;
|
||||
check();
|
||||
return;
|
||||
}
|
||||
pos += chunks_[i].width;
|
||||
}
|
||||
assert(pos == offset);
|
||||
chunks_.insert(chunks_.end(), with.chunks_.begin(), with.chunks_.end());
|
||||
width_ += with.width_;
|
||||
|
||||
for (int i = 0; i < with.width_; i++)
|
||||
bits_.at(offset + i) = with.bits_.at(i);
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::remove_const()
|
||||
{
|
||||
pack();
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
if (chunks_[i].wire != NULL)
|
||||
continue;
|
||||
width_ -= chunks_[i].width;
|
||||
chunks_.erase(chunks_.begin() + (i--));
|
||||
}
|
||||
unpack();
|
||||
|
||||
std::vector<RTLIL::SigBit> new_bits;
|
||||
new_bits.reserve(width_);
|
||||
|
||||
for (auto &bit : bits_)
|
||||
if (bit.wire != NULL)
|
||||
new_bits.push_back(bit);
|
||||
|
||||
bits_.swap(new_bits);
|
||||
width_ = bits_.size();
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::remove(int offset, int length)
|
||||
{
|
||||
pack();
|
||||
int pos = 0;
|
||||
unpack();
|
||||
|
||||
assert(offset >= 0);
|
||||
assert(length >= 0);
|
||||
assert(offset+length <= width_);
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
int orig_width = chunks_[i].width;
|
||||
if (pos+chunks_[i].width > offset && pos < offset+length) {
|
||||
int off = offset - pos;
|
||||
int len = length;
|
||||
if (off < 0) {
|
||||
len += off;
|
||||
off = 0;
|
||||
}
|
||||
if (len > chunks_[i].width-off)
|
||||
len = chunks_[i].width-off;
|
||||
RTLIL::SigChunk lsb_chunk = chunks_[i].extract(0, off);
|
||||
RTLIL::SigChunk msb_chunk = chunks_[i].extract(off+len, chunks_[i].width-off-len);
|
||||
if (lsb_chunk.width == 0 && msb_chunk.width == 0) {
|
||||
chunks_.erase(chunks_.begin()+i);
|
||||
i--;
|
||||
} else if (lsb_chunk.width == 0 && msb_chunk.width != 0) {
|
||||
chunks_[i] = msb_chunk;
|
||||
} else if (lsb_chunk.width != 0 && msb_chunk.width == 0) {
|
||||
chunks_[i] = lsb_chunk;
|
||||
} else if (lsb_chunk.width != 0 && msb_chunk.width != 0) {
|
||||
chunks_[i] = lsb_chunk;
|
||||
chunks_.insert(chunks_.begin()+i+1, msb_chunk);
|
||||
i++;
|
||||
} else
|
||||
assert(0);
|
||||
width_ -= len;
|
||||
}
|
||||
pos += orig_width;
|
||||
}
|
||||
assert(offset + length <= width_);
|
||||
|
||||
bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length);
|
||||
width_ = bits_.size();
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
|
||||
{
|
||||
pack();
|
||||
int pos = 0;
|
||||
RTLIL::SigSpec ret;
|
||||
assert(offset >= 0);
|
||||
assert(length >= 0);
|
||||
assert(offset+length <= width_);
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
if (pos+chunks_[i].width > offset && pos < offset+length) {
|
||||
int off = offset - pos;
|
||||
int len = length;
|
||||
if (off < 0) {
|
||||
len += off;
|
||||
off = 0;
|
||||
}
|
||||
if (len > chunks_[i].width-off)
|
||||
len = chunks_[i].width-off;
|
||||
ret.chunks_.push_back(chunks_[i].extract(off, len));
|
||||
ret.width_ += len;
|
||||
offset += len;
|
||||
length -= len;
|
||||
}
|
||||
pos += chunks_[i].width;
|
||||
}
|
||||
assert(length == 0);
|
||||
ret.check();
|
||||
return ret;
|
||||
unpack();
|
||||
return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
|
||||
|
@ -1819,27 +1736,34 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
|
|||
chunks_.push_back(signal.chunks_[i]);
|
||||
width_ += signal.chunks_[i].width;
|
||||
}
|
||||
|
||||
// check();
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
|
||||
{
|
||||
pack();
|
||||
if (chunks_.size() == 0)
|
||||
chunks_.push_back(bit);
|
||||
else
|
||||
if (bit.wire == NULL)
|
||||
if (chunks_.back().wire == NULL) {
|
||||
chunks_.back().data.bits.push_back(bit.data);
|
||||
chunks_.back().width++;
|
||||
} else
|
||||
chunks_.push_back(bit);
|
||||
if (packed())
|
||||
{
|
||||
if (chunks_.size() == 0)
|
||||
chunks_.push_back(bit);
|
||||
else
|
||||
if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset)
|
||||
chunks_.back().width++;
|
||||
if (bit.wire == NULL)
|
||||
if (chunks_.back().wire == NULL) {
|
||||
chunks_.back().data.bits.push_back(bit.data);
|
||||
chunks_.back().width++;
|
||||
} else
|
||||
chunks_.push_back(bit);
|
||||
else
|
||||
chunks_.push_back(bit);
|
||||
if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset)
|
||||
chunks_.back().width++;
|
||||
else
|
||||
chunks_.push_back(bit);
|
||||
}
|
||||
else
|
||||
bits_.push_back(bit);
|
||||
|
||||
width_++;
|
||||
|
||||
// check();
|
||||
}
|
||||
|
||||
|
@ -1911,23 +1835,30 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
|
|||
|
||||
void RTLIL::SigSpec::check() const
|
||||
{
|
||||
pack();
|
||||
|
||||
int w = 0;
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
const RTLIL::SigChunk chunk = chunks_[i];
|
||||
if (chunk.wire == NULL) {
|
||||
assert(chunk.offset == 0);
|
||||
assert(chunk.data.bits.size() == (size_t)chunk.width);
|
||||
} else {
|
||||
assert(chunk.offset >= 0);
|
||||
assert(chunk.width >= 0);
|
||||
assert(chunk.offset + chunk.width <= chunk.wire->width);
|
||||
assert(chunk.data.bits.size() == 0);
|
||||
if (packed())
|
||||
{
|
||||
int w = 0;
|
||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||
const RTLIL::SigChunk chunk = chunks_[i];
|
||||
if (chunk.wire == NULL) {
|
||||
assert(chunk.offset == 0);
|
||||
assert(chunk.data.bits.size() == (size_t)chunk.width);
|
||||
} else {
|
||||
assert(chunk.offset >= 0);
|
||||
assert(chunk.width >= 0);
|
||||
assert(chunk.offset + chunk.width <= chunk.wire->width);
|
||||
assert(chunk.data.bits.size() == 0);
|
||||
}
|
||||
w += chunk.width;
|
||||
}
|
||||
w += chunk.width;
|
||||
assert(w == width_);
|
||||
assert(bits_.empty());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(width_ == SIZE(bits_));
|
||||
assert(chunks_.empty());
|
||||
}
|
||||
assert(w == width_);
|
||||
}
|
||||
|
||||
bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
|
||||
|
|
Loading…
Reference in New Issue