mirror of https://github.com/YosysHQ/yosys.git
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:
parent
fb560a560f
commit
2f8cf84882
|
|
@ -427,6 +427,24 @@ struct AlumaccWorker
|
||||||
eq_cells.push_back(cell);
|
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)
|
for (auto cell : lge_cells)
|
||||||
{
|
{
|
||||||
log(" creating $alu model for %s (%s):", cell, cell->type.unescape());
|
log(" creating $alu model for %s (%s):", cell, cell->type.unescape());
|
||||||
|
|
@ -442,14 +460,14 @@ struct AlumaccWorker
|
||||||
alunode_t *n = nullptr;
|
alunode_t *n = nullptr;
|
||||||
|
|
||||||
for (auto node : sig_alu[RTLIL::SigSig(A, B)])
|
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;
|
n = node;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
for (auto node : sig_alu[RTLIL::SigSig(B, A)])
|
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;
|
n = node;
|
||||||
cmp_less = !cmp_less;
|
cmp_less = !cmp_less;
|
||||||
std::swap(A, B);
|
std::swap(A, B);
|
||||||
|
|
@ -488,14 +506,14 @@ struct AlumaccWorker
|
||||||
alunode_t *n = nullptr;
|
alunode_t *n = nullptr;
|
||||||
|
|
||||||
for (auto node : sig_alu[RTLIL::SigSig(A, B)])
|
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;
|
n = node;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
for (auto node : sig_alu[RTLIL::SigSig(B, A)])
|
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;
|
n = node;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue