From 7c050b8495bfb12d84bc7c6d1263145f4416d4ad Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:06:58 +1200 Subject: [PATCH] alumacc: cmp_mergeable function Replace all the existing mergeable checks with a call to a single function. Fix remaining discrepencies (undersized output and mismatched signed inputs). --- passes/techmap/alumacc.cc | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index e42585874..2a1fcb9f9 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -427,6 +427,24 @@ struct AlumaccWorker eq_cells.push_back(cell); } + auto cmp_mergeable = [](const alunode_t *node, const SigSpec cmp_A, const SigSpec cmp_B, bool is_signed) { + if (!node->invert_b || node->c != State::S1) { + // comparators need subtraction + return false; + } + if (max(GetSize(cmp_A), GetSize(cmp_B)) > GetSize(node->y)) { + // must have at least as many output bits + return false; + } + if (is_signed != node->is_signed) { + if (GetSize(cmp_A) != GetSize(cmp_B)) { + // mismatched input widths are problematic when mixing signedness + return false; + } + } + return true; + }; + for (auto cell : lge_cells) { log(" creating $alu model for %s (%s):", cell, cell->type.unescape()); @@ -442,14 +460,14 @@ struct AlumaccWorker alunode_t *n = nullptr; for (auto node : sig_alu[RTLIL::SigSig(A, B)]) - if (node->invert_b && node->c == State::S1) { + if (cmp_mergeable(node, A, B, is_signed)) { n = node; break; } if (n == nullptr) { for (auto node : sig_alu[RTLIL::SigSig(B, A)]) - if (node->is_signed == is_signed && node->invert_b && node->c == State::S1) { + if (cmp_mergeable(node, B, A, is_signed)) { n = node; cmp_less = !cmp_less; std::swap(A, B); @@ -488,14 +506,14 @@ struct AlumaccWorker alunode_t *n = nullptr; for (auto node : sig_alu[RTLIL::SigSig(A, B)]) - if (node->invert_b && node->c == State::S1) { + if (cmp_mergeable(node, A, B, is_signed)) { n = node; break; } if (n == nullptr) { for (auto node : sig_alu[RTLIL::SigSig(B, A)]) - if (node->is_signed == is_signed && node->invert_b && node->c == State::S1) { + if (cmp_mergeable(node, B, A, is_signed)) { n = node; break; }