aboutsummaryrefslogtreecommitdiffstats
path: root/mistral
diff options
context:
space:
mode:
authorLofty <dan.ravensloft@gmail.com>2021-12-21 21:04:05 +0000
committerLofty <dan.ravensloft@gmail.com>2022-03-09 17:13:54 +0000
commit33e031a2841de813cae420becd8ece4286e08e0a (patch)
treef6b369ebed681be80a2867a740bd006f29daff44 /mistral
parentaf6735bdf413d1b3663d085b573f2aaf3e018e44 (diff)
downloadnextpnr-33e031a2841de813cae420becd8ece4286e08e0a.tar.gz
nextpnr-33e031a2841de813cae420becd8ece4286e08e0a.tar.bz2
nextpnr-33e031a2841de813cae420becd8ece4286e08e0a.zip
mistral: M10K cell function
Diffstat (limited to 'mistral')
-rw-r--r--mistral/constids.inc4
-rw-r--r--mistral/m10k.cc73
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<int> 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