minor cleanup

This commit is contained in:
Wolfgang Spraul 2012-11-24 14:40:25 +01:00
parent aa4021f7a4
commit 67c08bfc0a
14 changed files with 191 additions and 240 deletions

View File

@ -1862,8 +1862,7 @@ int main(int argc, char** argv)
MEMUSAGE();
printf("O Building memory model...\n");
if ((rc = fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS,
XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
if ((rc = fpga_build_model(&model, XC6SLX9)))
goto fail;
printf("O Done\n");
TIME_AND_MEM();

View File

@ -53,8 +53,7 @@ int main(int argc, char** argv)
}
// build model
if ((rc = fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS,
XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
if ((rc = fpga_build_model(&model, XC6SLX9)))
FAIL(rc);
if (print_swbits) {

View File

@ -34,8 +34,7 @@ int main(int argc, char** argv)
struct fpgadev_logic logic_cfg;
net_idx_t inA_net, inB_net, out_net;
fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING);
fpga_build_model(&model, XC6SLX9);
fpga_find_iob(&model, "P55", &iob_clk_y, &iob_clk_x, &iob_clk_type_idx);
fdev_iob_input(&model, iob_clk_y, iob_clk_x, iob_clk_type_idx,
@ -86,30 +85,29 @@ int main(int argc, char** argv)
logic_cfg.sync_attr = SYNCATTR_ASYNC;
logic_cfg.precyinit = PRECYINIT_0;
logic_cfg.cout_used = 1;
rc = fdev_logic_setconf(tstate->model, y, x, type_idx, logic_cfg);
if (rc) FAIL(rc);
logic_setconf(tstate->model, y, x, type_idx, logic_cfg);
if ((rc = fnet_new(&model, &inA_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
DEV_IOB, iob_inA_type_idx, IOB_OUT_I))) FAIL(rc);
if ((rc = fnet_add_port(&model, inA_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D3))) FAIL(rc);
if ((rc = fnet_autoroute(&model, inA_net))) FAIL(rc);
fnet_new(&model, &inA_net);
fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
DEV_IOB, iob_inA_type_idx, IOB_OUT_I);
fnet_add_port(&model, inA_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D3);
fnet_autoroute(&model, inA_net);
if ((rc = fnet_new(&model, &inB_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, inB_net, iob_inB_y, iob_inB_x,
DEV_IOB, iob_inB_type_idx, IOB_OUT_I))) FAIL(rc);
if ((rc = fnet_add_port(&model, inB_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D5))) FAIL(rc);
if ((rc = fnet_autoroute(&model, inB_net))) FAIL(rc);
fnet_new(&model, &inB_net);
fnet_add_port(&model, inB_net, iob_inB_y, iob_inB_x,
DEV_IOB, iob_inB_type_idx, IOB_OUT_I);
fnet_add_port(&model, inB_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D5);
fnet_autoroute(&model, inB_net);
if ((rc = fnet_new(&model, &out_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, out_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LO_D))) FAIL(rc);
if ((rc = fnet_add_port(&model, out_net, iob_out_y, iob_out_x,
DEV_IOB, iob_out_type_idx, IOB_IN_O))) FAIL(rc);
if ((rc = fnet_autoroute(&model, out_net))) FAIL(rc);
fnet_new(&model, &out_net);
fnet_add_port(&model, out_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LO_D);
fnet_add_port(&model, out_net, iob_out_y, iob_out_x,
DEV_IOB, iob_out_type_idx, IOB_IN_O);
fnet_autoroute(&model, out_net);
#endif
write_floorplan(stdout, &model, FP_DEFAULT);

View File

@ -47,8 +47,7 @@ int main(int argc, char** argv)
// on the output for now
xmlInitParser();
if (fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))
if (fpga_build_model(&model, XC6SLX9))
goto fail;
doc = xmlParseDoc(empty_svg);

View File

@ -41,8 +41,7 @@ int main(int argc, char** argv)
goto fail;
}
if ((rc = fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS,
XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
if ((rc = fpga_build_model(&model, XC6SLX9)))
goto fail;
if ((rc = read_floorplan(&model, fp))) goto fail;

View File

@ -32,56 +32,51 @@ int main(int argc, char** argv)
int iob_out_y, iob_out_x, iob_out_type_idx;
int logic_y, logic_x, logic_type_idx;
net_idx_t inA_net, inB_net, out_net;
int rc;
if ((rc = fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS,
XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
FAIL(rc);
fpga_build_model(&model, XC6SLX9);
if ((rc = fpga_find_iob(&model, "P45", &iob_inA_y, &iob_inA_x,
&iob_inA_type_idx))) FAIL(rc);
if ((rc = fdev_iob_input(&model, iob_inA_y, iob_inA_x,
iob_inA_type_idx, IO_LVCMOS33))) FAIL(rc);
fpga_find_iob(&model, "P45", &iob_inA_y, &iob_inA_x,
&iob_inA_type_idx);
fdev_iob_input(&model, iob_inA_y, iob_inA_x,
iob_inA_type_idx, IO_LVCMOS33);
if ((rc = fpga_find_iob(&model, "P46", &iob_inB_y, &iob_inB_x,
&iob_inB_type_idx))) FAIL(rc);
if ((rc = fdev_iob_input(&model, iob_inB_y, iob_inB_x,
iob_inB_type_idx, IO_LVCMOS33))) FAIL(rc);
fpga_find_iob(&model, "P46", &iob_inB_y, &iob_inB_x,
&iob_inB_type_idx);
fdev_iob_input(&model, iob_inB_y, iob_inB_x,
iob_inB_type_idx, IO_LVCMOS33);
if ((rc = fpga_find_iob(&model, "P48", &iob_out_y, &iob_out_x,
&iob_out_type_idx))) FAIL(rc);
if ((rc = fdev_iob_output(&model, iob_out_y, iob_out_x,
iob_out_type_idx, IO_LVCMOS33))) FAIL(rc);
fpga_find_iob(&model, "P48", &iob_out_y, &iob_out_x,
&iob_out_type_idx);
fdev_iob_output(&model, iob_out_y, iob_out_x,
iob_out_type_idx, IO_LVCMOS33);
logic_y = 68;
logic_x = 13;
logic_type_idx = DEV_LOG_X;
if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
LUT_D, 6, "A3*A5", ZTERM))) FAIL(rc);
fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
LUT_D, 6, "A3*A5", ZTERM);
if ((rc = fnet_new(&model, &inA_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
DEV_IOB, iob_inA_type_idx, IOB_OUT_I))) FAIL(rc);
if ((rc = fnet_add_port(&model, inA_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D3))) FAIL(rc);
if ((rc = fnet_autoroute(&model, inA_net))) FAIL(rc);
fnet_new(&model, &inA_net);
fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
DEV_IOB, iob_inA_type_idx, IOB_OUT_I);
fnet_add_port(&model, inA_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D3);
fnet_autoroute(&model, inA_net);
if ((rc = fnet_new(&model, &inB_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, inB_net, iob_inB_y, iob_inB_x,
DEV_IOB, iob_inB_type_idx, IOB_OUT_I))) FAIL(rc);
if ((rc = fnet_add_port(&model, inB_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D5))) FAIL(rc);
if ((rc = fnet_autoroute(&model, inB_net))) FAIL(rc);
fnet_new(&model, &inB_net);
fnet_add_port(&model, inB_net, iob_inB_y, iob_inB_x,
DEV_IOB, iob_inB_type_idx, IOB_OUT_I);
fnet_add_port(&model, inB_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LI_D5);
fnet_autoroute(&model, inB_net);
if ((rc = fnet_new(&model, &out_net))) FAIL(rc);
if ((rc = fnet_add_port(&model, out_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LO_D))) FAIL(rc);
if ((rc = fnet_add_port(&model, out_net, iob_out_y, iob_out_x,
DEV_IOB, iob_out_type_idx, IOB_IN_O))) FAIL(rc);
if ((rc = fnet_autoroute(&model, out_net))) FAIL(rc);
fnet_new(&model, &out_net);
fnet_add_port(&model, out_net, logic_y, logic_x, DEV_LOGIC,
logic_type_idx, LO_D);
fnet_add_port(&model, out_net, iob_out_y, iob_out_x,
DEV_IOB, iob_out_type_idx, IOB_IN_O);
fnet_autoroute(&model, out_net);
if ((rc = write_floorplan(stdout, &model, FP_DEFAULT))) FAIL(rc);
return EXIT_SUCCESS;
fail:
return rc;
write_floorplan(stdout, &model, FP_DEFAULT);
return fpga_free_model(&model);
}

