mistral: Write LUT inits

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2021-05-11 21:07:22 +01:00
parent d1f635242d
commit bacba274a2
2 changed files with 72 additions and 1 deletions

View File

@ -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<CellInfo *, 2> luts{ctx->getBoundBelCell(alm_data.lut_bels[0]),
ctx->getBoundBelCell(alm_data.lut_bels[1])};
std::array<CellInfo *, 4> 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

View File

@ -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("<null>");
}
log("\n");
}
log("INIT: %016lx\n", mask);
log("\n");
}
#endif
return mask;
}