diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ffbd4b3ff..badb72f2b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2157,17 +2157,12 @@ void RTLIL::Module::remove(const pool &wires) } void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) { - log_assert(GetSize(lhs) == GetSize(rhs)); - lhs.unpack(); - rhs.unpack(); - for (int i = 0; i < GetSize(lhs); i++) { - RTLIL::SigBit &lhs_bit = lhs.bits_[i]; - RTLIL::SigBit &rhs_bit = rhs.bits_[i]; - if ((lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire)) || (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))) { - lhs_bit = State::Sx; - rhs_bit = State::Sx; - } - } + // When a deleted wire occurs on the lhs we can just remove that part + // of the assignment + lhs.remove2(*wires_p, &rhs); + + // Then replace all rhs occurrences with a dummy wire + (*this)(rhs); } }; @@ -4238,6 +4233,34 @@ void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigS check(); } +void RTLIL::SigSpec::remove2(const pool &pattern, RTLIL::SigSpec *other) +{ + if (other) + cover("kernel.rtlil.sigspec.remove_other"); + else + cover("kernel.rtlil.sigspec.remove"); + + unpack(); + + if (other != NULL) { + log_assert(width_ == other->width_); + other->unpack(); + } + + for (int i = GetSize(bits_) - 1; i >= 0; i--) { + if (bits_[i].wire != NULL && pattern.count(bits_[i].wire)) { + bits_.erase(bits_.begin() + i); + width_--; + if (other != NULL) { + other->bits_.erase(other->bits_.begin() + i); + other->width_--; + } + } + } + + check(); +} + RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const { if (other) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d419872c6..928bc0440 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -924,6 +924,7 @@ public: void remove(const pool &pattern, RTLIL::SigSpec *other) const; void remove2(const pool &pattern, RTLIL::SigSpec *other); void remove2(const std::set &pattern, RTLIL::SigSpec *other); + void remove2(const pool &pattern, RTLIL::SigSpec *other); void remove(int offset, int length = 1); void remove_const();