proc_prune: Make assign removal and promotion per-bit, remember promoted bits.

Fixes #2962.
This commit is contained in:
Marcelina Kościelnicka 2021-08-14 14:23:12 +02:00
parent 539d4ee907
commit faacc7ad89
2 changed files with 47 additions and 40 deletions

View File

@ -67,51 +67,36 @@ struct PruneWorker
} }
for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) { for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) {
RTLIL::SigSpec lhs = sigmap(it->first); RTLIL::SigSpec lhs = sigmap(it->first);
bool redundant = true; RTLIL::SigSpec rhs = sigmap(it->second);
for (auto &bit : lhs) { 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]) { if (bit.wire && !assigned[bit]) {
redundant = false; if (!affected[bit] && root) {
break; 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);
} }
} }
bool remove = false; if (GetSize(conn_lhs)) {
if (redundant) { promoted_count++;
removed_count++; module->connect(conn_lhs, conn_rhs);
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;
}
}
for (auto &bit : lhs)
if (bit.wire)
assigned.insert(bit);
for (auto &bit : lhs)
if (bit.wire)
affected.insert(bit);
} }
if (remove) if (GetSize(new_lhs) == 0) {
if (GetSize(conn_lhs) == 0)
removed_count++;
cs->actions.erase((it++).base() - 1); cs->actions.erase((it++).base() - 1);
else it++; } else {
it->first = new_lhs;
it->second = new_rhs;
it++;
}
} }
return assigned; return assigned;
} }

22
tests/proc/bug2962.ys Normal file
View File

@ -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