wires left and right
This commit is contained in:
parent
1dadb4c381
commit
f2a2c5d2b7
246
model.c
246
model.c
|
@ -208,7 +208,7 @@ const char* wpref(struct fpga_model* model, int y, int x, const char* wire_name)
|
|||
char* prefix;
|
||||
|
||||
if (is_aty(Y_CHIP_HORIZ_REGS, model, y)) {
|
||||
prefix = is_atx(X_CHIP_VERT_REGS, model, x+3)
|
||||
prefix = is_atx(X_CENTER_REGS_COL, model, x+3)
|
||||
? "REGC_INT_" : "REGH_";
|
||||
} else if (is_aty(Y_ROW_HORIZ_AXSYMM, model, y))
|
||||
prefix = "HCLK_";
|
||||
|
@ -401,7 +401,7 @@ int run_wires(struct fpga_model* model)
|
|||
{
|
||||
struct fpga_tile* tile;
|
||||
char buf[128];
|
||||
int x, y, i, rc, row, row_top_y, is_break;
|
||||
int x, y, i, rc, row, row_top_y, is_break, left_half;
|
||||
|
||||
rc = -1;
|
||||
// GCLK
|
||||
|
@ -413,6 +413,7 @@ int run_wires(struct fpga_model* model)
|
|||
row_top_y = TOP_IO_TILES + (model->cfg_rows-1-row)*(8+1/* middle of row */+8);
|
||||
if (row < (model->cfg_rows/2)) row_top_y++; // center regs
|
||||
|
||||
// net that connects the hclk of half the chip together horizontally
|
||||
gclk_net.last_inc = 15;
|
||||
next_net_o = 0;
|
||||
for (x = LEFT_IO_ROUTING;; x++) {
|
||||
|
@ -423,7 +424,7 @@ int run_wires(struct fpga_model* model)
|
|||
gclk_net.pts[next_net_o].x = x;
|
||||
if (is_atx(X_ROUTING_COL, model, x)) {
|
||||
gclk_net.pts[next_net_o++].name = "HCLK_GCLK%i_INT";
|
||||
} else if (is_atx(X_LOGIC_COL, model, x)) {
|
||||
} else if (is_atx(X_LOGIC_COL|X_LEFT_IO_DEVS_COL, model, x)) {
|
||||
gclk_net.pts[next_net_o++].name = "HCLK_GCLK%i_CLB";
|
||||
} else if (is_atx(X_FABRIC_BRAM_MACC_ROUTING_COL, model, x)) {
|
||||
gclk_net.pts[next_net_o++].name = "HCLK_GCLK%i_BRAM_INTER";
|
||||
|
@ -431,7 +432,7 @@ int run_wires(struct fpga_model* model)
|
|||
gclk_net.pts[next_net_o++].name = "HCLK_GCLK%i_BRAM";
|
||||
} else if (is_atx(X_FABRIC_MACC_COL, model, x)) {
|
||||
gclk_net.pts[next_net_o++].name = "HCLK_GCLK%i_DSP";
|
||||
} else if (is_atx(X_CHIP_VERT_REGS, model, x)) {
|
||||
} else if (is_atx(X_CENTER_REGS_COL, model, x)) {
|
||||
gclk_net.pts[next_net_o++].name = "CLKV_BUFH_LEFT_L%i";
|
||||
break;
|
||||
}
|
||||
|
@ -454,15 +455,19 @@ int run_wires(struct fpga_model* model)
|
|||
if (row < (model->cfg_rows/2)) row_top_y++; // center regs
|
||||
|
||||
is_break = 0;
|
||||
if (model->tiles[x].flags & TF_FABRIC_ROUTING_COL) {
|
||||
if (is_atx(X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x)) {
|
||||
if (row && row != model->cfg_rows/2)
|
||||
is_break = 1;
|
||||
} else {
|
||||
if (row)
|
||||
is_break = 1;
|
||||
else if (is_atx(X_ROUTING_TO_BRAM_COL|X_ROUTING_TO_MACC_COL, model, x))
|
||||
is_break = 1;
|
||||
} else if (row && row != model->cfg_rows/2)
|
||||
is_break = 1;
|
||||
}
|
||||
|
||||
// net inside row
|
||||
// vertical net inside row, pulling together 16 gclk
|
||||
// wires across top (8 tiles) and bottom (8 tiles) half
|
||||
// of the row.
|
||||
for (i = 0; i < 8; i++) {
|
||||
gclk_net.pts[i].name = "GCLK%i";
|
||||
gclk_net.pts[i].start_count = 0;
|
||||
|
@ -478,7 +483,7 @@ int run_wires(struct fpga_model* model)
|
|||
gclk_net.pts[7].name = "GCLK%i_BRK";
|
||||
if ((rc = add_conn_net(model, NOPREF_BI_F, &gclk_net))) goto xout;
|
||||
|
||||
// connection to hclk
|
||||
// connects gclk of each row tile to hclk tile at the middle of the row
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((rc = add_conn_range(model, NOPREF_BI_F,
|
||||
row_top_y+i, x, "GCLK%i", 0, 15,
|
||||
|
@ -487,9 +492,63 @@ int run_wires(struct fpga_model* model)
|
|||
row_top_y+9+i, x, (i == 7 && is_break) ? "GCLK%i_BRK" : "GCLK%i", 0, 15,
|
||||
row_top_y+8, x, "HCLK_GCLK%i", 0))) goto xout;
|
||||
}
|
||||
|
||||
if (x < model->center_x) {
|
||||
// long connection to CMT at center of chip
|
||||
if ((rc = add_conn_range(model, NOPREF_BI_F,
|
||||
row_top_y+8, x, "HCLK_GCLK%i_INT", 0, 15,
|
||||
row_top_y+7, model->center_x-1, "HCLK_CMT_GCLK%i_CLB", 0))) goto xout;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// wires running horizontally through the center regs, meeting
|
||||
// in the middle of each half (left and right), and the center
|
||||
// of the chip.
|
||||
left_half = 1;
|
||||
for (x = 0; x < model->tile_x_range; x++) {
|
||||
const char* fmt;
|
||||
|
||||
if (x == model->left_gclk_sep_x
|
||||
|| x == model->right_gclk_sep_x)
|
||||
continue;
|
||||
|
||||
if (is_atx(X_OUTER_LEFT, model, x)) {
|
||||
fmt = "REGL_CLKPLL%i";
|
||||
} else if (is_atx(X_INNER_LEFT, model, x)) {
|
||||
fmt = "REGL_LTERM_CLKPLL%i";
|
||||
} else if (is_atx(X_FABRIC_ROUTING_COL|X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x)) {
|
||||
fmt = "INT_CLKPLL%i";
|
||||
} else if (is_atx(X_LEFT_IO_DEVS_COL|X_FABRIC_BRAM_MACC_ROUTING_COL|X_FABRIC_LOGIC_COL|X_RIGHT_IO_DEVS_COL, model, x)) {
|
||||
fmt = "CLE_CLKPLL%i";
|
||||
} else if (is_atx(X_FABRIC_MACC_COL, model, x)) {
|
||||
fmt = "DSP_CLKPLL%i";
|
||||
} else if (is_atx(X_CENTER_ROUTING_COL, model, x)) {
|
||||
fmt = "REGC_INT_CLKPLL_IO_RT%i";
|
||||
} else if (is_atx(X_CENTER_LOGIC_COL, model, x)) {
|
||||
fmt = "REGC_CLECLKPLL_IO_LT%i";
|
||||
} else if (is_atx(X_CENTER_CMTPLL_COL, model, x)) {
|
||||
fmt = left_half ? "REGC_CLKPLL_IO_LT%i" : "REGC_CLKPLL_IO_RT%i";
|
||||
} else if (is_atx(X_CENTER_REGS_COL, model, x)) {
|
||||
fmt = "CLKC_PLL_IO_RT%i";
|
||||
} else if (is_atx(X_INNER_RIGHT, model, x)) {
|
||||
fmt = "REGR_RTERM_CLKPLL%i";
|
||||
} else if (is_atx(X_OUTER_RIGHT, model, x)) {
|
||||
fmt = "REGR_CLKPLL%i";
|
||||
} else continue;
|
||||
|
||||
if ((rc = add_conn_range(model, NOPREF_BI_F,
|
||||
model->center_y, x, fmt, 0, 1,
|
||||
model->center_y, left_half ? model->left_gclk_sep_x : model->right_gclk_sep_x,
|
||||
"INT_CLKPLL%i", 0))) goto xout;
|
||||
|
||||
if (left_half && is_atx(X_CENTER_CMTPLL_COL, model, x)) {
|
||||
left_half = 0;
|
||||
// x-- to redo the cmtpll col and wire
|
||||
// it up with the right side as well
|
||||
x--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < model->tile_y_range; y++) {
|
||||
|
@ -576,7 +635,7 @@ int run_wires(struct fpga_model* model)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (is_atx(X_CHIP_VERT_REGS, model, x+3)) {
|
||||
if (is_atx(X_CENTER_REGS_COL, model, x+3)) {
|
||||
if (tile[2].flags & (TF_PLL_DEV|TF_DCM_DEV)) {
|
||||
const char* prefix = (tile[2].flags & TF_PLL_DEV) ? "PLL_CLB2" : "DCM_CLB2";
|
||||
|
||||
|
@ -807,23 +866,42 @@ xout:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static char next_non_whitespace(const char* s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; s[i] == ' '; i++);
|
||||
return s[i];
|
||||
}
|
||||
|
||||
static char last_major(const char* str, int cur_o)
|
||||
{
|
||||
for (; cur_o; cur_o--) {
|
||||
if (str[cur_o-1] >= 'A' && str[cur_o-1] <= 'Z')
|
||||
return str[cur_o-1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_tiles(struct fpga_model* model)
|
||||
{
|
||||
int tile_rows, tile_columns, i, j, k, l, row_top_y, center_row, left_side;
|
||||
int start, end;
|
||||
int tile_rows, tile_columns, i, j, k, l, row_top_y, left_side;
|
||||
int start, end, no_io;
|
||||
char cur_cfgcol, last_col;
|
||||
struct fpga_tile* tile_i0;
|
||||
|
||||
tile_rows = 1 /* middle */ + (8+1+8)*model->cfg_rows + 2+2 /* two extra tiles at top and bottom */;
|
||||
tile_columns = 5 /* left */ + 5 /* right */;
|
||||
for (i = 0; model->cfg_columns[i] != 0; i++) {
|
||||
tile_columns += 2; // 2 for logic blocks L/M and minimum for others
|
||||
if (model->cfg_columns[i] == 'B' || model->cfg_columns[i] == 'D')
|
||||
tile_columns++; // 3 for bram or macc
|
||||
if (model->cfg_columns[i] == 'L' || model->cfg_columns[i] == 'M')
|
||||
tile_columns += 2; // 2 for logic blocks L/M
|
||||
else if (model->cfg_columns[i] == 'B' || model->cfg_columns[i] == 'D')
|
||||
tile_columns += 3; // 3 for bram or macc
|
||||
else if (model->cfg_columns[i] == 'R')
|
||||
tile_columns+=2; // 2+2 for middle IO+logic+PLL/DCM
|
||||
tile_columns += 2+2; // 2+2 for middle IO+logic+PLL/DCM
|
||||
}
|
||||
model->tile_x_range = tile_columns;
|
||||
model->tile_y_range = tile_rows;
|
||||
model->center_x = -1;
|
||||
model->tiles = calloc(tile_columns * tile_rows, sizeof(struct fpga_tile));
|
||||
if (!model->tiles) {
|
||||
fprintf(stderr, "%i: Out of memory.\n", __LINE__);
|
||||
|
@ -833,7 +911,7 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[i].type = NA;
|
||||
if (!(tile_rows % 2))
|
||||
fprintf(stderr, "Unexpected even number of tile rows (%i).\n", tile_rows);
|
||||
center_row = 2 /* top IO files */ + (model->cfg_rows/2)*(8+1/*middle of row clock*/+8);
|
||||
model->center_y = 2 /* top IO files */ + (model->cfg_rows/2)*(8+1/*middle of row clock*/+8);
|
||||
|
||||
//
|
||||
// top, bottom, center:
|
||||
|
@ -843,25 +921,29 @@ int init_tiles(struct fpga_model* model)
|
|||
left_side = 1; // turn off (=right side) when reaching the 'R' middle column
|
||||
i = 5; // skip left IO columns
|
||||
for (j = 0; model->cfg_columns[j]; j++) {
|
||||
switch (model->cfg_columns[j]) {
|
||||
cur_cfgcol = model->cfg_columns[j];
|
||||
switch (cur_cfgcol) {
|
||||
case 'L':
|
||||
case 'l':
|
||||
case 'M':
|
||||
case 'm':
|
||||
no_io = (next_non_whitespace(&model->cfg_columns[j+1]) == 'n');
|
||||
last_col = last_major(model->cfg_columns, j);
|
||||
|
||||
model->tiles[i].flags |= TF_FABRIC_ROUTING_COL;
|
||||
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);
|
||||
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles (center row)
|
||||
start = ((k == model->cfg_rows-1 && (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M')) ? 2 : 0);
|
||||
end = ((k == 0 && (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M')) ? 14 : 16);
|
||||
start = ((k == model->cfg_rows-1 && !no_io) ? 2 : 0);
|
||||
end = ((k == 0 && !no_io) ? 14 : 16);
|
||||
for (l = start; l < end; l++) {
|
||||
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
|
||||
if (l < 15 || (!k && (model->cfg_columns[j] == 'l' || model->cfg_columns[j] == 'm')))
|
||||
if (l < 15 || (!k && no_io))
|
||||
tile_i0->type = ROUTING;
|
||||
else
|
||||
tile_i0->type = ROUTING_BRK;
|
||||
if (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'l') {
|
||||
if (cur_cfgcol == 'L') {
|
||||
tile_i0[1].flags |= TF_LOGIC_XL_DEV;
|
||||
tile_i0[1].type = LOGIC_XL;
|
||||
} else {
|
||||
|
@ -869,7 +951,7 @@ int init_tiles(struct fpga_model* model)
|
|||
tile_i0[1].type = LOGIC_XM;
|
||||
}
|
||||
}
|
||||
if (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'l') {
|
||||
if (cur_cfgcol == 'L') {
|
||||
model->tiles[(row_top_y+8)*tile_columns + i].type = HCLK_ROUTING_XL;
|
||||
model->tiles[(row_top_y+8)*tile_columns + i + 1].type = HCLK_LOGIC_XL;
|
||||
} else {
|
||||
|
@ -878,17 +960,17 @@ int init_tiles(struct fpga_model* model)
|
|||
}
|
||||
}
|
||||
|
||||
if (j && model->cfg_columns[j-1] == 'R') {
|
||||
if (last_col == 'R') {
|
||||
model->tiles[tile_columns + i].type = IO_BUFPLL_TERM_T;
|
||||
model->tiles[(tile_rows-2)*tile_columns + i].type = IO_BUFPLL_TERM_B;
|
||||
} else {
|
||||
model->tiles[tile_columns + i].type = IO_TERM_T;
|
||||
if (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M')
|
||||
if (!no_io)
|
||||
model->tiles[(tile_rows-2)*tile_columns + i].type = IO_TERM_B;
|
||||
else
|
||||
model->tiles[(tile_rows-2)*tile_columns + i].type = LOGIC_ROUTING_TERM_B;
|
||||
}
|
||||
if (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M') {
|
||||
if (!no_io) {
|
||||
model->tiles[i].type = IO_T;
|
||||
model->tiles[(tile_rows-1)*tile_columns + i].type = IO_B;
|
||||
model->tiles[2*tile_columns + i].type = IO_ROUTING;
|
||||
|
@ -897,17 +979,17 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[(tile_rows-3)*tile_columns + i].type = IO_ROUTING;
|
||||
}
|
||||
|
||||
if (j && model->cfg_columns[j-1] == 'R') {
|
||||
if (last_col == 'R') {
|
||||
model->tiles[tile_columns + i + 1].type = IO_LOGIC_REG_TERM_T;
|
||||
model->tiles[(tile_rows-2)*tile_columns + i + 1].type = IO_LOGIC_REG_TERM_B;
|
||||
} else {
|
||||
model->tiles[tile_columns + i + 1].type = IO_LOGIC_TERM_T;
|
||||
if (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M')
|
||||
if (!no_io)
|
||||
model->tiles[(tile_rows-2)*tile_columns + i + 1].type = IO_LOGIC_TERM_B;
|
||||
else
|
||||
model->tiles[(tile_rows-2)*tile_columns + i + 1].type = LOGIC_NOIO_TERM_B;
|
||||
}
|
||||
if (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M') {
|
||||
if (!no_io) {
|
||||
model->tiles[2*tile_columns + i + 1].type = IO_OUTER_T;
|
||||
model->tiles[2*tile_columns + i + 1].flags |= TF_IOLOGIC_DELAY_DEV;
|
||||
model->tiles[3*tile_columns + i + 1].type = IO_INNER_T;
|
||||
|
@ -918,16 +1000,22 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[(tile_rows-3)*tile_columns + i + 1].flags |= TF_IOLOGIC_DELAY_DEV;
|
||||
}
|
||||
|
||||
if (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'l') {
|
||||
model->tiles[center_row*tile_columns + i].type = REGH_ROUTING_XL;
|
||||
model->tiles[center_row*tile_columns + i + 1].type = REGH_LOGIC_XL;
|
||||
if (cur_cfgcol == 'L') {
|
||||
model->tiles[model->center_y*tile_columns + i].type = REGH_ROUTING_XL;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_LOGIC_XL;
|
||||
} else {
|
||||
model->tiles[center_row*tile_columns + i].type = REGH_ROUTING_XM;
|
||||
model->tiles[center_row*tile_columns + i + 1].type = REGH_LOGIC_XM;
|
||||
model->tiles[model->center_y*tile_columns + i].type = REGH_ROUTING_XM;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_LOGIC_XM;
|
||||
}
|
||||
i += 2;
|
||||
break;
|
||||
case 'B':
|
||||
if (next_non_whitespace(&model->cfg_columns[j+1]) == 'g') {
|
||||
if (left_side)
|
||||
model->left_gclk_sep_x = i+2;
|
||||
else
|
||||
model->right_gclk_sep_x = i+2;
|
||||
}
|
||||
model->tiles[i].flags |= TF_FABRIC_ROUTING_COL;
|
||||
model->tiles[i+1].flags |= TF_FABRIC_BRAM_MACC_ROUTING_COL;
|
||||
model->tiles[i+2].flags |= TF_FABRIC_BRAM_COL;
|
||||
|
@ -958,9 +1046,9 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[tile_columns + i + 2].type = left_side ? BRAM_TERM_LT : BRAM_TERM_RT;
|
||||
model->tiles[(tile_rows-2)*tile_columns + i + 2].type = left_side ? BRAM_TERM_LB : BRAM_TERM_RB;
|
||||
|
||||
model->tiles[center_row*tile_columns + i].type = REGH_BRAM_ROUTING;
|
||||
model->tiles[center_row*tile_columns + i + 1].type = REGH_BRAM_ROUTING_VIA;
|
||||
model->tiles[center_row*tile_columns + i + 2].type = left_side ? REGH_BRAM_L : REGH_BRAM_R;
|
||||
model->tiles[model->center_y*tile_columns + i].type = REGH_BRAM_ROUTING;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_BRAM_ROUTING_VIA;
|
||||
model->tiles[model->center_y*tile_columns + i + 2].type = left_side ? REGH_BRAM_L : REGH_BRAM_R;
|
||||
i += 3;
|
||||
break;
|
||||
case 'D':
|
||||
|
@ -994,21 +1082,18 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[tile_columns + i + 2].type = left_side ? MACC_TERM_TL : MACC_TERM_TR;
|
||||
model->tiles[(tile_rows-2)*tile_columns + i + 2].type = left_side ? MACC_TERM_BL : MACC_TERM_BR;
|
||||
|
||||
model->tiles[center_row*tile_columns + i].type = REGH_MACC_ROUTING;
|
||||
model->tiles[center_row*tile_columns + i + 1].type = REGH_MACC_ROUTING_VIA;
|
||||
model->tiles[center_row*tile_columns + i + 2].type = REGH_MACC_L;
|
||||
model->tiles[model->center_y*tile_columns + i].type = REGH_MACC_ROUTING;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGH_MACC_ROUTING_VIA;
|
||||
model->tiles[model->center_y*tile_columns + i + 2].type = REGH_MACC_L;
|
||||
i += 3;
|
||||
break;
|
||||
case 'R':
|
||||
if (model->cfg_columns[j+1] != 'M') {
|
||||
if (next_non_whitespace(&model->cfg_columns[j+1]) != 'M') {
|
||||
// We expect a LOGIC_XM column to follow the center for
|
||||
// the top and bottom bufpll and reg routing.
|
||||
fprintf(stderr, "Expecting LOGIC_XM after center but found '%c'\n", model->cfg_columns[j+1]);
|
||||
}
|
||||
|
||||
model->tiles[i].flags |= TF_FABRIC_ROUTING_COL;
|
||||
model->tiles[i+1].flags |= TF_FABRIC_LOGIC_COL;
|
||||
model->tiles[i+3].flags |= TF_CHIP_VERT_REGS;
|
||||
model->center_x = i+3;
|
||||
|
||||
left_side = 0;
|
||||
for (k = model->cfg_rows-1; k >= 0; k--) {
|
||||
|
@ -1096,16 +1181,20 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[tile_columns + i + 3].type = REGV_TERM_T;
|
||||
model->tiles[(tile_rows-2)*tile_columns + i + 3].type = REGV_TERM_B;
|
||||
|
||||
model->tiles[center_row*tile_columns + i].type = REGC_ROUTING;
|
||||
model->tiles[center_row*tile_columns + i + 1].type = REGC_LOGIC;
|
||||
model->tiles[center_row*tile_columns + i + 2].type = REGC_CMT;
|
||||
model->tiles[center_row*tile_columns + i + 3].type = CENTER;
|
||||
model->tiles[model->center_y*tile_columns + i].type = REGC_ROUTING;
|
||||
model->tiles[model->center_y*tile_columns + i + 1].type = REGC_LOGIC;
|
||||
model->tiles[model->center_y*tile_columns + i + 2].type = REGC_CMT;
|
||||
model->tiles[model->center_y*tile_columns + i + 3].type = CENTER;
|
||||
|
||||
i += 4;
|
||||
break;
|
||||
case ' ': // space used to make string more readable only
|
||||
case 'g': // global clock separator
|
||||
case 'n': // noio for logic blocks
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unexpected column identifier '%c'\n", model->cfg_columns[j]);
|
||||
break;
|
||||
fprintf(stderr, "Ignoring unexpected column identifier '%c'\n", cur_cfgcol);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1192,22 +1281,22 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[(row_top_y+8)*tile_columns + 4].type = HCLK_MCB;
|
||||
}
|
||||
|
||||
model->tiles[(center_row-3)*tile_columns].type = IO_PCI_L;
|
||||
model->tiles[(center_row-2)*tile_columns].type = IO_PCI_CONN_L;
|
||||
model->tiles[(center_row-1)*tile_columns].type = IO_PCI_CONN_L;
|
||||
model->tiles[center_row*tile_columns].type = REG_L;
|
||||
model->tiles[(center_row+1)*tile_columns].type = IO_RDY_L;
|
||||
model->tiles[(model->center_y-3)*tile_columns].type = IO_PCI_L;
|
||||
model->tiles[(model->center_y-2)*tile_columns].type = IO_PCI_CONN_L;
|
||||
model->tiles[(model->center_y-1)*tile_columns].type = IO_PCI_CONN_L;
|
||||
model->tiles[model->center_y*tile_columns].type = REG_L;
|
||||
model->tiles[(model->center_y+1)*tile_columns].type = IO_RDY_L;
|
||||
|
||||
model->tiles[center_row*tile_columns + 1].type = REGH_IO_TERM_L;
|
||||
model->tiles[model->center_y*tile_columns + 1].type = REGH_IO_TERM_L;
|
||||
|
||||
model->tiles[tile_columns + 2].type = CORNER_TERM_T;
|
||||
model->tiles[(tile_rows-2)*tile_columns + 2].type = CORNER_TERM_B;
|
||||
model->tiles[center_row*tile_columns + 2].type = REGH_ROUTING_IO_L;
|
||||
model->tiles[model->center_y*tile_columns + 2].type = REGH_ROUTING_IO_L;
|
||||
|
||||
model->tiles[tile_columns + 3].type = ROUTING_IO_PCI_CE_L;
|
||||
model->tiles[(tile_rows-2)*tile_columns + 3].type = ROUTING_IO_PCI_CE_L;
|
||||
model->tiles[center_row*tile_columns + 3].type = REGH_IO_L;
|
||||
model->tiles[center_row*tile_columns + 4].type = REGH_MCB;
|
||||
model->tiles[model->center_y*tile_columns + 3].type = REGH_IO_L;
|
||||
model->tiles[model->center_y*tile_columns + 4].type = REGH_MCB;
|
||||
|
||||
//
|
||||
// right IO
|
||||
|
@ -1308,11 +1397,11 @@ int init_tiles(struct fpga_model* model)
|
|||
model->tiles[(tile_rows-2)*tile_columns + tile_columns - 5].type = CORNER_TERM_B;
|
||||
model->tiles[tile_columns + tile_columns - 4].type = ROUTING_IO_PCI_CE_R;
|
||||
model->tiles[(tile_rows-2)*tile_columns + tile_columns - 4].type = ROUTING_IO_PCI_CE_R;
|
||||
model->tiles[center_row*tile_columns + tile_columns - 1].type = REG_R;
|
||||
model->tiles[center_row*tile_columns + tile_columns - 2].type = REGH_IO_TERM_R;
|
||||
model->tiles[center_row*tile_columns + tile_columns - 3].type = REGH_MCB;
|
||||
model->tiles[center_row*tile_columns + tile_columns - 4].type = REGH_IO_R;
|
||||
model->tiles[center_row*tile_columns + tile_columns - 5].type = REGH_ROUTING_IO_R;
|
||||
model->tiles[model->center_y*tile_columns + tile_columns - 1].type = REG_R;
|
||||
model->tiles[model->center_y*tile_columns + tile_columns - 2].type = REGH_IO_TERM_R;
|
||||
model->tiles[model->center_y*tile_columns + tile_columns - 3].type = REGH_MCB;
|
||||
model->tiles[model->center_y*tile_columns + tile_columns - 4].type = REGH_IO_R;
|
||||
model->tiles[model->center_y*tile_columns + tile_columns - 5].type = REGH_ROUTING_IO_R;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1342,10 +1431,7 @@ int is_aty(int check, struct fpga_model* model, int y)
|
|||
if (y < 0) return 0;
|
||||
if (check & Y_INNER_TOP && y == 1) return 1;
|
||||
if (check & Y_INNER_BOTTOM && y == model->tile_y_range-2) return 1;
|
||||
if (check & Y_CHIP_HORIZ_REGS) {
|
||||
int center_tile = 2 /* top IO files */ + (model->cfg_rows/2)*(8+1/*middle of row clock*/+8);
|
||||
if (y == center_tile) return 1;
|
||||
}
|
||||
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)) {
|
||||
|
@ -1359,12 +1445,14 @@ int is_aty(int check, struct fpga_model* model, int y)
|
|||
int is_atx(int check, struct fpga_model* model, int x)
|
||||
{
|
||||
if (x < 0) return 0;
|
||||
if (check & X_OUTER_LEFT && !x) return 1;
|
||||
if (check & X_INNER_LEFT && x == 1) return 1;
|
||||
if (check & X_INNER_RIGHT && x == model->tile_x_range-2) return 1;
|
||||
if (check & X_CHIP_VERT_REGS && model->tiles[x].flags & TF_CHIP_VERT_REGS) return 1;
|
||||
if (check & X_OUTER_RIGHT && x == model->tile_x_range-1) return 1;
|
||||
if (check & X_ROUTING_COL
|
||||
&& (model->tiles[x].flags & TF_FABRIC_ROUTING_COL
|
||||
|| x == 2 || x == model->tile_x_range-5)) return 1;
|
||||
|| x == LEFT_IO_ROUTING || x == model->tile_x_range-5
|
||||
|| x == model->center_x-3)) return 1;
|
||||
if (model->tiles[x].flags & TF_FABRIC_ROUTING_COL) {
|
||||
if (check & X_ROUTING_TO_BRAM_COL
|
||||
&& model->tiles[x+1].flags & TF_FABRIC_BRAM_MACC_ROUTING_COL
|
||||
|
@ -1375,10 +1463,21 @@ int is_atx(int check, struct fpga_model* model, int x)
|
|||
}
|
||||
if (check & X_LOGIC_COL
|
||||
&& (model->tiles[x].flags & TF_FABRIC_LOGIC_COL
|
||||
|| x == 3)) return 1;
|
||||
|| x == model->center_x-2)) return 1;
|
||||
if (check & X_FABRIC_ROUTING_COL && model->tiles[x].flags & TF_FABRIC_ROUTING_COL) return 1;
|
||||
if (check & X_FABRIC_LOGIC_COL && model->tiles[x].flags & TF_FABRIC_LOGIC_COL) return 1;
|
||||
if (check & X_FABRIC_BRAM_MACC_ROUTING_COL && model->tiles[x].flags & TF_FABRIC_BRAM_MACC_ROUTING_COL) return 1;
|
||||
if (check & X_FABRIC_BRAM_COL && model->tiles[x].flags & TF_FABRIC_BRAM_COL) return 1;
|
||||
if (check & X_FABRIC_MACC_COL && model->tiles[x].flags & TF_FABRIC_MACC_COL) return 1;
|
||||
if (check & X_CENTER_ROUTING_COL && x == model->center_x-3) return 1;
|
||||
if (check & X_CENTER_LOGIC_COL && x == model->center_x-2) return 1;
|
||||
if (check & X_CENTER_CMTPLL_COL && x == model->center_x-1) return 1;
|
||||
if (check & X_CENTER_REGS_COL && x == model->center_x) return 1;
|
||||
if (check & X_LEFT_IO_ROUTING_COL && x == LEFT_IO_ROUTING) return 1;
|
||||
if (check & X_LEFT_IO_DEVS_COL && x == LEFT_IO_DEVS) return 1;
|
||||
if (check & X_RIGHT_IO_ROUTING_COL && x == model->tile_x_range-5) return 1;
|
||||
if (check & X_RIGHT_IO_DEVS_COL && x == model->tile_x_range-4) return 1;
|
||||
if (check & X_LEFT_SIDE && x < model->center_x) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1387,7 +1486,8 @@ int is_atyx(int check, struct fpga_model* model, int y, int x)
|
|||
if (y < 0 || x < 0) return 0;
|
||||
if (check & YX_ROUTING_TILE
|
||||
&& (model->tiles[x].flags & TF_FABRIC_ROUTING_COL
|
||||
|| x == 2 || x == model->tile_x_range-5)) {
|
||||
|| 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;
|
||||
}
|
||||
|
|
84
model.h
84
model.h
|
@ -27,21 +27,30 @@ struct hashed_strarray
|
|||
int bin_len[1024]; // points behind the last zero-termination
|
||||
};
|
||||
|
||||
//
|
||||
// columns
|
||||
// 'L' = X+L logic block
|
||||
// 'l' = X+L logic block without IO at top and bottom
|
||||
// 'M' = X+M logic block
|
||||
// 'm' = X+M logic block without IO at top and bottom
|
||||
// 'B' = block ram
|
||||
// 'D' = dsp (macc)
|
||||
// 'R' = registers and center IO/logic column
|
||||
//
|
||||
// 'n' = noio - can follow L or M to designate a logic
|
||||
// column without IO at top or bottom
|
||||
// 'g' = gclk - can follow LlMmBD to designate exactly one
|
||||
// place on the left and right side of the chip where
|
||||
// the global clock is separated into left and right
|
||||
// half (on each side of the chip, for a total of 4
|
||||
// vertical clock separations).
|
||||
//
|
||||
// wiring on the left and right side is described with 16
|
||||
// characters for each row - 'W' = wired, 'U' = unwired
|
||||
// order is top-down
|
||||
// characters for each row, order is top-down
|
||||
// 'W' = wired
|
||||
// 'U' = unwired
|
||||
//
|
||||
|
||||
#define XC6SLX9_ROWS 4
|
||||
#define XC6SLX9_COLUMNS "MLBMLDMRMlMLBML"
|
||||
#define XC6SLX9_COLUMNS "M L Bg M L D M R M Ln M L Bg M L"
|
||||
#define XC6SLX9_LEFT_WIRING \
|
||||
/* row 3 */ "UWUWUWUW" "WWWWUUUU" \
|
||||
/* row 2 */ "UUUUUUUU" "WWWWWWUU" \
|
||||
|
@ -60,6 +69,13 @@ struct fpga_model
|
|||
char cfg_left_wiring[1024], cfg_right_wiring[1024];
|
||||
|
||||
int tile_x_range, tile_y_range;
|
||||
int center_x;
|
||||
int center_y;
|
||||
// Left and right gclk separators will be located on
|
||||
// the device column (+1 or +2) of the logic or dsp/macc
|
||||
// column as indicated in the chip's cfg_columns with a 'g'.
|
||||
int left_gclk_sep_x, right_gclk_sep_x;
|
||||
|
||||
struct fpga_tile* tiles;
|
||||
struct hashed_strarray str;
|
||||
};
|
||||
|
@ -122,23 +138,23 @@ enum fpga_tile_type
|
|||
|
||||
// Some constant to make the core more readable
|
||||
#define LEFT_IO_ROUTING 2
|
||||
#define LEFT_IO_DEVS 3
|
||||
#define TOP_IO_TILES 2
|
||||
|
||||
// tile flags
|
||||
|
||||
#define TF_CHIP_VERT_REGS 0x00000001 // only set in y==0
|
||||
#define TF_FABRIC_ROUTING_COL 0x00000002 // only set in y==0, not for left and right IO routing
|
||||
#define TF_FABRIC_LOGIC_COL 0x00000004 // only set in y==0
|
||||
#define TF_FABRIC_BRAM_MACC_ROUTING_COL 0x00000008 // only set in y==0
|
||||
#define TF_FABRIC_BRAM_COL 0x00000010 // only set in y==0
|
||||
#define TF_FABRIC_MACC_COL 0x00000020 // only set in y==0
|
||||
#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
|
||||
#define TF_FABRIC_ROUTING_COL 0x00000001 // only set in y==0, not for left and right IO routing or center
|
||||
#define TF_FABRIC_LOGIC_COL 0x00000002 // only set in y==0
|
||||
#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
|
||||
|
||||
#define Y_INNER_TOP 0x0001
|
||||
#define Y_INNER_BOTTOM 0x0002
|
||||
|
@ -149,16 +165,28 @@ enum fpga_tile_type
|
|||
// multiple checks are combined with OR logic
|
||||
int is_aty(int check, struct fpga_model* model, int y);
|
||||
|
||||
#define X_INNER_LEFT 0x0001
|
||||
#define X_INNER_RIGHT 0x0002
|
||||
#define X_CHIP_VERT_REGS 0x0004
|
||||
#define X_ROUTING_COL 0x0008 // includes routing col in left and right IO
|
||||
#define X_ROUTING_TO_BRAM_COL 0x0010
|
||||
#define X_ROUTING_TO_MACC_COL 0x0020
|
||||
#define X_LOGIC_COL 0x0040 // includes the logic col in left IO
|
||||
#define X_FABRIC_BRAM_MACC_ROUTING_COL 0x0080
|
||||
#define X_FABRIC_BRAM_COL 0x0100
|
||||
#define X_FABRIC_MACC_COL 0x0200
|
||||
#define X_OUTER_LEFT 0x00000001
|
||||
#define X_INNER_LEFT 0x00000002
|
||||
#define X_INNER_RIGHT 0x00000004
|
||||
#define X_OUTER_RIGHT 0x00000008
|
||||
#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)
|
||||
|
||||
// multiple checks are combined with OR logic
|
||||
int is_atx(int check, struct fpga_model* model, int x);
|
||||
|
|
Loading…
Reference in New Issue
Block a user