/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2024 The Project Beyond Authors. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #include "location_map.h" NEXTPNR_NAMESPACE_BEGIN namespace { const Loc ng_ultra_place_cy_map[24] = { { 0, 1, 0 }, // S1 0 -> S2 0 CY24->CY1 { 0, 0, -1 }, // S1 1 -> S1 0 CY23->CY24 { 0, 0, -1 }, // S1 2 -> S1 1 CY22->CY23 { 0, 0, -1 }, // S1 3 -> S1 2 CY21->CY22 {-1, 0,+3}, // S5 0 -> S1 1 CY20->CY21 {0, 0, -1}, // S5 1 -> S5 0 CY19->CY20 {0, 0, -1}, // S5 2 -> S5 1 CY18->CY19 {0, 0, -1}, // S5 3 -> S5 2 CY17->CY18 {-1, 0,+3}, // S9 0 -> S5 1 CY16->CY17 {0, 0, -1}, // S9 1 -> S9 0 CY15->CY16 {0, 0, -1}, // S9 2 -> S9 1 CY14->CY15 {0, 0, -1}, // S9 3 -> S9 2 CY13->CY14 {0, 0, +1}, // S2 0 -> S2 1 CY1->CY2 {0, 0, +1}, // S2 1 -> S2 2 CY2->CY3 {0, 0, +1}, // S2 2 -> S2 3 CY3->CY4 {1, 0, -3}, // S2 3 -> S6 0 CY4->CY5 {0, 0, +1}, // S6 0 -> S6 1 CY5->CY6 {0, 0, +1}, // S6 1 -> S6 2 CY6->CY7 {0, 0, +1}, // S6 2 -> S6 3 CY7->CY8 {1, 0, -3}, // S6 3 -> S10 0 CY8->CY9 {0, 0, +1}, // S10 0 -> S10 1 CY9->CY10 {0, 0, +1}, // S10 1 -> S10 2 CY10->CY11 {0, 0, +1}, // S10 2 -> S10 3 CY11->CY12 {0,-1, 0}, // S10 3 -> S9 3 CY12->CY13 }; const Loc ng_ultra_place_xrf[] = { {-1, 0, 1},// I/O1 {-1, 0, 2},// I/O2 {-1, 0, 5},// I/O3 {-1, 0, 6},// I/O4 {-1, 0, 7},// I/O5 {-1, 0, 9},// I/O6 {-1, 0, 10},// I/O7 {-1, 0, 13},// I/O8 {-1, 0, 14},// I/O9 {-1, 0, 15},// I/O10 {-1, 0, 16},// I/O11 {-1, 0, 17},// I/O12 {-1, 0, 18},// I/O13 {-1, 0, 21},// I/O14 {-1, 0, 24},// I/O15 {-1, 0, 25},// I/O16 {-1, 0, 26},// I/O17 {-1, 0, 29},// I/O18 {+1, 0, 1},// I/O19 {+1, 0, 2},// I/O20 {+1, 0, 5},// I/O21 {+1, 0, 6},// I/O22 {+1, 0, 7},// I/O23 {+1, 0, 9},// I/O24 {+1, 0, 10},// I/O25 {+1, 0, 13},// I/O26 {+1, 0, 14},// I/O27 {+1, 0, 15},// I/O28 {+1, 0, 16},// I/O29 {+1, 0, 17},// I/O30 {+1, 0, 18},// I/O31 {+1, 0, 21},// I/O32 {+1, 0, 24},// I/O33 {+1, 0, 25},// I/O34 {+1, 0, 26},// I/O35 {+1, 0, 29},// I/O36 {-1, 0, 4},// RA1 {-1, 0, 12},// RA2 {-1, 0, 20},// RA3 {-1, 0, 27},// RA4 {-1, 0, 31},// RA5 {+1, 0, 4},// RA6 {+1, 0, 12},// RA7 {+1, 0, 20},// RA8 {+1, 0, 27},// RA9 {+1, 0, 31},// RA10 {-1, 0, 3},// WA1 {-1, 0, 11},// WA2 {-1, 0, 19},// WA3 {-1, 0, 23},// WA4 {-1, 0, 28},// WA5 {+1, 0, 3},// WA6 {-1, 0, 0},// WE {-1, 0, 8},// WEA }; const Loc ng_ultra_place_cdc1[] = { {+1, 0, 1}, // AI1 {+1, 0, 2}, // AI2 {+1, 0, 9}, // AI3 {+1, 0, 17},// AI4 {+1, 0, 18},// AI5 {+1, 0, 25},// AI6 {+1, 0, 3}, // BI1 {+1, 0, 10},// BI2 {+1, 0, 11},// BI3 {+1, 0, 19},// BI4 {+1, 0, 26},// BI5 {+1, 0, 27},// BI6 { 0, 0, 22},// ASRSTI { 0, 0, 30},// ADRSTI {+1, 0, 24},// BSRSTI {+1, 0, 8}, // BDRSTI }; const Loc ng_ultra_place_cdc2[] = { {-1, 0, 4}, // AI1 {-1, 0, 5}, // AI2 {-1, 0, 12},// AI3 {-1, 0, 20},// AI4 {-1, 0, 21},// AI5 {-1, 0, 28},// AI6 {-1, 0, 6}, // BI1 {-1, 0, 13},// BI2 {-1, 0, 14},// BI3 {-1, 0, 22},// BI4 {-1, 0, 29},// BI5 {-1, 0, 30},// BI6 { 0, 0, 22},// ASRSTI { 0, 0, 30},// ADRSTI {-1, 0, 23},// BSRSTI {-1, 0, 7}, // BDRSTI }; const Loc ng_ultra_place_xcdc[] = { { 0, 0, 1}, // AI1 { 0, 0, 2}, // AI2 { 0, 0, 9}, // AI3 { 0, 0, 17},// AI4 { 0, 0, 18},// AI5 { 0, 0, 25},// AI6 { 0, 0, 4}, // BI1 { 0, 0, 5}, // BI2 { 0, 0, 12},// BI3 { 0, 0, 20},// BI4 { 0, 0, 21},// BI5 { 0, 0, 28},// BI6 {-1, 0, 22},// ASRSTI {-1, 0, 30},// ADRSTI {+1, 0, 22},// BSRSTI {+1, 0, 30},// BDRSTI { 0, 0, 3}, // CI1 { 0, 0, 10},// CI2 { 0, 0, 11},// CI3 { 0, 0, 19},// CI4 { 0, 0, 26},// CI5 { 0, 0, 27},// CI6 { 0, 0, 6}, // DI1 { 0, 0, 13},// DI2 { 0, 0, 14},// DI3 { 0, 0, 22},// DI4 { 0, 0, 29},// DI5 { 0, 0, 30},// DI6 { 0, 0, 24},// CSRSTI { 0, 0, 8}, // CDRSTI { 0, 0, 23},// DSRSTI { 0, 0, 7}, // DDRSTI }; const Loc ng_ultra_place_fifo1[] = { {-1, 0, 1}, // I/O1 {-1, 0, 2}, // I/O2 {-1, 0, 5}, // I/O3 {-1, 0, 6}, // I/O4 {-1, 0, 7}, // I/O5 {-1, 0, 9}, // I/O6 {-1, 0, 10},// I/O7 {-1, 0, 13},// I/O8 {-1, 0, 14},// I/O9 {-1, 0, 15},// I/O10 {-1, 0, 16},// I/O11 {-1, 0, 17},// I/O12 {-1, 0, 18},// I/O13 {-1, 0, 21},// I/O14 {-1, 0, 24},// I/O15 {-1, 0, 25},// I/O16 {-1, 0, 26},// I/O17 {-1, 0, 29},// I/O18 { 0, 0, 0},// I/O19 { 0, 0, 0},// I/O20 { 0, 0, 0},// I/O21 { 0, 0, 0},// I/O22 { 0, 0, 0},// I/O23 { 0, 0, 0},// I/O24 { 0, 0, 0},// I/O25 { 0, 0, 0},// I/O26 { 0, 0, 0},// I/O27 { 0, 0, 0},// I/O28 { 0, 0, 0},// I/O29 { 0, 0, 0},// I/O30 { 0, 0, 0},// I/O31 { 0, 0, 0},// I/O32 { 0, 0, 0},// I/O33 { 0, 0, 0},// I/O34 { 0, 0, 0},// I/O35 { 0, 0, 0},// I/O36 { 0, 0, 3}, // RAI1/RAO1 { 0, 0, 10},// RAI2/RAO2 { 0, 0, 11},// RAI3/RAO3 { 0, 0, 19},// RAI4/RAO4 { 0, 0, 26},// RAI5/RAO5 { 0, 0, 27},// RAI6/RAO6 { 0, 0, 0},// RAI7/RAO7 { 0, 0, 1}, // WAI1/WAO1 { 0, 0, 2}, // WAI2/WAO2 { 0, 0, 9}, // WAI3/WAO3 { 0, 0, 17},// WAI4/WAO4 { 0, 0, 18},// WAI5/WAO5 { 0, 0, 25},// WAI6/WAO6 { 0, 0, 0},// WAI7/WAO7 {-1, 0, 0}, // WE {-1, 0, 8}, // WEA {-1, 0, 22},// WRSTI1/WRSTO {-1, 0, 30},// RRSTI1/RRSTO { 0, 0, 8}, // WRSTI2 { 0, 0, 24},// RRSTI2 { 0, 0, 0}, // WRSTI3/WRSTO { 0, 0, 0}, // RRSTI3/RRSTO { 0, 0, 0}, // WRSTI4 { 0, 0, 0}, // RRSTI4 {-1, 0, 3}, // WEQ {-1, 0, 4}, // REQ // {-1, 0, 11}, WEQ // {-1, 0, 12}, REQ // {-1, 0, 19}, WEQ // {-1, 0, 20}, REQ // {-1, 0, 27}, WEQ // {-1, 0, 28}, REQ { 0, 0, 0}, // WEQ2 { 0, 0, 0}, // REQ2 }; const Loc ng_ultra_place_fifo2[] = { {+1, 0, 1}, // I/O1 {+1, 0, 2}, // I/O2 {+1, 0, 5}, // I/O3 {+1, 0, 6}, // I/O4 {+1, 0, 7}, // I/O5 {+1, 0, 9}, // I/O6 {+1, 0, 10},// I/O7 {+1, 0, 13},// I/O8 {+1, 0, 14},// I/O9 {+1, 0, 15},// I/O10 {+1, 0, 16},// I/O11 {+1, 0, 17},// I/O12 {+1, 0, 18},// I/O13 {+1, 0, 21},// I/O14 {+1, 0, 24},// I/O15 {+1, 0, 25},// I/O16 {+1, 0, 26},// I/O17 {+1, 0, 29},// I/O18 { 0, 0, 0},// I/O19 { 0, 0, 0},// I/O20 { 0, 0, 0},// I/O21 { 0, 0, 0},// I/O22 { 0, 0, 0},// I/O23 { 0, 0, 0},// I/O24 { 0, 0, 0},// I/O25 { 0, 0, 0},// I/O26 { 0, 0, 0},// I/O27 { 0, 0, 0},// I/O28 { 0, 0, 0},// I/O29 { 0, 0, 0},// I/O30 { 0, 0, 0},// I/O31 { 0, 0, 0},// I/O32 { 0, 0, 0},// I/O33 { 0, 0, 0},// I/O34 { 0, 0, 0},// I/O35 { 0, 0, 0},// I/O36 { 0, 0, 6}, // RAI1/RAO1 { 0, 0, 13},// RAI2/RAO2 { 0, 0, 14},// RAI3/RAO3 { 0, 0, 22},// RAI4/RAO4 { 0, 0, 29},// RAI5/RAO5 { 0, 0, 30},// RAI6/RAO6 { 0, 0, 0},// RAI7/RAO7 { 0, 0, 4}, // WAI1/WAO1 { 0, 0, 5}, // WAI2/WAO2 { 0, 0, 12},// WAI3/WAO3 { 0, 0, 20},// WAI4/WAO4 { 0, 0, 21},// WAI5/WAO5 { 0, 0, 28},// WAI6/WAO6 { 0, 0, 0},// WAI7/WAO7 {+1, 0, 0}, // WE {+1, 0, 8}, // WEA {+1, 0, 22},// WRSTI1/WRSTO {+1, 0, 30},// RRSTI1/RRSTO { 0, 0, 7}, // WRSTI2 { 0, 0, 23},// RRSTI2 { 0, 0, 0}, // WRSTI3/WRSTO { 0, 0, 0}, // RRSTI3/RRSTO { 0, 0, 0}, // WRSTI4 { 0, 0, 0}, // RRSTI4 {+1, 0, 3}, // WEQ {+1, 0, 4}, // REQ // {+1, 0, 11}, WEQ // {+1, 0, 12}, REQ // {+1, 0, 19}, WEQ // {+1, 0, 20}, REQ // {+1, 0, 27}, WEQ // {+1, 0, 28}, REQ { 0, 0, 0}, // WEQ2 { 0, 0, 0}, // REQ2 }; const Loc ng_ultra_place_xfifo[] = { {-1, 0, 1}, // I/O1 {-1, 0, 2}, // I/O2 {-1, 0, 5}, // I/O3 {-1, 0, 6}, // I/O4 {-1, 0, 7}, // I/O5 {-1, 0, 9}, // I/O6 {-1, 0, 10},// I/O7 {-1, 0, 13},// I/O8 {-1, 0, 14},// I/O9 {-1, 0, 15},// I/O10 {-1, 0, 16},// I/O11 {-1, 0, 17},// I/O12 {-1, 0, 18},// I/O13 {-1, 0, 21},// I/O14 {-1, 0, 24},// I/O15 {-1, 0, 25},// I/O16 {-1, 0, 26},// I/O17 {-1, 0, 29},// I/O18 {+1, 0, 1}, // I/O19 {+1, 0, 2}, // I/O20 {+1, 0, 5}, // I/O21 {+1, 0, 6}, // I/O22 {+1, 0, 7}, // I/O23 {+1, 0, 9}, // I/O24 {+1, 0, 10},// I/O25 {+1, 0, 13},// I/O26 {+1, 0, 14},// I/O27 {+1, 0, 15},// I/O28 {+1, 0, 16},// I/O29 {+1, 0, 17},// I/O30 {+1, 0, 18},// I/O31 {+1, 0, 21},// I/O32 {+1, 0, 24},// I/O33 {+1, 0, 25},// I/O34 {+1, 0, 26},// I/O35 {+1, 0, 29},// I/O36 { 0, 0, 3}, // RAI1/RAO1 { 0, 0, 10},// RAI2/RAO2 { 0, 0, 11},// RAI3/RAO3 { 0, 0, 19},// RAI4/RAO4 { 0, 0, 26},// RAI5/RAO5 { 0, 0, 27},// RAI6/RAO6 { 0, 0, 6}, // RAI7/RAO7 { 0, 0, 1}, // WAI1/WAO1 { 0, 0, 2}, // WAI2/WAO2 { 0, 0, 9}, // WAI3/WAO3 { 0, 0, 17},// WAI4/WAO4 { 0, 0, 18},// WAI5/WAO5 { 0, 0, 25},// WAI6/WAO6 { 0, 0, 4}, // WAI7/WAO7 {-1, 0, 0}, // WE {-1, 0, 8}, // WEA {-1, 0, 22},// WRSTI1/WRSTO {-1, 0, 30},// RRSTI1/RRSTO { 0, 0, 8}, // WRSTI2 { 0, 0, 24},// RRSTI2 {+1, 0, 22},// WRSTI3/WRSTO {+1, 0, 30},// RRSTI3/RRSTO { 0, 0, 7}, // WRSTI4 { 0, 0, 23},// RRSTI4 {-1, 0, 3}, // WEQ1 {-1, 0, 4}, // REQ1 // {-1, 0, 11}, WEQ1 // {-1, 0, 12}, REQ1 // {-1, 0, 19}, WEQ1 // {-1, 0, 20}, REQ1 // {-1, 0, 27}, WEQ1 // {-1, 0, 28}, REQ1 {+1, 0, 3}, // WEQ2 {+1, 0, 4}, // REQ2 // {+1, 0, 11}, WEQ2 // {+1, 0, 12}, REQ2 // {+1, 0, 19}, WEQ2 // {+1, 0, 20}, REQ2 // {+1, 0, 27}, WEQ2 // {+1, 0, 28}, REQ2 }; }; namespace ng_ultra { Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc) { BelId bel = impl->ctx->getBelByLocation(loc); if (impl->dsp_cascade.count(bel)==0) { loc.z = -1; // End of chain return loc; } BelId dsp = impl->dsp_cascade.at(bel); return impl->ctx->getBelLocation(dsp); } Loc getNextLocInCYChain(Loc loc) { int section = (loc.x % 4 - 1 + 3 * (loc.y % 4)) * 4 + loc.z - BEL_CY_Z; Loc result = ng_ultra_place_cy_map[section]; result.x += loc.x; result.y += loc.y; result.z += loc.z; return result; } Loc getNextLocInLUTChain(Loc loc) { Loc result = loc; result.x = loc.x; result.y = loc.y; result.z = (loc.z + 8) % 32; // BEL_LUT_Z is 0 return result; } Loc getNextLocInDFFChain(Loc loc) { Loc result = loc; if (loc.z == 31) { if ((loc.x & 3) == 3) { result.z = -1; // End of chain return result; } result.z = 0; result.x++; return result; } int z = loc.z + 8; if (z>31) z++; result.z = z % 32; // BEL_LUT_Z is 0 return result; } Loc getCYFE(Loc root, int pos) { int p[] = { 2-1, 25-1, 10-1, 17-1 }; int cy = root.z - BEL_CY_Z; Loc result; result.x = root.x; result.y = root.y; result.z = p[pos] + cy * 2; return result; } Loc getXLUTFE(Loc root, int pos) { Loc result; result.x = root.x; result.y = root.y; result.z = root.z - BEL_XLUT_Z + 8 * pos; return result; } Loc getXRFFE(Loc root, int pos) { Loc result = ng_ultra_place_xrf[pos]; if (root.z == BEL_XRF_Z) { // XRF1 result.x += root.x; } else { // RF1 or RF2 result.x = root.x + ((root.z == BEL_RF_Z) ? -1 : +1); } result.y = root.y; return result; } Loc getCDCFE(Loc root, int pos) { Loc result; if (root.z == BEL_CDC_Z) { result = ng_ultra_place_cdc1[pos]; } else if (root.z == BEL_CDC_Z+1) { result = ng_ultra_place_cdc2[pos]; } else if (root.z == BEL_XCDC_Z) { result = ng_ultra_place_xcdc[pos]; } else { log_error("Trying to place CDC on wrong location.\n"); } result.x += root.x; result.y = root.y; return result; } Loc getFIFOFE(Loc root, int pos) { Loc result; if (root.z == BEL_FIFO_Z) { result = ng_ultra_place_fifo1[pos]; } else if (root.z == BEL_FIFO_Z+1) { result = ng_ultra_place_fifo2[pos]; } else if (root.z == BEL_XFIFO_Z) { result = ng_ultra_place_xfifo[pos]; } else { log_error("Trying to place CDC on wrong location.\n"); } result.x += root.x; result.y = root.y; return result; } }; NEXTPNR_NAMESPACE_END