View File

@ -15,41 +15,6 @@
#include "helper.h"
//
// columns
// 'L' = X+L logic block
// 'M' = X+M logic block
// '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, order is top-down
// 'W' = wired
// 'U' = unwired
//
#define XC6SLX9_ROWS 4
#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" \
/* row 1 */ "WWWUUWUU" "WUUWUUWU" \
/* row 0 */ "UWUUWUUW" "UUWWWWUU"
#define XC6SLX9_RIGHT_WIRING \
/* row 3 */ "UUWWUWUW" "WWWWUUUU" \
/* row 2 */ "UUUUUUUU" "WWWWWWUU" \
/* row 1 */ "WWWUUWUU" "WUUWUUWU" \
/* row 0 */ "UWUUWUUW" "UUWWWWUU"
#define LEFT_SIDE_MAJOR 1
struct fpga_model
@ -57,9 +22,6 @@ struct fpga_model
int rc; // if rc != 0, all function calls will immediately return
const struct xc_info *xci;
int cfg_rows;
char cfg_columns[512];
char cfg_left_wiring[1024], cfg_right_wiring[1024];
int x_width, y_height;
int center_x;
@ -793,9 +755,7 @@ struct fpga_tile
uint32_t* switches;
};
int fpga_build_model(struct fpga_model* model,
int idcode, int fpga_rows, const char* columns,
const char* left_wiring, const char* right_wiring);
int fpga_build_model(struct fpga_model* model, int idcode);
// returns model->rc (model itself will be memset to 0)
int fpga_free_model(struct fpga_model* model);

