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(); MEMUSAGE();
printf("O Building memory model...\n"); printf("O Building memory model...\n");
if ((rc = fpga_build_model(&model, XC6SLX9, XC6SLX9_ROWS, if ((rc = fpga_build_model(&model, XC6SLX9)))
XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING)))
goto fail; goto fail;
printf("O Done\n"); printf("O Done\n");
TIME_AND_MEM(); TIME_AND_MEM();

View File

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

View File

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

View File

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

View File

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

View File

@ -15,41 +15,6 @@
#include "helper.h" #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 #define LEFT_SIDE_MAJOR 1
struct fpga_model struct fpga_model
@ -57,9 +22,6 @@ struct fpga_model
int rc; // if rc != 0, all function calls will immediately return int rc; // if rc != 0, all function calls will immediately return
const struct xc_info *xci; 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 x_width, y_height;
int center_x; int center_x;
@ -793,9 +755,7 @@ struct fpga_tile
uint32_t* switches; uint32_t* switches;
}; };
int fpga_build_model(struct fpga_model* model, int fpga_build_model(struct fpga_model* model, int idcode);
int idcode, int fpga_rows, const char* columns,
const char* left_wiring, const char* right_wiring);
// returns model->rc (model itself will be memset to 0) // returns model->rc (model itself will be memset to 0)
int fpga_free_model(struct fpga_model* model); 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; struct w_net gclk_net;
RC_CHECK(model); RC_CHECK(model);
for (row = model->cfg_rows-1; row >= 0; row--) { for (row = model->xci->num_rows-1; row >= 0; row--) {
row_top_y = TOP_IO_TILES + (model->cfg_rows-1-row)*(8+1/* middle of row */+8); row_top_y = TOP_IO_TILES + (model->xci->num_rows-1-row)*(8+1/* middle of row */+8);
if (row < (model->cfg_rows/2)) row_top_y++; // center regs if (row < (model->xci->num_rows/2)) row_top_y++; // center regs
// net that connects the hclk of half the chip together horizontally // net that connects the hclk of half the chip together horizontally
gclk_net.last_inc = 15; 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++) { for (x = 0; x < model->x_width; x++) {
if (is_atx(X_ROUTING_COL, model, x)) { if (is_atx(X_ROUTING_COL, model, x)) {
for (row = model->cfg_rows-1; row >= 0; row--) { for (row = model->xci->num_rows-1; row >= 0; row--) {
row_top_y = 2 /* top IO */ + (model->cfg_rows-1-row)*(8+1/* middle of row */+8); row_top_y = 2 /* top IO */ + (model->xci->num_rows-1-row)*(8+1/* middle of row */+8);
if (row < (model->cfg_rows/2)) row_top_y++; // center regs if (row < (model->xci->num_rows/2)) row_top_y++; // center regs
is_break = 0; is_break = 0;
if (is_atx(X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x)) { 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; is_break = 1;
} else { } else {
if (row) if (row)
@ -3542,7 +3542,7 @@ static int run_logic_inout(struct fpga_model* model)
} }
} }
// LOGICIN // 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; y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs if (y > model->center_y) y++; // central regs

View File

@ -21,7 +21,7 @@ int init_devices(struct fpga_model* model)
RC_CHECK(model); RC_CHECK(model);
// DCM, PLL // 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; y = TOP_IO_TILES + HALF_ROW-1 + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs if (y > model->center_y) y++; // central regs
x = model->center_x-CENTER_CMTPLL_O; x = model->center_x-CENTER_CMTPLL_O;
@ -132,7 +132,7 @@ int init_devices(struct fpga_model* model)
} }
// BUFH // 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; y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs if (y > model->center_y) y++; // central regs
x = model->center_x; 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 // calculate distance to center and check
// that y is not pointing to the center // 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) return;
if (y > dist_to_center) y--; if (y > dist_to_center) y--;
// check that y is not pointing past the last row // 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); if (row_pos) *row_pos = y%(8+1+8);
} }

View File

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

View File

