diff --git a/model.c b/model.c index be7f9a1..332f4c2 100644 --- a/model.c +++ b/model.c @@ -118,9 +118,28 @@ static int init_devices(struct fpga_model* model) static int init_ports(struct fpga_model* model) { - int x, y, i, j, k, rc; + int x, y, i, j, k, row_num, row_pos, rc; for (x = 0; x < model->tile_x_range; x++) { + if (is_atx(X_FABRIC_ROUTING_COL|X_CENTER_ROUTING_COL|X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x)) { + for (y = TOP_IO_TILES; y < model->tile_y_range - BOTTOM_IO_TILES; y++) { + int keep_out = is_atx(X_ROUTING_NO_IO|X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x) ? 0 : 2; + if (y < TOP_IO_TILES+keep_out + || y > model->tile_y_range-BOTTOM_IO_TILES-keep_out-1) continue; + is_in_row(model, y, &row_num, &row_pos); + if (row_pos < 0 || row_pos == 8) continue; + + if (is_atx(X_FABRIC_ROUTING_COL, model, x) + || (is_atx(X_CENTER_ROUTING_COL, model, x) && (row_pos != 7 && (row_pos != 9 || row_num%2))) + || (is_atx(X_LEFT_IO_ROUTING_COL, model, x) && !is_aty(Y_LEFT_WIRED, model, y)) + || (is_atx(X_RIGHT_IO_ROUTING_COL, model, x) && !is_aty(Y_RIGHT_WIRED, model, y))) { + for (i = 0; i <= 1; i++) { + rc = add_connpt_name(model, y, x, pf("GFAN%i", i)); + if (rc) goto xout; + } + } + } + } if (is_atx(X_ROUTING_COL, model, x)) { for (y = TOP_IO_TILES; y < model->tile_y_range - BOTTOM_IO_TILES; y++) { if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, @@ -183,6 +202,16 @@ static int init_ports(struct fpga_model* model) static const char* pref[] = {"CE", "RST", ""}; static const char* seq[] = {"A", "B", "C", "D", "M", "P", "OPMODE", ""}; + is_in_row(model, y, &row_num, &row_pos); + if (!row_num && row_pos == LAST_POS_IN_ROW) { + rc = add_connpt_name(model, y, x, "CARRYIN_DSP48A1_SITE"); + if (rc) goto xout; + for (i = 0; i <= 47; i++) { + rc = add_connpt_name(model, y, x, pf("PCIN%i_DSP48A1_SITE", i)); + if (rc) goto xout; + } + } + rc = add_connpt_name(model, y, x, "CLK_DSP48A1_SITE"); if (rc) goto xout; rc = add_connpt_name(model, y, x, "CARRYOUT_DSP48A1_SITE"); @@ -1299,6 +1328,7 @@ static int init_tiles(struct fpga_model* model) last_col = last_major(model->cfg_columns, j); model->tiles[i].flags |= TF_FABRIC_ROUTING_COL; + if (no_io) model->tiles[i].flags |= TF_ROUTING_NO_IO; model->tiles[i+1].flags |= TF_FABRIC_LOGIC_COL; for (k = model->cfg_rows-1; k >= 0; k--) { row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8); @@ -1385,6 +1415,7 @@ static int init_tiles(struct fpga_model* model) model->right_gclk_sep_x = i+2; } model->tiles[i].flags |= TF_FABRIC_ROUTING_COL; + model->tiles[i].flags |= TF_ROUTING_NO_IO; // no_io always on for BRAM model->tiles[i+1].flags |= TF_FABRIC_BRAM_MACC_ROUTING_COL; model->tiles[i+2].flags |= TF_FABRIC_BRAM_COL; for (k = model->cfg_rows-1; k >= 0; k--) { @@ -1421,6 +1452,7 @@ static int init_tiles(struct fpga_model* model) break; case 'D': model->tiles[i].flags |= TF_FABRIC_ROUTING_COL; + model->tiles[i].flags |= TF_ROUTING_NO_IO; // no_io always on for MACC model->tiles[i+1].flags |= TF_FABRIC_BRAM_MACC_ROUTING_COL; model->tiles[i+2].flags |= TF_FABRIC_MACC_COL; for (k = model->cfg_rows-1; k >= 0; k--) { @@ -1578,8 +1610,10 @@ static int init_tiles(struct fpga_model* model) // // +0 // - if (model->cfg_left_wiring[(model->cfg_rows-1-k)*16+l] == 'W') + if (model->cfg_left_wiring[(model->cfg_rows-1-k)*16+l] == 'W') { + model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns].flags |= TF_WIRED; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns].type = IO_L; + } // // +1 // @@ -1678,6 +1712,9 @@ static int init_tiles(struct fpga_model* model) // // -1 // + if (model->cfg_right_wiring[(model->cfg_rows-1-k)*16+l] == 'W') + model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 1].flags |= TF_WIRED; + if (k == model->cfg_rows/2 && l == 13) model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 1].type = IO_RDY_R; else if (k == model->cfg_rows/2 && l == 14) @@ -2040,27 +2077,6 @@ static char last_major(const char* str, int cur_o) return 0; } -static int is_in_row(struct fpga_model* model, int y, int* row_pos) -{ - int dist_to_center; - - if (y < 2) return 0; - // normalize y to beginning of rows - y -= 2; - - // calculate distance to center and check - // that y is not pointing to the center - dist_to_center = (model->cfg_rows/2)*(8+1/*middle of row*/+8); - if (y == dist_to_center) return 0; - if (y > dist_to_center) y--; - - // check that y is not pointing past the last row - if (y >= model->cfg_rows*(8+1+8)) return 0; - - if (row_pos) *row_pos = y%(8+1+8); - return 1; -} - int is_aty(int check, struct fpga_model* model, int y) { if (y < 0) return 0; @@ -2069,11 +2085,12 @@ int is_aty(int check, struct fpga_model* model, int y) if (check & Y_CHIP_HORIZ_REGS && y == model->center_y) return 1; if (check & (Y_ROW_HORIZ_AXSYMM|Y_BOTTOM_OF_ROW)) { int row_pos; - if (is_in_row(model, y, &row_pos)) { - if (check & Y_ROW_HORIZ_AXSYMM && row_pos == 8) return 1; - if (check & Y_BOTTOM_OF_ROW && row_pos == 16) return 1; - } + is_in_row(model, y, 0 /* row_num */, &row_pos); + if (check & Y_ROW_HORIZ_AXSYMM && row_pos == 8) return 1; + if (check & Y_BOTTOM_OF_ROW && row_pos == 16) return 1; } + if (check & Y_LEFT_WIRED && model->tiles[y*model->tile_x_range].flags & TF_WIRED) return 1; + if (check & Y_RIGHT_WIRED && model->tiles[y*model->tile_x_range + model->tile_x_range-RIGHT_OUTER_O].flags & TF_WIRED) return 1; return 0; } @@ -2096,6 +2113,7 @@ int is_atx(int check, struct fpga_model* model, int x) && model->tiles[x+1].flags & TF_FABRIC_BRAM_MACC_ROUTING_COL && model->tiles[x+2].flags & TF_FABRIC_MACC_COL) return 1; } + if (check & X_ROUTING_NO_IO && model->tiles[x].flags & TF_ROUTING_NO_IO) return 1; if (check & X_LOGIC_COL && (model->tiles[x].flags & TF_FABRIC_LOGIC_COL || x == model->center_x-2)) return 1; @@ -2126,11 +2144,36 @@ int is_atyx(int check, struct fpga_model* model, int y, int x) || x == LEFT_IO_ROUTING || x == model->tile_x_range-5 || x == model->center_x-3)) { int row_pos; - if (is_in_row(model, y, &row_pos) && row_pos != 8) return 1; + is_in_row(model, y, 0 /* row_num */, &row_pos); + if (row_pos >= 0 && row_pos != 8) return 1; } return 0; } +void is_in_row(const struct fpga_model* model, int y, + int* row_num, int* row_pos) +{ + int dist_to_center; + + if (row_num) *row_num = -1; + if (row_pos) *row_pos = -1; + if (y < 2) return; + // normalize y to beginning of rows + y -= 2; + + // calculate distance to center and check + // that y is not pointing to the center + dist_to_center = (model->cfg_rows/2)*(8+1/*middle of row*/+8); + if (y == dist_to_center) return; + if (y > dist_to_center) y--; + + // check that y is not pointing past the last row + if (y >= model->cfg_rows*(8+1+8)) return; + + if (row_num) *row_num = model->cfg_rows-(y/(8+1+8))-1; + if (row_pos) *row_pos = y%(8+1+8); +} + static const char* fpga_ttstr[] = // tile type strings { [NA] = "NA", diff --git a/model.h b/model.h index 9c0d611..264731f 100644 --- a/model.h +++ b/model.h @@ -140,6 +140,7 @@ enum fpga_tile_type #define TOP_INNER_ROW 1 #define BOTTOM_IO_TILES 2 #define HALF_ROW 8 +#define LAST_POS_IN_ROW 16 // including hclk at 8 #define YX_TILE(model, y, x) (&(model)->tiles[(y)*model->tile_x_range+(x)]) @@ -157,19 +158,28 @@ enum fpga_tile_type #define TF_FABRIC_BRAM_MACC_ROUTING_COL 0x00000004 // only set in y==0 #define TF_FABRIC_BRAM_COL 0x00000008 // only set in y==0 #define TF_FABRIC_MACC_COL 0x00000010 // only set in y==0 -#define TF_BRAM_DEV 0x00000020 -#define TF_MACC_DEV 0x00000040 -#define TF_LOGIC_XL_DEV 0x00000080 -#define TF_LOGIC_XM_DEV 0x00000100 -#define TF_IOLOGIC_DELAY_DEV 0x00000200 -#define TF_DCM_DEV 0x00000400 -#define TF_PLL_DEV 0x00000800 +// TF_ROUTING_NO_IO is only set in y==0 - automatically for BRAM and MACC +// routing, and manually for logic routing with the noio flag in the column +// configuration string +#define TF_ROUTING_NO_IO 0x00000020 +#define TF_BRAM_DEV 0x00000040 +#define TF_MACC_DEV 0x00000080 +#define TF_LOGIC_XL_DEV 0x00000100 +#define TF_LOGIC_XM_DEV 0x00000200 +#define TF_IOLOGIC_DELAY_DEV 0x00000400 +#define TF_DCM_DEV 0x00000800 +#define TF_PLL_DEV 0x00001000 +// TF_WIRED is only set for x==0 on the left side or x==tile_x_range-1 +// on the right side. +#define TF_WIRED 0x00002000 #define Y_INNER_TOP 0x0001 #define Y_INNER_BOTTOM 0x0002 #define Y_CHIP_HORIZ_REGS 0x0004 #define Y_ROW_HORIZ_AXSYMM 0x0008 #define Y_BOTTOM_OF_ROW 0x0010 +#define Y_LEFT_WIRED 0x0020 +#define Y_RIGHT_WIRED 0x0040 // multiple checks are combined with OR logic int is_aty(int check, struct fpga_model* model, int y); @@ -181,23 +191,24 @@ int is_aty(int check, struct fpga_model* model, int y); #define X_ROUTING_COL 0x00000010 // includes routing col in left and right IO and center #define X_ROUTING_TO_BRAM_COL 0x00000020 #define X_ROUTING_TO_MACC_COL 0x00000040 -#define X_LOGIC_COL 0x00000080 // includes the center logic col -#define X_FABRIC_ROUTING_COL 0x00000100 -#define X_FABRIC_LOGIC_COL 0x00000200 -#define X_FABRIC_BRAM_MACC_ROUTING_COL 0x00000400 -#define X_FABRIC_BRAM_COL 0x00000800 -#define X_FABRIC_MACC_COL 0x00001000 -#define X_CENTER_ROUTING_COL 0x00002000 -#define X_CENTER_LOGIC_COL 0x00004000 -#define X_CENTER_CMTPLL_COL 0x00008000 -#define X_CENTER_REGS_COL 0x00010000 -#define X_LEFT_IO_ROUTING_COL 0x00020000 -#define X_LEFT_IO_DEVS_COL 0x00040000 -#define X_RIGHT_IO_ROUTING_COL 0x00080000 -#define X_RIGHT_IO_DEVS_COL 0x00100000 -#define X_LEFT_SIDE 0x00200000 // true for anything left of the center (not including center) -#define X_LEFT_MCB 0x00400000 -#define X_RIGHT_MCB 0x00800000 +#define X_ROUTING_NO_IO 0x00000080 +#define X_LOGIC_COL 0x00000100 // includes the center logic col +#define X_FABRIC_ROUTING_COL 0x00000200 +#define X_FABRIC_LOGIC_COL 0x00000400 +#define X_FABRIC_BRAM_MACC_ROUTING_COL 0x00000800 +#define X_FABRIC_BRAM_COL 0x00001000 +#define X_FABRIC_MACC_COL 0x00002000 +#define X_CENTER_ROUTING_COL 0x00004000 +#define X_CENTER_LOGIC_COL 0x00008000 +#define X_CENTER_CMTPLL_COL 0x00010000 +#define X_CENTER_REGS_COL 0x00020000 +#define X_LEFT_IO_ROUTING_COL 0x00040000 +#define X_LEFT_IO_DEVS_COL 0x00080000 +#define X_RIGHT_IO_ROUTING_COL 0x00100000 +#define X_RIGHT_IO_DEVS_COL 0x00200000 +#define X_LEFT_SIDE 0x00400000 // true for anything left of the center (not including center) +#define X_LEFT_MCB 0x00800000 +#define X_RIGHT_MCB 0x01000000 // multiple checks are combined with OR logic int is_atx(int check, struct fpga_model* model, int x); @@ -207,6 +218,12 @@ int is_atx(int check, struct fpga_model* model, int x); int is_atyx(int check, struct fpga_model* model, int y, int x); +// if not in row, both return values (if given) will +// be set to -1. the row_pos is 0..7 for the upper half, +// 8 for the hclk, and 9..16 for the lower half. +void is_in_row(const struct fpga_model* model, int y, + int* row_num, int* row_pos); + #define SWITCH_BIDIRECTIONAL 0x40000000 struct fpga_tile diff --git a/new_fp.c b/new_fp.c index 471cab2..007ba67 100644 --- a/new_fp.c +++ b/new_fp.c @@ -102,6 +102,7 @@ int printf_tiles(struct fpga_model* model) PRINT_FLAG(TF_IOLOGIC_DELAY_DEV); PRINT_FLAG(TF_DCM_DEV); PRINT_FLAG(TF_PLL_DEV); + PRINT_FLAG(TF_WIRED); if (tf) printf(" 0x%x", tf); printf("\n");