From 2f2fde7e6cd687433c687b1f678ceb4bd25f588e Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 12 May 2021 20:41:52 +0100 Subject: [PATCH] mistral: Write arith mode to bitstream (not yet functional) Signed-off-by: gatecat --- mistral/bitstream.cc | 3 +++ mistral/lab.cc | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mistral/bitstream.cc b/mistral/bitstream.cc index 3337c38e..713ca9bb 100644 --- a/mistral/bitstream.cc +++ b/mistral/bitstream.cc @@ -222,6 +222,9 @@ struct MistralBitgen cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::BDFF0, alm, CycloneV::NLUT); cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::BDFF1, alm, CycloneV::NLUT); cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::BDFF1L, alm, CycloneV::NLUT); + + if ((luts[0] && luts[0]->combInfo.is_carry) || (luts[1] && luts[1]->combInfo.is_carry)) + cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::ARITH_SEL, alm, CycloneV::ADDER); } void write_labs() diff --git a/mistral/lab.cc b/mistral/lab.cc index 202753b4..77bdac09 100644 --- a/mistral/lab.cc +++ b/mistral/lab.cc @@ -366,21 +366,34 @@ bool Arch::is_alm_legal(uint32_t lab, uint8_t alm) const return false; } - // Never allow two disjoint carry chains to accidentally stack + bool carry_mode = false; + for (int i = 0; i < 2; i++) { if (!luts[i]) continue; + if (!luts[i]->combInfo.is_carry) + continue; + carry_mode = true; + // Never allow two disjoint carry chains to accidentally stack if (luts[i]->combInfo.carry_start && carry_used(this, alm_data.lut_bels[i], id_CI)) return false; if (luts[i]->combInfo.carry_end && carry_used(this, alm_data.lut_bels[i], id_CO)) return false; } + for (int i = 0; i < 2; i++) { + if (!luts[i]) + continue; + // No mixing of carry and non-carry + if (luts[i]->combInfo.is_carry != carry_mode) + return false; + } + // For each ALM half; check FF control set sharing and input routeability for (int i = 0; i < 2; i++) { // There are two ways to route from the fabric into FF data - either routing through a LUT or using the E/F // signals and SLOAD=1 (*PKREF*) - bool route_thru_lut_avail = !luts[i] && (total_lut_inputs < 8) && (used_lut_bits < 64); + bool route_thru_lut_avail = !luts[i] && !carry_mode && (total_lut_inputs < 8) && (used_lut_bits < 64); // E/F is available if this LUT is using 3 or fewer inputs - this is conservative and sharing can probably // improve this situation bool ef_available = (!luts[i] || luts[i]->combInfo.used_lut_input_count <= 3);