@ -7,6 +7,7 @@
#include <stdarg.h> #include <stdarg.h>
#include "model.h" #include "model.h"
#include "parts.h"
int init_tiles(struct fpga_model* model) int init_tiles(struct fpga_model* model)
{ {
@ -16,14 +17,14 @@ int init_tiles(struct fpga_model* model)
struct fpga_tile* tile_i0; struct fpga_tile* tile_i0;
RC_CHECK(model); 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; tile_columns = LEFT_SIDE_WIDTH + RIGHT_SIDE_WIDTH;
for (i = 0; model->cfg_columns[i] != 0; i++) { for (i = 0; model->xci->major_str[i] != 0; i++) {
if (model->cfg_columns[i] == 'L' || model->cfg_columns[i] == 'M') if (model->xci->major_str[i] == 'L' || model->xci->major_str[i] == 'M')
tile_columns += 2; // 2 for logic blocks L/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 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 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)); 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; model->tiles[i].type = NA;
if (!(tile_rows % 2)) if (!(tile_rows % 2))
fprintf(stderr, "Unexpected even number of tile rows (%i).\n", tile_rows); 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: // top, bottom, center:
@ -55,15 +56,15 @@ int init_tiles(struct fpga_model* model)
model->x_major[i] = LEFT_SIDE_MAJOR; model->x_major[i] = LEFT_SIDE_MAJOR;
cur_major = LEFT_SIDE_MAJOR+1; cur_major = LEFT_SIDE_MAJOR+1;
// i is now LEFT_SIDE_WIDTH (5) // i is now LEFT_SIDE_WIDTH (5)
for (j = 0; model->cfg_columns[j]; j++) { for (j = 0; model->xci->major_str[j]; j++) {
cur_cfgcol = model->cfg_columns[j]; cur_cfgcol = model->xci->major_str[j];
switch (cur_cfgcol) { switch (cur_cfgcol) {
case 'L': case 'L':
case 'l': case 'l':
case 'M': case 'M':
case 'm': case 'm':
no_io = (next_non_whitespace(&model->cfg_columns[j+1]) == 'n'); no_io = (next_non_whitespace(&model->xci->major_str[j+1]) == 'n');
last_col = last_major(model->cfg_columns, j); last_col = last_major(model->xci->major_str, j);
model->tiles[i].flags |= TF_FABRIC_ROUTING_COL; model->tiles[i].flags |= TF_FABRIC_ROUTING_COL;
if (no_io) model->tiles[i].flags |= TF_ROUTING_NO_IO; 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') (cur_cfgcol == 'L' || cur_cfgcol == 'l')
? TF_FABRIC_LOGIC_XL_COL ? TF_FABRIC_LOGIC_XL_COL
: TF_FABRIC_LOGIC_XM_COL; : TF_FABRIC_LOGIC_XM_COL;
for (k = model->cfg_rows-1; k >= 0; k--) { for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8); row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles (center row) if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles (center row)
start = ((k == model->cfg_rows-1 && !no_io) ? 2 : 0); start = ((k == model->xci->num_rows-1 && !no_io) ? 2 : 0);
end = ((k == 0 && !no_io) ? 14 : 16); end = ((k == 0 && !no_io) ? 14 : 16);
for (l = start; l < end; l++) { for (l = start; l < end; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i]; 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; break;
case 'B': 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) if (left_side)
model->left_gclk_sep_x = i+2; model->left_gclk_sep_x = i+2;
else 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].flags |= TF_ROUTING_NO_IO; // no_io always on for BRAM
model->tiles[i+1].flags |= TF_FABRIC_BRAM_VIA_COL; model->tiles[i+1].flags |= TF_FABRIC_BRAM_VIA_COL;
model->tiles[i+2].flags |= TF_FABRIC_BRAM_COL; model->tiles[i+2].flags |= TF_FABRIC_BRAM_COL;
for (k = model->cfg_rows-1; k >= 0; k--) { for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8); row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) { for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i]; tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
if (l < 15) 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].flags |= TF_ROUTING_NO_IO; // no_io always on for MACC
model->tiles[i+1].flags |= TF_FABRIC_MACC_VIA_COL; model->tiles[i+1].flags |= TF_FABRIC_MACC_VIA_COL;
model->tiles[i+2].flags |= TF_FABRIC_MACC_COL; model->tiles[i+2].flags |= TF_FABRIC_MACC_COL;
for (k = model->cfg_rows-1; k >= 0; k--) { for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8); row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) { for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i]; tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
if (l < 15) if (l < 15)
@ -241,22 +242,22 @@ int init_tiles(struct fpga_model* model)
break; break;
case 'R': 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 // We expect a LOGIC_XM column to follow the center for
// the top and bottom bufpll and reg routing. // 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; model->center_x = i+3;
left_side = 0; left_side = 0;
for (k = model->cfg_rows-1; k >= 0; k--) { for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8); row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) { for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i]; 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) if (l < 15)
tile_i0->type = ROUTING; tile_i0->type = ROUTING;
else else
@ -265,7 +266,7 @@ int init_tiles(struct fpga_model* model)
tile_i0[1].type = ROUTING_VIA_IO; tile_i0[1].type = ROUTING_VIA_IO;
else if (l == 8) else if (l == 8)
tile_i0[1].type = (k%2) ? ROUTING_VIA_CARRY : ROUTING_VIA_IO_DCM; 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; tile_i0[1].type = ROUTING_VIA_REGC;
else { else {
tile_i0[1].type = LOGIC_XL; tile_i0[1].type = LOGIC_XL;
@ -280,28 +281,28 @@ int init_tiles(struct fpga_model* model)
if (l == 7) { if (l == 7) {
if (k%2) { // odd 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].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 } 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].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 // four midbuf tiles, in the middle of the top and bottom halves
if (l == 15) { 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; 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].flags |= TF_CENTER_MIDBUF;
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = REGV_HCLKBUF_B; model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = REGV_HCLKBUF_B;
} else } else
model->tiles[(row_top_y+l+1)*tile_columns + i + 3].type = REGV_BRK; 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].flags |= TF_CENTER_MIDBUF;
model->tiles[(row_top_y+l)*tile_columns + i + 3].type = REGV_HCLKBUF_T; 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; model->tiles[(row_top_y+l)*tile_columns + i + 3].type = REGV_MIDBUF_B;
else if (l == 8) 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 else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i + 3].type = REGV; 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 // left IO
// //
for (k = model->cfg_rows-1; k >= 0; k--) { for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8); row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) { for (l = 0; l < 16; l++) {
// //
// +0 // +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].flags |= TF_WIRED;
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns].type = IO_L; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns].type = IO_L;
} }
// //
// +1 // +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; 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; 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; 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; 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; model->tiles[(row_top_y+l)*tile_columns + 1].type = IO_TERM_L_LOWER_BOT;
else else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 1].type = IO_TERM_L; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 1].type = IO_TERM_L;
// //
// +2 // +2
// //
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') {
if (l == 15 && k && k != model->cfg_rows/2) 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; model->tiles[(row_top_y+l+1)*tile_columns + 2].type = ROUTING_IO_L_BRK;
else else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 2].type = ROUTING_IO_L; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 2].type = ROUTING_IO_L;
} else { // unwired } 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; 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; model->tiles[(row_top_y+l+1)*tile_columns + 2].type = ROUTING_GCLK;
else else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 2].type = ROUTING; 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 // +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].flags |= TF_IOLOGIC_DELAY_DEV;
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 3].type = ROUTING_IO_VIA_L; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 3].type = ROUTING_IO_VIA_L;
} else { // unwired } 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; model->tiles[(row_top_y+l)*tile_columns + 3].type = CORNER_TL;
} else if (!k && l == 15) { } else if (!k && l == 15) {
model->tiles[(row_top_y+l+1)*tile_columns + 3].type = CORNER_BL; model->tiles[(row_top_y+l+1)*tile_columns + 3].type = CORNER_BL;
} else { } 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; model->tiles[(row_top_y+l+1)*tile_columns + 3].type = ROUTING_VIA_CARRY;
else else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + 3].type = ROUTING_VIA; 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 + 1].type = HCLK_TERM_L;
model->tiles[(row_top_y+8)*tile_columns + 2].type = HCLK_ROUTING_IO_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->xci->num_rows/2) { // top half
if (k > (model->cfg_rows*3)/4) if (k > (model->xci->num_rows*3)/4)
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_TOP_UP_L; 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; model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_TOP_SPLIT_L;
else else
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_TOP_DN_L; model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_TOP_DN_L;
} else { // bottom half } 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; 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; model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_BOT_SPLIT_L;
else else
model->tiles[(row_top_y+8)*tile_columns + 3].type = HCLK_IO_BOT_UP_L; 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 // right IO
// //
for (k = model->cfg_rows-1; k >= 0; k--) { for (k = model->xci->num_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8); row_top_y = 2 /* top IO tiles */ + (model->xci->num_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles if (k<(model->xci->num_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) { for (l = 0; l < 16; l++) {
// //
// -1 // -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; 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; 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; 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; 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; model->tiles[(row_top_y+l)*tile_columns + tile_columns - 1].type = IO_PCI_R;
else { 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; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 1].type = IO_R;
} }
// //
// -2 // -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; 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; 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; 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; 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; model->tiles[(row_top_y+l)*tile_columns + tile_columns - 2].type = IO_TERM_R_LOWER_BOT;
else else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 2].type = IO_TERM_R; 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 // -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].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; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 4].type = ROUTING_IO_VIA_R;
} else { } 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; 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; 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; model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 4].type = ROUTING_VIA_CARRY;
else if (!k && l == 14) else if (!k && l == 14)
model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 4].type = CORNER_BR_UPPER; 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 // -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; model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 5].type = IO_ROUTING;
else { 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; 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; model->tiles[(row_top_y+l+1)*tile_columns + tile_columns - 5].type = ROUTING_GCLK;
else else
model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + tile_columns - 5].type = ROUTING; 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 - 3].type = HCLK_MCB;
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 5].type = HCLK_ROUTING_IO_R; 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->xci->num_rows/2) { // top half
if (k > (model->cfg_rows*3)/4) 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; 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; model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_TOP_SPLIT_R;
else else
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_TOP_DN_R; model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_TOP_DN_R;
} else { // bottom half } 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; 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; model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_BOT_SPLIT_R;
else else
model->tiles[(row_top_y+8)*tile_columns + tile_columns - 4].type = HCLK_IO_BOT_UP_R; 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; 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 struct xc_info
{ {
int idcode; int idcode;

View File

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