From d6600fb1d508fe7526b4157b8e5e66baaff367ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 8 Jan 2024 14:06:38 +0100 Subject: [PATCH 1/3] rtlil: Fix handling of connections on wire deletion --- kernel/rtlil.cc | 45 ++++++++++++++++++++++++++++++++++----------- kernel/rtlil.h | 1 + 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ffbd4b3ff0c..badb72f2b20 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 d419872c66a..928bc044049 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -924,6 +924,7 @@ struct RTLIL::SigSpec 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(); From c035289383d6151d508519777e110e7fff2d12c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 9 Jan 2024 17:25:31 +0100 Subject: [PATCH 2/3] rtlil: Do not create dummy wires when deleting wires in connections --- kernel/rtlil.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index badb72f2b20..47598825674 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2157,12 +2157,10 @@ void RTLIL::Module::remove(const pool &wires) } void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) { - // When a deleted wire occurs on the lhs we can just remove that part + // If a deleted wire occurs on the lhs or rhs we just remove that part // of the assignment lhs.remove2(*wires_p, &rhs); - - // Then replace all rhs occurrences with a dummy wire - (*this)(rhs); + rhs.remove2(*wires_p, &lhs); } }; From ea3dc7c1b4f8446693edb4c5918a6d9e0366a595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 22 Jan 2024 14:42:45 +0100 Subject: [PATCH 3/3] rtlil: Add wire deletion test --- tests/various/bug4082.ys | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/various/bug4082.ys diff --git a/tests/various/bug4082.ys b/tests/various/bug4082.ys new file mode 100644 index 00000000000..272be2fad27 --- /dev/null +++ b/tests/various/bug4082.ys @@ -0,0 +1,8 @@ +read_verilog <