View File

@ -2785,9 +2785,9 @@ static int run_gclk(struct fpga_model* model)
struct w_net gclk_net;
RC_CHECK(model);
for (row = model->cfg_rows-1; row >= 0; row--) {
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
for (row = model->xci->num_rows-1; row >= 0; row--) {
row_top_y = TOP_IO_TILES + (model->xci->num_rows-1-row)*(8+1/* middle of row */+8);
if (row < (model->xci->num_rows/2)) row_top_y++; // center regs
// net that connects the hclk of half the chip together horizontally
gclk_net.last_inc = 15;
@ -2844,13 +2844,13 @@ static int run_gclk(struct fpga_model* model)
}
for (x = 0; x < model->x_width; x++) {
if (is_atx(X_ROUTING_COL, model, x)) {
for (row = model->cfg_rows-1; row >= 0; row--) {
row_top_y = 2 /* top IO */ + (model->cfg_rows-1-row)*(8+1/* middle of row */+8);
if (row < (model->cfg_rows/2)) row_top_y++; // center regs
for (row = model->xci->num_rows-1; row >= 0; row--) {
row_top_y = 2 /* top IO */ + (model->xci->num_rows-1-row)*(8+1/* middle of row */+8);
if (row < (model->xci->num_rows/2)) row_top_y++; // center regs
is_break = 0;
if (is_atx(X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x)) {
if (row && row != model->cfg_rows/2)
if (row && row != model->xci->num_rows/2)
is_break = 1;
} else {
if (row)
@ -3542,7 +3542,7 @@ static int run_logic_inout(struct fpga_model* model)
}
}
// LOGICIN
for (i = 0; i < model->cfg_rows; i++) {
for (i = 0; i < model->xci->num_rows; i++) {
y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs

View File

@ -21,7 +21,7 @@ int init_devices(struct fpga_model* model)
RC_CHECK(model);
// DCM, PLL
for (i = 0; i < model->cfg_rows; i++) {
for (i = 0; i < model->xci->num_rows; i++) {
y = TOP_IO_TILES + HALF_ROW-1 + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs
x = model->center_x-CENTER_CMTPLL_O;
@ -132,7 +132,7 @@ int init_devices(struct fpga_model* model)
}
// BUFH
for (i = 0; i < model->cfg_rows; i++) {
for (i = 0; i < model->xci->num_rows; i++) {
y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs
x = model->center_x;

View File

@ -697,14 +697,14 @@ void is_in_row(const struct fpga_model* model, int y,
// 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);
dist_to_center = (model->xci->num_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 (y >= model->xci->num_rows*(8+1+8)) return;
if (row_num) *row_num = model->cfg_rows-(y/(8+1+8))-1;
if (row_num) *row_num = model->xci->num_rows-(y/(8+1+8))-1;
if (row_pos) *row_pos = y%(8+1+8);
}

View File

@ -11,52 +11,32 @@
static int s_high_speed_replicate = 1;
int fpga_build_model(struct fpga_model* model, int idcode, int fpga_rows,
const char* columns, const char* left_wiring, const char* right_wiring)
int fpga_build_model(struct fpga_model* model, int idcode)
{
int rc;
memset(model, 0, sizeof(*model));
model->xci = xc_info(idcode);
if (!model->xci) FAIL(EINVAL);
model->cfg_rows = fpga_rows;
strncpy(model->cfg_columns, columns, sizeof(model->cfg_columns)-1);
strncpy(model->cfg_left_wiring, left_wiring,
sizeof(model->cfg_left_wiring)-1);
strncpy(model->cfg_right_wiring, right_wiring,
sizeof(model->cfg_right_wiring)-1);
if (!model->xci) RC_FAIL(model, EINVAL);
strarray_init(&model->str, STRIDX_64K);
rc = get_xc6_routing_bitpos(&model->sw_bitpos, &model->num_bitpos);
if (rc) FAIL(rc);
if (rc) RC_FAIL(model, rc);
// The order of tiles, then devices, then ports, then
// connections and finally switches is important so
// that the codes can build upon each other.
rc = init_tiles(model);
if (rc) FAIL(rc);
rc = init_devices(model);
if (rc) FAIL(rc);
if (s_high_speed_replicate) {
rc = replicate_routing_switches(model);
if (rc) FAIL(rc);
}
init_tiles(model);
init_devices(model);
if (s_high_speed_replicate)
replicate_routing_switches(model);
// todo: compare.ports only works if other switches and conns
// are disabled, as long as not all connections are supported
rc = init_ports(model, /*dup_warn*/ !s_high_speed_replicate);
if (rc) FAIL(rc);
init_ports(model, /*dup_warn*/ !s_high_speed_replicate);
init_conns(model);
init_switches(model, /*routing_sw*/ !s_high_speed_replicate);
rc = init_conns(model);
if (rc) FAIL(rc);
rc = init_switches(model, /*routing_sw*/ !s_high_speed_replicate);
if (rc) FAIL(rc);
return 0;
fail:
return rc;
RC_RETURN(model);
}
int fpga_free_model(struct fpga_model* model)

View File

@ -7,6 +7,7 @@
#include <stdarg.h>
#include "model.h"
#include "parts.h"
int init_tiles(struct fpga_model* model)
{
@ -16,14 +17,14 @@ int init_tiles(struct fpga_model* model)
struct fpga_tile* tile_i0;
RC_CHECK(model);
tile_rows = 1 /* middle */ + (8+1+8)*model->cfg_rows + 2+2 /* two extra tiles at top and bottom */;
tile_rows = 1 /* middle */ + (8+1+8)*model->xci->num_rows + 2+2 /* two extra tiles at top and bottom */;
tile_columns = LEFT_SIDE_WIDTH + RIGHT_SIDE_WIDTH;
for (i = 0; model->cfg_columns[i] != 0; i++) {
if (model->cfg_columns[i] == 'L' || model->cfg_columns[i] == 'M')
for (i = 0; model->xci->major_str[i] != 0; i++) {
if (model->xci->major_str[i] == 'L' || model->xci->major_str[i] == 'M')
tile_columns += 2; // 2 for logic blocks L/M
else if (model->cfg_columns[i] == 'B' || model->cfg_columns[i] == 'D')
else if (model->xci->major_str[i] == 'B' || model->xci->major_str[i] == 'D')
tile_columns += 3; // 3 for bram or macc
else if (model->cfg_columns[i] == 'R')
else if (model->xci->major_str[i] == 'R')
tile_columns += 2+2; // 2+2 for middle IO+logic+PLL/DCM
}
model->tmp_str = malloc((tile_columns > tile_rows ? tile_columns : tile_rows) * sizeof(*model->tmp_str));
@ -43,7 +44,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);
model->center_y = 2 /* top IO files */ + (model->cfg_rows/2)*(8+1/*middle of row clock*/+8);
model->center_y = 2 /* top IO files */ + (model->xci->num_rows/2)*(8+1/*middle of row clock*/+8);
//
// top, bottom, center:
@ -55,15 +56,15 @@ int init_tiles(struct fpga_model* model)
model->x_major[i] = LEFT_SIDE_MAJOR;
cur_major = LEFT_SIDE_MAJOR+1;
// i is now LEFT_SIDE_WIDTH (5)
for (j = 0; model->cfg_columns[j]; j++) {
cur_cfgcol = model->cfg_columns[j];
for (j = 0; model->xci->major_str[j]; j++) {
cur_cfgcol = model->xci->major_str[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);
no_io = (next_non_whitespace(&model->xci->major_str[j+1]) == 'n');
last_col = last_major(model->xci->major_str, j);
model->tiles[i].flags |= TF_FABRIC_ROUTING_COL;
if (no_io) model->tiles[i].flags |= TF_ROUTING_NO_IO;
@ -71,10 +72,10 @@ int init_tiles(struct fpga_model* model)
(cur_cfgcol == 'L' || cur_cfgcol == 'l')
? TF_FABRIC_LOGIC_XL_COL
: TF_FABRIC_LOGIC_XM_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 && !no_io) ? 2 : 0);
for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles (center row)
start = ((k == model->xci->num_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];
@ -153,7 +154,7 @@ int init_tiles(struct fpga_model* model)
break;
case 'B':
if (next_non_whitespace(&model->cfg_columns[j+1]) == 'g') {
if (next_non_whitespace(&model->xci->major_str[j+1]) == 'g') {
if (left_side)
model->left_gclk_sep_x = i+2;
else
@ -163,9 +164,9 @@ int init_tiles(struct fpga_model* model)
model->tiles[i].flags |= TF_ROUTING_NO_IO; // no_io always on for BRAM
model->tiles[i+1].flags |= TF_FABRIC_BRAM_VIA_COL;
model->tiles[i+2].flags |= TF_FABRIC_BRAM_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
for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
if (l < 15)
@ -204,9 +205,9 @@ int init_tiles(struct fpga_model* model)
model->tiles[i].flags |= TF_ROUTING_NO_IO; // no_io always on for MACC
model->tiles[i+1].flags |= TF_FABRIC_MACC_VIA_COL;
model->tiles[i+2].flags |= TF_FABRIC_MACC_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
for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
if (l < 15)
@ -241,22 +242,22 @@ int init_tiles(struct fpga_model* model)
break;
case 'R':
if (next_non_whitespace(&model->cfg_columns[j+1]) != 'M') {
if (next_non_whitespace(&model->xci->major_str[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]);
fprintf(stderr, "Expecting LOGIC_XM after center but found '%c'\n", model->xci->major_str[j+1]);
}
model->center_x = i+3;
left_side = 0;
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
for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
if ((k < model->cfg_rows-1 || l >= 2) && (k || l<14)) {
if ((k < model->xci->num_rows-1 || l >= 2) && (k || l<14)) {
if (l < 15)
tile_i0->type = ROUTING;
else
@ -265,7 +266,7 @@ int init_tiles(struct fpga_model* model)
tile_i0[1].type = ROUTING_VIA_IO;
else if (l == 8)
tile_i0[1].type = (k%2) ? ROUTING_VIA_CARRY : ROUTING_VIA_IO_DCM;
else if (l == 15 && k==model->cfg_rows/2)
else if (l == 15 && k==model->xci->num_rows/2)
tile_i0[1].type = ROUTING_VIA_REGC;
else {
tile_i0[1].type = LOGIC_XL;
@ -280,28 +281,28 @@ int init_tiles(struct fpga_model* model)
if (l == 7) {
if (k%2) { // odd
model->tiles[(row_top_y+l)*tile_columns + i + 2].flags |= TF_PLL_DEV;
model->tiles[(row_top_y+l)*tile_columns + i + 2].type = (k<(model->cfg_rows/2)) ? PLL_B : PLL_T;
model->tiles[(row_top_y+l)*tile_columns + i + 2].type = (k<(model->xci->num_rows/2)) ? PLL_B : PLL_T;
} else { // even
model->tiles[(row_top_y+l)*tile_columns + i + 2].flags |= TF_DCM_DEV;
model->tiles[(row_top_y+l)*tile_columns + i + 2].type = (k<(model->cfg_rows/2)) ? DCM_B : DCM_T;
model->tiles[(row_top_y+l)*tile_columns + i + 2].type = (k<(model->xci->num_rows/2)) ? DCM_B : DCM_T;
}
}
// four midbuf tiles, in the middle of the top and bottom halves
if (l == 15) {
if (k == model->cfg_rows*3/4)
if (k == model->xci->num_rows*3/4)
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = REGV_MIDBUF_T;
else if (k == model->cfg_rows/4) {
else if (k == model->xci->num_rows/4) {
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].flags |= TF_CENTER_MIDBUF;
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = REGV_HCLKBUF_B;
} else
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = REGV_BRK;
} else if (l == 0 && k == model->cfg_rows*3/4-1) {
} else if (l == 0 && k == model->xci->num_rows*3/4-1) {
model->tiles[(row_top_y+l)*tile_columns + i + 3].flags |= TF_CENTER_MIDBUF;
model->tiles[(row_top_y+l)*tile_columns + i + 3].type = REGV_HCLKBUF_T;
} else if (l == 0 && k == model->cfg_rows/4-1)
} else if (l == 0 && k == model->xci->num_rows/4-1)
model->tiles[(row_top_y+l)*tile_columns + i + 3].type = REGV_MIDBUF_B;
else if (l == 8)
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = (k<model->cfg_rows/2) ? REGV_B : REGV_T;
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = (k<model->xci->num_rows/2) ? REGV_B : REGV_T;
else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i + 3].type = REGV;
}
@ -362,45 +363,45 @@ int init_tiles(struct fpga_model* model)
// left IO
//
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
for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
//
// +0
//
if (model->cfg_left_wiring[(model->cfg_rows-1-k)*16+l] == 'W') {
if (model->xci->left_wiring[(model->xci->num_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
//
if ((k == model->cfg_rows-1 && !l) || (!k && l==15))
if ((k == model->xci->num_rows-1 && !l) || (!k && l==15))
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 1].type = CORNER_TERM_L;
else if (k == model->cfg_rows/2 && l == 12)
else if (k == model->xci->num_rows/2 && l == 12)
model->tiles[(row_top_y+l+1)*tile_columns + 1].type = IO_TERM_L_UPPER_TOP;
else if (k == model->cfg_rows/2 && l == 13)
else if (k == model->xci->num_rows/2 && l == 13)
model->tiles[(row_top_y+l+1)*tile_columns + 1].type = IO_TERM_L_UPPER_BOT;
else if (k == (model->cfg_rows/2)-1 && !l)
else if (k == (model->xci->num_rows/2)-1 && !l)
model->tiles[(row_top_y+l)*tile_columns + 1].type = IO_TERM_L_LOWER_TOP;
else if (k == (model->cfg_rows/2)-1 && l == 1)
else if (k == (model->xci->num_rows/2)-1 && l == 1)
model->tiles[(row_top_y+l)*tile_columns + 1].type = IO_TERM_L_LOWER_BOT;
else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 1].type = IO_TERM_L;
//
// +2
//
if (model->cfg_left_wiring[(model->cfg_rows-1-k)*16+l] == 'W') {
if (l == 15 && k && k != model->cfg_rows/2)
if (model->xci->left_wiring[(model->xci->num_rows-1-k)*16+l] == 'W') {
if (l == 15 && k && k != model->xci->num_rows/2)
model->tiles[(row_top_y+l+1)*tile_columns + 2].type = ROUTING_IO_L_BRK;
else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 2].type = ROUTING_IO_L;
} else { // unwired
if (k && k != model->cfg_rows/2 && l == 15)
if (k && k != model->xci->num_rows/2 && l == 15)
model->tiles[(row_top_y+l+1)*tile_columns + 2].type = ROUTING_BRK;
else if (k == model->cfg_rows/2 && l == 14)
else if (k == model->xci->num_rows/2 && l == 14)
model->tiles[(row_top_y+l+1)*tile_columns + 2].type = ROUTING_GCLK;
else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 2].type = ROUTING;
@ -408,16 +409,16 @@ int init_tiles(struct fpga_model* model)
//
// +3
//
if (model->cfg_left_wiring[(model->cfg_rows-1-k)*16+l] == 'W') {
if (model->xci->left_wiring[(model->xci->num_rows-1-k)*16+l] == 'W') {
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 3].flags |= TF_IOLOGIC_DELAY_DEV;
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 3].type = ROUTING_IO_VIA_L;
} else { // unwired
if (k == model->cfg_rows-1 && !l) {
if (k == model->xci->num_rows-1 && !l) {
model->tiles[(row_top_y+l)*tile_columns + 3].type = CORNER_TL;
} else if (!k && l == 15) {
model->tiles[(row_top_y+l+1)*tile_columns + 3].type = CORNER_BL;
} else {
if (k && k != model->cfg_rows/2 && l == 15)
if (k && k != model->xci->num_rows/2 && l == 15)
model->tiles[(row_top_y+l+1)*tile_columns + 3].type = ROUTING_VIA_CARRY;
else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 3].type = ROUTING_VIA;
@ -426,17 +427,17 @@ int init_tiles(struct fpga_model* model)
}
model->tiles[(row_top_y+8)*tile_columns + 1].type = HCLK_TERM_L;
model->tiles[(row_top_y+8)*tile_columns + 2].type = HCLK_ROUTING_IO_L;
if (k >= model->cfg_rows/2) { // top half
if (k > (model->cfg_rows*3)/4)
if (k >= model->xci->num_rows/2) { // top half
if (k > (model->xci->num_rows*3)/4)
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_TOP_UP_L;
else if (k == (model->cfg_rows*3)/4)
else if (k == (model->xci->num_rows*3)/4)
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_TOP_SPLIT_L;
else
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_TOP_DN_L;
} else { // bottom half
if (k < model->cfg_rows/4 - 1)
if (k < model->xci->num_rows/4 - 1)
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_BOT_DN_L;
else if (k == model->cfg_rows/4 - 1)
else if (k == model->xci->num_rows/4 - 1)
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_BOT_SPLIT_L;
else
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_BOT_UP_L;
@ -465,41 +466,41 @@ int init_tiles(struct fpga_model* model)
// right IO
//
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
for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
//
// -1
//
if (model->cfg_right_wiring[(model->cfg_rows-1-k)*16+l] == 'W')
if (model->xci->right_wiring[(model->xci->num_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)
if (k == model->xci->num_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)
else if (k == model->xci->num_rows/2 && l == 14)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 1].type = IO_PCI_CONN_R;
else if (k == model->cfg_rows/2 && l == 15)
else if (k == model->xci->num_rows/2 && l == 15)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 1].type = IO_PCI_CONN_R;
else if (k == model->cfg_rows/2-1 && !l)
else if (k == model->xci->num_rows/2-1 && !l)
model->tiles[(row_top_y+l)*tile_columns + tile_columns - 1].type = IO_PCI_R;
else {
if (model->cfg_right_wiring[(model->cfg_rows-1-k)*16+l] == 'W')
if (model->xci->right_wiring[(model->xci->num_rows-1-k)*16+l] == 'W')
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 1].type = IO_R;
}
//
// -2
//
if ((k == model->cfg_rows-1 && (!l || l == 1)) || (!k && (l==15 || l==14)))
if ((k == model->xci->num_rows-1 && (!l || l == 1)) || (!k && (l==15 || l==14)))
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 2].type = CORNER_TERM_R;
else if (k == model->cfg_rows/2 && l == 12)
else if (k == model->xci->num_rows/2 && l == 12)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 2].type = IO_TERM_R_UPPER_TOP;
else if (k == model->cfg_rows/2 && l == 13)
else if (k == model->xci->num_rows/2 && l == 13)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 2].type = IO_TERM_R_UPPER_BOT;
else if (k == (model->cfg_rows/2)-1 && !l)
else if (k == (model->xci->num_rows/2)-1 && !l)
model->tiles[(row_top_y+l)*tile_columns + tile_columns - 2].type = IO_TERM_R_LOWER_TOP;
else if (k == (model->cfg_rows/2)-1 && l == 1)
else if (k == (model->xci->num_rows/2)-1 && l == 1)
model->tiles[(row_top_y+l)*tile_columns + tile_columns - 2].type = IO_TERM_R_LOWER_BOT;
else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 2].type = IO_TERM_R;
@ -509,15 +510,15 @@ int init_tiles(struct fpga_model* model)
//
// -4
//
if (model->cfg_right_wiring[(model->cfg_rows-1-k)*16+l] == 'W') {
if (model->xci->right_wiring[(model->xci->num_rows-1-k)*16+l] == 'W') {
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 4].flags |= TF_IOLOGIC_DELAY_DEV;
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 4].type = ROUTING_IO_VIA_R;
} else {
if (k == model->cfg_rows-1 && l == 0)
if (k == model->xci->num_rows-1 && l == 0)
model->tiles[(row_top_y+l)*tile_columns + tile_columns - 4].type = CORNER_TR_UPPER;
else if (k == model->cfg_rows-1 && l == 1)
else if (k == model->xci->num_rows-1 && l == 1)
model->tiles[(row_top_y+l)*tile_columns + tile_columns - 4].type = CORNER_TR_LOWER;
else if (k && k != model->cfg_rows/2 && l == 15)
else if (k && k != model->xci->num_rows/2 && l == 15)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 4].type = ROUTING_VIA_CARRY;
else if (!k && l == 14)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 4].type = CORNER_BR_UPPER;
@ -529,12 +530,12 @@ int init_tiles(struct fpga_model* model)
//
// -5
//
if (model->cfg_right_wiring[(model->cfg_rows-1-k)*16+l] == 'W')
if (model->xci->right_wiring[(model->xci->num_rows-1-k)*16+l] == 'W')
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 5].type = IO_ROUTING;
else {
if (k && k != model->cfg_rows/2 && l == 15)
if (k && k != model->xci->num_rows/2 && l == 15)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 5].type = ROUTING_BRK;
else if (k == model->cfg_rows/2 && l == 14)
else if (k == model->xci->num_rows/2 && l == 14)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 5].type = ROUTING_GCLK;
else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 5].type = ROUTING;
@ -544,17 +545,17 @@ int init_tiles(struct fpga_model* model)
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 3].type = HCLK_MCB;
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 5].type = HCLK_ROUTING_IO_R;
if (k >= model->cfg_rows/2) { // top half
if (k > (model->cfg_rows*3)/4)
if (k >= model->xci->num_rows/2) { // top half
if (k > (model->xci->num_rows*3)/4)
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_TOP_UP_R;
else if (k == (model->cfg_rows*3)/4)
else if (k == (model->xci->num_rows*3)/4)
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_TOP_SPLIT_R;
else
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_TOP_DN_R;
} else { // bottom half
if (k < model->cfg_rows/4 - 1)
if (k < model->xci->num_rows/4 - 1)
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_BOT_DN_R;
else if (k == model->cfg_rows/4 - 1)
else if (k == model->xci->num_rows/4 - 1)
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_BOT_SPLIT_R;
else
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_BOT_UP_R;

View File

@ -54,6 +54,28 @@ struct xc_type2_info
int val;
};
//
// major_str
// 'L' = X+L logic block
// 'M' = X+M logic block
// '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).
//
// left_wiring and right_wiring are described with 16
// characters for each row, order is top-down
// 'W' = wired
// 'U' = unwired
//
struct xc_info
{
int idcode;

View File

@ -14,8 +14,7 @@ int main(int argc, char** argv)
struct fpga_model model;
int no_conns, rc;
if ((rc = fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS,
XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
if ((rc = fpga_build_model(&model, XC6SLX9)))
goto fail;
no_conns = 0;