From 33e031a2841de813cae420becd8ece4286e08e0a Mon Sep 17 00:00:00 2001 From: Lofty Date: Tue, 21 Dec 2021 21:04:05 +0000 Subject: mistral: M10K cell function --- mistral/constids.inc | 4 ++- mistral/m10k.cc | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/mistral/constids.inc b/mistral/constids.inc index 82cd9ecc..e032bf53 100644 --- a/mistral/constids.inc +++ b/mistral/constids.inc @@ -101,6 +101,8 @@ X(cyclonev_hps_interface_mpu_general_purpose) X(MISTRAL_M10K) X(ADDRSTALLA) X(ADDRSTALLB) +X(CFG_ABITS) +X(CFG_DBITS) X(clkout) X(clkout1) @@ -108,4 +110,4 @@ X(compress_rbf) X(oscena) X(placer) X(router) -X(step) \ No newline at end of file +X(step) diff --git a/mistral/m10k.cc b/mistral/m10k.cc index 4ab35096..d6aa1ed2 100644 --- a/mistral/m10k.cc +++ b/mistral/m10k.cc @@ -46,7 +46,7 @@ void Arch::create_m10k(int x, int y) } for (int z = 0; z < 4; z++) { add_bel_pin(bel, id(stringf("ENABLE[%d]", z)), PORT_IN, - get_port(CycloneV::M10K, x, y, -1, CycloneV::ENABLE, 0)); + get_port(CycloneV::M10K, x, y, -1, CycloneV::ENABLE, z)); } for (int z = 0; z < 12; z++) { add_bel_pin(bel, id(stringf("ADDRA[%d]", z)), PORT_IN, @@ -66,4 +66,75 @@ void Arch::create_m10k(int x, int y) } } +static void assign_lab_pins(Context *ctx, CellInfo *cell) +{ + auto abits = cell->attrs[id_CFG_ABITS].as_int64(); + auto dbits = cell->attrs[id_CFG_DBITS].as_int64(); + NPNR_ASSERT(abits >= 7 && abits <= 13); + NPNR_ASSERT(dbits == 1 || dbits == 2 || dbits == 5 || dbits == 10 || dbits == 20); + + // Quartus doesn't seem to generate ADDRSTALL[AB], BYTEENABLE[AB][01]. + + // It *does* generate ACLR[01] but leaves them unconnected if unused. + + // Enables. + // RDEN[0] and WREN[1] are left unconnected. + cell->pin_data[ctx->id("A1EN")].bel_pins = {ctx->id("RDEN[1]")}; + cell->pin_data[ctx->id("B1EN")].bel_pins = {ctx->id("WREN[0]")}; + + // Clocks. + cell->pin_data[ctx->id("CLK1")].bel_pins = {ctx->id("CLKIN[0]")}; + + // Enables left unconnected. + + // Address lines. + int addr_offset = std::max(12 - std::max(abits, int64_t{9}), 0l); + int bit_offset = 0; + if (abits == 13) { + cell->pin_data[ctx->id("A1ADDR[0]")].bel_pins = {ctx->id("DATAAIN[4]")}; + cell->pin_data[ctx->id("B1ADDR[0]")].bel_pins = {ctx->id("DATABIN[19]")}; + bit_offset = 1; + } + for (int bit = bit_offset; bit < abits; bit++) { + cell->pin_data[ctx->id(stringf("A1ADDR[%d]", bit))].bel_pins = {ctx->id(stringf("ADDRA[%d]", bit + addr_offset))}; + cell->pin_data[ctx->id(stringf("B1ADDR[%d]", bit))].bel_pins = {ctx->id(stringf("ADDRB[%d]", bit + addr_offset))}; + } + + // Data lines + std::vector offsets; + offsets.push_back(0); + if (abits >= 10 && dbits <= 10) { + offsets.push_back(10); + } + if (abits >= 11 && dbits <= 5) { + offsets.push_back(5); + offsets.push_back(15); + } + if (abits >= 12 && dbits <= 2) { + offsets.push_back(2); + offsets.push_back(7); + offsets.push_back(12); + offsets.push_back(17); + } + if (abits == 13 && dbits == 1) { + offsets.push_back(1); + offsets.push_back(3); + offsets.push_back(6); + offsets.push_back(8); + offsets.push_back(11); + offsets.push_back(13); + offsets.push_back(16); + offsets.push_back(18); + } + for (int bit = 0; bit < dbits; bit++) { + for (int offset : offsets) { + cell->pin_data[ctx->id(stringf("A1DATA[%d]", bit))].bel_pins.push_back(ctx->id(stringf("DATAAIN[%d]", bit + offset))); + } + } + + for (int bit = 0; bit < dbits; bit++) { + cell->pin_data[ctx->id(stringf("B1DATA[%d]", bit))].bel_pins = {ctx->id(stringf("DATABOUT[%d]", bit))}; + } +} + NEXTPNR_NAMESPACE_END \ No newline at end of file -- cgit v1.2.3