From bacba274a2edf4bf8cb05b109388e6e18ca5fc16 Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 11 May 2021 21:07:22 +0100 Subject: [PATCH] mistral: Write LUT inits Signed-off-by: gatecat --- mistral/bitstream.cc | 37 +++++++++++++++++++++++++++++++++++++ mistral/lab.cc | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/mistral/bitstream.cc b/mistral/bitstream.cc index 2d64c337..3337c38e 100644 --- a/mistral/bitstream.cc +++ b/mistral/bitstream.cc @@ -196,6 +196,42 @@ struct MistralBitgen } } + void write_alm(uint32_t lab, uint8_t alm) + { + auto &alm_data = ctx->labs.at(lab).alms.at(alm); + + std::array luts{ctx->getBoundBelCell(alm_data.lut_bels[0]), + ctx->getBoundBelCell(alm_data.lut_bels[1])}; + std::array ffs{ + ctx->getBoundBelCell(alm_data.ff_bels[0]), ctx->getBoundBelCell(alm_data.ff_bels[1]), + ctx->getBoundBelCell(alm_data.ff_bels[2]), ctx->getBoundBelCell(alm_data.ff_bels[3])}; + // Skip empty ALMs + if (std::all_of(luts.begin(), luts.end(), [](CellInfo *c) { return !c; }) && + std::all_of(ffs.begin(), ffs.end(), [](CellInfo *c) { return !c; })) + return; + + auto pos = alm_data.lut_bels[0].pos; + // Combinational mode - TODO: flop feedback + cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::MODE, alm, alm_data.l6_mode ? CycloneV::L6 : CycloneV::L5); + // LUT function + cv->bmux_r_set(CycloneV::LAB, pos, CycloneV::LUT_MASK, alm, ctx->compute_lut_mask(lab, alm)); + // DFF output - foce to LUT for now... + cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::TDFF0, alm, CycloneV::NLUT); + cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::TDFF1, alm, CycloneV::NLUT); + cv->bmux_m_set(CycloneV::LAB, pos, CycloneV::TDFF1L, alm, CycloneV::NLUT); + 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); + } + + void write_labs() + { + for (size_t lab = 0; lab < ctx->labs.size(); lab++) { + for (uint8_t alm = 0; alm < 10; alm++) + write_alm(lab, alm); + } + } + void run() { cv->clear(); @@ -203,6 +239,7 @@ struct MistralBitgen write_routing(); write_dqs(); write_cells(); + write_labs(); } }; } // namespace diff --git a/mistral/lab.cc b/mistral/lab.cc index 663b86e2..e93ef8a8 100644 --- a/mistral/lab.cc +++ b/mistral/lab.cc @@ -732,11 +732,45 @@ uint64_t Arch::compute_lut_mask(uint32_t lab, uint8_t alm) index |= (1 << k); } if ((init >> index) & 0x1) { - mask |= (1U << uint64_t(j + offset)); + mask |= (1ULL << uint64_t(j + offset)); } } } + // TODO: always inverted, or just certain paths? + mask = ~mask; + +#if 1 + if (getCtx()->debug) { + auto pos = alm_data.lut_bels[0].pos; + log("ALM %03d.%03d.%d\n", CycloneV::pos2x(pos), CycloneV::pos2y(pos), alm); + for (int i = 0; i < 2; i++) { + log(" LUT%d: ", i); + if (luts[i]) { + log("%s:%s", nameOf(luts[i]), nameOf(luts[i]->type)); + for (auto &pin : luts[i]->pin_data) { + if (!luts[i]->ports.count(pin.first) || luts[i]->ports.at(pin.first).type != PORT_IN) + continue; + log(" %s:", nameOf(pin.first)); + if (pin.second.state == PIN_0) + log("0"); + else if (pin.second.state == PIN_1) + log("1"); + else if (pin.second.state == PIN_INV) + log("~"); + for (auto bp : pin.second.bel_pins) + log("%s", nameOf(bp)); + } + } else { + log(""); + } + log("\n"); + } + log("INIT: %016lx\n", mask); + log("\n"); + } +#endif + return mask; }