aboutsummaryrefslogtreecommitdiffstats
path: root/mistral
diff options
context:
space:
mode:
Diffstat (limited to 'mistral')
-rw-r--r--mistral/bitstream.cc3
-rw-r--r--mistral/lab.cc17
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);