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()
|
void RTLIL::SigSpec::sort()
|
||||||
{
|
{
|
||||||
pack();
|
unpack();
|
||||||
expand();
|
std::sort(bits_.begin(), bits_.end());
|
||||||
std::sort(chunks_.begin(), chunks_.end());
|
|
||||||
optimize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::sort_and_unify()
|
void RTLIL::SigSpec::sort_and_unify()
|
||||||
{
|
{
|
||||||
pack();
|
*this = this->to_sigbit_set();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
|
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
|
void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const
|
||||||
{
|
{
|
||||||
pack();
|
unpack();
|
||||||
pattern.pack();
|
pattern.unpack();
|
||||||
with.pack();
|
with.unpack();
|
||||||
|
|
||||||
if (other != NULL)
|
assert(other != NULL);
|
||||||
other->pack();
|
assert(width_ == other->width_);
|
||||||
|
other->unpack();
|
||||||
|
|
||||||
int pos = 0, restart_pos = 0;
|
assert(pattern.width_ == with.width_);
|
||||||
assert(other == NULL || width_ == other->width_);
|
|
||||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
std::map<RTLIL::SigBit, RTLIL::SigBit> pattern_map;
|
||||||
restart:
|
for (int i = 0; i < SIZE(pattern.bits_); i++)
|
||||||
const RTLIL::SigChunk &ch1 = chunks_[i];
|
if (pattern.bits_[i].wire != NULL)
|
||||||
if (chunks_[i].wire != NULL && pos >= restart_pos)
|
pattern_map[pattern.bits_[i]] = with.bits_[i];
|
||||||
for (size_t j = 0, poff = 0; j < pattern.chunks_.size(); j++) {
|
|
||||||
const RTLIL::SigChunk &ch2 = pattern.chunks_[j];
|
for (int i = 0; i < SIZE(bits_); i++)
|
||||||
assert(ch2.wire != NULL);
|
if (pattern_map.count(bits_[i]))
|
||||||
if (ch1.wire == ch2.wire) {
|
other->bits_[i] = pattern_map.at(bits_[i]);
|
||||||
int lower = std::max(ch1.offset, ch2.offset);
|
|
||||||
int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width);
|
other->check();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern)
|
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)
|
void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
|
||||||
{
|
{
|
||||||
pack();
|
unpack();
|
||||||
pattern.pack();
|
|
||||||
|
|
||||||
if (other != NULL)
|
if (other != NULL) {
|
||||||
other->pack();
|
assert(width_ == other->width_);
|
||||||
|
other->unpack();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
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)
|
void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
|
||||||
{
|
{
|
||||||
pack();
|
unpack();
|
||||||
with.pack();
|
with.unpack();
|
||||||
|
|
||||||
int pos = 0;
|
|
||||||
assert(offset >= 0);
|
assert(offset >= 0);
|
||||||
assert(with.width_ >= 0);
|
assert(with.width_ >= 0);
|
||||||
assert(offset+with.width_ <= width_);
|
assert(offset+with.width_ <= width_);
|
||||||
remove(offset, with.width_);
|
|
||||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
for (int i = 0; i < with.width_; i++)
|
||||||
if (pos == offset) {
|
bits_.at(offset + i) = with.bits_.at(i);
|
||||||
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_;
|
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::remove_const()
|
void RTLIL::SigSpec::remove_const()
|
||||||
{
|
{
|
||||||
pack();
|
unpack();
|
||||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
|
||||||
if (chunks_[i].wire != NULL)
|
std::vector<RTLIL::SigBit> new_bits;
|
||||||
continue;
|
new_bits.reserve(width_);
|
||||||
width_ -= chunks_[i].width;
|
|
||||||
chunks_.erase(chunks_.begin() + (i--));
|
for (auto &bit : bits_)
|
||||||
}
|
if (bit.wire != NULL)
|
||||||
|
new_bits.push_back(bit);
|
||||||
|
|
||||||
|
bits_.swap(new_bits);
|
||||||
|
width_ = bits_.size();
|
||||||
|
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::remove(int offset, int length)
|
void RTLIL::SigSpec::remove(int offset, int length)
|
||||||
{
|
{
|
||||||
pack();
|
unpack();
|
||||||
int pos = 0;
|
|
||||||
assert(offset >= 0);
|
assert(offset >= 0);
|
||||||
assert(length >= 0);
|
assert(length >= 0);
|
||||||
assert(offset+length <= width_);
|
assert(offset + length <= width_);
|
||||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
|
||||||
int orig_width = chunks_[i].width;
|
bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length);
|
||||||
if (pos+chunks_[i].width > offset && pos < offset+length) {
|
width_ = bits_.size();
|
||||||
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;
|
|
||||||
}
|
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
|
RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
|
||||||
{
|
{
|
||||||
pack();
|
unpack();
|
||||||
int pos = 0;
|
return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
|
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]);
|
chunks_.push_back(signal.chunks_[i]);
|
||||||
width_ += signal.chunks_[i].width;
|
width_ += signal.chunks_[i].width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check();
|
// check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
|
void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
|
||||||
{
|
{
|
||||||
pack();
|
if (packed())
|
||||||
if (chunks_.size() == 0)
|
{
|
||||||
chunks_.push_back(bit);
|
if (chunks_.size() == 0)
|
||||||
else
|
chunks_.push_back(bit);
|
||||||
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
|
else
|
||||||
if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset)
|
if (bit.wire == NULL)
|
||||||
chunks_.back().width++;
|
if (chunks_.back().wire == NULL) {
|
||||||
|
chunks_.back().data.bits.push_back(bit.data);
|
||||||
|
chunks_.back().width++;
|
||||||
|
} else
|
||||||
|
chunks_.push_back(bit);
|
||||||
else
|
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_++;
|
width_++;
|
||||||
|
|
||||||
// check();
|
// check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1911,23 +1835,30 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
|
||||||
|
|
||||||
void RTLIL::SigSpec::check() const
|
void RTLIL::SigSpec::check() const
|
||||||
{
|
{
|
||||||
pack();
|
if (packed())
|
||||||
|
{
|
||||||
int w = 0;
|
int w = 0;
|
||||||
for (size_t i = 0; i < chunks_.size(); i++) {
|
for (size_t i = 0; i < chunks_.size(); i++) {
|
||||||
const RTLIL::SigChunk chunk = chunks_[i];
|
const RTLIL::SigChunk chunk = chunks_[i];
|
||||||
if (chunk.wire == NULL) {
|
if (chunk.wire == NULL) {
|
||||||
assert(chunk.offset == 0);
|
assert(chunk.offset == 0);
|
||||||
assert(chunk.data.bits.size() == (size_t)chunk.width);
|
assert(chunk.data.bits.size() == (size_t)chunk.width);
|
||||||
} else {
|
} else {
|
||||||
assert(chunk.offset >= 0);
|
assert(chunk.offset >= 0);
|
||||||
assert(chunk.width >= 0);
|
assert(chunk.width >= 0);
|
||||||
assert(chunk.offset + chunk.width <= chunk.wire->width);
|
assert(chunk.offset + chunk.width <= chunk.wire->width);
|
||||||
assert(chunk.data.bits.size() == 0);
|
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
|
bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
|
||||||
|
|
Loading…
Reference in New Issue