From faacc7ad897437a8169af9dbbab6818f88c7b1a9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 14 Aug 2021 14:23:12 +0200 Subject: [PATCH] proc_prune: Make assign removal and promotion per-bit, remember promoted bits. Fixes #2962. --- passes/proc/proc_prune.cc | 65 +++++++++++++++------------------------ tests/proc/bug2962.ys | 22 +++++++++++++ 2 files changed, 47 insertions(+), 40 deletions(-) create mode 100644 tests/proc/bug2962.ys diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc index bd122b91f..9f1080ef6 100644 --- a/passes/proc/proc_prune.cc +++ b/passes/proc/proc_prune.cc @@ -67,51 +67,36 @@ struct PruneWorker } for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) { RTLIL::SigSpec lhs = sigmap(it->first); - bool redundant = true; - for (auto &bit : lhs) { + RTLIL::SigSpec rhs = sigmap(it->second); + SigSpec new_lhs, new_rhs; + SigSpec conn_lhs, conn_rhs; + for (int i = 0; i < GetSize(lhs); i++) { + SigBit bit = lhs[i]; if (bit.wire && !assigned[bit]) { - redundant = false; - break; - } - } - bool remove = false; - if (redundant) { - removed_count++; - remove = true; - } else { - if (root) { - bool promotable = true; - for (auto &bit : lhs) { - if (bit.wire && affected[bit] && !assigned[bit]) { - promotable = false; - break; - } - } - if (promotable) { - RTLIL::SigSpec rhs = sigmap(it->second); - RTLIL::SigSig conn; - for (int i = 0; i < GetSize(lhs); i++) { - RTLIL::SigBit lhs_bit = lhs[i]; - if (lhs_bit.wire && !assigned[lhs_bit]) { - conn.first.append(lhs_bit); - conn.second.append(rhs.extract(i)); - } - } - promoted_count++; - module->connect(conn); - remove = true; + if (!affected[bit] && root) { + conn_lhs.append(bit); + conn_rhs.append(rhs[i]); + } else { + new_lhs.append(bit); + new_rhs.append(rhs[i]); } + assigned.insert(bit); + affected.insert(bit); } - for (auto &bit : lhs) - if (bit.wire) - assigned.insert(bit); - for (auto &bit : lhs) - if (bit.wire) - affected.insert(bit); } - if (remove) + if (GetSize(conn_lhs)) { + promoted_count++; + module->connect(conn_lhs, conn_rhs); + } + if (GetSize(new_lhs) == 0) { + if (GetSize(conn_lhs) == 0) + removed_count++; cs->actions.erase((it++).base() - 1); - else it++; + } else { + it->first = new_lhs; + it->second = new_rhs; + it++; + } } return assigned; } diff --git a/tests/proc/bug2962.ys b/tests/proc/bug2962.ys new file mode 100644 index 000000000..99da8db5d --- /dev/null +++ b/tests/proc/bug2962.ys @@ -0,0 +1,22 @@ +read_ilang << EOT +module \top + wire width 4 input 1 \a + wire width 2 input 2 \b + wire input 3 \clk + wire width 4 output 4 \q + wire input 5 \en + wire width 4 \nq + process \p + assign \nq \a + assign \nq [1:0] \b + switch \en + case 1'1 + assign \nq [3] 1'0 + end + sync posedge \clk + update \q \nq + end +end +EOT +proc +check -assert -- 2.30.2