rtlil: Replace the packed `SigSpec::extract` impl

This commit is contained in:
Martin Povišer 2024-04-22 16:23:51 +02:00
parent 0d30a4d479
commit 178eceb32d
1 changed files with 21 additions and 25 deletions

View File

@ -4438,37 +4438,33 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
cover("kernel.rtlil.sigspec.extract_pos"); cover("kernel.rtlil.sigspec.extract_pos");
if (packed()) if (packed()) {
{
if (chunks_.size() == 1)
return chunks_[0].extract(offset, length);
SigSpec extracted; SigSpec extracted;
int end = offset + length; extracted.width_ = length;
int chunk_end = 0;
for (auto const &chunk : chunks_) auto it = chunks_.begin();
{ for (; offset; offset -= it->width, it++) {
int chunk_begin = chunk_end; if (offset < it->width) {
chunk_end += chunk.width; int chunk_length = min(it->width - offset, length);
int extract_begin = std::max(chunk_begin, offset); extracted.chunks_.emplace_back(it->extract(offset, chunk_length));
int extract_end = std::min(chunk_end, end); length -= chunk_length;
if (extract_begin >= extract_end) it++;
continue; break;
int extract_offset = extract_begin - chunk_begin; }
int extract_len = extract_end - extract_begin; }
if (extract_offset == 0 && extract_len == chunk.width) for (; length; length -= it->width, it++) {
extracted.chunks_.emplace_back(chunk); if (length >= it->width) {
else extracted.chunks_.emplace_back(*it);
extracted.chunks_.emplace_back( } else {
chunk.extract(extract_offset, extract_len)); extracted.chunks_.emplace_back(it->extract(0, length));
break;
}
} }
extracted.width_ = length;
return extracted; return extracted;
} else {
return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
} }
return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
} }
void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)