From 98121308e09e39f56a1e61ae9ede31eaa963f47b Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 17 May 2023 10:00:09 +0200 Subject: [PATCH] mistral: Don't allow route-through LUTs in carry-mode ALMs Signed-off-by: gatecat --- mistral/arch.h | 1 + mistral/lab.cc | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mistral/arch.h b/mistral/arch.h index 7cdc9f6b..a9d10808 100644 --- a/mistral/arch.h +++ b/mistral/arch.h @@ -48,6 +48,7 @@ struct ALMInfo std::array ff_bels; bool l6_mode = false; + bool carry_mode = false; // Which CLK/ENA and ACLR is chosen for each half std::array clk_ena_idx, aclr_idx; diff --git a/mistral/lab.cc b/mistral/lab.cc index d65ccf53..8bcde3e3 100644 --- a/mistral/lab.cc +++ b/mistral/lab.cc @@ -425,7 +425,7 @@ bool Arch::is_alm_legal(uint32_t lab, uint8_t alm) const return false; } - bool carry_mode = false; + bool carry_mode = (luts[0] && luts[0]->combInfo.is_carry) || (luts[1] && luts[1]->combInfo.is_carry); // No mixing of carry and non-carry if (luts[0] && luts[1] && luts[0]->combInfo.is_carry != luts[1]->combInfo.is_carry) @@ -811,6 +811,7 @@ void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm) // This function should also insert route-through LUTs to legalise flipflop inputs as needed. auto &alm_data = labs.at(lab).alms.at(alm); alm_data.l6_mode = false; + alm_data.carry_mode = false; std::array luts{getBoundBelCell(alm_data.lut_bels[0]), getBoundBelCell(alm_data.lut_bels[1])}; std::array ffs{getBoundBelCell(alm_data.ff_bels[0]), getBoundBelCell(alm_data.ff_bels[1]), getBoundBelCell(alm_data.ff_bels[2]), getBoundBelCell(alm_data.ff_bels[3])}; @@ -820,6 +821,8 @@ void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm) // Currently we treat LUT6s and MLABs as a special case, as they never share inputs or have fixed mappings if (!luts[i]) continue; + if (luts[i]->combInfo.is_carry) + alm_data.carry_mode = true; if (luts[i]->type == id_MISTRAL_ALUT6) { alm_data.l6_mode = true; NPNR_ASSERT(luts[1 - i] == nullptr); // only allow one LUT6 per ALM and no other LUTs @@ -916,7 +919,7 @@ void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm) continue; for (int j = 0; j < 2; j++) { CellInfo *ff = ffs[i * 2 + j]; - if (!ff || !ff->ffInfo.datain || alm_data.l6_mode) + if (!ff || !ff->ffInfo.datain || alm_data.l6_mode || alm_data.carry_mode) continue; CellInfo *rt_lut = createCell(idf("%s$ROUTETHRU", nameOf(ff)), id_MISTRAL_BUF); rt_lut->addInput(id_A); @@ -1045,10 +1048,12 @@ uint64_t Arch::compute_lut_mask(uint32_t lab, uint8_t alm) } } CellPinState state = lut->get_pin_state(log_pin); - if (state == PIN_0) + if (state == PIN_0) { continue; - else if (state == PIN_1) + } else if (state == PIN_1) { index |= (1 << init_idx); + continue; + } // Ignore if no associated physical pin if (lut->getPort(log_pin) == nullptr || lut->pin_data.at(log_pin).bel_pins.empty()) continue;