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).
This commit is contained in:
Krystine Sherwin 2026-07-29 11:06:58 +12:00
parent 8962b6b6db
commit 7c050b8495
No known key found for this signature in database
1 changed files with 22 additions and 4 deletions

View File

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